* Re: [PATCHv3 5/7] Add approval request for incoming pairing requests with OOB mechanism
From: Johan Hedberg @ 2010-11-16 16:24 UTC (permalink / raw)
To: Szymon Janc; +Cc: linux-bluetooth, marcel
In-Reply-To: <1289922247-20712-6-git-send-email-szymon.janc@tieto.com>
Hi Szymon,
On Tue, Nov 16, 2010, Szymon Janc wrote:
> + if (!device_has_oob_data(device)
> + || btd_event_user_approve(&BDADDR(index), dba))
That should be:
if (!device_has_oob_data(device) ||
btd_event_user_approve(&BDADDR(index), dba) < 0)
Otherwise it looks like btd_event_user_approve might return a boolean.
> + req->msg = dbus_message_new_method_call(agent->name, agent->path,
> + "org.bluez.Agent", "RequestApproval");
I think the name of this method is one of the more important things to
get right before we push this upstream. I'm not so sure of the current
proposal. I have a feeling that it'd be a good idea to have the term
"pair" somewhere explicitly in the name. How about "RequestPairing"? I
know Marcel will have something to say about this too.
Johan
^ permalink raw reply
* Re: [PATCHv3 1/7] Add support for Out of Band (OOB) association model.
From: Johan Hedberg @ 2010-11-16 16:16 UTC (permalink / raw)
To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1289922247-20712-2-git-send-email-szymon.janc@tieto.com>
Hi Szymon,
On Tue, Nov 16, 2010, Szymon Janc wrote:
> +gboolean device_get_oob_data(struct btd_device *device, uint8_t *hash,
> + uint8_t *randomizer)
Looks like the continuation line should be indented a bit more. Basicly
indent at least past the ( on the above line and as much as possible as
long as the entire line stays under 79 columns. I think I saw other
places with the same issue so please fix those too.
> +void device_set_oob_data(struct btd_device *device, uint8_t *hash,
> + uint8_t *randomizer);
> +gboolean device_get_oob_data(struct btd_device *device, uint8_t *hash,
> + uint8_t *randomizer);
> +gboolean device_has_oob_data(struct btd_device *device);
I suppose you could just use get_oob_data(dev, NULL, NULL) instead of
having a separate has_oob_data function.
> +gboolean device_request_oob_data(struct btd_device *device, void *cb);
Why is the callback type void* instead of having a well defined
signature?
> +void device_set_local_auth_cap(struct btd_device *device, uint8_t auth,
> + uint8_t cap);
> +void device_get_local_auth_cap(struct btd_device *device, uint8_t *auth,
> + uint8_t *cap);
This local_cap/auth in struct device had me wondering a little bit since
it felt like that should actually be in struct adapter, however this is
really per adapter-device pair data in which case it should be fine,
right?
> +static void btd_event_io_cap_reply(struct btd_device *device)
> +{
> + io_capability_reply_cp cp;
> + int dev;
> + struct btd_adapter *adapter = device_get_adapter(device);
> + uint16_t dev_id = adapter_get_dev_id(adapter);
> +
> + dev = hci_open_dev(dev_id);
That's a no no. Only hciops should use raw HCI sockets anymore. If you
need to do something like this you'll need to add a new adapter_ops
callback and send your HCI command through that.
> {
> struct btd_adapter *adapter;
> struct btd_device *device;
> struct agent *agent = NULL;
> uint8_t agent_cap;
> int err;
> + uint8_t cap;
> + uint8_t auth;
These can be on the same line.
> + if (!plugin || !plugin->local_data_read|| !plugin->plugin_deactivated
> + || !plugin->request_remote_data
> + || active_plugin == plugin)
> + return;
When you split lines the break should be after || && etc. In this case
you could also consider splitting this up into multiple if-statements
for better readability.
Johan
^ permalink raw reply
* [PATCHv3 7/7] simple-agent - add RequestApproval method for OOB pairing
From: Szymon Janc @ 2010-11-16 15:44 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1289922247-20712-1-git-send-email-szymon.janc@tieto.com>
---
test/simple-agent | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/test/simple-agent b/test/simple-agent
index f2cc3dd..43f03fe 100755
--- a/test/simple-agent
+++ b/test/simple-agent
@@ -69,6 +69,16 @@ class Agent(dbus.service.Object):
raise Rejected("Mode change by user")
@dbus.service.method("org.bluez.Agent",
+ in_signature="o", out_signature="")
+
+ def RequestApproval(self, device):
+ print "RequestApproval (%s)" % (device)
+ approve = raw_input("Approve pairing (yes/no): ")
+ if (approve == "yes"):
+ return
+ raise Rejected("Not approved")
+
+ @dbus.service.method("org.bluez.Agent",
in_signature="", out_signature="")
def Cancel(self):
print "Cancel"
--
1.7.1
^ permalink raw reply related
* [PATCHv3 6/7] Update DBus OOB API with RequestApproval method.
From: Szymon Janc @ 2010-11-16 15:44 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1289922247-20712-1-git-send-email-szymon.janc@tieto.com>
---
doc/oob-api.txt | 14 ++++++++++++++
1 files changed, 14 insertions(+), 0 deletions(-)
diff --git a/doc/oob-api.txt b/doc/oob-api.txt
index 051b868..3a89f59 100644
--- a/doc/oob-api.txt
+++ b/doc/oob-api.txt
@@ -62,3 +62,17 @@ Methods void RegisterProvider(object provider)
Possible errors: org.bluez.Error.ReadFailed
org.bluez.Error.NoProvider
org.bluez.Error.InProgress
+
+--------------------------------------------------------------------------------
+
+Service unique name
+Interface org.bluez.Agent
+Object path freely definable
+
+Methods void RequestApproval(object device)
+
+ This method gets called when the service daemon
+ needs to confirm incoming OOB pairing request.
+
+ Possible errors: org.bluez.Error.Rejected
+ org.bluez.Error.Canceled
--
1.7.1
^ permalink raw reply related
* [PATCHv3 5/7] Add approval request for incoming pairing requests with OOB mechanism
From: Szymon Janc @ 2010-11-16 15:44 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1289922247-20712-1-git-send-email-szymon.janc@tieto.com>
---
plugins/hciops.c | 42 ++++++++++++++++++++++++++++++--------
src/adapter.c | 7 ++++++
src/adapter.h | 3 ++
src/agent.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
src/agent.h | 3 ++
src/device.c | 22 ++++++++++++++++++++
src/device.h | 1 +
src/event.c | 41 +++++++++++++++++++++++++++++++++++++
src/event.h | 1 +
9 files changed, 169 insertions(+), 10 deletions(-)
diff --git a/plugins/hciops.c b/plugins/hciops.c
index 75e6b0c..9546874 100644
--- a/plugins/hciops.c
+++ b/plugins/hciops.c
@@ -520,15 +520,8 @@ static void remote_oob_data_request(int index, void *ptr)
adapter = manager_find_adapter(&BDADDR(index));
device = adapter_find_device(adapter, da);
- if (device_has_oob_data(device)) {
- remote_oob_data_reply_cp cp;
-
- bacpy(&cp.bdaddr, dba);
- device_get_oob_data(device,cp.hash,cp.randomizer);
-
- hci_send_cmd(SK(index), OGF_LINK_CTL, OCF_REMOTE_OOB_DATA_REPLY,
- REMOTE_OOB_DATA_REPLY_CP_SIZE, &cp);
- } else
+ if (!device_has_oob_data(device)
+ || btd_event_user_approve(&BDADDR(index), dba))
hci_send_cmd(SK(index),
OGF_LINK_CTL, OCF_REMOTE_OOB_DATA_NEG_REPLY, 6,
ptr);
@@ -2217,6 +2210,36 @@ static int hciops_passkey_reply(int index, bdaddr_t *bdaddr, uint32_t passkey)
return err;
}
+static int hciops_approve_reply(int index, bdaddr_t *bdaddr, gboolean approved)
+{
+ int err;
+ struct btd_adapter *adapter;
+ struct btd_device *device;
+ char da[18];
+
+ ba2str(bdaddr, da);
+ adapter = manager_find_adapter_by_id(index);
+ device = adapter_find_device(adapter, da);
+
+ if (approved) {
+ remote_oob_data_reply_cp cp;
+
+ bacpy(&cp.bdaddr, bdaddr);
+ device_get_oob_data(device,cp.hash,cp.randomizer);
+
+ err = hci_send_cmd(SK(index), OGF_LINK_CTL,
+ OCF_REMOTE_OOB_DATA_REPLY,
+ REMOTE_OOB_DATA_REPLY_CP_SIZE, &cp);
+ } else
+ err = hci_send_cmd(SK(index), OGF_LINK_CTL,
+ OCF_REMOTE_OOB_DATA_NEG_REPLY, 6, bdaddr);
+
+ if (err < 0)
+ err = -errno;
+
+ return err;
+}
+
static int hciops_get_auth_info(int index, bdaddr_t *bdaddr, uint8_t *auth)
{
struct hci_auth_info_req req;
@@ -2365,6 +2388,7 @@ static struct btd_adapter_ops hci_ops = {
.pincode_reply = hciops_pincode_reply,
.confirm_reply = hciops_confirm_reply,
.passkey_reply = hciops_passkey_reply,
+ .approve_reply = hciops_approve_reply,
.get_auth_info = hciops_get_auth_info,
.read_scan_enable = hciops_read_scan_enable,
.read_ssp_mode = hciops_read_ssp_mode,
diff --git a/src/adapter.c b/src/adapter.c
index 39a6514..ab680f3 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -3692,6 +3692,13 @@ int btd_adapter_passkey_reply(struct btd_adapter *adapter, bdaddr_t *bdaddr,
return adapter_ops->passkey_reply(adapter->dev_id, bdaddr, passkey);
}
+int btd_adapter_approve_reply(struct btd_adapter *adapter, bdaddr_t *bdaddr,
+ gboolean success)
+{
+ DBG("reply %u", success);
+ return adapter_ops->approve_reply(adapter->dev_id, bdaddr, success);
+}
+
int btd_adapter_get_auth_info(struct btd_adapter *adapter, bdaddr_t *bdaddr,
uint8_t *auth)
{
diff --git a/src/adapter.h b/src/adapter.h
index cc62865..cf66129 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -221,6 +221,7 @@ struct btd_adapter_ops {
int (*pincode_reply) (int index, bdaddr_t *bdaddr, const char *pin);
int (*confirm_reply) (int index, bdaddr_t *bdaddr, gboolean success);
int (*passkey_reply) (int index, bdaddr_t *bdaddr, uint32_t passkey);
+ int (*approve_reply) (int index, bdaddr_t *bdaddr, gboolean success);
int (*get_auth_info) (int index, bdaddr_t *bdaddr, uint8_t *auth);
int (*read_scan_enable) (int index);
int (*read_ssp_mode) (int index);
@@ -272,6 +273,8 @@ int btd_adapter_confirm_reply(struct btd_adapter *adapter, bdaddr_t *bdaddr,
gboolean success);
int btd_adapter_passkey_reply(struct btd_adapter *adapter, bdaddr_t *bdaddr,
uint32_t passkey);
+int btd_adapter_approve_reply(struct btd_adapter *adapter, bdaddr_t *bdaddr,
+ gboolean success);
int btd_adapter_get_auth_info(struct btd_adapter *adapter, bdaddr_t *bdaddr,
uint8_t *auth);
diff --git a/src/agent.c b/src/agent.c
index 2ddfd6e..a4b26b6 100644
--- a/src/agent.c
+++ b/src/agent.c
@@ -55,7 +55,8 @@ typedef enum {
AGENT_REQUEST_CONFIRMATION,
AGENT_REQUEST_PINCODE,
AGENT_REQUEST_AUTHORIZE,
- AGENT_REQUEST_CONFIRM_MODE
+ AGENT_REQUEST_CONFIRM_MODE,
+ AGENT_REQUEST_APPROVAL
} agent_request_type_t;
struct agent {
@@ -693,6 +694,62 @@ failed:
return err;
}
+static int approval_request_new(struct agent_request *req,
+ const char *device_path)
+{
+ struct agent *agent = req->agent;
+
+ req->msg = dbus_message_new_method_call(agent->name, agent->path,
+ "org.bluez.Agent", "RequestApproval");
+ if (req->msg == NULL) {
+ error("Couldn't allocate D-Bus message");
+ return -ENOMEM;
+ }
+
+ dbus_message_append_args(req->msg,
+ DBUS_TYPE_OBJECT_PATH, &device_path,
+ DBUS_TYPE_INVALID);
+
+ if (dbus_connection_send_with_reply(connection, req->msg,
+ &req->call, REQUEST_TIMEOUT) == FALSE) {
+ error("D-Bus send failed");
+ return -EIO;
+ }
+
+ dbus_pending_call_set_notify(req->call, simple_agent_reply, req, NULL);
+
+ return 0;
+}
+
+int agent_request_approval (struct agent *agent, struct btd_device *device,
+ agent_cb cb, void *user_data, GDestroyNotify destroy)
+{
+ struct agent_request *req;
+ const gchar *dev_path = device_get_path(device);
+ int err;
+
+ if (agent->request)
+ return -EBUSY;
+
+ DBG("Calling Agent.RequestApproval: name=%s, path=%s", agent->name,
+ agent->path);
+
+ req = agent_request_new(agent, AGENT_REQUEST_APPROVAL, cb,
+ user_data, destroy);
+
+ err = approval_request_new(req, dev_path);
+ if (err < 0)
+ goto failed;
+
+ agent->request = req;
+
+ return 0;
+
+failed:
+ agent_request_free(req, FALSE);
+ return err;
+}
+
static int request_fallback(struct agent_request *req,
DBusPendingCallNotifyFunction function)
{
diff --git a/src/agent.h b/src/agent.h
index e184250..73dd531 100644
--- a/src/agent.h
+++ b/src/agent.h
@@ -64,6 +64,9 @@ int agent_request_confirmation(struct agent *agent, struct btd_device *device,
int agent_display_passkey(struct agent *agent, struct btd_device *device,
uint32_t passkey);
+int agent_request_approval (struct agent *agent, struct btd_device *device,
+ agent_cb cb, void *user_data, GDestroyNotify destroy);
+
int agent_cancel(struct agent *agent);
gboolean agent_is_busy(struct agent *agent, void *user_data);
diff --git a/src/device.c b/src/device.c
index 24fd44d..a507fe8 100644
--- a/src/device.c
+++ b/src/device.c
@@ -2245,6 +2245,21 @@ static void passkey_cb(struct agent *agent, DBusError *err,
device->authr->agent = NULL;
}
+static void approve_cb(struct agent *agent, DBusError *err, void *data)
+{
+ struct authentication_req *auth = data;
+ struct btd_device *device = auth->device;
+
+ /* No need to reply anything if the authentication already failed */
+ if (auth->cb == NULL)
+ return;
+
+ ((agent_cb) auth->cb)(agent, err, device);
+
+ device->authr->cb = NULL;
+ device->authr->agent = NULL;
+}
+
int device_request_authentication(struct btd_device *device, auth_type_t type,
uint32_t passkey, void *cb)
{
@@ -2283,6 +2298,10 @@ int device_request_authentication(struct btd_device *device, auth_type_t type,
case AUTH_TYPE_NOTIFY:
err = agent_display_passkey(agent, device, passkey);
break;
+ case AUTH_TYPE_APPROVE:
+ err = agent_request_approval (agent, device, approve_cb, auth,
+ NULL);
+ break;
case AUTH_TYPE_AUTO:
err = 0;
break;
@@ -2324,6 +2343,9 @@ static void cancel_authentication(struct authentication_req *auth)
case AUTH_TYPE_PASSKEY:
((agent_passkey_cb) auth->cb)(agent, &err, 0, device);
break;
+ case AUTH_TYPE_APPROVE:
+ ((agent_cb) auth->cb)(agent, &err, device);
+ break;
case AUTH_TYPE_NOTIFY:
case AUTH_TYPE_AUTO:
/* User Notify/Auto doesn't require any reply */
diff --git a/src/device.h b/src/device.h
index b62cdc5..2da3311 100644
--- a/src/device.h
+++ b/src/device.h
@@ -33,6 +33,7 @@ typedef enum {
AUTH_TYPE_CONFIRM,
AUTH_TYPE_NOTIFY,
AUTH_TYPE_AUTO,
+ AUTH_TYPE_APPROVE
} auth_type_t;
struct btd_device *device_create(DBusConnection *conn, struct btd_adapter *adapter,
diff --git a/src/event.c b/src/event.c
index 5a5a288..957a17d 100644
--- a/src/event.c
+++ b/src/event.c
@@ -175,6 +175,18 @@ static void passkey_cb(struct agent *agent, DBusError *err, uint32_t passkey,
btd_adapter_passkey_reply(adapter, &bdaddr, passkey);
}
+static void approve_cb(struct agent *agent, DBusError *err, void *user_data)
+{
+ struct btd_device *device = user_data;
+ struct btd_adapter *adapter = device_get_adapter(device);
+ bdaddr_t bdaddr;
+ gboolean approve = (err == NULL) ? TRUE : FALSE;
+
+ device_get_address(device, &bdaddr);
+
+ btd_adapter_approve_reply(adapter, &bdaddr, approve);
+}
+
int btd_event_user_confirm(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey)
{
struct btd_adapter *adapter;
@@ -264,6 +276,35 @@ int btd_event_user_notify(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey)
passkey, NULL);
}
+int btd_event_user_approve(bdaddr_t *sba, bdaddr_t *dba)
+{
+ struct btd_adapter *adapter;
+ struct btd_device *device;
+ struct agent *agent;
+ uint8_t cap;
+
+ if (!get_adapter_and_device(sba, dba, &adapter, &device, TRUE))
+ return -ENODEV;
+
+ agent = device_get_agent(device);
+ if (!agent)
+ return -ENODEV;
+
+ cap = agent_get_io_capability(agent);
+
+ /* If initiator or agent has no input capability approve immediately. */
+ if (device_is_bonding(device, NULL) || cap == 0x00 || cap == 0x03) {
+ bdaddr_t bdaddr;
+
+ device_get_address(device, &bdaddr);
+ btd_adapter_approve_reply(adapter, &bdaddr, TRUE);
+ return 0;
+ }
+
+ return device_request_authentication(device, AUTH_TYPE_APPROVE, 0,
+ approve_cb);
+}
+
void btd_event_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer,
uint8_t status)
{
diff --git a/src/event.h b/src/event.h
index a3e7dda..c1ea2ef 100644
--- a/src/event.h
+++ b/src/event.h
@@ -42,6 +42,7 @@ int btd_event_set_io_cap(bdaddr_t *local, bdaddr_t *remote,
int btd_event_user_confirm(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey);
int btd_event_user_passkey(bdaddr_t *sba, bdaddr_t *dba);
int btd_event_user_notify(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey);
+int btd_event_user_approve(bdaddr_t *sba, bdaddr_t *dba);
int btd_event_link_key_notify(bdaddr_t *local, bdaddr_t *peer,
uint8_t *key, uint8_t key_type,
int pin_length, uint8_t old_key_type);
--
1.7.1
^ permalink raw reply related
* [PATCHv3 4/7] Add simple-oobprovider for testing.
From: Szymon Janc @ 2010-11-16 15:44 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1289922247-20712-1-git-send-email-szymon.janc@tieto.com>
---
test/simple-oobprovider | 61 +++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 61 insertions(+), 0 deletions(-)
create mode 100755 test/simple-oobprovider
diff --git a/test/simple-oobprovider b/test/simple-oobprovider
new file mode 100755
index 0000000..4a1ebd8
--- /dev/null
+++ b/test/simple-oobprovider
@@ -0,0 +1,61 @@
+#!/usr/bin/python
+# Copyright (C) 2010 ST-Ericsson SA
+# Author: Szymon Janc <szymon.janc@tieto.com> for ST-Ericsson
+
+import gobject
+
+import sys
+import dbus
+import dbus.service
+import dbus.mainloop.glib
+
+class NoOobData(dbus.DBusException):
+ _dbus_error_name = "org.bluez.Error.NoData"
+
+
+class Provider(dbus.service.Object):
+
+ remotedata = None
+
+ @dbus.service.method("org.bluez.OOB",
+ in_signature="s", out_signature="ayay")
+
+ def RequestRemoteOobData(self, device):
+ print "RequestRemoteOobData for %s" % (device)
+ if (self.remotedata != None):
+ return self.remotedata
+ raise NoOobData("No OOB data present")
+
+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")
+
+ adapter_path = manager.DefaultAdapter()
+ adapter = dbus.Interface(bus.get_object("org.bluez",
+ adapter_path), "org.bluez.Adapter")
+
+ oob = dbus.Interface(bus.get_object("org.bluez", "/org/bluez"),
+ "org.bluez.OOB")
+
+ path = "/test/oobprovider"
+ provider = Provider(bus, path)
+
+ mainloop = gobject.MainLoop()
+
+ oob.RegisterProvider(path)
+
+ print "Local data for %s:" % (adapter_path)
+ print oob.ReadLocalOobData(adapter_path)
+
+ provider.remotedata = input("Provide remote data (in python syntax):\n")
+
+ print "You may try pairing now"
+
+ mainloop.run()
+
+ #adapter.UnregisterProvider(path)
+ #print "Provider unregistered"
--
1.7.1
^ permalink raw reply related
* [PATCHv3 3/7] Add DBus OOB API documentation.
From: Szymon Janc @ 2010-11-16 15:44 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1289922247-20712-1-git-send-email-szymon.janc@tieto.com>
---
Makefile.am | 2 +-
doc/oob-api.txt | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 65 insertions(+), 1 deletions(-)
create mode 100644 doc/oob-api.txt
diff --git a/Makefile.am b/Makefile.am
index 1f8f7fb..9098084 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -358,7 +358,7 @@ EXTRA_DIST += doc/manager-api.txt \
doc/service-api.txt doc/agent-api.txt doc/attribute-api.txt \
doc/serial-api.txt doc/network-api.txt \
doc/input-api.txt doc/audio-api.txt doc/control-api.txt \
- doc/hfp-api.txt doc/assigned-numbers.txt
+ doc/hfp-api.txt doc/assigned-numbers.txt doc/oob-api.txt
AM_YFLAGS = -d
diff --git a/doc/oob-api.txt b/doc/oob-api.txt
new file mode 100644
index 0000000..051b868
--- /dev/null
+++ b/doc/oob-api.txt
@@ -0,0 +1,64 @@
+BlueZ D-Bus OOB API description
+*******************************
+
+Copyright (C) 2010 ST-Ericsson SA
+
+Author: Szymon Janc <szymon.janc@tieto.com> for ST-Ericsson
+
+OOB hierarchy
+=================
+
+Service unique name
+Interface org.bluez.OOB
+Object path freely definable
+
+Methods array{byte} hash, array{byte} randomizer
+ RequestRemoteOobData(object device)
+
+ This method gets called when the service daemon needs to
+ get device's hash and randomizer for an OOB
+ authentication. Each array should be 16 bytes long.
+
+ Possible errors: org.bluez.Error.NoData
+
+ void Release()
+
+ This method gets called when DBus plug-in for OOB was
+ deactivated. There is no need to unregister provider,
+ because when this method gets called it has already been
+ unregistered.
+
+--------------------------------------------------------------------------------
+
+Service org.bluez
+Interface org.bluez.OOB
+Object path /org/bluez
+
+Methods void RegisterProvider(object provider)
+
+ This method registers provider for DBus OOB plug-in.
+ When provider is successfully registered plug-in becomes
+ active. Only one provider can be registered at time.
+
+ Possible errors: org.bluez.Error.AlreadyExists
+
+ void UnregisterProvider(object provider)
+
+ This method unregisters provider for DBus OOB plug-in.
+
+ Possible errors: org.bluez.Error.DoesNotExist
+
+
+ array{byte} hash, array{byte} randomizer
+ ReadLocalOobData(object adapter)
+
+ This method reads local OOB data for adapter. Return
+ value is pair of arrays 16 bytes each. Only registered
+ provider should call this method.
+
+ Note: This method will generate and return new local
+ OOB data.
+
+ Possible errors: org.bluez.Error.ReadFailed
+ org.bluez.Error.NoProvider
+ org.bluez.Error.InProgress
--
1.7.1
^ permalink raw reply related
* [PATCHv3 2/7] Add DBus OOB plugin.
From: Szymon Janc @ 2010-11-16 15:44 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1289922247-20712-1-git-send-email-szymon.janc@tieto.com>
---
Makefile.am | 5 +
acinclude.m4 | 6 +
plugins/dbusoob.c | 353 +++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 364 insertions(+), 0 deletions(-)
create mode 100644 plugins/dbusoob.c
diff --git a/Makefile.am b/Makefile.am
index a61e754..1f8f7fb 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -216,6 +216,11 @@ builtin_modules += maemo6
builtin_sources += plugins/maemo6.c
endif
+if DBUSOOBPLUGIN
+builtin_modules += dbusoob
+builtin_sources += plugins/dbusoob.c
+endif
+
sbin_PROGRAMS += src/bluetoothd
src_bluetoothd_SOURCES = $(gdbus_sources) $(builtin_sources) \
diff --git a/acinclude.m4 b/acinclude.m4
index 287f07d..a52d063 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -193,6 +193,7 @@ AC_DEFUN([AC_ARG_BLUEZ], [
configfiles_enable=yes
telephony_driver=dummy
maemo6_enable=no
+ dbusoob_enable=no
AC_ARG_ENABLE(optimization, AC_HELP_STRING([--disable-optimization], [disable code optimization]), [
optimization_enable=${enableval}
@@ -316,6 +317,10 @@ AC_DEFUN([AC_ARG_BLUEZ], [
maemo6_enable=${enableval}
])
+ AC_ARG_ENABLE(dbusoob, AC_HELP_STRING([--enable-dbusoob], [compile with DBUS OOB plugin]), [
+ dbusoob_enable=${enableval}
+ ])
+
AC_ARG_ENABLE(hal, AC_HELP_STRING([--enable-hal], [Use HAL to determine adapter class]), [
hal_enable=${enableval}
])
@@ -372,4 +377,5 @@ AC_DEFUN([AC_ARG_BLUEZ], [
AM_CONDITIONAL(UDEVRULES, test "${udevrules_enable}" = "yes")
AM_CONDITIONAL(CONFIGFILES, test "${configfiles_enable}" = "yes")
AM_CONDITIONAL(MAEMO6PLUGIN, test "${maemo6_enable}" = "yes")
+ AM_CONDITIONAL(DBUSOOBPLUGIN, test "${dbusoob_enable}" = "yes")
])
diff --git a/plugins/dbusoob.c b/plugins/dbusoob.c
new file mode 100644
index 0000000..f347ef6
--- /dev/null
+++ b/plugins/dbusoob.c
@@ -0,0 +1,353 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2010 ST-Ericsson SA
+ *
+ * Author: Szymon Janc <szymon.janc@tieto.com> for ST-Ericsson
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <gdbus.h>
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/hci.h>
+#include <bluetooth/sdp.h>
+
+#include "plugin.h"
+#include "log.h"
+#include "manager.h"
+#include "device.h"
+#include "adapter.h"
+#include "dbus-common.h"
+#include "event.h"
+#include "error.h"
+#include "oob.h"
+
+#define REQUEST_TIMEOUT (10 * 1000) /* 10 seconds */
+#define OOB_INTERFACE "org.bluez.OOB"
+#define OOB_PATH "/org/bluez"
+
+struct oob_provider {
+ char *name;
+ char *path;
+
+ struct btd_adapter *adapter;
+ DBusMessage *msg;
+
+ guint listener_id;
+ gboolean exited;
+};
+
+static struct oob_provider *provider = NULL;
+static DBusConnection *connection = NULL;
+static struct oob_plugin dbusoob;
+
+static void destroy_provider(void)
+{
+ if (!provider->exited)
+ g_dbus_remove_watch(connection, provider->listener_id);
+
+ if (provider->msg)
+ dbus_message_unref(provider->msg);
+
+ g_free(provider->name);
+ g_free(provider->path);
+ g_free(provider);
+ provider = NULL;
+
+ oob_deactivate_plugin(&dbusoob);
+}
+
+static void provider_exited(DBusConnection *conn, void *user_data)
+{
+ DBG("Provider exited without calling Unregister");
+
+ provider->exited = TRUE;
+ destroy_provider();
+}
+
+static void create_provider(const char *path, const char *name)
+{
+ provider = g_new(struct oob_provider, 1);
+ provider->path = g_strdup(path);
+ provider->name = g_strdup(name);
+ provider->adapter = NULL;
+ provider->msg = NULL;
+ provider->exited = FALSE;
+ provider->listener_id = g_dbus_add_disconnect_watch(connection, name,
+ provider_exited, NULL, NULL);
+
+ oob_activate_plugin(&dbusoob);
+}
+
+static void request_remote_data_reply(DBusPendingCall *call, void *data)
+{
+ DBusMessage *msg;
+ DBusError err;
+ struct btd_device *device = data;
+ uint8_t *hash = NULL;
+ uint8_t *randomizer = NULL;
+ int32_t hlen, rlen;
+
+ msg = dbus_pending_call_steal_reply(call);
+
+ dbus_error_init(&err);
+ if (dbus_set_error_from_message(&err, msg)) {
+ error("Provider replied with an error: %s, %s", err.name,
+ err.message);
+ dbus_error_free(&err);
+ goto error;
+ }
+
+ dbus_error_init(&err);
+ if (!dbus_message_get_args(msg, &err,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &hash, &hlen,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &randomizer, &rlen,
+ DBUS_TYPE_INVALID) || hlen != 16 || rlen != 16) {
+ error("RequestRemoteOobData reply signature error: %s, %s",
+ err.name, err.message);
+ dbus_error_free(&err);
+ hash = NULL;
+ randomizer = NULL;
+ }
+
+error:
+ dbus_message_unref(msg);
+ dbus_pending_call_unref(call);
+
+ device_set_oob_data(device, hash, randomizer);
+}
+
+static gboolean request_remote_data(struct btd_device *device)
+{
+ DBusMessage* msg;
+ DBusPendingCall *call = NULL;
+ const gchar *path;
+ gboolean ret = FALSE;
+
+ msg = dbus_message_new_method_call(provider->name, provider->path,
+ OOB_INTERFACE, "RequestRemoteOobData");
+
+ if (!msg) {
+ error("Couldn't allocate D-Bus message");
+ goto error;
+ }
+
+ path = device_get_path(device);
+
+ if (!dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_INVALID)) {
+ error ("Couldn't append arguments");
+ goto error;
+ }
+
+ if (!dbus_connection_send_with_reply(connection, msg, &call,
+ REQUEST_TIMEOUT)) {
+ error("D-Bus send failed");
+ goto error;
+ }
+
+ if (!dbus_pending_call_set_notify(call, request_remote_data_reply,
+ device, NULL)) {
+ error("Couldn't set reply notification.");
+ dbus_pending_call_unref(call);
+ goto error;
+ }
+
+ ret = TRUE;
+
+error:
+ if (msg)
+ dbus_message_unref(msg);
+
+ return ret;
+}
+
+static void local_data_read(bdaddr_t *ba, uint8_t *hash, uint8_t *randomizer)
+{
+ struct DBusMessage *reply;
+ bdaddr_t addr;
+
+ if (!provider)
+ return;
+
+ adapter_get_address(provider->adapter, &addr);
+ if (bacmp(ba, &addr))
+ return;
+
+ if (hash && randomizer)
+ reply = g_dbus_create_reply(provider->msg,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &hash, 16,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &randomizer, 16,
+ DBUS_TYPE_INVALID);
+ else
+ reply = g_dbus_create_error(provider->msg,
+ ERROR_INTERFACE ".ReadFailed",
+ "Failed to read local OOB data.");
+
+ dbus_message_unref(provider->msg);
+ provider->msg = NULL;
+ provider->adapter = NULL;
+
+ if (!reply) {
+ error("Couldn't allocate D-Bus message");
+ return;
+ }
+
+ if (!g_dbus_send_message(connection, reply))
+ error("D-Bus send failed");
+}
+
+static DBusMessage *read_local_data(DBusConnection *conn, DBusMessage *msg,
+ void *data)
+{
+ const char *name;
+ const char *path;
+
+ if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_INVALID))
+ return NULL;
+
+ name = dbus_message_get_sender(msg);
+ if (!provider || strcmp(provider->name, name) != 0)
+ return g_dbus_create_error(msg, ERROR_INTERFACE ".NoProvider",
+ "Not OOB provider or no provider registered");
+
+ if (provider->msg)
+ return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress",
+ "Another request in progress.");
+
+ provider->adapter = manager_find_adapter_by_path(path);
+ if (!provider->adapter)
+ return g_dbus_create_error(msg, ERROR_INTERFACE ".ReadFailed",
+ "No adapter with given address found");
+
+ if (btd_adapter_read_local_oob_data(provider->adapter))
+ return g_dbus_create_error(msg, ERROR_INTERFACE ".ReadFailed",
+ "HCI request failed");
+
+ provider->msg = dbus_message_ref(msg);
+ return NULL;
+}
+
+static void plugin_deactivated(void)
+{
+ DBusMessage *msg;
+
+ msg = dbus_message_new_method_call(provider->name, provider->path,
+ OOB_INTERFACE, "Release");
+
+ if (!msg)
+ error("Couldn't allocate D-Bus message");
+ else if (!g_dbus_send_message(connection, msg))
+ error("D-Bus send failed");
+
+ destroy_provider();
+}
+
+static DBusMessage *register_provider(DBusConnection *conn, DBusMessage *msg,
+ void *data)
+{
+ const char *path;
+ const char *name;
+
+ if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_INVALID))
+ return NULL;
+
+ if (provider)
+ return g_dbus_create_error(msg, ERROR_INTERFACE ".AlreadyExists",
+ "OOB provider already registered");
+
+ name = dbus_message_get_sender(msg);
+ create_provider(path, name);
+
+ DBG("OOB provider registered at %s:%s", provider->name, provider->path);
+ return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *unregister_provider(DBusConnection *conn, DBusMessage *msg,
+ void *data)
+{
+ const char *path;
+ const char *name;
+
+ if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_INVALID))
+ return NULL;
+
+ name = dbus_message_get_sender(msg);
+
+ if (!provider || !g_str_equal(provider->path, path)
+ || !g_str_equal(provider->name, name))
+ return g_dbus_create_error(msg, ERROR_INTERFACE ".DoesNotExist",
+ "No such OOB provider registered");
+
+ DBG("OOB provider (%s:%s) unregistered", provider->name, provider->path);
+
+ destroy_provider();
+
+ return dbus_message_new_method_return(msg);
+}
+
+static GDBusMethodTable oob_methods[] = {
+ { "RegisterProvider", "o", "", register_provider},
+ { "UnregisterProvider", "o", "", unregister_provider},
+ { "ReadLocalOobData", "o", "ayay", read_local_data,
+ G_DBUS_METHOD_FLAG_ASYNC},
+ { }
+};
+
+static gboolean register_on_dbus(void)
+{
+ connection = get_dbus_connection();
+
+ if (!g_dbus_register_interface(connection, OOB_PATH, OOB_INTERFACE,
+ oob_methods, NULL, NULL, NULL, NULL)) {
+ error("OOB interface init failed on path %s", OOB_PATH);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static int dbusoob_init(void)
+{
+ DBG("Setup dbusoob plugin");
+
+ dbusoob.request_remote_data = request_remote_data;
+ dbusoob.local_data_read = local_data_read;
+ dbusoob.plugin_deactivated = plugin_deactivated;
+
+ return register_on_dbus();
+}
+
+static void dbusoob_exit(void)
+{
+ DBG("Cleanup dbusoob plugin");
+ oob_deactivate_plugin(&dbusoob);
+}
+
+BLUETOOTH_PLUGIN_DEFINE(dbusoob, VERSION,
+ BLUETOOTH_PLUGIN_PRIORITY_DEFAULT, dbusoob_init, dbusoob_exit)
--
1.7.1
^ permalink raw reply related
* [PATCHv3 1/7] Add support for Out of Band (OOB) association model.
From: Szymon Janc @ 2010-11-16 15:44 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1289922247-20712-1-git-send-email-szymon.janc@tieto.com>
---
Makefile.am | 3 +-
lib/hci.h | 3 ++
plugins/hciops.c | 72 +++++++++++++++++++++++++++++++++++++++++---------
src/adapter.c | 7 ++++-
src/adapter.h | 3 ++
src/device.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/device.h | 12 ++++++++
src/event.c | 75 +++++++++++++++++++++++++++++++++++++++-------------
src/event.h | 3 +-
src/oob.c | 61 +++++++++++++++++++++++++++++++++++++++++++
src/oob.h | 47 +++++++++++++++++++++++++++++++++
11 files changed, 326 insertions(+), 36 deletions(-)
create mode 100644 src/oob.c
create mode 100644 src/oob.h
diff --git a/Makefile.am b/Makefile.am
index da308a7..a61e754 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -238,7 +238,8 @@ src_bluetoothd_SOURCES = $(gdbus_sources) $(builtin_sources) \
src/adapter.h src/adapter.c \
src/device.h src/device.c \
src/dbus-common.c src/dbus-common.h \
- src/event.h src/event.c
+ src/event.h src/event.c \
+ src/oob.c
src_bluetoothd_LDADD = lib/libbluetooth.la @GLIB_LIBS@ @DBUS_LIBS@ \
@CAPNG_LIBS@ -ldl -lrt
src_bluetoothd_LDFLAGS = -Wl,--export-dynamic \
diff --git a/lib/hci.h b/lib/hci.h
index 0cb120f..409abd9 100644
--- a/lib/hci.h
+++ b/lib/hci.h
@@ -524,6 +524,9 @@ typedef struct {
#define OCF_REMOTE_OOB_DATA_NEG_REPLY 0x0033
+#define OOB_DATA_NOT_PRESENT 0x00
+#define OOB_DATA_PRESENT 0x01
+
#define OCF_IO_CAPABILITY_NEG_REPLY 0x0034
typedef struct {
bdaddr_t bdaddr;
diff --git a/plugins/hciops.c b/plugins/hciops.c
index 829011a..75e6b0c 100644
--- a/plugins/hciops.c
+++ b/plugins/hciops.c
@@ -3,6 +3,7 @@
* BlueZ - Bluetooth protocol stack for Linux
*
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2010 ST-Ericsson SA
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -47,6 +48,7 @@
#include "event.h"
#include "device.h"
#include "manager.h"
+#include "oob.h"
#define HCI_REQ_TIMEOUT 5000
@@ -509,20 +511,41 @@ static void user_passkey_notify(int index, void *ptr)
static void remote_oob_data_request(int index, void *ptr)
{
- hci_send_cmd(SK(index), OGF_LINK_CTL,
- OCF_REMOTE_OOB_DATA_NEG_REPLY, 6, ptr);
+ bdaddr_t *dba = ptr;
+ struct btd_adapter *adapter;
+ struct btd_device *device;
+ char da[18];
+
+ ba2str(dba, da);
+ adapter = manager_find_adapter(&BDADDR(index));
+ device = adapter_find_device(adapter, da);
+
+ if (device_has_oob_data(device)) {
+ remote_oob_data_reply_cp cp;
+
+ bacpy(&cp.bdaddr, dba);
+ device_get_oob_data(device,cp.hash,cp.randomizer);
+
+ hci_send_cmd(SK(index), OGF_LINK_CTL, OCF_REMOTE_OOB_DATA_REPLY,
+ REMOTE_OOB_DATA_REPLY_CP_SIZE, &cp);
+ } else
+ hci_send_cmd(SK(index),
+ OGF_LINK_CTL, OCF_REMOTE_OOB_DATA_NEG_REPLY, 6,
+ ptr);
}
static void io_capa_request(int index, void *ptr)
{
bdaddr_t *dba = ptr;
char sa[18], da[18];
- uint8_t cap, auth;
ba2str(&BDADDR(index), sa); ba2str(dba, da);
info("io_capa_request (sba=%s, dba=%s)", sa, da);
- if (btd_event_get_io_cap(&BDADDR(index), dba, &cap, &auth) < 0) {
+ /* If failed to establish IO capabilities then send negative reply
+ * immediately. Positive reply will be sent when IO capabilities are
+ * established. */
+ if (btd_event_request_io_cap(&BDADDR(index), dba)) {
io_capability_neg_reply_cp cp;
memset(&cp, 0, sizeof(cp));
bacpy(&cp.bdaddr, dba);
@@ -530,15 +553,6 @@ static void io_capa_request(int index, void *ptr)
hci_send_cmd(SK(index), OGF_LINK_CTL,
OCF_IO_CAPABILITY_NEG_REPLY,
IO_CAPABILITY_NEG_REPLY_CP_SIZE, &cp);
- } else {
- io_capability_reply_cp cp;
- memset(&cp, 0, sizeof(cp));
- bacpy(&cp.bdaddr, dba);
- cp.capability = cap;
- cp.oob_data = 0x00;
- cp.authentication = auth;
- hci_send_cmd(SK(index), OGF_LINK_CTL, OCF_IO_CAPABILITY_REPLY,
- IO_CAPABILITY_REPLY_CP_SIZE, &cp);
}
}
@@ -748,6 +762,15 @@ static void read_scan_complete(int index, uint8_t status, void *ptr)
adapter_mode_changed(adapter, rp->enable);
}
+static void read_local_oob_data_complete(bdaddr_t *local, uint8_t status,
+ read_local_oob_data_rp *rp)
+{
+ if (status)
+ oob_local_data_read(local, NULL, NULL);
+ else
+ oob_local_data_read(local, rp->hash, rp->randomizer);
+}
+
static inline void cmd_complete(int index, void *ptr)
{
evt_cmd_complete *evt = ptr;
@@ -808,6 +831,10 @@ static inline void cmd_complete(int index, void *ptr)
ptr += sizeof(evt_cmd_complete);
adapter_update_tx_power(&BDADDR(index), status, ptr);
break;
+ case cmd_opcode_pack(OGF_HOST_CTL, OCF_READ_LOCAL_OOB_DATA):
+ ptr += sizeof(evt_cmd_complete);
+ read_local_oob_data_complete(&BDADDR(index), status, ptr);
+ break;
};
}
@@ -2280,6 +2307,24 @@ static int hciops_get_remote_version(int index, uint16_t handle,
return 0;
}
+static int hciops_read_local_oob_data(int index)
+{
+ int dd;
+ int err = 0;
+
+ dd = hci_open_dev(index);
+ if (dd < 0)
+ return -EIO;
+
+ err = hci_send_cmd(dd, OGF_HOST_CTL, OCF_READ_LOCAL_OOB_DATA, 0, 0);
+ if (err < 0)
+ err = -errno;
+
+ hci_close_dev(dd);
+
+ return err;
+}
+
static struct btd_adapter_ops hci_ops = {
.setup = hciops_setup,
.cleanup = hciops_cleanup,
@@ -2326,6 +2371,7 @@ static struct btd_adapter_ops hci_ops = {
.write_le_host = hciops_write_le_host,
.get_remote_version = hciops_get_remote_version,
.encrypt_link = hciops_encrypt_link,
+ .read_local_oob_data = hciops_read_local_oob_data,
};
static int hciops_init(void)
diff --git a/src/adapter.c b/src/adapter.c
index 31014e5..39a6514 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -3265,7 +3265,7 @@ void adapter_remove_connection(struct btd_adapter *adapter,
/* clean pending HCI cmds */
device_get_address(device, &bdaddr);
- if (device_is_authenticating(device))
+ if (device_is_authenticating(device) || device_has_oob_data(device))
device_cancel_authentication(device, TRUE);
if (device_is_temporary(device)) {
@@ -3738,3 +3738,8 @@ int btd_adapter_encrypt_link(struct btd_adapter *adapter, bdaddr_t *bdaddr,
{
return adapter_ops->encrypt_link(adapter->dev_id, bdaddr, cb, user_data);
}
+
+int btd_adapter_read_local_oob_data(struct btd_adapter *adapter)
+{
+ return adapter_ops->read_local_oob_data(adapter->dev_id);
+}
diff --git a/src/adapter.h b/src/adapter.h
index 8019cfc..cc62865 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -229,6 +229,7 @@ struct btd_adapter_ops {
gboolean delayed);
int (*encrypt_link) (int index, bdaddr_t *bdaddr, bt_hci_result_t cb,
gpointer user_data);
+ int (*read_local_oob_data) (int index);
};
int btd_register_adapter_ops(struct btd_adapter_ops *ops, gboolean priority);
@@ -289,3 +290,5 @@ int btd_adapter_get_remote_version(struct btd_adapter *adapter,
int btd_adapter_encrypt_link(struct btd_adapter *adapter, bdaddr_t *bdaddr,
bt_hci_result_t cb, gpointer user_data);
+
+int btd_adapter_read_local_oob_data(struct btd_adapter *adapter);
diff --git a/src/device.c b/src/device.c
index 7c421e3..24fd44d 100644
--- a/src/device.c
+++ b/src/device.c
@@ -4,6 +4,7 @@
*
* Copyright (C) 2006-2010 Nokia Corporation
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2010 ST-Ericsson SA
*
*
* This program is free software; you can redistribute it and/or modify
@@ -59,6 +60,7 @@
#include "sdp-xml.h"
#include "storage.h"
#include "btio.h"
+#include "oob.h"
#define DEFAULT_XML_BUF_SIZE 1024
#define DISCONNECT_TIMER 2
@@ -132,6 +134,9 @@ struct btd_device {
uint8_t cap;
uint8_t auth;
+ uint8_t local_cap;
+ uint8_t local_auth;
+
uint16_t handle; /* Connection handle */
/* Whether were creating a security mode 3 connection */
@@ -149,6 +154,12 @@ struct btd_device {
gboolean has_debug_key;
uint8_t debug_key[16];
+
+ /* For OOB association model */
+ void (*oob_request_cb)(struct btd_device *device);
+ gboolean has_oob_data;
+ uint8_t hash[16];
+ uint8_t randomizer[16];
};
static uint16_t uuid_list[] = {
@@ -829,6 +840,69 @@ static DBusMessage *disconnect(DBusConnection *conn, DBusMessage *msg,
return NULL;
}
+void device_set_oob_data(struct btd_device *device, uint8_t *hash,
+ uint8_t *randomizer)
+{
+ if (!device)
+ return;
+
+ if (hash && randomizer) {
+ memcpy(device->hash, hash, 16);
+ memcpy(device->randomizer, randomizer, 16);
+ device->has_oob_data = TRUE;
+ }
+
+ if (device->oob_request_cb) {
+ device->oob_request_cb(device);
+ device->oob_request_cb = NULL;
+ }
+}
+
+gboolean device_get_oob_data(struct btd_device *device, uint8_t *hash,
+ uint8_t *randomizer)
+{
+ if (!device || !device->has_oob_data)
+ return FALSE;
+
+ memcpy(hash, device->hash, 16);
+ memcpy(randomizer, device->randomizer, 16);
+
+ return TRUE;
+}
+
+gboolean device_has_oob_data(struct btd_device *device)
+{
+ return device && device->has_oob_data;
+}
+
+gboolean device_request_oob_data(struct btd_device *device, void *cb)
+{
+ if (!device)
+ return FALSE;
+
+ device->oob_request_cb = cb;
+ return oob_request_remote_data(device);
+}
+
+void device_set_local_auth_cap(struct btd_device *device, uint8_t auth,
+ uint8_t cap)
+{
+ if (!device)
+ return;
+
+ device->local_auth = auth;
+ device->local_cap = cap;
+}
+void device_get_local_auth_cap(struct btd_device *device, uint8_t *auth,
+ uint8_t *cap)
+{
+ if (!device)
+ return;
+
+ *auth = device->local_auth;
+ *cap = device->local_cap;
+}
+
static GDBusMethodTable device_methods[] = {
{ "GetProperties", "", "a{sv}", get_properties },
{ "SetProperty", "sv", "", set_property },
@@ -2264,6 +2338,8 @@ void device_cancel_authentication(struct btd_device *device, gboolean aborted)
{
struct authentication_req *auth = device->authr;
+ device->has_oob_data = FALSE;
+
if (!auth)
return;
diff --git a/src/device.h b/src/device.h
index b570bd1..b62cdc5 100644
--- a/src/device.h
+++ b/src/device.h
@@ -4,6 +4,7 @@
*
* Copyright (C) 2006-2010 Nokia Corporation
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2010 ST-Ericsson SA
*
*
* This program is free software; you can redistribute it and/or modify
@@ -89,6 +90,17 @@ void device_remove_connection(struct btd_device *device, DBusConnection *conn,
gboolean device_has_connection(struct btd_device *device, uint16_t handle);
void device_request_disconnect(struct btd_device *device, DBusMessage *msg);
+void device_set_oob_data(struct btd_device *device, uint8_t *hash,
+ uint8_t *randomizer);
+gboolean device_get_oob_data(struct btd_device *device, uint8_t *hash,
+ uint8_t *randomizer);
+gboolean device_has_oob_data(struct btd_device *device);
+gboolean device_request_oob_data(struct btd_device *device, void *cb);
+void device_set_local_auth_cap(struct btd_device *device, uint8_t auth,
+ uint8_t cap);
+void device_get_local_auth_cap(struct btd_device *device, uint8_t *auth,
+ uint8_t *cap);
+
typedef void (*disconnect_watch) (struct btd_device *device, gboolean removal,
void *user_data);
diff --git a/src/event.c b/src/event.c
index e943c63..5a5a288 100644
--- a/src/event.c
+++ b/src/event.c
@@ -4,6 +4,7 @@
*
* Copyright (C) 2006-2010 Nokia Corporation
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2010 ST-Ericsson SA
*
*
* This program is free software; you can redistribute it and/or modify
@@ -274,7 +275,7 @@ void btd_event_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer,
if (!get_adapter_and_device(local, peer, &adapter, &device, TRUE))
return;
- if (!device_is_authenticating(device)) {
+ if (!device_is_authenticating(device) && !device_has_oob_data(device)) {
/* This means that there was no pending PIN or SSP token
* request from the controller, i.e. this is not a new
* pairing */
@@ -756,26 +757,56 @@ void btd_event_returned_link_key(bdaddr_t *local, bdaddr_t *peer)
device_set_paired(device, TRUE);
}
-int btd_event_get_io_cap(bdaddr_t *local, bdaddr_t *remote,
- uint8_t *cap, uint8_t *auth)
+static void btd_event_io_cap_reply(struct btd_device *device)
+{
+ io_capability_reply_cp cp;
+ int dev;
+ struct btd_adapter *adapter = device_get_adapter(device);
+ uint16_t dev_id = adapter_get_dev_id(adapter);
+
+ dev = hci_open_dev(dev_id);
+ if (dev < 0) {
+ error("hci_open_dev(%d): %s (%d)", dev_id,
+ strerror(errno), errno);
+ return;
+ }
+
+ memset(&cp, 0, sizeof(cp));
+ device_get_address(device, &cp.bdaddr);
+ device_get_local_auth_cap(device, &cp.authentication, &cp.capability);
+ cp.oob_data = device_has_oob_data(device)
+ ? OOB_DATA_PRESENT : OOB_DATA_NOT_PRESENT;
+
+ DBG("final capabilities reply is cap=0x%02x, auth=0x%02x, oob=0x%02x",
+ cp.capability, cp.authentication, cp.oob_data);
+
+ hci_send_cmd(dev, OGF_LINK_CTL, OCF_IO_CAPABILITY_REPLY,
+ IO_CAPABILITY_REPLY_CP_SIZE, &cp);
+
+ hci_close_dev(dev);
+}
+
+int btd_event_request_io_cap(bdaddr_t *local, bdaddr_t *remote)
{
struct btd_adapter *adapter;
struct btd_device *device;
struct agent *agent = NULL;
uint8_t agent_cap;
int err;
+ uint8_t cap;
+ uint8_t auth;
if (!get_adapter_and_device(local, remote, &adapter, &device, TRUE))
return -ENODEV;
- err = btd_adapter_get_auth_info(adapter, remote, auth);
+ err = btd_adapter_get_auth_info(adapter, remote, &auth);
if (err < 0)
return err;
- DBG("initial authentication requirement is 0x%02x", *auth);
+ DBG("initial authentication requirement is 0x%02x", auth);
- if (*auth == 0xff)
- *auth = device_get_auth(device);
+ if (auth == 0xff)
+ auth = device_get_auth(device);
/* Check if the adapter is not pairable and if there isn't a bonding
* in progress */
@@ -784,11 +815,11 @@ int btd_event_get_io_cap(bdaddr_t *local, bdaddr_t *remote,
if (device_get_auth(device) < 0x02) {
DBG("Allowing no bonding in non-bondable mode");
/* No input, no output */
- *cap = 0x03;
+ cap = 0x03;
/* Kernel defaults to general bonding and so
* overwrite for this special case. Otherwise
* non-pairable test cases will fail. */
- *auth = 0x00;
+ auth = 0x00;
goto done;
}
return -EPERM;
@@ -804,13 +835,13 @@ int btd_event_get_io_cap(bdaddr_t *local, bdaddr_t *remote,
}
/* No agent available, and no bonding case */
- if (*auth == 0x00 || *auth == 0x04) {
+ if (auth == 0x00 || auth == 0x04) {
DBG("Allowing no bonding without agent");
/* No input, no output */
- *cap = 0x03;
+ cap = 0x03;
/* If kernel defaults to general bonding, set it
* back to no bonding */
- *auth = 0x00;
+ auth = 0x00;
goto done;
}
@@ -820,7 +851,7 @@ int btd_event_get_io_cap(bdaddr_t *local, bdaddr_t *remote,
agent_cap = agent_get_io_capability(agent);
- if (*auth == 0x00 || *auth == 0x04) {
+ if (auth == 0x00 || auth == 0x04) {
/* If remote requests dedicated bonding follow that lead */
if (device_get_auth(device) == 0x02 ||
device_get_auth(device) == 0x03) {
@@ -829,9 +860,9 @@ int btd_event_get_io_cap(bdaddr_t *local, bdaddr_t *remote,
* then require it, otherwise don't */
if (device_get_cap(device) == 0x03 ||
agent_cap == 0x03)
- *auth = 0x02;
+ auth = 0x02;
else
- *auth = 0x03;
+ auth = 0x03;
}
/* If remote indicates no bonding then follow that. This
@@ -839,7 +870,7 @@ int btd_event_get_io_cap(bdaddr_t *local, bdaddr_t *remote,
* as default. */
if (device_get_auth(device) == 0x00 ||
device_get_auth(device) == 0x01)
- *auth = 0x00;
+ auth = 0x00;
/* If remote requires MITM then also require it, unless
* our IO capability is NoInputNoOutput (so some
@@ -847,13 +878,19 @@ int btd_event_get_io_cap(bdaddr_t *local, bdaddr_t *remote,
if (device_get_auth(device) != 0xff &&
(device_get_auth(device) & 0x01) &&
agent_cap != 0x03)
- *auth |= 0x01;
+ auth |= 0x01;
}
- *cap = agent_get_io_capability(agent);
+ cap = agent_get_io_capability(agent);
done:
- DBG("final authentication requirement is 0x%02x", *auth);
+ DBG("final authentication requirement is 0x%02x", auth);
+
+ device_set_local_auth_cap(device, auth, cap);
+
+ /* If failed to request remote OOB data then reply immediately. */
+ if (!device_request_oob_data(device, btd_event_io_cap_reply))
+ btd_event_io_cap_reply(device);
return 0;
}
diff --git a/src/event.h b/src/event.h
index 4a7b9c9..a3e7dda 100644
--- a/src/event.h
+++ b/src/event.h
@@ -36,8 +36,7 @@ void btd_event_le_set_scan_enable_complete(bdaddr_t *local, uint8_t status);
void btd_event_write_simple_pairing_mode_complete(bdaddr_t *local);
void btd_event_read_simple_pairing_mode_complete(bdaddr_t *local, void *ptr);
void btd_event_returned_link_key(bdaddr_t *local, bdaddr_t *peer);
-int btd_event_get_io_cap(bdaddr_t *local, bdaddr_t *remote,
- uint8_t *cap, uint8_t *auth);
+int btd_event_request_io_cap(bdaddr_t *local, bdaddr_t *remote);
int btd_event_set_io_cap(bdaddr_t *local, bdaddr_t *remote,
uint8_t cap, uint8_t auth);
int btd_event_user_confirm(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey);
diff --git a/src/oob.c b/src/oob.c
new file mode 100644
index 0000000..4b8b01d
--- /dev/null
+++ b/src/oob.c
@@ -0,0 +1,61 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2010 ST-Ericsson SA
+ *
+ * Author: Szymon Janc <szymon.janc@tieto.com> for ST-Ericsson
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <glib.h>
+#include "manager.h"
+#include "adapter.h"
+#include "oob.h"
+
+static struct oob_plugin *active_plugin = NULL;
+
+void oob_activate_plugin(struct oob_plugin *plugin)
+{
+ if (!plugin || !plugin->local_data_read|| !plugin->plugin_deactivated
+ || !plugin->request_remote_data
+ || active_plugin == plugin)
+ return;
+
+ if (active_plugin)
+ active_plugin->plugin_deactivated();
+
+ active_plugin = plugin;
+}
+
+void oob_deactivate_plugin(struct oob_plugin *plugin)
+{
+ if (active_plugin == plugin)
+ active_plugin = NULL;
+}
+
+gboolean oob_request_remote_data(struct btd_device *device)
+{
+ return active_plugin && active_plugin->request_remote_data(device);
+}
+
+void oob_local_data_read(bdaddr_t *ba, uint8_t *hash, uint8_t *randomizer)
+{
+ if (active_plugin)
+ active_plugin->local_data_read(ba, hash, randomizer);
+}
diff --git a/src/oob.h b/src/oob.h
new file mode 100644
index 0000000..d0d22e2
--- /dev/null
+++ b/src/oob.h
@@ -0,0 +1,47 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2010 ST-Ericsson SA
+ *
+ * Author: Szymon Janc <szymon.janc@tieto.com> for ST-Ericsson
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+struct oob_plugin
+{
+ /* If request was successfully send this functions should return TRUE.
+ * Function should not block for too long. */
+ gboolean (*request_remote_data)(struct btd_device *device);
+
+ /* New local OOB data was read. If corresponding HCI command failed,
+ * hash and randomizer are NULL */
+ void (*local_data_read)(bdaddr_t *ba, uint8_t *hash,
+ uint8_t *randomizer);
+
+ /* Plug-in was deactivated (called only for active plug-in). */
+ void (*plugin_deactivated)(void);
+};
+
+/* These functions are called by OOB plug-in. */
+void oob_activate_plugin(struct oob_plugin *plugin);
+void oob_deactivate_plugin(struct oob_plugin *plugin);
+
+/* These functions are called from stack to interact with OOB plug-in. */
+gboolean oob_request_remote_data(struct btd_device *device);
+void oob_local_data_read(bdaddr_t *ba, uint8_t *hash, uint8_t *randomizer);
--
1.7.1
^ permalink raw reply related
* [PATCHv3 0/7] Support for out of band association model
From: Szymon Janc @ 2010-11-16 15:44 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
Changes since v2:
- DBus provider Deactive() changed to Release() to be consistent with
Agent API
- DBus UpdateLocalOobData() changed to ReadLocalOobData() and explanation
note in documentation added
- renamed all update local oob data functions to read equivalents to keep
names consistent (with hci command) in call chain
Szymon Janc (7):
Add support for Out of Band (OOB) association model.
Add DBus OOB plugin.
Add DBus OOB API documentation.
Add simple-oobprovider for testing.
Add approval request for incoming pairing requests with OOB mechanism
Update DBus OOB API with RequestApproval method.
simple-agent - add RequestApproval method for OOB pairing
Makefile.am | 10 +-
acinclude.m4 | 6 +
doc/oob-api.txt | 78 +++++++++++
lib/hci.h | 3 +
plugins/dbusoob.c | 353 +++++++++++++++++++++++++++++++++++++++++++++++
plugins/hciops.c | 96 +++++++++++--
src/adapter.c | 14 ++-
src/adapter.h | 6 +
src/agent.c | 59 ++++++++-
src/agent.h | 3 +
src/device.c | 98 +++++++++++++
src/device.h | 13 ++
src/event.c | 116 +++++++++++++---
src/event.h | 4 +-
src/oob.c | 61 ++++++++
src/oob.h | 47 +++++++
test/simple-agent | 10 ++
test/simple-oobprovider | 61 ++++++++
18 files changed, 1000 insertions(+), 38 deletions(-)
create mode 100644 doc/oob-api.txt
create mode 100644 plugins/dbusoob.c
create mode 100644 src/oob.c
create mode 100644 src/oob.h
create mode 100755 test/simple-oobprovider
^ permalink raw reply
* Re: [PATCH] Adding a new option to specify security level for gatttool
From: Johan Hedberg @ 2010-11-16 15:36 UTC (permalink / raw)
To: Sheldon Demario; +Cc: linux-bluetooth
In-Reply-To: <1289913613-3717-1-git-send-email-sheldon.demario@openbossa.org>
Hi Sheldon,
On Tue, Nov 16, 2010, Sheldon Demario wrote:
> ---
> TODO | 6 ------
> attrib/gatttool.c | 15 +++++++++++++--
> 2 files changed, 13 insertions(+), 8 deletions(-)
In general the patch seems fine, but:
> + if (strncmp(opt_sec_level, "medium", 6) == 0)
> + sec_level = BT_IO_SEC_MEDIUM;
> + else if (strncmp(opt_sec_level, "high", 4) == 0)
> + sec_level = BT_IO_SEC_HIGH;
> + else
> + sec_level = BT_IO_SEC_LOW;
Why do you use strncmp instead of strcmp (or even g_str_equal)? I don't
think there's any need to map e.g. "mediumfoobar" to BT_IO_SEC_MEDIUM ;)
Johan
^ permalink raw reply
* Re: [PATCH v2 2/2] Split pull_contacts to smaller functions
From: Johan Hedberg @ 2010-11-16 15:22 UTC (permalink / raw)
To: Bartosz Szatkowski; +Cc: linux-bluetooth
In-Reply-To: <1289915995-2749-1-git-send-email-bulislaw@linux.com>
Hi Bartosz,
On Tue, Nov 16, 2010, Bartosz Szatkowski wrote:
> +static void contact_init(struct phonebook_contact **contact, char **reply)
> +{
> + if (*contact == NULL)
> + *contact = g_new0(struct phonebook_contact, 1);
Could you do this initialization before calling this function and pass
just a simple pointer to it. I think it'd be a cleaner approach.
> +static void contact_add_numbers(struct phonebook_contact **contact, char **reply)
Over 79 column line. Please split it.
> + if ((g_strcmp0(reply[COL_OTHER_NUMBER], reply[COL_CELL_NUMBER]) != 0) &&
> + (g_strcmp0(reply[COL_OTHER_NUMBER], reply[COL_WORK_NUMBER]) != 0) &&
> + (g_strcmp0(reply[COL_OTHER_NUMBER], reply[COL_HOME_NUMBER]) != 0))
> + add_phone_number(*contact, reply[COL_OTHER_NUMBER], TEL_TYPE_OTHER);
> +}
Same here. However, I think you can make it considerably more readable
with something like:
if (g_strcmp0(reply[COL_OTHER_NUMBER], reply[COL_CELL_NUMBER]) == 0)
return;
if (g_strcmp0(reply[COL_OTHER_NUMBER], reply[COL_WORK_NUMBER]) == 0)
return;
if (g_strcmp0(reply[COL_OTHER_NUMBER], reply[COL_HOME_NUMBER]) == 0)
return;
add_phone_number(*contact, reply[COL_OTHER_NUMBER], TEL_TYPE_OTHER);
> +static void contact_add_emails(struct phonebook_contact **contact, char **reply)
Over 79 column line.
> +{
> + add_email(*contact, reply[COL_HOME_EMAIL], EMAIL_TYPE_HOME);
> + add_email(*contact, reply[COL_WORK_EMAIL], EMAIL_TYPE_WORK);
> + add_email(*contact, reply[COL_OTHER_EMAIL], EMAIL_TYPE_OTHER);
> +}
Why does the function take a pointer to pointer when a simple pointer
would be enough?
> +static void contact_add_addresses(struct phonebook_contact **contact, char **reply)
Over 79 columns and unnecessary ** pointer again.
> + home_addr = g_strdup_printf("%s;%s;%s;%s;%s;%s;%s",
> + reply[COL_HOME_ADDR_POBOX], reply[COL_HOME_ADDR_EXT],
> + reply[COL_HOME_ADDR_STREET], reply[COL_HOME_ADDR_LOCALITY],
> + reply[COL_HOME_ADDR_REGION], reply[COL_HOME_ADDR_CODE],
> + reply[COL_HOME_ADDR_COUNTRY]);
> +
> + work_addr = g_strdup_printf("%s;%s;%s;%s;%s;%s;%s",
> + reply[COL_WORK_ADDR_POBOX], reply[COL_WORK_ADDR_EXT],
> + reply[COL_WORK_ADDR_STREET], reply[COL_WORK_ADDR_LOCALITY],
> + reply[COL_WORK_ADDR_REGION], reply[COL_WORK_ADDR_CODE],
> + reply[COL_WORK_ADDR_COUNTRY]);
> +
> + other_addr = g_strdup_printf("%s;%s;%s;%s;%s;%s;%s",
> + reply[COL_OTHER_ADDR_POBOX], reply[COL_OTHER_ADDR_EXT],
> + reply[COL_OTHER_ADDR_STREET], reply[COL_OTHER_ADDR_LOCALITY],
> + reply[COL_OTHER_ADDR_REGION], reply[COL_OTHER_ADDR_CODE],
> + reply[COL_OTHER_ADDR_COUNTRY]);
All of these are over 79 columns.
> +static void contact_add_organization(struct phonebook_contact **contact, char **reply)
Same here. And a simple * pointer is enough.
Johan
^ permalink raw reply
* [PATCH v2 2/2] Split pull_contacts to smaller functions
From: Bartosz Szatkowski @ 2010-11-16 13:59 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Bartosz Szatkowski
Parts of pull_contact responsible for filling contact fields moved
to new functions.
---
plugins/phonebook-tracker.c | 159 ++++++++++++++++++++++++------------------
1 files changed, 91 insertions(+), 68 deletions(-)
diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index 71ed2f0..e7de001 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -1395,6 +1395,92 @@ static void add_affiliation(char **field, const char *value)
*field = g_strdup(value);
}
+static void contact_init(struct phonebook_contact **contact, char **reply)
+{
+ if (*contact == NULL)
+ *contact = g_new0(struct phonebook_contact, 1);
+
+ (*contact)->fullname = g_strdup(reply[COL_FULL_NAME]);
+ (*contact)->family = g_strdup(reply[COL_FAMILY_NAME]);
+ (*contact)->given = g_strdup(reply[COL_GIVEN_NAME]);
+ (*contact)->additional = g_strdup(reply[COL_ADDITIONAL_NAME]);
+ (*contact)->prefix = g_strdup(reply[COL_NAME_PREFIX]);
+ (*contact)->suffix = g_strdup(reply[COL_NAME_SUFFIX]);
+ (*contact)->birthday = g_strdup(reply[COL_BIRTH_DATE]);
+ (*contact)->nickname = g_strdup(reply[COL_NICKNAME]);
+ (*contact)->website = g_strdup(reply[COL_URL]);
+ (*contact)->photo = g_strdup(reply[COL_PHOTO]);
+ (*contact)->company = g_strdup(reply[COL_ORG_NAME]);
+ (*contact)->department = g_strdup(reply[COL_ORG_DEPARTMENT]);
+ (*contact)->role = g_strdup(reply[COL_ORG_ROLE]);
+ (*contact)->uid = g_strdup(reply[COL_UID]);
+ (*contact)->title = g_strdup(reply[COL_TITLE]);
+
+ set_call_type(*contact, reply[COL_DATE], reply[COL_SENT],
+ reply[COL_ANSWERED]);
+}
+
+static void contact_add_numbers(struct phonebook_contact **contact, char **reply)
+{
+ add_phone_number(*contact, reply[COL_HOME_NUMBER], TEL_TYPE_HOME);
+ add_phone_number(*contact, reply[COL_WORK_NUMBER], TEL_TYPE_WORK);
+ add_phone_number(*contact, reply[COL_FAX_NUMBER], TEL_TYPE_FAX);
+ add_phone_number(*contact, reply[COL_CELL_NUMBER], TEL_TYPE_MOBILE);
+ if ((g_strcmp0(reply[COL_OTHER_NUMBER], reply[COL_CELL_NUMBER]) != 0) &&
+ (g_strcmp0(reply[COL_OTHER_NUMBER], reply[COL_WORK_NUMBER]) != 0) &&
+ (g_strcmp0(reply[COL_OTHER_NUMBER], reply[COL_HOME_NUMBER]) != 0))
+ add_phone_number(*contact, reply[COL_OTHER_NUMBER], TEL_TYPE_OTHER);
+}
+
+static void contact_add_emails(struct phonebook_contact **contact, char **reply)
+{
+ add_email(*contact, reply[COL_HOME_EMAIL], EMAIL_TYPE_HOME);
+ add_email(*contact, reply[COL_WORK_EMAIL], EMAIL_TYPE_WORK);
+ add_email(*contact, reply[COL_OTHER_EMAIL], EMAIL_TYPE_OTHER);
+}
+
+static void contact_add_addresses(struct phonebook_contact **contact, char **reply)
+{
+
+ char *home_addr, *work_addr, *other_addr;
+
+ home_addr = g_strdup_printf("%s;%s;%s;%s;%s;%s;%s",
+ reply[COL_HOME_ADDR_POBOX], reply[COL_HOME_ADDR_EXT],
+ reply[COL_HOME_ADDR_STREET], reply[COL_HOME_ADDR_LOCALITY],
+ reply[COL_HOME_ADDR_REGION], reply[COL_HOME_ADDR_CODE],
+ reply[COL_HOME_ADDR_COUNTRY]);
+
+ work_addr = g_strdup_printf("%s;%s;%s;%s;%s;%s;%s",
+ reply[COL_WORK_ADDR_POBOX], reply[COL_WORK_ADDR_EXT],
+ reply[COL_WORK_ADDR_STREET], reply[COL_WORK_ADDR_LOCALITY],
+ reply[COL_WORK_ADDR_REGION], reply[COL_WORK_ADDR_CODE],
+ reply[COL_WORK_ADDR_COUNTRY]);
+
+ other_addr = g_strdup_printf("%s;%s;%s;%s;%s;%s;%s",
+ reply[COL_OTHER_ADDR_POBOX], reply[COL_OTHER_ADDR_EXT],
+ reply[COL_OTHER_ADDR_STREET], reply[COL_OTHER_ADDR_LOCALITY],
+ reply[COL_OTHER_ADDR_REGION], reply[COL_OTHER_ADDR_CODE],
+ reply[COL_OTHER_ADDR_COUNTRY]);
+
+ add_address(*contact, home_addr, ADDR_TYPE_HOME);
+ add_address(*contact, work_addr, ADDR_TYPE_WORK);
+ add_address(*contact, other_addr, ADDR_TYPE_OTHER);
+
+ g_free(home_addr);
+ g_free(work_addr);
+ g_free(other_addr);
+}
+
+static void contact_add_organization(struct phonebook_contact **contact, char **reply)
+{
+ /* Adding fields connected by nco:hasAffiliation - they may be in
+ * separate replies */
+ add_affiliation(&(*contact)->title, reply[COL_TITLE]);
+ add_affiliation(&(*contact)->company, reply[COL_ORG_NAME]);
+ add_affiliation(&(*contact)->department, reply[COL_ORG_DEPARTMENT]);
+ add_affiliation(&(*contact)->role, reply[COL_ORG_ROLE]);
+}
+
static void pull_contacts(char **reply, int num_fields, void *user_data)
{
struct phonebook_data *data = user_data;
@@ -1404,7 +1490,6 @@ static void pull_contacts(char **reply, int num_fields, void *user_data)
GString *vcards;
int last_index, i;
gboolean cdata_present = FALSE;
- char *home_addr, *work_addr, *other_addr;
static char *temp_id = NULL;
if (num_fields < 0) {
@@ -1455,75 +1540,13 @@ static void pull_contacts(char **reply, int num_fields, void *user_data)
return;
add_entry:
- contact = g_new0(struct phonebook_contact, 1);
- contact->fullname = g_strdup(reply[COL_FULL_NAME]);
- contact->family = g_strdup(reply[COL_FAMILY_NAME]);
- contact->given = g_strdup(reply[COL_GIVEN_NAME]);
- contact->additional = g_strdup(reply[COL_ADDITIONAL_NAME]);
- contact->prefix = g_strdup(reply[COL_NAME_PREFIX]);
- contact->suffix = g_strdup(reply[COL_NAME_SUFFIX]);
- contact->birthday = g_strdup(reply[COL_BIRTH_DATE]);
- contact->nickname = g_strdup(reply[COL_NICKNAME]);
- contact->website = g_strdup(reply[COL_URL]);
- contact->photo = g_strdup(reply[COL_PHOTO]);
- contact->company = g_strdup(reply[COL_ORG_NAME]);
- contact->department = g_strdup(reply[COL_ORG_DEPARTMENT]);
- contact->role = g_strdup(reply[COL_ORG_ROLE]);
- contact->uid = g_strdup(reply[COL_UID]);
- contact->title = g_strdup(reply[COL_TITLE]);
-
- set_call_type(contact, reply[COL_DATE], reply[COL_SENT],
- reply[COL_ANSWERED]);
+ contact_init(&contact, reply);
add_numbers:
- /* Adding phone numbers to contact struct */
- add_phone_number(contact, reply[COL_HOME_NUMBER], TEL_TYPE_HOME);
- add_phone_number(contact, reply[COL_WORK_NUMBER], TEL_TYPE_WORK);
- add_phone_number(contact, reply[COL_FAX_NUMBER], TEL_TYPE_FAX);
- add_phone_number(contact, reply[COL_CELL_NUMBER], TEL_TYPE_MOBILE);
- if ((g_strcmp0(reply[COL_OTHER_NUMBER], reply[COL_CELL_NUMBER]) != 0) &&
- (g_strcmp0(reply[COL_OTHER_NUMBER], reply[COL_WORK_NUMBER]) != 0) &&
- (g_strcmp0(reply[COL_OTHER_NUMBER], reply[COL_HOME_NUMBER]) != 0))
- add_phone_number(contact, reply[COL_OTHER_NUMBER], TEL_TYPE_OTHER);
-
- /* Adding emails */
- add_email(contact, reply[COL_HOME_EMAIL], EMAIL_TYPE_HOME);
- add_email(contact, reply[COL_WORK_EMAIL], EMAIL_TYPE_WORK);
- add_email(contact, reply[COL_OTHER_EMAIL], EMAIL_TYPE_OTHER);
-
- /* Adding addresses */
- home_addr = g_strdup_printf("%s;%s;%s;%s;%s;%s;%s",
- reply[COL_HOME_ADDR_POBOX], reply[COL_HOME_ADDR_EXT],
- reply[COL_HOME_ADDR_STREET], reply[COL_HOME_ADDR_LOCALITY],
- reply[COL_HOME_ADDR_REGION], reply[COL_HOME_ADDR_CODE],
- reply[COL_HOME_ADDR_COUNTRY]);
-
- work_addr = g_strdup_printf("%s;%s;%s;%s;%s;%s;%s",
- reply[COL_WORK_ADDR_POBOX], reply[COL_WORK_ADDR_EXT],
- reply[COL_WORK_ADDR_STREET], reply[COL_WORK_ADDR_LOCALITY],
- reply[COL_WORK_ADDR_REGION], reply[COL_WORK_ADDR_CODE],
- reply[COL_WORK_ADDR_COUNTRY]);
-
- other_addr = g_strdup_printf("%s;%s;%s;%s;%s;%s;%s",
- reply[COL_OTHER_ADDR_POBOX], reply[COL_OTHER_ADDR_EXT],
- reply[COL_OTHER_ADDR_STREET], reply[COL_OTHER_ADDR_LOCALITY],
- reply[COL_OTHER_ADDR_REGION], reply[COL_OTHER_ADDR_CODE],
- reply[COL_OTHER_ADDR_COUNTRY]);
-
- add_address(contact, home_addr, ADDR_TYPE_HOME);
- add_address(contact, work_addr, ADDR_TYPE_WORK);
- add_address(contact, other_addr, ADDR_TYPE_OTHER);
-
- g_free(home_addr);
- g_free(work_addr);
- g_free(other_addr);
-
- /* Adding fields connected by nco:hasAffiliation - they may be in
- * separate replies */
- add_affiliation(&contact->title, reply[COL_TITLE]);
- add_affiliation(&contact->company, reply[COL_ORG_NAME]);
- add_affiliation(&contact->department, reply[COL_ORG_DEPARTMENT]);
- add_affiliation(&contact->role, reply[COL_ORG_ROLE]);
+ contact_add_numbers(&contact, reply);
+ contact_add_emails(&contact, reply);
+ contact_add_addresses(&contact, reply);
+ contact_add_organization(&contact, reply);
DBG("contact %p", contact);
--
1.7.0.4
^ permalink raw reply related
* Re: [PATCH] Fix typos in adapter documentation
From: Johan Hedberg @ 2010-11-16 13:41 UTC (permalink / raw)
To: Jose Antonio Santos Cadenas; +Cc: linux-bluetooth
In-Reply-To: <1289846883-8748-1-git-send-email-santoscadenas@gmail.com>
Hi Jose,
On Mon, Nov 15, 2010, Jose Antonio Santos Cadenas wrote:
> ---
> doc/adapter-api.txt | 8 ++++----
> 1 files changed, 4 insertions(+), 4 deletions(-)
Thanks. The patch has been pushed upstream.
Johan
^ permalink raw reply
* Re: Regarding HDP
From: Raul Herbster @ 2010-11-16 13:39 UTC (permalink / raw)
To: steven bluez; +Cc: linux-bluetooth
In-Reply-To: <AANLkTi=ZZcbEP+NX9PxT_K_9XnCQfKbSugCYJa_na=SY@mail.gmail.com>
Hi Steve,
HDP profile is available in PTS for testing. At project wizard, you
have to select the HDP profile option, so HDP test suite is enabled.
In addition, don´t forget to enable option TSPC_ALL at PTS PICS
configuration.
[]´s
--Raul
2010/11/16 steven bluez <steven.bluez@gmail.com>:
> Hi All,
> How to test the following HDP profile with Pts?.Is it
> available in PTs as option or any other way is available??
>
> Thanks,
> Steven.
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* Re: [PATCH 2/2] Split pull_contacts to smaller functions
From: Johan Hedberg @ 2010-11-16 13:37 UTC (permalink / raw)
To: Bartosz Szatkowski; +Cc: linux-bluetooth
In-Reply-To: <1289822497-5338-2-git-send-email-bulislaw@linux.com>
Hi Bartosz,
On Mon, Nov 15, 2010, Bartosz Szatkowski wrote:
> Parts of pull_contact responsible for filling contact fields moved
> to new functions.
> ---
> plugins/phonebook-tracker.c | 159 ++++++++++++++++++++++++------------------
> 1 files changed, 91 insertions(+), 68 deletions(-)
This one doesn't apply cleanly to current git. Could you please resend it?
Johan
^ permalink raw reply
* Re: [PATCH 1/2] Using field names instead of numbers in PBAP
From: Johan Hedberg @ 2010-11-16 13:35 UTC (permalink / raw)
To: Bartosz Szatkowski; +Cc: linux-bluetooth
In-Reply-To: <1289822497-5338-1-git-send-email-bulislaw@linux.com>
Hi Bartosz,
On Mon, Nov 15, 2010, Bartosz Szatkowski wrote:
> Previously addressing via field numbers and field names were mixed in PBAP
> query replies. Now there is defined name for each data base reply field.
> ---
> plugins/phonebook-tracker.c | 104 +++++++++++++++++++++++++++++++-----------
> 1 files changed, 77 insertions(+), 27 deletions(-)
Pushed upstream. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH] Adding a new option to specify medium security level for gatttool
From: Sheldon Demario @ 2010-11-16 13:35 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Johan Hedberg
In-Reply-To: <20101111205448.GA22890@jh-x301>
Hey Johan,
--sec-level seems more clear than --security to me, because it makes
explicit that the option is about "level". But is easy to change if you
want to.
Sheldon
On 11/11/2010 03:54 PM, Johan Hedberg wrote:
> Hi Sheldon,
>
> On Wed, Nov 10, 2010, Sheldon Demario wrote:
>> -- Add command line support to use medium instead of (default) low
>> - security level with gatttool (--sec-level)
>> -
>> - Priority: Low
>> - Complexity: C1
>> -
> <snip>
>> + { "sec-medium", 's', 0, G_OPTION_ARG_NONE,&opt_medium_sec,
>> + "Use medium instead of default low security level",
>> + NULL},
> Maybe the TODO entry should have been more clear, but I'd prefer if the
> option would be of the format "--sec-level<level>" where<level> is
> "low", "medium" or "high". I'm not completely sure I like --sec-level
> either (even though I did write the original TODO entry :) What do you
> think about simply "--security<level>"?
>
> Johan
^ permalink raw reply
* Re: [PATCH v2] Fix pull phonebook with non-zero offset parameter
From: Johan Hedberg @ 2010-11-16 13:34 UTC (permalink / raw)
To: Rafal Michalski; +Cc: linux-bluetooth
In-Reply-To: <1289817700-32136-1-git-send-email-michalski.raf@gmail.com>
Hi Rafal,
On Mon, Nov 15, 2010, Rafal Michalski wrote:
> For non-zero liststartoffset parameter, contacts which index was before
> offset were indexed more than once (e.g. when contact had more than one
> phone number or address etc.), so pulling was started earlier - before
> offset index was reached. This patch fix this problem and each contact
> is indexed only once.
> ---
> plugins/phonebook-tracker.c | 9 ++++++++-
> 1 files changed, 8 insertions(+), 1 deletions(-)
Pushed upstream. Thanks.
Johan
^ permalink raw reply
* [PATCH] Adding a new option to specify security level for gatttool
From: Sheldon Demario @ 2010-11-16 13:20 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Sheldon Demario
---
TODO | 6 ------
attrib/gatttool.c | 15 +++++++++++++--
2 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/TODO b/TODO
index c0a25f1..49a9e76 100644
--- a/TODO
+++ b/TODO
@@ -123,12 +123,6 @@ ATT/GATT
Priority: Low
Complexity: C1
-- Add command line support to use medium instead of (default) low
- security level with gatttool (--sec-level)
-
- Priority: Low
- Complexity: C1
-
- Implement Server characteristic Configuration support in the attribute
server to manage characteristic value broadcasting. There is a single
instance of the Server Characteristic Configuration for all clients.
diff --git a/attrib/gatttool.c b/attrib/gatttool.c
index b9f5138..bb4fb80 100644
--- a/attrib/gatttool.c
+++ b/attrib/gatttool.c
@@ -49,6 +49,7 @@
static gchar *opt_src = NULL;
static gchar *opt_dst = NULL;
static gchar *opt_value = NULL;
+static gchar *opt_sec_level = "low";
static int opt_start = 0x0001;
static int opt_end = 0xffff;
static int opt_handle = -1;
@@ -84,6 +85,7 @@ static GIOChannel *do_connect(gboolean le)
GIOChannel *chan;
bdaddr_t sba, dba;
GError *err = NULL;
+ BtIOSecLevel sec_level;
/* This check is required because currently setsockopt() returns no
* errors for MTU values smaller than the allowed minimum. */
@@ -109,13 +111,20 @@ static GIOChannel *do_connect(gboolean le)
} else
bacpy(&sba, BDADDR_ANY);
+ if (strncmp(opt_sec_level, "medium", 6) == 0)
+ sec_level = BT_IO_SEC_MEDIUM;
+ else if (strncmp(opt_sec_level, "high", 4) == 0)
+ sec_level = BT_IO_SEC_HIGH;
+ else
+ sec_level = BT_IO_SEC_LOW;
+
if (le)
chan = bt_io_connect(BT_IO_L2CAP, connect_cb, NULL, NULL, &err,
BT_IO_OPT_SOURCE_BDADDR, &sba,
BT_IO_OPT_DEST_BDADDR, &dba,
BT_IO_OPT_CID, GATT_CID,
BT_IO_OPT_OMTU, opt_mtu,
- BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
+ BT_IO_OPT_SEC_LEVEL, sec_level,
BT_IO_OPT_INVALID);
else
chan = bt_io_connect(BT_IO_L2CAP, connect_cb, NULL, NULL, &err,
@@ -123,7 +132,7 @@ static GIOChannel *do_connect(gboolean le)
BT_IO_OPT_DEST_BDADDR, &dba,
BT_IO_OPT_PSM, opt_psm,
BT_IO_OPT_OMTU, opt_mtu,
- BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
+ BT_IO_OPT_SEC_LEVEL, sec_level,
BT_IO_OPT_INVALID);
if (err) {
@@ -519,6 +528,8 @@ static GOptionEntry options[] = {
"Specify the MTU size", "MTU" },
{ "psm", 'p', 0, G_OPTION_ARG_INT, &opt_psm,
"Specify the PSM for GATT/ATT over BR/EDR", "PSM" },
+ { "sec-level", 'l', 0, G_OPTION_ARG_STRING, &opt_sec_level,
+ "Set security level. Default: low", "[low | medium | high]"},
{ NULL },
};
--
1.6.2.rc2
^ permalink raw reply related
* Regarding HDP
From: steven bluez @ 2010-11-16 11:08 UTC (permalink / raw)
To: linux-bluetooth
Hi All,
How to test the following HDP profile with Pts?.Is it
available in PTs as option or any other way is available??
Thanks,
Steven.
^ permalink raw reply
* Re: [PATCH 3/4] Add DBus OOB API documentation.
From: Szymon Janc @ 2010-11-16 10:12 UTC (permalink / raw)
To: jaikumar Ganesh; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <AANLkTik+LOzvJMG=of7cwrQ3j2a0mDvN4Rnq_d4rtwKB@mail.gmail.com>
> >> Why are we enforcing this limitation ?
> >
> > Spec requires that each hash&randomizer values should be used only for one OOB
> > transfer. Implementation enforces that by allowing only one active OOB plugin
> > at time and DBUS OOB plugin only 'expose' plugin API over DBUS. So this
> > limitation is a consequence of that.
>
> I don't think the spec says that. It just says every single time the
> call to read the local adapters hash
> and randomizer is done you get new values. You can use the value that
> you have obtained for as many OOB pairings
> as you wish.
Please see note in Vol2. Part E. 7.3.60:
"Each OOB transfer will have unique C and R values so after each OOB
transfer this command shall be used to obtain a new set of values for the next
OOB transfer."
--
Szymon Janc
^ permalink raw reply
* RE: [RFC] Interface to set LE connection parameters
From: tim.howes @ 2010-11-16 9:56 UTC (permalink / raw)
To: ville.tervo; +Cc: linux-bluetooth
In-Reply-To: <20101115151739.GD16464@null>
Ville,
> > As you note the different profiles would likely have different
> connection parameters. The different profiles may be running on the
> same LE link (indeed the same L2CAP [fixed] channel).
> >
>
> I guess the latency should override power requirements. Low power
> profile can
> operate on low latency link but low latency profile fails on high
> latency. Of
> course this gets much more complicated if there are more requirements.
Agreed.
>
> Are these (latency and power) the only characteristics we need to deal
> with.
> There might be some also. I'm not too familiar with profile drafts.
I think these are the main issues; however I wonder whether link supervision timeout may conflict for different use cases. Even if it is not the link supervision the lifetime of the physical link may differ between profiles (some may want the link up for a long time but send no data). Slightly off-topic; but still it raises issues around the type of API and the arbitration of different profile requirements on the same link.
> > Do you have a view on how the different profiles - on the same link -
> would have different requests arbitrated, and where that arbitration
> would be done? I'd imagine that the API towards the profiles should be
> of the abstract form - such as you mention (eg BT_LE_LOW_LAT). This
> would make it easier to arbitrate the different requests, as compared
> to if the profiles see an API of the "numerical" form (eg interval = N
> ms). I guess the arbitration could happen in user or kernel space; as
> long as there is something with singleton-like semantics to do it.
> >
>
> I think I need to get more details from profile specs and try to find
> out the
> requirements from them.
As an aside, it's not just the application profiles. If you have a link to a device with high latency and need to do more service search using GATT then you might want to lower the latency temporarily. This may impact the type of API control you give GATT applications versus any in-built GATT service discovery.
> Right now I'm trying to find out what would be the right interface from
> kernel
> to user space.
>
> > Also - a quick observation: yes, the connection parameters are only
> for LE links; however they have some semantic similarity with sniff
> mode in BR. Especially in the abstract form ("Low Latency" verus "Low
> Power"). Does BlueZ present an API like this already for BR (I'm new
> to BlueZ...I was more of a Symbian guy ;)? If not it might be worth
> having one API for both BR/Sniff and LE/Connection Parameters - and do
> the appropriate mapping "under the hood".
>
> Actually this has been discussed earlier and we need also some api to
> change
> sniff behaviour. Reason for this is broken devices which does not turn
> on
> normal mode when low latency is needed. I guess Jaikumar had some
> patches
> regarding this?
I think it's a bit deeper than broken devices: the specifications offer no real way for devices to agree why a particular mode (eg active or sniff) is needed at a particular time. This then gives interoperability problems because one side may decide it wants sniff mode; but the other does not know why.
Tim
This message is for the designated recipient only and may contain privileged, proprietary, or otherwise private information. If you have received it in error, please notify the sender immediately and delete the original. Any other use of the email by you is prohibited.
^ permalink raw reply
* HCI UART 3Wire support in Linux
From: Suraj Sumangala @ 2010-11-16 9:47 UTC (permalink / raw)
To: linux-bluetooth@vger.kernel.org; +Cc: Jothikumar Mothilal, Gustavo F. Padovan
Hi,
We are trying to add HCI UART 3Wire support in the transport driver for
AR300x Bluetooth controller.
Is there any driver implementation that support HCI UART 3Wire protocol?
Regards
Suraj
^ permalink raw reply
* Re: [RFC] Interface to set LE connection parameters
From: Ville Tervo @ 2010-11-16 8:56 UTC (permalink / raw)
To: ext Mike Tsai; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <35B17FE5076C7040809188FBE7913F98406D465470@SC1EXMB-MBCL.global.atheros.com>
Hi Mike,
n Mon, Nov 15, 2010 at 07:15:44PM +0100, ext Mike Tsai wrote:
> Hi Ville,
>
> -----Original Message-----
> From: linux-bluetooth-owner@vger.kernel.org [mailto:linux-bluetooth-owner@vger.kernel.org] On Behalf Of Ville Tervo
> Sent: Monday, November 15, 2010 4:07 AM
> To: linux-bluetooth@vger.kernel.org
> Subject: [RFC] Interface to set LE connection parameters
>
> Hi,
>
> LE profiles have different requirements for connection parameters. Mainly
> trying to balance between power consumption and latencies. Probably more will
> factors will be in future.
>
> Currently I have plan to introduce new l2cap socket option which can be used
> before connection creation to set inital settings and also change settings
> while having a connection.
>
> Since there is no equivalents in EDR/BR connection I'm planning to make then
> apply only LE connection.
>
>
> Other question which parameters should be exposed to user space? Connection
> creation and connection update have these common parameters. Connection
> creation has in addition some other parameters also but they should be handled
> in some other way.
>
> __le16 conn_interval_min;
> __le16 conn_interval_max;
> __le16 conn_latency;
> __le16 supervision_timeout;
> __le16 min_ce_len;
> __le16 max_ce_len;
>
> So far I have had two ideas. The first is to simply expose all these fields
> with sock_opt. In that way profiles would be able to define their requirements
> also in future without any sock opt changes.
>
> Second is to define BT_LE_LOW_LAT for low latency connection requirements and
> BT_LE_LOW_POWER connection where the latency is not an issue. It would make
> usage of this sock opt interface simplier. OTOH the only user should be
> bluetoothd so it doesn't need to be as simple as possible.
>
>
> Comments please.
>
> [MTsai] - how about following parameters,
>
> Scan internal,
> Scan window,
> Peer address type,
These are connection creation parameters. Maybe BT_LE_LOW_LAT/BT_LE_LOW_POWER
could be used also for these values. But I think they should defined in some
other way.
--
Ville
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox