* [PATCH 1/3] Bluetooth: Simplify remote features callback function logic
From: johan.hedberg @ 2010-11-10 15:11 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Johan Hedberg
From: Johan Hedberg <johan.hedberg@nokia.com>
The current remote and remote extended features event callbacks logic
can be made simpler by using a label and goto statements instead of the
current multiple levels of nested if statements.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
net/bluetooth/hci_event.c | 91 +++++++++++++++++++++++----------------------
1 files changed, 47 insertions(+), 44 deletions(-)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 84093b0..8430276 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1162,33 +1162,33 @@ static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
- if (conn) {
- if (!ev->status)
- memcpy(conn->features, ev->features, 8);
+ if (!conn)
+ goto unlock;
- if (conn->state == BT_CONFIG) {
- if (!ev->status && lmp_ssp_capable(hdev) &&
- lmp_ssp_capable(conn)) {
- struct hci_cp_read_remote_ext_features cp;
- cp.handle = ev->handle;
- cp.page = 0x01;
- hci_send_cmd(hdev,
- HCI_OP_READ_REMOTE_EXT_FEATURES,
- sizeof(cp), &cp);
- } else if (!ev->status && conn->out &&
- conn->sec_level == BT_SECURITY_HIGH) {
- struct hci_cp_auth_requested cp;
- cp.handle = ev->handle;
- hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
+ if (!ev->status)
+ memcpy(conn->features, ev->features, 8);
+
+ if (conn->state != BT_CONFIG)
+ goto unlock;
+
+ if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
+ struct hci_cp_read_remote_ext_features cp;
+ cp.handle = ev->handle;
+ cp.page = 0x01;
+ hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
sizeof(cp), &cp);
- } else {
- conn->state = BT_CONNECTED;
- hci_proto_connect_cfm(conn, ev->status);
- hci_conn_put(conn);
- }
- }
+ } else if (!ev->status && conn->out &&
+ conn->sec_level == BT_SECURITY_HIGH) {
+ struct hci_cp_auth_requested cp;
+ cp.handle = ev->handle;
+ hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
+ } else {
+ conn->state = BT_CONNECTED;
+ hci_proto_connect_cfm(conn, ev->status);
+ hci_conn_put(conn);
}
+unlock:
hci_dev_unlock(hdev);
}
@@ -1646,32 +1646,35 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
- if (conn) {
- if (!ev->status && ev->page == 0x01) {
- struct inquiry_entry *ie;
+ if (!conn)
+ goto unlock;
- if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst)))
- ie->data.ssp_mode = (ev->features[0] & 0x01);
+ if (!ev->status && ev->page == 0x01) {
+ struct inquiry_entry *ie;
- conn->ssp_mode = (ev->features[0] & 0x01);
- }
+ if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst)))
+ ie->data.ssp_mode = (ev->features[0] & 0x01);
- if (conn->state == BT_CONFIG) {
- if (!ev->status && hdev->ssp_mode > 0 &&
- conn->ssp_mode > 0 && conn->out &&
- conn->sec_level != BT_SECURITY_SDP) {
- struct hci_cp_auth_requested cp;
- cp.handle = ev->handle;
- hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
- sizeof(cp), &cp);
- } else {
- conn->state = BT_CONNECTED;
- hci_proto_connect_cfm(conn, ev->status);
- hci_conn_put(conn);
- }
- }
+ conn->ssp_mode = (ev->features[0] & 0x01);
+ }
+
+ if (conn->state != BT_CONFIG)
+ goto unlock;
+
+ if (!ev->status && hdev->ssp_mode > 0 &&
+ conn->ssp_mode > 0 && conn->out &&
+ conn->sec_level != BT_SECURITY_SDP) {
+ struct hci_cp_auth_requested cp;
+ cp.handle = ev->handle;
+ hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
+ sizeof(cp), &cp);
+ } else {
+ conn->state = BT_CONNECTED;
+ hci_proto_connect_cfm(conn, ev->status);
+ hci_conn_put(conn);
}
+unlock:
hci_dev_unlock(hdev);
}
--
1.7.2.3
^ permalink raw reply related
* [PATCHv2 7/7] simple-agent - add RequestApproval method for OOB pairing
From: Szymon Janc @ 2010-11-10 13:31 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1289395877-12384-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
* [PATCHv2 6/7] Update DBus OOB API with RequestApproval method.
From: Szymon Janc @ 2010-11-10 13:31 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1289395877-12384-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 b0f76db..7b93514 100644
--- a/doc/oob-api.txt
+++ b/doc/oob-api.txt
@@ -59,3 +59,17 @@ Methods void RegisterProvider(object provider)
Possible errors: org.bluez.Error.UpdateFailed
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
* [PATCHv2 5/7] Add approval request for incoming pairing requests with OOB mechanism
From: Szymon Janc @ 2010-11-10 13:31 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1289395877-12384-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 88bcf15..d66e3d2 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
* [PATCHv2 4/7] Add simple-oobprovider for testing.
From: Szymon Janc @ 2010-11-10 13:31 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1289395877-12384-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..8e89fdb
--- /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.UpdateLocalOobData(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
* [PATCHv2 3/7] Add DBus OOB API documentation.
From: Szymon Janc @ 2010-11-10 13:31 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1289395877-12384-1-git-send-email-szymon.janc@tieto.com>
---
Makefile.am | 2 +-
doc/oob-api.txt | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 62 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..b0f76db
--- /dev/null
+++ b/doc/oob-api.txt
@@ -0,0 +1,61 @@
+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 Deactivate()
+
+ 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
+ UpdateLocalOobData(object adapter)
+
+ This method generates new local OOB data for adapter.
+ Return value is pair of arrays 16 bytes each. Only
+ registered provider should call this method.
+
+ Possible errors: org.bluez.Error.UpdateFailed
+ org.bluez.Error.NoProvider
+ org.bluez.Error.InProgress
--
1.7.1
^ permalink raw reply related
* [PATCHv2 2/7] Add DBus OOB plugin.
From: Szymon Janc @ 2010-11-10 13:31 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1289395877-12384-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..7fc0c52
--- /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_updated(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 ".UpdateFailed",
+ "Failed to update local OOB.");
+
+ 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 *update_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 ".UpdateFailed",
+ "No adapter with given address found");
+
+ if (btd_adapter_read_local_oob_data(provider->adapter))
+ return g_dbus_create_error(msg, ERROR_INTERFACE ".UpdateFailed",
+ "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, "Deactivate");
+
+ 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},
+ { "UpdateLocalOobData", "o", "ayay", update_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_updated = local_data_updated;
+ 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
* [PATCHv2 1/7] Add support for Out of Band (OOB) association model.
From: Szymon Janc @ 2010-11-10 13:31 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1289395877-12384-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..88bcf15 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_updated(local, NULL, NULL);
+ else
+ oob_local_data_updated(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..cc20c67
--- /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_updated|| !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_updated(bdaddr_t *ba, uint8_t *hash, uint8_t *randomizer)
+{
+ if (active_plugin)
+ active_plugin->local_data_updated(ba, hash, randomizer);
+}
diff --git a/src/oob.h b/src/oob.h
new file mode 100644
index 0000000..b3e3623
--- /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);
+
+ /* Local OOB data updated. If corresponding HCI command failed, hash
+ * and randomizer are NULL */
+ void (*local_data_updated)(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_updated(bdaddr_t *ba, uint8_t *hash, uint8_t *randomizer);
--
1.7.1
^ permalink raw reply related
* [PATCHv2 0/7] Support for out of band association model
From: Szymon Janc @ 2010-11-10 13:31 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
Hello,
New version with some bugfixes/improvements and small changes in DBus API.
New feature is support for approval for incoming OOB pairing request.
Comments are welcome.
This email was sent on behalf of ST-Ericsson SA.
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 | 75 ++++++++++
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, 997 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 v2] Bluetooth: Automate remote name requests
From: Johan Hedberg @ 2010-11-10 13:17 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1289367862.9615.243.camel@aeonflux>
Hi Marcel,
On Wed, Nov 10, 2010, Marcel Holtmann wrote:
> please split this patch into two. One creating the common function for
> the authentication requested and one for adding the name request.
>
> My brain actually core dumps when following the logic and making sure
> that it is still correct. I pretty sure it is correct, but the whole
> patch is damn hard to review.
Yeah, sorry about this. I know the patch ended up being quite complex.
I'll resend it in three parts in a moment:
1. getting rid of multiple nested if-statements in the remote features
callbacks.
2. create a unified authentication request function
3. add the remote name request
Johan
^ permalink raw reply
* [PATCH 7/7] Changed number of fields selected via pbap queries
From: Bartosz Szatkowski @ 2010-11-10 13:15 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Bartosz Szatkowski
In-Reply-To: <1289394930-6694-1-git-send-email-bulislaw@linux.com>
After fixing type handling in PBAP, there are more fields selected in each
query, contacts_other_query_from_uri needed to be adjusted.
---
plugins/phonebook-tracker.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index f195f3f..672d59f 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -822,6 +822,7 @@
"SELECT \"\" \"\" \"\" \"\" \"\" \"\" \"\" \"\" \"\" \"\" \"\" "\
"\"\" \"\" \"\" \"\" \"\" \"\" \"\" \"\" \"\" \"\" \"\" \"\" " \
"\"\" \"\" \"\" \"\" \"\" \"\" \"\" \"\" \"\" \"\" \"\" " \
+ "\"\" \"\" \"\" \"\" \"\" \"\" \"\" \"\" \"\" " \
"nco:phoneNumber(?t) \"NOTACALL\" \"false\" \"false\" <%s> " \
"WHERE { " \
"<%s> a nco:Contact . " \
--
1.7.0.4
^ permalink raw reply related
* [PATCH 6/7] Fix proper type handling in contact_query_from_uri
From: Bartosz Szatkowski @ 2010-11-10 13:15 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Bartosz Szatkowski
In-Reply-To: <1289394930-6694-1-git-send-email-bulislaw@linux.com>
Previously all phone numbers, addresses and emails was considered to be "work".
Now there are three working types for emails and addresses: "work", "home",
"other" and four for phone numbers - these three as well as "cell".
---
plugins/phonebook-tracker.c | 38 ++++++++++++++++++++++++++------------
1 files changed, 26 insertions(+), 12 deletions(-)
diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index 616cc96..f195f3f 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -767,41 +767,55 @@
"} GROUP BY ?call ORDER BY DESC(nmo:receivedDate(?call))"
#define CONTACTS_QUERY_FROM_URI \
- "SELECT ?v nco:fullname(<%s>) " \
+ "SELECT nco:phoneNumber(?v) nco:fullname(<%s>) " \
"nco:nameFamily(<%s>) nco:nameGiven(<%s>) " \
"nco:nameAdditional(<%s>) nco:nameHonorificPrefix(<%s>) " \
"nco:nameHonorificSuffix(<%s>) nco:emailAddress(?e) " \
"nco:phoneNumber(?w) nco:pobox(?p) nco:extendedAddress(?p) " \
"nco:streetAddress(?p) nco:locality(?p) nco:region(?p) " \
- "nco:postalcode(?p) nco:country(?p) ?f nco:emailAddress(?ew)" \
+ "nco:postalcode(?p) nco:country(?p) ?f nco:emailAddress(?ew) " \
"nco:birthDate(<%s>) nco:nickname(<%s>) nco:url(<%s>) " \
"nco:photo(<%s>) nco:fullname(?o) nco:department(?a) " \
"nco:role(?a) nco:pobox(?pw) nco:extendedAddress(?pw) " \
"nco:streetAddress(?pw) nco:locality(?pw) nco:region(?pw) " \
"nco:postalcode(?pw) nco:country(?pw) nco:contactUID(<%s>) " \
- "nco:title(?a) nco:phoneNumber(?t) " \
+ "nco:title(?a) ?t nco:pobox(?po) nco:extendedAddress(?po) " \
+ "nco:streetAddress(?po) nco:locality(?po) nco:region(?po) " \
+ "nco:postalcode(?po) nco:country(?po) nco:emailAddress(?eo) " \
+ "?vc " \
"\"NOTACALL\" \"false\" \"false\" <%s> " \
"WHERE { " \
- "<%s> a nco:Contact . " \
- "OPTIONAL { <%s> nco:hasPhoneNumber ?h . \
- OPTIONAL {" \
+ "<%s> a nco:PersonContact . " \
+ "OPTIONAL { <%s> nco:hasPhoneNumber ?h . " \
+ "OPTIONAL {" \
"?h a nco:FaxNumber ; " \
"nco:phoneNumber ?f . " \
"}" \
"OPTIONAL {" \
+ "?h a nco:CellPhoneNumber ; " \
+ "nco:phoneNumber ?vc" \
+ "}" \
+ "OPTIONAL {" \
"?h a nco:VoicePhoneNumber ; " \
- "nco:phoneNumber ?v" \
+ "nco:phoneNumber ?t" \
"}" \
"}" \
- "OPTIONAL { <%s> nco:hasEmailAddress ?e . } " \
- "OPTIONAL { <%s> nco:hasPostalAddress ?p . } " \
"OPTIONAL { " \
"<%s> nco:hasAffiliation ?a . " \
- "OPTIONAL { ?a nco:hasPhoneNumber ?w . }" \
- "OPTIONAL { ?a nco:hasEmailAddress ?ew . }" \
- "OPTIONAL { ?a nco:hasPostalAddress ?pw . } " \
+ "OPTIONAL { ?a rdfs:label \"Work\" . " \
+ "OPTIONAL { ?a nco:hasEmailAddress ?ew . } " \
+ "OPTIONAL { ?a nco:hasPostalAddress ?pw . } " \
+ "OPTIONAL { ?a nco:hasPhoneNumber ?w . } " \
+ "}" \
+ "OPTIONAL { ?a rdfs:label \"Home\" . " \
+ "OPTIONAL { ?a nco:hasEmailAddress ?e . } " \
+ "OPTIONAL { ?a nco:hasPostalAddress ?p . } " \
+ "OPTIONAL { ?a nco:hasPhoneNumber ?v . } " \
+ "}" \
"OPTIONAL { ?a nco:org ?o . } " \
"} " \
+ "OPTIONAL { <%s> nco:hasPostalAddress ?po . } " \
+ "OPTIONAL { <%s> nco:hasEmailAddress ?eo . } " \
"}"
#define CONTACTS_OTHER_QUERY_FROM_URI \
--
1.7.0.4
^ permalink raw reply related
* [PATCH 5/7] Fix proper type handling in combined_calls_query
From: Bartosz Szatkowski @ 2010-11-10 13:15 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Bartosz Szatkowski
In-Reply-To: <1289394930-6694-1-git-send-email-bulislaw@linux.com>
Previously all phone numbers, addresses and emails was considered to be "work".
Now there are three working types for emails and addresses: "work", "home",
"other" and four for phone numbers - these three as well as "cell".
---
plugins/phonebook-tracker.c | 152 +++++++++++++++++++++++++++++++++---------
1 files changed, 119 insertions(+), 33 deletions(-)
diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index c40eb63..616cc96 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -536,11 +536,11 @@
"} GROUP BY ?call ORDER BY DESC(nmo:sentDate(?call))"
#define COMBINED_CALLS_QUERY \
- "SELECT nco:phoneNumber(?h) nco:fullname(?c) " \
+ "SELECT ?h nco:fullname(?c) " \
"nco:nameFamily(?c) nco:nameGiven(?c) " \
"nco:nameAdditional(?c) nco:nameHonorificPrefix(?c) " \
"nco:nameHonorificSuffix(?c) nco:emailAddress(?e) " \
- "nco:phoneNumber(?w) nco:pobox(?p) nco:extendedAddress(?p) " \
+ "?w nco:pobox(?p) nco:extendedAddress(?p) " \
"nco:streetAddress(?p) nco:locality(?p) nco:region(?p) " \
"nco:postalcode(?p) nco:country(?p) \"\" nco:emailAddress(?ew) "\
"nco:birthDate(?c) nco:nickname(?c) nco:url(?c) " \
@@ -548,7 +548,11 @@
"nco:role(?a) nco:pobox(?pw) nco:extendedAddress(?pw) " \
"nco:streetAddress(?pw) nco:locality(?pw) nco:region(?pw) " \
"nco:postalcode(?pw) nco:country(?pw) nco:contactUID(?c) " \
- "nco:title(?a) nco:phoneNumber(?t) nmo:receivedDate(?call) " \
+ "nco:title(?a) nco:phoneNumber(?t) nco:pobox(?po) " \
+ "nco:extendedAddress(?po) nco:streetAddress(?po) " \
+ "nco:locality(?po) nco:region(?po) nco:postalcode(?po) " \
+ "nco:country(?po) nco:emailAddress(?eo) ?vc " \
+ "nmo:receivedDate(?call) " \
"nmo:isSent(?call) nmo:isAnswered(?call) ?x " \
"WHERE { " \
"{ " \
@@ -557,74 +561,156 @@
"?call a nmo:Call ; " \
"nmo:to ?x ; " \
"nmo:isSent true . " \
- "} UNION { " \
- "?x a nco:Contact . " \
- "?x nco:hasPhoneNumber ?h . " \
- "?call a nmo:Call ; " \
- "nmo:to ?x ; " \
- "nmo:isSent true . " \
"?c a nco:PersonContact . " \
- "?c nco:hasPhoneNumber ?h . " \
- "OPTIONAL { ?c nco:hasEmailAddress ?e . } " \
- "OPTIONAL { ?c nco:hasPostalAddress ?p . } " \
+ "?c nco:hasPhoneNumber ?t . " \
+ "OPTIONAL { " \
+ "?t a nco:CellPhoneNumber ; " \
+ "nco:phoneNumber ?vc . " \
+ "} " \
+ "OPTIONAL { ?c nco:hasPostalAddress ?po . } " \
+ "OPTIONAL { ?c nco:hasEmailAddress ?eo . } " \
"OPTIONAL { " \
"?c nco:hasAffiliation ?a . " \
+ "OPTIONAL { " \
+ "?a rdfs:label \"Work\" . " \
"OPTIONAL { ?a nco:hasEmailAddress ?ew . } " \
"OPTIONAL { ?a nco:hasPostalAddress ?pw . } " \
+ "}" \
+ "OPTIONAL { " \
+ "?a rdfs:label \"Home\" . " \
+ "OPTIONAL { ?a nco:hasEmailAddress ?e . } " \
+ "OPTIONAL { ?a nco:hasPostalAddress ?p . } " \
+ "} " \
"OPTIONAL { ?a nco:org ?o . } " \
"} " \
"} UNION { " \
"?x a nco:Contact . " \
- "?x nco:hasPhoneNumber ?w . " \
+ "?x nco:hasPhoneNumber ?tmp . " \
"?call a nmo:Call ; " \
"nmo:to ?x ; " \
"nmo:isSent true . " \
"?c a nco:PersonContact . " \
- "OPTIONAL { ?c nco:hasEmailAddress ?e . } " \
- "OPTIONAL { ?c nco:hasPostalAddress ?p . } " \
"?c nco:hasAffiliation ?a . " \
- "?a nco:hasPhoneNumber ?w . " \
- "OPTIONAL { ?a nco:hasEmailAddress ?ew . } " \
- "OPTIONAL { ?a nco:hasPostalAddress ?pw . } " \
- "OPTIONAL { ?a nco:org ?o . } " \
+ "?a nco:hasPhoneNumber ?tmp . " \
+ "OPTIONAL { " \
+ "?a rdfs:label \"Work\" . " \
+ "?tmp nco:phoneNumber ?w . " \
+ "OPTIONAL { ?a nco:hasEmailAddress ?ew . } " \
+ "OPTIONAL { ?a nco:hasPostalAddress ?pw . } " \
+ "OPTIONAL { ?a nco:org ?o . } " \
+ "{ " \
+ "SELECT ?p ?e ?c WHERE { " \
+ "?c nco:hasAffiliation ?b . " \
+ "?b rdfs:label \"Home\" . " \
+ "OPTIONAL {?b nco:hasEmailAddress ?e . } " \
+ "OPTIONAL {?b nco:hasPostalAddress ?p . }} " \
+ "} " \
+ "}" \
+ "OPTIONAL { " \
+ "?a rdfs:label \"Home\" . " \
+ "?tmp nco:phoneNumber ?h . " \
+ "OPTIONAL { ?a nco:hasEmailAddress ?e . } " \
+ "OPTIONAL { ?a nco:hasPostalAddress ?p . } " \
+ "OPTIONAL { ?a nco:org ?o . } " \
+ "{ " \
+ "SELECT ?pw ?ew ?c WHERE { " \
+ "?c nco:hasAffiliation ?b . " \
+ "?b rdfs:label \"Work\" . " \
+ "OPTIONAL {?b nco:hasEmailAddress ?ew . } " \
+ "OPTIONAL {?b nco:hasPostalAddress ?pw . }} " \
+ "} " \
+ "}" \
"} UNION { " \
"?x a nco:Contact . " \
"?x nco:hasPhoneNumber ?t . " \
"?call a nmo:Call ; " \
- "nmo:from ?x ; " \
- "nmo:isSent false . " \
+ "nmo:to ?x ; " \
+ "nmo:isSent true . " \
+ "OPTIONAL {?c a nco:PersonContact ; " \
+ "nco:hasPhoneNumber ?t . } " \
+ "OPTIONAL {?c a nco:PersonContact ; " \
+ "nco:hasAffiliation ?a . " \
+ "?a nco:hasPhoneNumber ?t . } " \
+ "FILTER ( !bound(?c) && !bound(?a) ) . " \
"} UNION { " \
"?x a nco:Contact . " \
- "?x nco:hasPhoneNumber ?h . " \
+ "?x nco:hasPhoneNumber ?t . " \
"?call a nmo:Call ; " \
"nmo:from ?x ; " \
"nmo:isSent false . " \
"?c a nco:PersonContact . " \
- "?c nco:hasPhoneNumber ?h . " \
- "OPTIONAL { ?c nco:hasEmailAddress ?e . } " \
- "OPTIONAL { ?c nco:hasPostalAddress ?p . } " \
+ "?c nco:hasPhoneNumber ?t . " \
+ "OPTIONAL { " \
+ "?t a nco:CellPhoneNumber ; " \
+ "nco:phoneNumber ?vc . " \
+ "} " \
+ "OPTIONAL { ?c nco:hasPostalAddress ?po . } " \
+ "OPTIONAL { ?c nco:hasEmailAddress ?eo . } " \
"OPTIONAL { " \
"?c nco:hasAffiliation ?a . " \
+ "OPTIONAL { " \
+ "?a rdfs:label \"Work\" . " \
"OPTIONAL { ?a nco:hasEmailAddress ?ew . } " \
"OPTIONAL { ?a nco:hasPostalAddress ?pw . } " \
+ "}" \
+ "OPTIONAL { " \
+ "?a rdfs:label \"Home\" . " \
+ "OPTIONAL { ?a nco:hasEmailAddress ?e . } " \
+ "OPTIONAL { ?a nco:hasPostalAddress ?p . } " \
+ "} " \
"OPTIONAL { ?a nco:org ?o . } " \
"} " \
"} UNION { " \
"?x a nco:Contact . " \
- "?x nco:hasPhoneNumber ?w . " \
+ "?x nco:hasPhoneNumber ?tmp . " \
"?call a nmo:Call ; " \
"nmo:from ?x ; " \
"nmo:isSent false . " \
"?c a nco:PersonContact . " \
- "OPTIONAL { ?c nco:hasEmailAddress ?e . } " \
- "OPTIONAL { ?c nco:hasPostalAddress ?p . } " \
"?c nco:hasAffiliation ?a . " \
- "?a nco:hasPhoneNumber ?w . " \
- "OPTIONAL { ?a nco:hasEmailAddress ?ew . } " \
- "OPTIONAL { ?a nco:hasPostalAddress ?pw . } " \
- "OPTIONAL { ?a nco:org ?o . } " \
+ "?a nco:hasPhoneNumber ?tmp . " \
+ "OPTIONAL { " \
+ "?a rdfs:label \"Work\" . " \
+ "?tmp nco:phoneNumber ?w . " \
+ "OPTIONAL { ?a nco:hasEmailAddress ?ew . } " \
+ "OPTIONAL { ?a nco:hasPostalAddress ?pw . } " \
+ "OPTIONAL { ?a nco:org ?o . } " \
+ "{ " \
+ "SELECT ?p ?e ?c WHERE { " \
+ "?c nco:hasAffiliation ?b . " \
+ "?b rdfs:label \"Home\" . " \
+ "OPTIONAL {?b nco:hasEmailAddress ?e . } " \
+ "OPTIONAL {?b nco:hasPostalAddress ?p . }} " \
+ "} " \
+ "}" \
+ "OPTIONAL { " \
+ "?a rdfs:label \"Home\" . " \
+ "?tmp nco:phoneNumber ?h . " \
+ "OPTIONAL { ?a nco:hasEmailAddress ?e . } " \
+ "OPTIONAL { ?a nco:hasPostalAddress ?p . } " \
+ "OPTIONAL { ?a nco:org ?o . } " \
+ "{ " \
+ "SELECT ?pw ?ew ?c WHERE { " \
+ "?c nco:hasAffiliation ?b . " \
+ "?b rdfs:label \"Work\" . " \
+ "OPTIONAL {?b nco:hasEmailAddress ?ew . } " \
+ "OPTIONAL {?b nco:hasPostalAddress ?pw . }} " \
+ "} " \
+ "}" \
+ "} UNION { " \
+ "?x a nco:Contact . " \
+ "?x nco:hasPhoneNumber ?t . " \
+ "?call a nmo:Call ; " \
+ "nmo:from ?x ; " \
+ "nmo:isSent false . " \
+ "OPTIONAL {?c a nco:PersonContact ; " \
+ "nco:hasPhoneNumber ?t . } " \
+ "OPTIONAL {?c a nco:PersonContact ; " \
+ "nco:hasAffiliation ?a . " \
+ "?a nco:hasPhoneNumber ?t . } " \
+ "FILTER ( !bound(?c) && !bound(?a) ) . " \
"} " \
- "} GROUP BY ?call ORDER BY DESC(nmo:receivedDate(?call)) "
+ "} ORDER BY DESC(nmo:receivedDate(?call)) "
#define COMBINED_CALLS_LIST \
"SELECT ?c nco:nameFamily(?c) nco:nameGiven(?c) " \
--
1.7.0.4
^ permalink raw reply related
* [PATCH 4/7] Fix proper type handling in outgoing_calls_query
From: Bartosz Szatkowski @ 2010-11-10 13:15 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Bartosz Szatkowski
In-Reply-To: <1289394930-6694-1-git-send-email-bulislaw@linux.com>
Previously all phone numbers, addresses and emails was considered to be "work".
Now there are three working types for emails and addresses: "work", "home",
"other" and four for phone numbers - these three as well as "cell".
---
plugins/phonebook-tracker.c | 85 +++++++++++++++++++++++++++++++++----------
1 files changed, 65 insertions(+), 20 deletions(-)
diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index bd67699..c40eb63 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -404,19 +404,23 @@
"} GROUP BY ?call ORDER BY DESC(nmo:receivedDate(?call))"
#define OUTGOING_CALLS_QUERY \
- "SELECT nco:phoneNumber(?h) nco:fullname(?c) " \
+ "SELECT ?h nco:fullname(?c) " \
"nco:nameFamily(?c) nco:nameGiven(?c) " \
"nco:nameAdditional(?c) nco:nameHonorificPrefix(?c) " \
"nco:nameHonorificSuffix(?c) nco:emailAddress(?e) " \
- "nco:phoneNumber(?w) nco:pobox(?p) nco:extendedAddress(?p) " \
+ "?w nco:pobox(?p) nco:extendedAddress(?p) " \
"nco:streetAddress(?p) nco:locality(?p) nco:region(?p) " \
- "nco:postalcode(?p) nco:country(?p) \"\" nco:emailAddress(?ew)" \
+ "nco:postalcode(?p) nco:country(?p) \"\" nco:emailAddress(?ew) "\
"nco:birthDate(?c) nco:nickname(?c) nco:url(?c) " \
"nco:photo(?c) nco:fullname(?o) nco:department(?a) " \
"nco:role(?a) nco:pobox(?pw) nco:extendedAddress(?pw) " \
"nco:streetAddress(?pw) nco:locality(?pw) nco:region(?pw) " \
"nco:postalcode(?pw) nco:country(?pw) nco:contactUID(?c) " \
- "nco:title(?a) nco:phoneNumber(?t) nmo:receivedDate(?call) " \
+ "nco:title(?a) nco:phoneNumber(?t) nco:pobox(?po) " \
+ "nco:extendedAddress(?po) nco:streetAddress(?po) " \
+ "nco:locality(?po) nco:region(?po) nco:postalcode(?po) " \
+ "nco:country(?po) nco:emailAddress(?eo) ?vc " \
+ "nmo:receivedDate(?call) " \
"nmo:isSent(?call) nmo:isAnswered(?call) ?x " \
"WHERE { " \
"{ " \
@@ -425,38 +429,79 @@
"?call a nmo:Call ; " \
"nmo:to ?x ; " \
"nmo:isSent true . " \
+ "?c a nco:PersonContact . " \
+ "?c nco:hasPhoneNumber ?t . " \
+ "OPTIONAL { " \
+ "?t a nco:CellPhoneNumber ; " \
+ "nco:phoneNumber ?vc . " \
+ "} " \
+ "OPTIONAL { ?c nco:hasPostalAddress ?po . } " \
+ "OPTIONAL { ?c nco:hasEmailAddress ?eo . } " \
+ "OPTIONAL { " \
+ "?c nco:hasAffiliation ?a . " \
+ "OPTIONAL { " \
+ "?a rdfs:label \"Work\" . " \
+ "OPTIONAL { ?a nco:hasEmailAddress ?ew . } " \
+ "OPTIONAL { ?a nco:hasPostalAddress ?pw . } " \
+ "}" \
+ "OPTIONAL { " \
+ "?a rdfs:label \"Home\" . " \
+ "OPTIONAL { ?a nco:hasEmailAddress ?e . } " \
+ "OPTIONAL { ?a nco:hasPostalAddress ?p . } " \
+ "} " \
+ "OPTIONAL { ?a nco:org ?o . } " \
+ "} " \
"} UNION { " \
"?x a nco:Contact . " \
- "?x nco:hasPhoneNumber ?h . " \
+ "?x nco:hasPhoneNumber ?tmp . " \
"?call a nmo:Call ; " \
"nmo:to ?x ; " \
"nmo:isSent true . " \
"?c a nco:PersonContact . " \
- "?c nco:hasPhoneNumber ?h . " \
- "OPTIONAL { ?c nco:hasEmailAddress ?e . } " \
- "OPTIONAL { ?c nco:hasPostalAddress ?p . } " \
+ "?c nco:hasAffiliation ?a . " \
+ "?a nco:hasPhoneNumber ?tmp . " \
"OPTIONAL { " \
- "?c nco:hasAffiliation ?a . " \
+ "?a rdfs:label \"Work\" . " \
+ "?tmp nco:phoneNumber ?w . " \
"OPTIONAL { ?a nco:hasEmailAddress ?ew . } " \
"OPTIONAL { ?a nco:hasPostalAddress ?pw . } " \
"OPTIONAL { ?a nco:org ?o . } " \
- "} " \
+ "{ " \
+ "SELECT ?p ?e ?c WHERE { " \
+ "?c nco:hasAffiliation ?b . " \
+ "?b rdfs:label \"Home\" . " \
+ "OPTIONAL {?b nco:hasEmailAddress ?e . } " \
+ "OPTIONAL {?b nco:hasPostalAddress ?p . }} " \
+ "} " \
+ "}" \
+ "OPTIONAL { " \
+ "?a rdfs:label \"Home\" . " \
+ "?tmp nco:phoneNumber ?h . " \
+ "OPTIONAL { ?a nco:hasEmailAddress ?e . } " \
+ "OPTIONAL { ?a nco:hasPostalAddress ?p . } " \
+ "OPTIONAL { ?a nco:org ?o . } " \
+ "{ " \
+ "SELECT ?pw ?ew ?c WHERE { " \
+ "?c nco:hasAffiliation ?b . " \
+ "?b rdfs:label \"Work\" . " \
+ "OPTIONAL {?b nco:hasEmailAddress ?ew . } " \
+ "OPTIONAL {?b nco:hasPostalAddress ?pw . }} " \
+ "} " \
+ "}" \
"} UNION { " \
"?x a nco:Contact . " \
- "?x nco:hasPhoneNumber ?w . " \
+ "?x nco:hasPhoneNumber ?t . " \
"?call a nmo:Call ; " \
"nmo:to ?x ; " \
"nmo:isSent true . " \
- "?c a nco:PersonContact . " \
- "OPTIONAL { ?c nco:hasEmailAddress ?e . } " \
- "OPTIONAL { ?c nco:hasPostalAddress ?p . } " \
- "?c nco:hasAffiliation ?a . " \
- "?a nco:hasPhoneNumber ?w . " \
- "OPTIONAL { ?a nco:hasEmailAddress ?ew . } " \
- "OPTIONAL { ?a nco:hasPostalAddress ?pw . } " \
- "OPTIONAL { ?a nco:org ?o . } " \
+ "OPTIONAL {?c a nco:PersonContact ; " \
+ "nco:hasPhoneNumber ?t . } " \
+ "OPTIONAL {?c a nco:PersonContact ; " \
+ "nco:hasAffiliation ?a . " \
+ "?a nco:hasPhoneNumber ?t . } " \
+ "FILTER ( !bound(?c) && !bound(?a) ) . " \
"} " \
- "} GROUP BY ?call ORDER BY DESC(nmo:sentDate(?call)) "
+ "} ORDER BY DESC(nmo:sentDate(?call)) "
#define OUTGOING_CALLS_LIST \
"SELECT ?c nco:nameFamily(?c) " \
--
1.7.0.4
^ permalink raw reply related
* [PATCH 3/7] Fix proper type handling in incoming_calls_query
From: Bartosz Szatkowski @ 2010-11-10 13:15 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Bartosz Szatkowski
In-Reply-To: <1289394930-6694-1-git-send-email-bulislaw@linux.com>
Previously all phone numbers, addresses and emails was considered to be "work".
Now there are three working types for emails and addresses: "work", "home",
"other" and four for phone numbers - these three as well as "cell".
---
plugins/phonebook-tracker.c | 83 +++++++++++++++++++++++++++++++++----------
1 files changed, 64 insertions(+), 19 deletions(-)
diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index e84c589..bd67699 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -266,11 +266,11 @@
"} GROUP BY ?call ORDER BY DESC(nmo:receivedDate(?call))"
#define INCOMING_CALLS_QUERY \
- "SELECT nco:phoneNumber(?h) nco:fullname(?c) " \
+ "SELECT ?h nco:fullname(?c) " \
"nco:nameFamily(?c) nco:nameGiven(?c) " \
"nco:nameAdditional(?c) nco:nameHonorificPrefix(?c) " \
"nco:nameHonorificSuffix(?c) nco:emailAddress(?e) " \
- "nco:phoneNumber(?w) nco:pobox(?p) nco:extendedAddress(?p) " \
+ "?w nco:pobox(?p) nco:extendedAddress(?p) " \
"nco:streetAddress(?p) nco:locality(?p) nco:region(?p) " \
"nco:postalcode(?p) nco:country(?p) \"\" nco:emailAddress(?ew) "\
"nco:birthDate(?c) nco:nickname(?c) nco:url(?c) " \
@@ -278,7 +278,11 @@
"nco:role(?a) nco:pobox(?pw) nco:extendedAddress(?pw) " \
"nco:streetAddress(?pw) nco:locality(?pw) nco:region(?pw) " \
"nco:postalcode(?pw) nco:country(?pw) nco:contactUID(?c) " \
- "nco:title(?a) nco:phoneNumber(?t) nmo:receivedDate(?call) " \
+ "nco:title(?a) nco:phoneNumber(?t) nco:pobox(?po) " \
+ "nco:extendedAddress(?po) nco:streetAddress(?po) " \
+ "nco:locality(?po) nco:region(?po) nco:postalcode(?po) " \
+ "nco:country(?po) nco:emailAddress(?eo) ?vc " \
+ "nmo:receivedDate(?call) " \
"nmo:isSent(?call) nmo:isAnswered(?call) ?x " \
"WHERE { " \
"{ " \
@@ -288,40 +292,81 @@
"nmo:from ?x ; " \
"nmo:isSent false ; " \
"nmo:isAnswered true . " \
+ "?c a nco:PersonContact . " \
+ "?c nco:hasPhoneNumber ?t . " \
+ "OPTIONAL { " \
+ "?t a nco:CellPhoneNumber ; " \
+ "nco:phoneNumber ?vc . " \
+ "} " \
+ "OPTIONAL { ?c nco:hasPostalAddress ?po . } " \
+ "OPTIONAL { ?c nco:hasEmailAddress ?eo . } " \
+ "OPTIONAL { " \
+ "?c nco:hasAffiliation ?a . " \
+ "OPTIONAL { " \
+ "?a rdfs:label \"Work\" . " \
+ "OPTIONAL { ?a nco:hasEmailAddress ?ew . } " \
+ "OPTIONAL { ?a nco:hasPostalAddress ?pw . } " \
+ "}" \
+ "OPTIONAL { " \
+ "?a rdfs:label \"Home\" . " \
+ "OPTIONAL { ?a nco:hasEmailAddress ?e . } " \
+ "OPTIONAL { ?a nco:hasPostalAddress ?p . } " \
+ "} " \
+ "OPTIONAL { ?a nco:org ?o . } " \
+ "} " \
"} UNION { " \
"?x a nco:Contact . " \
- "?x nco:hasPhoneNumber ?h . " \
+ "?x nco:hasPhoneNumber ?tmp . " \
"?call a nmo:Call ; " \
"nmo:from ?x ; " \
"nmo:isSent false ; " \
"nmo:isAnswered true . " \
"?c a nco:PersonContact . " \
- "?c nco:hasPhoneNumber ?h . " \
- "OPTIONAL { ?c nco:hasEmailAddress ?e . } " \
- "OPTIONAL { ?c nco:hasPostalAddress ?p . } " \
+ "?c nco:hasAffiliation ?a . " \
+ "?a nco:hasPhoneNumber ?tmp . " \
"OPTIONAL { " \
- "?c nco:hasAffiliation ?a . " \
+ "?a rdfs:label \"Work\" . " \
+ "?tmp nco:phoneNumber ?w . " \
"OPTIONAL { ?a nco:hasEmailAddress ?ew . } " \
"OPTIONAL { ?a nco:hasPostalAddress ?pw . } " \
"OPTIONAL { ?a nco:org ?o . } " \
- "} " \
+ "{ " \
+ "SELECT ?p ?e ?c WHERE { " \
+ "?c nco:hasAffiliation ?b . " \
+ "?b rdfs:label \"Home\" . " \
+ "OPTIONAL {?b nco:hasEmailAddress ?e . } " \
+ "OPTIONAL {?b nco:hasPostalAddress ?p . }} " \
+ "} " \
+ "}" \
+ "OPTIONAL { " \
+ "?a rdfs:label \"Home\" . " \
+ "?tmp nco:phoneNumber ?h . " \
+ "OPTIONAL { ?a nco:hasEmailAddress ?e . } " \
+ "OPTIONAL { ?a nco:hasPostalAddress ?p . } " \
+ "OPTIONAL { ?a nco:org ?o . } " \
+ "{ " \
+ "SELECT ?pw ?ew ?c WHERE { " \
+ "?c nco:hasAffiliation ?b . " \
+ "?b rdfs:label \"Work\" . " \
+ "OPTIONAL {?b nco:hasEmailAddress ?ew . } " \
+ "OPTIONAL {?b nco:hasPostalAddress ?pw . }} " \
+ "} " \
+ "}" \
"} UNION { " \
"?x a nco:Contact . " \
- "?x nco:hasPhoneNumber ?w . " \
+ "?x nco:hasPhoneNumber ?t . " \
"?call a nmo:Call ; " \
"nmo:from ?x ; " \
"nmo:isSent false ; " \
"nmo:isAnswered true . " \
- "?c a nco:PersonContact . " \
- "OPTIONAL { ?c nco:hasEmailAddress ?e . } " \
- "OPTIONAL { ?c nco:hasPostalAddress ?p . } " \
- "?c nco:hasAffiliation ?a . " \
- "?a nco:hasPhoneNumber ?w . " \
- "OPTIONAL { ?a nco:hasEmailAddress ?ew . } " \
- "OPTIONAL { ?a nco:hasPostalAddress ?pw . } " \
- "OPTIONAL { ?a nco:org ?o . } " \
+ "OPTIONAL {?c a nco:PersonContact ; " \
+ "nco:hasPhoneNumber ?t . } " \
+ "OPTIONAL {?c a nco:PersonContact ; " \
+ "nco:hasAffiliation ?a . " \
+ "?a nco:hasPhoneNumber ?t . } " \
+ "FILTER ( !bound(?c) && !bound(?a) ) . " \
"} " \
- "} GROUP BY ?call ORDER BY DESC(nmo:receivedDate(?call)) "
+ "} ORDER BY DESC(nmo:receivedDate(?call)) "
#define INCOMING_CALLS_LIST \
"SELECT ?c nco:nameFamily(?c) " \
--
1.7.0.4
^ permalink raw reply related
* [PATCH 2/7] Fix proper type handling in missed_calls_query
From: Bartosz Szatkowski @ 2010-11-10 13:15 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Bartosz Szatkowski
In-Reply-To: <1289394930-6694-1-git-send-email-bulislaw@linux.com>
Previously all phone numbers, addresses and emails was considered to be "work".
Now there are three working types for emails and addresses: "work", "home",
"other" and four for phone numbers - these three as well as "cell".
---
plugins/phonebook-tracker.c | 84 +++++++++++++++++++++++++++++++++----------
1 files changed, 65 insertions(+), 19 deletions(-)
diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index 83327e0..e84c589 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -127,11 +127,11 @@
"} GROUP BY ?c"
#define MISSED_CALLS_QUERY \
- "SELECT nco:phoneNumber(?h) nco:fullname(?c) " \
+ "SELECT ?h nco:fullname(?c) " \
"nco:nameFamily(?c) nco:nameGiven(?c) " \
"nco:nameAdditional(?c) nco:nameHonorificPrefix(?c) " \
"nco:nameHonorificSuffix(?c) nco:emailAddress(?e) " \
- "nco:phoneNumber(?w) nco:pobox(?p) nco:extendedAddress(?p) " \
+ "?w nco:pobox(?p) nco:extendedAddress(?p) " \
"nco:streetAddress(?p) nco:locality(?p) nco:region(?p) " \
"nco:postalcode(?p) nco:country(?p) \"\" nco:emailAddress(?ew) "\
"nco:birthDate(?c) nco:nickname(?c) nco:url(?c) " \
@@ -139,7 +139,11 @@
"nco:role(?a) nco:pobox(?pw) nco:extendedAddress(?pw) " \
"nco:streetAddress(?pw) nco:locality(?pw) nco:region(?pw) " \
"nco:postalcode(?pw) nco:country(?pw) nco:contactUID(?c) " \
- "nco:title(?a) nco:phoneNumber(?t) nmo:receivedDate(?call) " \
+ "nco:title(?a) nco:phoneNumber(?t) nco:pobox(?po) " \
+ "nco:extendedAddress(?po) nco:streetAddress(?po) " \
+ "nco:locality(?po) nco:region(?po) nco:postalcode(?po) " \
+ "nco:country(?po) nco:emailAddress(?eo) ?vc " \
+ "nmo:receivedDate(?call) " \
"nmo:isSent(?call) nmo:isAnswered(?call) ?x " \
"WHERE { " \
"{ " \
@@ -149,40 +153,82 @@
"nmo:from ?x ; " \
"nmo:isSent false ; " \
"nmo:isAnswered false . " \
+ "?c a nco:PersonContact . " \
+ "?c nco:hasPhoneNumber ?t . " \
+ "OPTIONAL { " \
+ "?t a nco:CellPhoneNumber ; " \
+ "nco:phoneNumber ?vc . " \
+ "} " \
+ "OPTIONAL { ?c nco:hasPostalAddress ?po . } " \
+ "OPTIONAL { ?c nco:hasEmailAddress ?eo . } " \
+ "OPTIONAL { " \
+ "?c nco:hasAffiliation ?a . " \
+ "OPTIONAL { " \
+ "?a rdfs:label \"Work\" . " \
+ "OPTIONAL { ?a nco:hasEmailAddress ?ew . } " \
+ "OPTIONAL { ?a nco:hasPostalAddress ?pw . } " \
+ "}" \
+ "OPTIONAL { " \
+ "?a rdfs:label \"Home\" . " \
+ "OPTIONAL { ?a nco:hasEmailAddress ?e . } " \
+ "OPTIONAL { ?a nco:hasPostalAddress ?p . } " \
+ "} " \
+ "OPTIONAL { ?a nco:org ?o . } " \
+ "} " \
"} UNION { " \
"?x a nco:Contact . " \
- "?x nco:hasPhoneNumber ?h . " \
+ "?x nco:hasPhoneNumber ?tmp . " \
"?call a nmo:Call ; " \
"nmo:from ?x ; " \
"nmo:isSent false ; " \
"nmo:isAnswered false . " \
"?c a nco:PersonContact . " \
- "?c nco:hasPhoneNumber ?h . " \
- "OPTIONAL { ?c nco:hasEmailAddress ?e . } " \
- "OPTIONAL { ?c nco:hasPostalAddress ?p . } " \
+ "?c nco:hasAffiliation ?a . " \
+ "?a nco:hasPhoneNumber ?tmp . " \
"OPTIONAL { " \
- "?c nco:hasAffiliation ?a . " \
+ "?a rdfs:label \"Work\" . " \
+ "?tmp nco:phoneNumber ?w . " \
"OPTIONAL { ?a nco:hasEmailAddress ?ew . } " \
"OPTIONAL { ?a nco:hasPostalAddress ?pw . } " \
"OPTIONAL { ?a nco:org ?o . } " \
- "} " \
+ "{ " \
+ "SELECT ?p ?e ?c WHERE { " \
+ "?c nco:hasAffiliation ?b . " \
+ "?b rdfs:label \"Home\" . " \
+ "OPTIONAL {?b nco:hasEmailAddress ?e . } " \
+ "OPTIONAL {?b nco:hasPostalAddress ?p . }} " \
+ "} " \
+ "}" \
+ "OPTIONAL { " \
+ "?a rdfs:label \"Home\" . " \
+ "?tmp nco:phoneNumber ?h . " \
+ "OPTIONAL { ?a nco:hasEmailAddress ?e . } " \
+ "OPTIONAL { ?a nco:hasPostalAddress ?p . } " \
+ "OPTIONAL { ?a nco:org ?o . } " \
+ "{ " \
+ "SELECT ?pw ?ew ?c WHERE { " \
+ "?c nco:hasAffiliation ?b . " \
+ "?b rdfs:label \"Work\" . " \
+ "OPTIONAL {?b nco:hasEmailAddress ?ew . } " \
+ "OPTIONAL {?b nco:hasPostalAddress ?pw . }} " \
+ "} " \
+ "}" \
"} UNION { " \
"?x a nco:Contact . " \
- "?x nco:hasPhoneNumber ?w . " \
+ "?x nco:hasPhoneNumber ?t . " \
"?call a nmo:Call ; " \
"nmo:from ?x ; " \
"nmo:isSent false ; " \
"nmo:isAnswered false . " \
- "?c a nco:PersonContact . " \
- "OPTIONAL { ?c nco:hasEmailAddress ?e . } " \
- "OPTIONAL { ?c nco:hasPostalAddress ?p . } " \
- "?c nco:hasAffiliation ?a . " \
- "?a nco:hasPhoneNumber ?w . " \
- "OPTIONAL { ?a nco:hasEmailAddress ?ew . } " \
- "OPTIONAL { ?a nco:hasPostalAddress ?pw . } " \
- "OPTIONAL { ?a nco:org ?o . } " \
+ "OPTIONAL {?c a nco:PersonContact ; " \
+ "nco:hasPhoneNumber ?t . } " \
+ "OPTIONAL {?c a nco:PersonContact ; " \
+ "nco:hasAffiliation ?a . " \
+ "?a nco:hasPhoneNumber ?t . } " \
+ "FILTER ( !bound(?c) && !bound(?a) ) . " \
"} " \
- "} GROUP BY ?call ORDER BY DESC(nmo:receivedDate(?call)) "
+ "} ORDER BY DESC(nmo:receivedDate(?call)) "
+
#define MISSED_CALLS_LIST \
"SELECT ?c nco:nameFamily(?c) " \
--
1.7.0.4
^ permalink raw reply related
* [PATCH 1/7] Fix proper type handling in contacts_query_all
From: Bartosz Szatkowski @ 2010-11-10 13:15 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Bartosz Szatkowski
Previously all phone numbers, addresses and emails was considered to be "work".
Now there are three working types for emails and addresses: "work", "home",
"other" and four for phone numbers - these three as well as "cell".
---
plugins/phonebook-tracker.c | 61 +++++++++++++++++++++++++++++++------------
1 files changed, 44 insertions(+), 17 deletions(-)
diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index 58f52ab..83327e0 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -43,8 +43,8 @@
#define TRACKER_RESOURCES_INTERFACE "org.freedesktop.Tracker1.Resources"
#define TRACKER_DEFAULT_CONTACT_ME "http://www.semanticdesktop.org/ontologies/2007/03/22/nco#default-contact-me"
-#define CONTACTS_ID_COL 38
-#define PULL_QUERY_COL_AMOUNT 39
+#define CONTACTS_ID_COL 47
+#define PULL_QUERY_COL_AMOUNT 48
#define COUNT_QUERY_COL_AMOUNT 1
#define COL_HOME_NUMBER 0
#define COL_HOME_EMAIL 7
@@ -52,14 +52,16 @@
#define COL_FAX_NUMBER 16
#define COL_WORK_EMAIL 17
#define COL_OTHER_NUMBER 34
-#define COL_DATE 35
-#define COL_SENT 36
-#define COL_ANSWERED 37
+#define COL_OTHER_EMAIL 42
+#define COL_CELL_NUMBER 43
+#define COL_DATE 44
+#define COL_SENT 45
+#define COL_ANSWERED 46
#define ADDR_FIELD_AMOUNT 7
#define CONTACT_ID_PREFIX "contact:"
#define CONTACTS_QUERY_ALL \
- "SELECT ?v nco:fullname(?c) " \
+ "SELECT nco:phoneNumber(?v) nco:fullname(?c) " \
"nco:nameFamily(?c) nco:nameGiven(?c) " \
"nco:nameAdditional(?c) nco:nameHonorificPrefix(?c) " \
"nco:nameHonorificSuffix(?c) nco:emailAddress(?e) " \
@@ -71,29 +73,43 @@
"nco:role(?a) nco:pobox(?pw) nco:extendedAddress(?pw) " \
"nco:streetAddress(?pw) nco:locality(?pw) nco:region(?pw) " \
"nco:postalcode(?pw) nco:country(?pw) nco:contactUID(?c) " \
- "nco:title(?a) nco:phoneNumber(?t) " \
+ "nco:title(?a) ?t nco:pobox(?po) nco:extendedAddress(?po) " \
+ "nco:streetAddress(?po) nco:locality(?po) nco:region(?po) " \
+ "nco:postalcode(?po) nco:country(?po) nco:emailAddress(?eo) " \
+ "?vc " \
"\"NOTACALL\" \"false\" \"false\" ?c " \
"WHERE { " \
"?c a nco:PersonContact . " \
- "OPTIONAL { ?c nco:hasPhoneNumber ?h . \
- OPTIONAL {" \
+ "OPTIONAL { ?c nco:hasPhoneNumber ?h . " \
+ "OPTIONAL {" \
"?h a nco:FaxNumber ; " \
"nco:phoneNumber ?f . " \
"}" \
"OPTIONAL {" \
+ "?h a nco:CellPhoneNumber ; " \
+ "nco:phoneNumber ?vc" \
+ "}" \
+ "OPTIONAL {" \
"?h a nco:VoicePhoneNumber ; " \
- "nco:phoneNumber ?v" \
+ "nco:phoneNumber ?t" \
"}" \
"}" \
- "OPTIONAL { ?c nco:hasEmailAddress ?e . } " \
- "OPTIONAL { ?c nco:hasPostalAddress ?p . } " \
"OPTIONAL { " \
"?c nco:hasAffiliation ?a . " \
- "OPTIONAL { ?a nco:hasPhoneNumber ?w . } " \
- "OPTIONAL { ?a nco:hasEmailAddress ?ew . } " \
- "OPTIONAL { ?a nco:hasPostalAddress ?pw . } " \
+ "OPTIONAL { ?a rdfs:label \"Work\" . " \
+ "OPTIONAL { ?a nco:hasEmailAddress ?ew . } " \
+ "OPTIONAL { ?a nco:hasPostalAddress ?pw . } " \
+ "OPTIONAL { ?a nco:hasPhoneNumber ?w . } " \
+ "}" \
+ "OPTIONAL { ?a rdfs:label \"Home\" . " \
+ "OPTIONAL { ?a nco:hasEmailAddress ?e . } " \
+ "OPTIONAL { ?a nco:hasPostalAddress ?p . } " \
+ "OPTIONAL { ?a nco:hasPhoneNumber ?v . } " \
+ "}" \
"OPTIONAL { ?a nco:org ?o . } " \
"} " \
+ "OPTIONAL { ?c nco:hasPostalAddress ?po . } " \
+ "OPTIONAL { ?c nco:hasEmailAddress ?eo . } " \
"}"
#define CONTACTS_QUERY_ALL_LIST \
@@ -1107,7 +1123,7 @@ 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;
+ char *home_addr, *work_addr, *other_addr;
if (num_fields < 0) {
data->cb(NULL, 0, num_fields, 0, data->user_data);
@@ -1178,11 +1194,16 @@ add_numbers:
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_OTHER_NUMBER], TEL_TYPE_OTHER);
+ 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",
@@ -1193,11 +1214,17 @@ add_numbers:
reply[25], reply[26], reply[27], reply[28],
reply[29], reply[30], reply[31]);
+ other_addr = g_strdup_printf("%s;%s;%s;%s;%s;%s;%s",
+ reply[35], reply[36], reply[37], reply[38],
+ reply[39], reply[40], reply[41]);
+
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 */
--
1.7.0.4
^ permalink raw reply related
* [PATCH v5] Bluetooth: btwilink driver
From: pavan_savoy @ 2010-11-10 13:07 UTC (permalink / raw)
To: marcel, padovan; +Cc: linux-bluetooth, linux-kernel, Pavan Savoy
From: Pavan Savoy <pavan_savoy@ti.com>
Marcel,
Thanks for the comments...
This patch contains,
v5 comments :-
declaration and assiging of variables and private data fixed up.
proper casting.
removed redundant un-necessary checks in send_frame.
HCI_RUNNING fixes in terms of test_and_set/clear bit instead of set and
clear.
removed redundant checks for hdev, skb being NULL.
removed module_param of reset, also WiLink don't need HCI_RESET anyways.
removed ti_st_register_dev function and functionality moved to _probe.
module_init/exit function names fixed up.
stat byte counter increments and tx_complete is similar to hci_ldisc.
Also I have not implemented the flush routine, since the functionality
which needs to be done in flush routine is done in the underlying driver
which is the shared transport driver and moreover the btwilink driver by
itself doesn't maintains queue or data relevant to transport, so nothing
to do.
And Yes, I have verified this driver with multiple up/down reset on
hci0.
Also I generally test a2dp/ftp to verify large data transfers.
Please review and comment.
Thanks,
Pavan
v4 comments :-
module init now returns what platform_driver_register returns.
type casting of void* private data has been removed
v3 comments :-
Lizardo,
I have taken care of most of the comments you had.
Have re-wrote some of the code commenting you've mentioned.
Thanks for the comments,
The other few like -EPERM for platform driver registration is to keep
it similar to other drivers, type casting is maintained just to feel safe
and have style similar to other drivers.
BT_WILINK in Kconfig is similar to BT_MRVL.
I hope those aren't too critical.
-- patch description --
This is the bluetooth protocol driver for the TI WiLink7 chipsets.
Texas Instrument's WiLink chipsets combine wireless technologies
like BT, FM, GPS and WLAN onto a single chip.
This Bluetooth driver works on top of the TI_ST shared transport
line discipline driver which also allows other drivers like
FM V4L2 and GPS character driver to make use of the same UART interface.
Kconfig and Makefile modifications to enable the Bluetooth
driver for Texas Instrument's WiLink 7 chipset.
Signed-off-by: Pavan Savoy <pavan_savoy@ti.com>
---
drivers/bluetooth/Kconfig | 10 +
drivers/bluetooth/Makefile | 1 +
drivers/bluetooth/btwilink.c | 379 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 390 insertions(+), 0 deletions(-)
create mode 100644 drivers/bluetooth/btwilink.c
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
index 02deef4..8e0de9a 100644
--- a/drivers/bluetooth/Kconfig
+++ b/drivers/bluetooth/Kconfig
@@ -219,4 +219,14 @@ config BT_ATH3K
Say Y here to compile support for "Atheros firmware download driver"
into the kernel or say M to compile it as module (ath3k).
+config BT_WILINK
+ tristate "Texas Instruments WiLink7 driver"
+ depends on TI_ST
+ help
+ This enables the Bluetooth driver for Texas Instrument's BT/FM/GPS
+ combo devices. This makes use of shared transport line discipline
+ core driver to communicate with the BT core of the combo chip.
+
+ Say Y here to compile support for Texas Instrument's WiLink7 driver
+ into the kernel or say M to compile it as module.
endmenu
diff --git a/drivers/bluetooth/Makefile b/drivers/bluetooth/Makefile
index 71bdf13..f4460f4 100644
--- a/drivers/bluetooth/Makefile
+++ b/drivers/bluetooth/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_BT_HCIBTSDIO) += btsdio.o
obj-$(CONFIG_BT_ATH3K) += ath3k.o
obj-$(CONFIG_BT_MRVL) += btmrvl.o
obj-$(CONFIG_BT_MRVL_SDIO) += btmrvl_sdio.o
+obj-$(CONFIG_BT_WILINK) += btwilink.o
btmrvl-y := btmrvl_main.o
btmrvl-$(CONFIG_DEBUG_FS) += btmrvl_debugfs.o
diff --git a/drivers/bluetooth/btwilink.c b/drivers/bluetooth/btwilink.c
new file mode 100644
index 0000000..1b1c4bc
--- /dev/null
+++ b/drivers/bluetooth/btwilink.c
@@ -0,0 +1,379 @@
+/*
+ * Texas Instrument's Bluetooth Driver For Shared Transport.
+ *
+ * Bluetooth Driver acts as interface between HCI core and
+ * TI Shared Transport Layer.
+ *
+ * Copyright (C) 2009-2010 Texas Instruments
+ * Author: Raja Mani <raja_mani@ti.com>
+ * Pavan Savoy <pavan_savoy@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+#include <linux/ti_wilink_st.h>
+
+/* Bluetooth Driver Version */
+#define VERSION "1.0"
+
+/* Number of seconds to wait for registration completion
+ * when ST returns PENDING status.
+ */
+#define BT_REGISTER_TIMEOUT 6000 /* 6 sec */
+
+/**
+ * struct ti_st - driver operation structure
+ * @hdev: hci device pointer which binds to bt driver
+ * @reg_status: ST registration callback status
+ * @st_write: write function provided by the ST driver
+ * to be used by the driver during send_frame.
+ * @wait_reg_completion - completion sync between ti_st_open
+ * and ti_st_registration_completion_cb.
+ */
+struct ti_st {
+ struct hci_dev *hdev;
+ char reg_status;
+ long (*st_write) (struct sk_buff *);
+ struct completion wait_reg_completion;
+};
+
+/* Increments HCI counters based on pocket ID (cmd,acl,sco) */
+static inline void ti_st_tx_complete(struct ti_st *hst, int pkt_type)
+{
+ struct hci_dev *hdev = hst->hdev;
+
+ /* Update HCI stat counters */
+ switch (pkt_type) {
+ case HCI_COMMAND_PKT:
+ hdev->stat.cmd_tx++;
+ break;
+
+ case HCI_ACLDATA_PKT:
+ hdev->stat.acl_tx++;
+ break;
+
+ case HCI_SCODATA_PKT:
+ hdev->stat.sco_tx++;
+ break;
+ }
+}
+
+/* ------- Interfaces to Shared Transport ------ */
+
+/* Called by ST layer to indicate protocol registration completion
+ * status.ti_st_open() function will wait for signal from this
+ * API when st_register() function returns ST_PENDING.
+ */
+static void st_registration_completion_cb(void *priv_data, char data)
+{
+ struct ti_st *lhst = priv_data;
+
+ /* Save registration status for use in ti_st_open() */
+ lhst->reg_status = data;
+ /* complete the wait in ti_st_open() */
+ complete(&lhst->wait_reg_completion);
+}
+
+/* Called by Shared Transport layer when receive data is
+ * available */
+static long st_receive(void *priv_data, struct sk_buff *skb)
+{
+ struct ti_st *lhst = priv_data;
+ int err;
+
+ if (!skb)
+ return -EFAULT;
+
+ if (!lhst) {
+ kfree_skb(skb);
+ return -EFAULT;
+ }
+
+ skb->dev = (void *) lhst->hdev;
+
+ /* Forward skb to HCI core layer */
+ err = hci_recv_frame(skb);
+ if (err < 0) {
+ BT_ERR("Unable to push skb to HCI core(%d)", err);
+ return err;
+ }
+
+ lhst->hdev->stat.byte_rx += skb->len;
+
+ return 0;
+}
+
+/* ------- Interfaces to HCI layer ------ */
+/* protocol structure registered with shared transport */
+static struct st_proto_s ti_st_proto = {
+ .type = ST_BT,
+ .recv = st_receive,
+ .reg_complete_cb = st_registration_completion_cb,
+};
+
+/* Called from HCI core to initialize the device */
+static int ti_st_open(struct hci_dev *hdev)
+{
+ unsigned long timeleft;
+ struct ti_st *hst;
+ int err;
+
+ BT_DBG("%s %p", hdev->name, hdev);
+
+ /* provide contexts for callbacks from ST */
+ hst = hdev->driver_data;
+ ti_st_proto.priv_data = hst;
+
+ err = st_register(&ti_st_proto);
+ if (err == -EINPROGRESS) {
+ /* Prepare wait-for-completion handler data structures.
+ * Needed to synchronize this and
+ * st_registration_completion_cb() functions.
+ */
+ init_completion(&hst->wait_reg_completion);
+
+ /* Reset ST registration callback status flag , this value
+ * will be updated in ti_st_registration_completion_cb()
+ * function whenever it called from ST driver.
+ */
+ hst->reg_status = -EINPROGRESS;
+
+ /* ST is busy with either protocol registration or firmware
+ * download. Wait until the registration callback is called
+ */
+ BT_DBG(" waiting for registration completion signal from ST");
+
+ timeleft = wait_for_completion_timeout
+ (&hst->wait_reg_completion,
+ msecs_to_jiffies(BT_REGISTER_TIMEOUT));
+ if (!timeleft) {
+ BT_ERR("Timeout(%d sec),didn't get reg "
+ "completion signal from ST",
+ BT_REGISTER_TIMEOUT / 1000);
+ return -ETIMEDOUT;
+ }
+
+ /* Is ST registration callback called with ERROR status? */
+ if (hst->reg_status != 0) {
+ BT_ERR("ST registration completed with invalid "
+ "status %d", hst->reg_status);
+ return -EAGAIN;
+ }
+ err = 0;
+ } else if (err == -EPERM) {
+ BT_ERR("st_register failed %d", err);
+ return err;
+ }
+
+ /* ti_st_proto.write is filled up by the underlying shared
+ * transport driver upon registration
+ */
+ hst->st_write = ti_st_proto.write;
+ if (!hst->st_write) {
+ BT_ERR("undefined ST write function");
+
+ /* Undo registration with ST */
+ err = st_unregister(ST_BT);
+ if (err)
+ BT_ERR("st_unregister() failed with error %d", err);
+
+ hst->st_write = NULL;
+ return err;
+ }
+
+ /* Registration with ST layer is successful,
+ * hardware is ready to accept commands from HCI core.
+ */
+ if (test_and_set_bit(HCI_RUNNING, &hdev->flags)) {
+ clear_bit(HCI_RUNNING, &hdev->flags);
+ err = st_unregister(ST_BT);
+ if (err)
+ BT_ERR("st_unregister() failed with error %d", err);
+ hst->st_write = NULL;
+ }
+
+ return err;
+}
+
+/* Close device */
+static int ti_st_close(struct hci_dev *hdev)
+{
+ int err;
+ struct ti_st *hst = hdev->driver_data;
+
+ /* continue to unregister from transport */
+ err = st_unregister(ST_BT);
+ if (err)
+ BT_ERR("st_unregister() failed with error %d", err);
+
+ hst->st_write = NULL;
+
+ if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
+ return 0;
+
+ return err;
+}
+
+static int ti_st_send_frame(struct sk_buff *skb)
+{
+ struct hci_dev *hdev;
+ struct ti_st *hst;
+ long len;
+
+ hdev = (struct hci_dev *)skb->dev;
+
+ if (!test_bit(HCI_RUNNING, &hdev->flags))
+ return -EBUSY;
+
+ hst = hdev->driver_data;
+
+ /* Prepend skb with frame type */
+ memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
+
+ BT_DBG(" %s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type,
+ skb->len);
+
+ /* Insert skb to shared transport layer's transmit queue.
+ * Freeing skb memory is taken care in shared transport layer,
+ * so don't free skb memory here.
+ */
+ len = hst->st_write(skb);
+ if (len < 0) {
+ kfree_skb(skb);
+ BT_ERR(" ST write failed (%ld)", len);
+ return -EAGAIN;
+ }
+
+ /* ST accepted our skb. So, Go ahead and do rest */
+ hdev->stat.byte_tx += len;
+ ti_st_tx_complete(hst, bt_cb(skb)->pkt_type);
+
+ return 0;
+}
+
+static void ti_st_destruct(struct hci_dev *hdev)
+{
+ BT_DBG("%s", hdev->name);
+
+ /* free ti_st memory */
+ kfree(hdev->driver_data);
+
+ return;
+}
+
+static int bt_ti_probe(struct platform_device *pdev)
+{
+ static struct ti_st *hst;
+ struct hci_dev *hdev;
+ int err;
+
+ hst = kzalloc(sizeof(struct ti_st), GFP_KERNEL);
+ if (!hst)
+ return -ENOMEM;
+
+ /* Expose "hciX" device to user space */
+ hdev = hci_alloc_dev();
+ if (!hdev)
+ return -ENOMEM;
+
+ BT_DBG("hdev %p", hdev);
+
+ hst->hdev = hdev;
+ hdev->bus = HCI_UART;
+ hdev->driver_data = hst;
+ hdev->open = ti_st_open;
+ hdev->close = ti_st_close;
+ hdev->flush = NULL;
+ hdev->send = ti_st_send_frame;
+ hdev->destruct = ti_st_destruct;
+ hdev->owner = THIS_MODULE;
+
+ err = hci_register_dev(hdev);
+ if (err < 0) {
+ BT_ERR("Can't register HCI device error %d", err);
+ hci_free_dev(hdev);
+ return err;
+ }
+
+ BT_DBG(" HCI device registered (hdev %p)", hdev);
+
+ dev_set_drvdata(&pdev->dev, hst);
+ return err;
+}
+
+static int bt_ti_remove(struct platform_device *pdev)
+{
+ struct hci_dev *hdev;
+ struct ti_st *hst = dev_get_drvdata(&pdev->dev);
+
+ if (!hst)
+ return -EFAULT;
+
+ hdev = hst->hdev;
+ ti_st_close(hdev);
+ hci_unregister_dev(hdev);
+
+ /* Free HCI device memory */
+ hci_free_dev(hdev);
+
+ /* Free driver data memory */
+ kfree(hst);
+
+ dev_set_drvdata(&pdev->dev, NULL);
+ return 0;
+}
+
+static struct platform_driver btwilink_driver = {
+ .probe = bt_ti_probe,
+ .remove = bt_ti_remove,
+ .driver = {
+ .name = "btwilink",
+ .owner = THIS_MODULE,
+ },
+};
+
+/* ------- Module Init/Exit interfaces ------ */
+static int __init btwilink_init(void)
+{
+ long ret;
+
+ BT_INFO(" Bluetooth Driver for TI WiLink - Version %s", VERSION);
+
+ ret = platform_driver_register(&btwilink_driver);
+ if (ret != 0) {
+ BT_ERR("btwilink platform driver registration failed");
+ return ret;
+ }
+ return 0;
+}
+
+static void __exit btwilink_exit(void)
+{
+ platform_driver_unregister(&btwilink_driver);
+}
+
+module_init(btwilink_init);
+module_exit(btwilink_exit);
+
+/* ------ Module Info ------ */
+
+MODULE_AUTHOR("Raja Mani <raja_mani@ti.com>");
+MODULE_DESCRIPTION("Bluetooth Driver for TI Shared Transport" VERSION);
+MODULE_VERSION(VERSION);
+MODULE_LICENSE("GPL");
--
1.5.6.3
^ permalink raw reply related
* Re: [PATCH] Fix segfault in HDP during device re-creation
From: Jose Antonio Santos Cadenas @ 2010-11-10 13:02 UTC (permalink / raw)
To: Elvis Pfützenreuter; +Cc: linux-bluetooth
In-Reply-To: <BCBAC715-C7A9-415F-BE62-F843DE5A72D1@signove.com>
Hi Elvis,
2010/11/10 Elvis Pfützenreuter <epx@signove.com>:
>> Hi Elvis,
>>
>> 2010/11/10 Elvis Pfützenreuter <epx@signove.com>:
>>>>> ---
>>>>> health/hdp.c | 1 +
>>>>> 1 files changed, 1 insertions(+), 0 deletions(-)
>>>>>
>>>>> diff --git a/health/hdp.c b/health/hdp.c
>>>>> index 1eba8e1..d361b27 100644
>>>>> --- a/health/hdp.c
>>>>> +++ b/health/hdp.c
>>>>> @@ -259,6 +259,7 @@ static void device_unref_mcl(struct hdp_device *hdp_device)
>>>>> if (!hdp_device->mcl)
>>>>> return;
>>>>>
>>>>> + mcap_close_mcl(hdp_device->mcl, FALSE);
>>>>> mcap_mcl_unref(hdp_device->mcl);
>>>>> hdp_device->mcl = NULL;
>>>>> hdp_device->mcl_conn = FALSE;
>>>>> --
>>>>> 1.7.1
>>>>>
>>>>>
>>>>
>>>> Please Elvis, try this solution and tell us if it fix the segfault problem.
>>>
>>> Yes, it seems to have fixed the problem. And far cleaner :)
>>>
>>> I hadn't proposed a lookalike solution because this seems to disable MCL caching completely. HDP already calls mcap_close_mcl(cache=FALSE) when takes the initiative of closing the MCL; this patch takes care of remaining case.
>>
>> This function doesn't disable the caching in general, it just closes
>> this MCL without catching it, but caching is still active for all the
>> other MCL's. Additionally, nothing happens if mcap_close_mcl is called
>> more than once, so this patch takes care of this too.
>
> Indeed, MCL disconnection and hdp_device destruction are different moments. Still fulfilling the caffeine quota for this morning :P
Of course they are, but when a device is removed, is completely normal
that you (HDP) would like to delete the MCAP cache because you (HDP)
are forgetting this device so you won't have any structures for the
data channels nor other structs in HDP needed to manage the
reconnections of the data channels that could be cached. The way to
uncache an mcl in MCAP is to close it indicating that you don't want
to cache it. This is just what this patch to.
>
>>>
>>> So, perhaps it would be better to get rid of caching code in mcap.c?
>>
>> I can't understand this, can you explain this more?. As I see, MCAP
>> should do the catching because it holds all the information about the
>> channels that are connected and can cache it, HDP could not do this
>> without MCAP. More over, if in the future more profiles use MCAP they
>> may want to cache too.
>
> I do have the opinion that caching in mcap.c is more complicated than it could be.
My opinion is that caching in MCAP is the correct way because MCAP is
dealing with sending and receiving commands and need to retain certain
structures that are necessary for it, this structures do not concern
to HDP, only concerns to MCAP and should be MCAP who stores (caches)
them.
> I'd have used a single list with a CLOSED flag. Also, there is some confusion in nomenclature (mcap_uncache_mcl() recovers from the cache, while mcl_uncached_cb callback means that MCL has been invalidated). This is source of bugs like this one.
This is a different issue. Probably the nomenclature is not as clear
as it should be but I think that this is not the point here,
nevertheless we can change it too.
>
> At the very least, cached MCLs should have mcl->cb zeroed. if MCAP level caches MCLs, very well, but HDP level should be asked to set callbacks and user data again, as if it were a new MCL. (Actually, mcl_reconnected in hdp.c seems to do that; not sure why it did not avoid the particular bug that is under discussion.)
It is supposed that if HDP (or any other profile using MCAP) wants to
use cache, it should keep its variables all the time that it is
interested in caching them. If the profile using MCAP don't want to
keep its state should tell MCAP that it is not interested in caching
(as the patch in this thread does) because it is deleting its own
state.
Regards.
Jose
^ permalink raw reply
* Re: [RFC] Bluetooth Low energy support
From: Ville Tervo @ 2010-11-10 12:51 UTC (permalink / raw)
To: ext Anderson Lizardo; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <AANLkTi=iCXfycMzHbgwS3jbvCxJvzVh97iSDRf4WhQeQ@mail.gmail.com>
On Wed, Nov 10, 2010 at 11:46:47AM +0100, ext Anderson Lizardo wrote:
> On Wed, Nov 10, 2010 at 2:20 AM, Ville Tervo <ville.tervo@nokia.com> wrote:
> > On Tue, Nov 09, 2010 at 05:25:10PM +0100, ext Anderson Lizardo wrote:
> >> While doing tests with your most recent trees (using devel HW from
> >> TI), I'm getting consistent panic on the following test:
> >>
> >> (dev1) hciconfig hciX leadv
> >> (dev2) hcitool -i hciX lecc <dev2_addr>
> >
> > Did you have server listening on dev 2 on ATT socket?
>
> I had no bluetoothd running on any side (not sure if that was your question).
That was actually my question :) Thanks.
--
VIlle
^ permalink raw reply
* Re: [PATCH] Fix segfault in HDP during device re-creation
From: Elvis Pfützenreuter @ 2010-11-10 12:40 UTC (permalink / raw)
To: Jose Antonio Santos Cadenas; +Cc: linux-bluetooth
In-Reply-To: <AANLkTim=3tZWao0Kzqq8nr4Z=dOrXL_aK76Ernx=UqQS@mail.gmail.com>
> Hi Elvis,
>
> 2010/11/10 Elvis Pfützenreuter <epx@signove.com>:
>>>> ---
>>>> health/hdp.c | 1 +
>>>> 1 files changed, 1 insertions(+), 0 deletions(-)
>>>>
>>>> diff --git a/health/hdp.c b/health/hdp.c
>>>> index 1eba8e1..d361b27 100644
>>>> --- a/health/hdp.c
>>>> +++ b/health/hdp.c
>>>> @@ -259,6 +259,7 @@ static void device_unref_mcl(struct hdp_device *hdp_device)
>>>> if (!hdp_device->mcl)
>>>> return;
>>>>
>>>> + mcap_close_mcl(hdp_device->mcl, FALSE);
>>>> mcap_mcl_unref(hdp_device->mcl);
>>>> hdp_device->mcl = NULL;
>>>> hdp_device->mcl_conn = FALSE;
>>>> --
>>>> 1.7.1
>>>>
>>>>
>>>
>>> Please Elvis, try this solution and tell us if it fix the segfault problem.
>>
>> Yes, it seems to have fixed the problem. And far cleaner :)
>>
>> I hadn't proposed a lookalike solution because this seems to disable MCL caching completely. HDP already calls mcap_close_mcl(cache=FALSE) when takes the initiative of closing the MCL; this patch takes care of remaining case.
>
> This function doesn't disable the caching in general, it just closes
> this MCL without catching it, but caching is still active for all the
> other MCL's. Additionally, nothing happens if mcap_close_mcl is called
> more than once, so this patch takes care of this too.
Indeed, MCL disconnection and hdp_device destruction are different moments. Still fulfilling the caffeine quota for this morning :P
>>
>> So, perhaps it would be better to get rid of caching code in mcap.c?
>
> I can't understand this, can you explain this more?. As I see, MCAP
> should do the catching because it holds all the information about the
> channels that are connected and can cache it, HDP could not do this
> without MCAP. More over, if in the future more profiles use MCAP they
> may want to cache too.
I do have the opinion that caching in mcap.c is more complicated than it could be. I'd have used a single list with a CLOSED flag. Also, there is some confusion in nomenclature (mcap_uncache_mcl() recovers from the cache, while mcl_uncached_cb callback means that MCL has been invalidated). This is source of bugs like this one.
At the very least, cached MCLs should have mcl->cb zeroed. if MCAP level caches MCLs, very well, but HDP level should be asked to set callbacks and user data again, as if it were a new MCL. (Actually, mcl_reconnected in hdp.c seems to do that; not sure why it did not avoid the particular bug that is under discussion.)
^ permalink raw reply
* Re: [PATCH] Fix segfault in HDP during device re-creation
From: Jose Antonio Santos Cadenas @ 2010-11-10 11:49 UTC (permalink / raw)
To: Elvis Pfützenreuter; +Cc: linux-bluetooth
In-Reply-To: <126814B4-25DA-4BA4-A0B8-0E5D57001EF7@signove.com>
Hi Elvis,
2010/11/10 Elvis Pfützenreuter <epx@signove.com>:
>>> ---
>>> health/hdp.c | 1 +
>>> 1 files changed, 1 insertions(+), 0 deletions(-)
>>>
>>> diff --git a/health/hdp.c b/health/hdp.c
>>> index 1eba8e1..d361b27 100644
>>> --- a/health/hdp.c
>>> +++ b/health/hdp.c
>>> @@ -259,6 +259,7 @@ static void device_unref_mcl(struct hdp_device *hdp_device)
>>> if (!hdp_device->mcl)
>>> return;
>>>
>>> + mcap_close_mcl(hdp_device->mcl, FALSE);
>>> mcap_mcl_unref(hdp_device->mcl);
>>> hdp_device->mcl = NULL;
>>> hdp_device->mcl_conn = FALSE;
>>> --
>>> 1.7.1
>>>
>>>
>>
>> Please Elvis, try this solution and tell us if it fix the segfault problem.
>
> Yes, it seems to have fixed the problem. And far cleaner :)
>
> I hadn't proposed a lookalike solution because this seems to disable MCL caching completely. HDP already calls mcap_close_mcl(cache=FALSE) when takes the initiative of closing the MCL; this patch takes care of remaining case.
This function doesn't disable the caching in general, it just closes
this MCL without catching it, but caching is still active for all the
other MCL's. Additionally, nothing happens if mcap_close_mcl is called
more than once, so this patch takes care of this too.
>
> The only place hdp.c calls mcap_close_mcl(cache=TRUE) is when mcap_mcl_set_cb() fails, which seems "impossible", because it only depends on valid parameters to succeed.
This is because HDP wants to cache as long as possible.
>
> So, perhaps it would be better to get rid of caching code in mcap.c?
I can't understand this, can you explain this more?. As I see, MCAP
should do the catching because it holds all the information about the
channels that are connected and can cache it, HDP could not do this
without MCAP. More over, if in the future more profiles use MCAP they
may want to cache too.
Regards
^ permalink raw reply
* [PATCH] Fix pull phonebook reply if filter not set
From: Lukasz Pawlik @ 2010-11-10 11:43 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Lukasz Pawlik
According to the PBAP specification if filter is not set or is set to
0x00000000 in the application parameters header all attributes of the vCard
should be returned. Previously only mandatory attributes were returned in
phonebook pull reply. This patch fix this and now all currently supported
vCards attributes will be returned.
---
plugins/vcard.c | 10 ++++++++--
1 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/plugins/vcard.c b/plugins/vcard.c
index 41f9fbd..3f69189 100644
--- a/plugins/vcard.c
+++ b/plugins/vcard.c
@@ -457,10 +457,16 @@ static void vcard_printf_end(GString *vcards)
void phonebook_add_contact(GString *vcards, struct phonebook_contact *contact,
uint64_t filter, uint8_t format)
{
- if (format == FORMAT_VCARD30)
+ if (format == FORMAT_VCARD30 && filter)
filter |= (FILTER_VERSION | FILTER_FN | FILTER_N | FILTER_TEL);
- else if (format == FORMAT_VCARD21)
+ else if (format == FORMAT_VCARD21 && filter)
filter |= (FILTER_VERSION | FILTER_N | FILTER_TEL);
+ else
+ filter = (FILTER_VERSION | FILTER_UID | FILTER_N | FILTER_FN |
+ FILTER_TEL | FILTER_EMAIL | FILTER_ADR |
+ FILTER_BDAY | FILTER_NICKNAME | FILTER_URL |
+ FILTER_PHOTO | FILTER_ORG | FILTER_ROLE |
+ FILTER_TITLE | FILTER_X_IRMC_CALL_DATETIME);
vcard_printf_begin(vcards, format);
--
1.7.0.4
^ permalink raw reply related
* Re: [PATCH] Fix segfault in HDP during device re-creation
From: Elvis Pfützenreuter @ 2010-11-10 11:36 UTC (permalink / raw)
To: Jose Antonio Santos Cadenas; +Cc: linux-bluetooth
In-Reply-To: <AANLkTimoQRAHXJ65xa1-TMKGUfLujw8f9MhzxrxPXHmY@mail.gmail.com>
>> ---
>> health/hdp.c | 1 +
>> 1 files changed, 1 insertions(+), 0 deletions(-)
>>
>> diff --git a/health/hdp.c b/health/hdp.c
>> index 1eba8e1..d361b27 100644
>> --- a/health/hdp.c
>> +++ b/health/hdp.c
>> @@ -259,6 +259,7 @@ static void device_unref_mcl(struct hdp_device *hdp_device)
>> if (!hdp_device->mcl)
>> return;
>>
>> + mcap_close_mcl(hdp_device->mcl, FALSE);
>> mcap_mcl_unref(hdp_device->mcl);
>> hdp_device->mcl = NULL;
>> hdp_device->mcl_conn = FALSE;
>> --
>> 1.7.1
>>
>>
>
> Please Elvis, try this solution and tell us if it fix the segfault problem.
Yes, it seems to have fixed the problem. And far cleaner :)
I hadn't proposed a lookalike solution because this seems to disable MCL caching completely. HDP already calls mcap_close_mcl(cache=FALSE) when takes the initiative of closing the MCL; this patch takes care of remaining case.
The only place hdp.c calls mcap_close_mcl(cache=TRUE) is when mcap_mcl_set_cb() fails, which seems "impossible", because it only depends on valid parameters to succeed.
So, perhaps it would be better to get rid of caching code in mcap.c?
^ permalink raw reply
* RE: [PATCH 1/4] Sim Access Profile API
From: Waldemar.Rymarkiewicz @ 2010-11-10 11:12 UTC (permalink / raw)
To: marcel; +Cc: linux-bluetooth, suraj, johan.hedberg, joakim.xj.ceder
In-Reply-To: <1289367190.9615.235.camel@aeonflux>
Hi Marcel,=20
>> + void Disable()
>> +
>> + Shudown SAP server and remove the SDP record.
>> +
>> + Possible errors: org.bluez.Error.Failed
>
>I don't like this. If you have properties then just changing=20
>the property should be enough. So a SetProperty is more appropriate.
I see another option to get rid of 'Enabled' property and leave the methods=
. What would you say on that?
>> +
>> + void Disconnect(boolean type)
>> +
>> + Disconnect SAP client from the server.=20
>The 'type'
>> + parameter indicates disconnection type.
>> +
>> + True - gracefull disconnection
>> + False - immediate disconnection
>> +
>> + Possible errors: org.bluez.Error.Failed
>
>I don't like this style of method names at all. Using method=20
>names like GracefulDisconnect and ImmediateDisconnect would be better.
That's fine.
>However I am not sure we should differentiate here at all. We=20
>should always to the graceful disconnect. What will the=20
>immediate disconnect bring us?
That's actually intended for testing only. One of PTS test cases expects th=
e tester to trigger immediate disconnect.
In practce, it is only used when connection to sim card is lost, but this i=
s obviously done internally.
Thanks,
/Waldek=
^ 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