* [PATCH_v2 3/3] android/hidhost: Set info request from HAL is not supported
From: Ravi kumar Veeramally @ 2013-11-12 15:07 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1384268835-7570-1-git-send-email-ravikumar.veeramally@linux.intel.com>
Data from hal_cmd_hidhost_set_info is usefull only when we create
UHID device. Once device is created all the transactions will be
done through the fd. There is no way to use this information
once device is created with HID internals.
---
android/hidhost.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/android/hidhost.c b/android/hidhost.c
index 556e5a5..95a98c3 100644
--- a/android/hidhost.c
+++ b/android/hidhost.c
@@ -839,9 +839,13 @@ static uint8_t bt_hid_virtual_unplug(struct hal_cmd_hidhost_virtual_unplug *cmd,
static uint8_t bt_hid_info(struct hal_cmd_hidhost_set_info *cmd, uint16_t len)
{
- DBG("Not Implemented");
+ /* Data from hal_cmd_hidhost_set_info is usefull only when we create
+ * UHID device. Once device is created all the transactions will be
+ * done through the fd. There is no way to use this information
+ * once device is created with HID internals. */
+ DBG("Not supported");
- return HAL_STATUS_FAILED;
+ return HAL_STATUS_UNSUPPORTED;
}
static uint8_t bt_hid_get_protocol(struct hal_cmd_hidhost_get_protocol *cmd,
--
1.8.3.2
^ permalink raw reply related
* [PATCH v3 0/5] Add support for registering local SDP records
From: Szymon Janc @ 2013-11-12 15:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
v3:
- fixed Johan comments
V2:
- don't use bt_uuid_t
- few bugfixes
V1 cover:
This adds support for manipulating local SDP database with
bt_adapter_add_record and bt_adapter_remove_record functions. Those should
be called when HAL service is registered or unregistered.
This also adds DeviceID record as at least 1 local UUID is needed by Android to
properly handle remote device profiles.
Last but not least: With this serie it is possible to connect HID device from
Android UI (Settings application). \O/
--
BR
Szymon Janc
Marcin Kraglak (3):
android: Add and remove sdp records and uuids
android: Clear adapter uuids during initialization
android: Add support for getting UUIDs property
Szymon Janc (2):
android: Remove not needed include
android: Register DeviceID record when adapter is initialized
android/adapter.c | 202 ++++++++++++++++++++++++++++++++++++++++++++++++++----
android/adapter.h | 3 +
2 files changed, 192 insertions(+), 13 deletions(-)
--
1.8.4.2
^ permalink raw reply
* [PATCH v3 1/5] android: Add and remove sdp records and uuids
From: Szymon Janc @ 2013-11-12 15:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Marcin Kraglak
In-Reply-To: <1384270586-9853-1-git-send-email-szymon.janc@tieto.com>
From: Marcin Kraglak <marcin.kraglak@tieto.com>
This is api for adding and removing sdp records and uuids
via mgmt interface. Local profiles have to store handle to
own records to remove them in cleanup. Additionally list of
uuids is created in bt_adapter struct.
---
android/adapter.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
android/adapter.h | 3 ++
2 files changed, 116 insertions(+)
diff --git a/android/adapter.c b/android/adapter.c
index 65b3170..ac5878b 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -40,6 +40,7 @@
#include "lib/sdp_lib.h"
#include "lib/uuid.h"
#include "src/sdp-client.h"
+#include "src/sdpd.h"
#include "log.h"
#include "hal-msg.h"
#include "ipc.h"
@@ -74,6 +75,7 @@ struct bt_adapter {
bool discovering;
uint32_t discoverable_timeout;
+ GSList *uuids;
};
struct browse_req {
@@ -986,6 +988,117 @@ static void load_link_keys(GSList *keys)
}
}
+/* output uint128 is in host order */
+static void uuid16_to_uint128(uint16_t uuid, uint128_t *u128)
+{
+ uuid_t uuid16, uuid128;
+
+ sdp_uuid16_create(&uuid16, uuid);
+ sdp_uuid16_to_uuid128(&uuid128, &uuid16);
+
+ ntoh128(&uuid128.value.uuid128, u128);
+}
+
+static void remove_uuid_complete(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ if (status != MGMT_STATUS_SUCCESS) {
+ error("Failed to remove UUID: %s (0x%02x)",
+ mgmt_errstr(status), status);
+ return;
+ }
+
+ mgmt_dev_class_changed_event(adapter->index, length, param, NULL);
+}
+
+static void remove_uuid(uint16_t uuid)
+{
+ uint128_t uint128;
+ struct mgmt_cp_remove_uuid cp;
+
+ uuid16_to_uint128(uuid, &uint128);
+ htob128(&uint128, (uint128_t *) cp.uuid);
+
+ mgmt_send(adapter->mgmt, MGMT_OP_REMOVE_UUID,
+ adapter->index, sizeof(cp), &cp,
+ remove_uuid_complete, NULL, NULL);
+}
+
+static void add_uuid_complete(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ if (status != MGMT_STATUS_SUCCESS) {
+ error("Failed to add UUID: %s (0x%02x)",
+ mgmt_errstr(status), status);
+ return;
+ }
+
+ mgmt_dev_class_changed_event(adapter->index, length, param, NULL);
+}
+
+static void add_uuid(uint8_t svc_hint, uint16_t uuid)
+{
+ uint128_t uint128;
+ struct mgmt_cp_add_uuid cp;
+
+ uuid16_to_uint128(uuid, &uint128);
+
+ htob128(&uint128, (uint128_t *) cp.uuid);
+ cp.svc_hint = svc_hint;
+
+ mgmt_send(adapter->mgmt, MGMT_OP_ADD_UUID,
+ adapter->index, sizeof(cp), &cp,
+ add_uuid_complete, NULL, NULL);
+}
+
+int bt_adapter_add_record(sdp_record_t *rec, uint8_t svc_hint)
+{
+ uint16_t uuid;
+
+ /* TODO support all types? */
+ if (rec->svclass.type != SDP_UUID16) {
+ warn("Ignoring unsupported UUID type");
+ return -EINVAL;
+ }
+
+ uuid = rec->svclass.value.uuid16;
+
+ if (g_slist_find(adapter->uuids, GUINT_TO_POINTER(uuid))) {
+ DBG("UUID 0x%x already added", uuid);
+ return -EALREADY;
+ }
+
+ adapter->uuids = g_slist_prepend(adapter->uuids,
+ GUINT_TO_POINTER(uuid));
+
+ add_uuid(svc_hint, uuid);
+
+ return add_record_to_server(&adapter->bdaddr, rec);
+}
+
+void bt_adapter_remove_record(uint32_t handle)
+{
+ sdp_record_t *rec;
+ GSList *uuid_found;
+ uint16_t uuid;
+
+ rec = sdp_record_find(handle);
+ if (!rec)
+ return;
+
+ uuid = rec->svclass.value.uuid16;
+
+ uuid_found = g_slist_find(adapter->uuids, GUINT_TO_POINTER(uuid));
+ if (uuid_found) {
+ remove_uuid(uuid);
+
+ adapter->uuids = g_slist_remove(adapter->uuids,
+ uuid_found->data);
+ }
+
+ remove_record_from_server(handle);
+}
+
static void set_mode_complete(uint8_t status, uint16_t length,
const void *param, void *user_data)
{
diff --git a/android/adapter.h b/android/adapter.h
index c62b859..0e84cb0 100644
--- a/android/adapter.h
+++ b/android/adapter.h
@@ -32,3 +32,6 @@ const bdaddr_t *bt_adapter_get_address(void);
bool bt_adapter_register(int sk);
void bt_adapter_unregister(void);
+
+int bt_adapter_add_record(sdp_record_t *rec, uint8_t svc_hint);
+void bt_adapter_remove_record(uint32_t handle);
--
1.8.4.2
^ permalink raw reply related
* [PATCH v3 2/5] android: Remove not needed include
From: Szymon Janc @ 2013-11-12 15:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1384270586-9853-1-git-send-email-szymon.janc@tieto.com>
bt_uuid_t is not used so lib/uuid.h doesn't need to be included.
---
android/adapter.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/android/adapter.c b/android/adapter.c
index ac5878b..92949f9 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -38,7 +38,6 @@
#include "src/eir.h"
#include "lib/sdp.h"
#include "lib/sdp_lib.h"
-#include "lib/uuid.h"
#include "src/sdp-client.h"
#include "src/sdpd.h"
#include "log.h"
--
1.8.4.2
^ permalink raw reply related
* [PATCH v3 3/5] android: Clear adapter uuids during initialization
From: Szymon Janc @ 2013-11-12 15:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Marcin Kraglak
In-Reply-To: <1384270586-9853-1-git-send-email-szymon.janc@tieto.com>
From: Marcin Kraglak <marcin.kraglak@tieto.com>
Clear adapter uuids during init. We have to do it before
other profiles will be able to register sdp records and add
their uuids.
---
android/adapter.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/android/adapter.c b/android/adapter.c
index 92949f9..a42cdcb 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -1208,6 +1208,17 @@ static uint8_t set_discoverable_timeout(uint8_t *timeout)
return HAL_STATUS_SUCCESS;
}
+
+static void clear_uuids(void)
+{
+ struct mgmt_cp_remove_uuid cp;
+
+ memset(&cp, 0, sizeof(cp));
+
+ mgmt_send(adapter->mgmt, MGMT_OP_REMOVE_UUID, adapter->index,
+ sizeof(cp), &cp, NULL, NULL, NULL);
+}
+
static void read_info_complete(uint8_t status, uint16_t length, const void *param,
void *user_data)
{
@@ -1248,6 +1259,8 @@ static void read_info_complete(uint8_t status, uint16_t length, const void *para
/* TODO: Register all event notification handlers */
register_mgmt_handlers();
+ clear_uuids();
+
load_link_keys(NULL);
set_io_capability();
--
1.8.4.2
^ permalink raw reply related
* [PATCH v3 4/5] android: Add support for getting UUIDs property
From: Szymon Janc @ 2013-11-12 15:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Marcin Kraglak
In-Reply-To: <1384270586-9853-1-git-send-email-szymon.janc@tieto.com>
From: Marcin Kraglak <marcin.kraglak@tieto.com>
This method will call adapter_properties_cb with uuids of
adapter. Method is called also when uuid is added or removed.
---
android/adapter.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 47 insertions(+), 8 deletions(-)
diff --git a/android/adapter.c b/android/adapter.c
index a42cdcb..2c95e54 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -998,6 +998,45 @@ static void uuid16_to_uint128(uint16_t uuid, uint128_t *u128)
ntoh128(&uuid128.value.uuid128, u128);
}
+static bool get_uuids(void)
+{
+ struct hal_ev_adapter_props_changed *ev;
+ GSList *list = adapter->uuids;
+ unsigned int uuid_count = g_slist_length(list);
+ int len = uuid_count * sizeof(uint128_t);
+ uint8_t buf[BASELEN_PROP_CHANGED + len];
+ uint8_t *p;
+ int i;
+
+ memset(buf, 0, sizeof(buf));
+ ev = (void *) buf;
+
+ ev->num_props = 1;
+ ev->status = HAL_STATUS_SUCCESS;
+
+ ev->props[0].type = HAL_PROP_ADAPTER_UUIDS;
+ ev->props[0].len = len;
+ p = ev->props->val;
+
+ for (; list; list = g_slist_next(list)) {
+ uint16_t uuid = GPOINTER_TO_UINT(list->data);
+ uint128_t uint128;
+
+ uuid16_to_uint128(uuid, &uint128);
+
+ /* Android expects swapped bytes in uuid */
+ for (i = 0; i < 16; i++)
+ p[15 - i] = uint128.data[i];
+
+ p += sizeof(uint128_t);
+ }
+
+ ipc_send(notification_sk, HAL_SERVICE_ID_BLUETOOTH,
+ HAL_EV_ADAPTER_PROPS_CHANGED, sizeof(buf), ev, -1);
+
+ return true;
+}
+
static void remove_uuid_complete(uint8_t status, uint16_t length,
const void *param, void *user_data)
{
@@ -1008,6 +1047,10 @@ static void remove_uuid_complete(uint8_t status, uint16_t length,
}
mgmt_dev_class_changed_event(adapter->index, length, param, NULL);
+
+ /* send notification only if bluetooth service is registered */
+ if (notification_sk >= 0)
+ get_uuids();
}
static void remove_uuid(uint16_t uuid)
@@ -1033,6 +1076,10 @@ static void add_uuid_complete(uint8_t status, uint16_t length,
}
mgmt_dev_class_changed_event(adapter->index, length, param, NULL);
+
+ /* send notification only if bluetooth service is registered */
+ if (notification_sk >= 0)
+ get_uuids();
}
static void add_uuid(uint8_t svc_hint, uint16_t uuid)
@@ -1346,14 +1393,6 @@ static bool get_name(void)
return true;
}
-static bool get_uuids(void)
-{
- DBG("Not implemented");
-
- /* TODO: Add implementation */
-
- return false;
-}
static bool get_class(void)
{
--
1.8.4.2
^ permalink raw reply related
* [PATCH v3 5/5] android: Register DeviceID record when adapter is initialized
From: Szymon Janc @ 2013-11-12 15:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1384270586-9853-1-git-send-email-szymon.janc@tieto.com>
Register DeviceID SDP record and update local UUIDs after DeviceID
information is passed to kernel.
---
android/adapter.c | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/android/adapter.c b/android/adapter.c
index 2c95e54..2fd6aeb 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -46,6 +46,10 @@
#include "utils.h"
#include "adapter.h"
+#define DEVICE_ID_SOURCE 0x0002 /* USB */
+#define DEVICE_ID_VENDOR 0x1d6b /* Linux Foundation */
+#define DEVICE_ID_PRODUCT 0x0247 /* BlueZ for Android */
+
/* Default to DisplayYesNo */
#define DEFAULT_IO_CAPABILITY 0x01
/* Default discoverable timeout 120sec as in Android */
@@ -1197,20 +1201,28 @@ static void set_device_id(void)
{
struct mgmt_cp_set_device_id cp;
uint8_t major, minor;
+ uint16_t version;
if (sscanf(VERSION, "%hhu.%hhu", &major, &minor) != 2)
return;
+ version = major << 8 | minor;
+
memset(&cp, 0, sizeof(cp));
- cp.source = htobs(0x0002); /* USB */
- cp.vendor = htobs(0x1d6b); /* Linux Foundation */
- cp.product = htobs(0x0247); /* BlueZ for Android */
- cp.version = htobs(major << 8 | minor);
+ cp.source = htobs(DEVICE_ID_SOURCE);
+ cp.vendor = htobs(DEVICE_ID_VENDOR);
+ cp.product = htobs(DEVICE_ID_PRODUCT);
+ cp.version = htobs(version);
if (mgmt_send(adapter->mgmt, MGMT_OP_SET_DEVICE_ID,
adapter->index, sizeof(cp), &cp,
NULL, NULL, NULL) == 0)
error("Failed to set device id");
+
+ register_device_id(DEVICE_ID_SOURCE, DEVICE_ID_VENDOR,
+ DEVICE_ID_PRODUCT, version);
+
+ bt_adapter_add_record(sdp_record_find(0x10000), 0x00);
}
static void set_adapter_name_complete(uint8_t status, uint16_t length,
--
1.8.4.2
^ permalink raw reply related
* Re: [PATCH 2/3] android/hidhost: Remove deprecated idle opcode from ipc document
From: Marcel Holtmann @ 2013-11-12 15:57 UTC (permalink / raw)
To: Ravi Kumar Veeramally; +Cc: linux-bluetooth@vger.kernel.org development
In-Reply-To: <5281F502.9080506@linux.intel.com>
Hi Ravi,
>>> Idle time is deprecated in HID 1_1. So remove it from ipc document
>>> and update GET_REPORT and VIRTUAL_UNPLUG opcode values.
>>> ---
>>> android/hal-ipc-api.txt | 10 ++--------
>>> android/hal-msg.h | 4 ++--
>>> 2 files changed, 4 insertions(+), 10 deletions(-)
>>>
>>> diff --git a/android/hal-ipc-api.txt b/android/hal-ipc-api.txt
>>> index 91ea280..57f4c13 100644
>>> --- a/android/hal-ipc-api.txt
>>> +++ b/android/hal-ipc-api.txt
>>> @@ -614,20 +614,14 @@ Notifications:
>>> 0x01 = Boot
>>> 0xff = Unsupported
>>>
>>> - Opcode 0x84 - Idle Time notification
>>> -
>>> - Notification parameters: Remote address (6 octets)
>>> - Status (1 octet)
>>> - Idle time (2 octets)
>> so what does HID_1.1 actually mean? I still see this notification in bt_hh.h.
>>
>> Regards
>>
>> Marcel
>>
> In HID_SPEC_V11 (3.1) Get Idle and Set Idle are deprecated. And even in bt_hh.h
> get_idle and set_idle interfaces are not available. Bluedroid had implementation
> of those two in bluedroid/btif/src/btif_hh.c but in interface struct those are commented out.
> I didn't find the call back call there. That's why I updated ipc-doc.
if they are not using this notification in the Bluetooth service, then we do not need to implemented.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH v3 0/5] Add support for registering local SDP records
From: Johan Hedberg @ 2013-11-12 17:00 UTC (permalink / raw)
To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1384270586-9853-1-git-send-email-szymon.janc@tieto.com>
Hi Szymon,
On Tue, Nov 12, 2013, Szymon Janc wrote:
> v3:
> - fixed Johan comments
>
> V2:
> - don't use bt_uuid_t
> - few bugfixes
>
> V1 cover:
> This adds support for manipulating local SDP database with
> bt_adapter_add_record and bt_adapter_remove_record functions. Those should
> be called when HAL service is registered or unregistered.
>
> This also adds DeviceID record as at least 1 local UUID is needed by Android to
> properly handle remote device profiles.
>
> Last but not least: With this serie it is possible to connect HID device from
> Android UI (Settings application). \O/
>
> --
> BR
> Szymon Janc
>
> Marcin Kraglak (3):
> android: Add and remove sdp records and uuids
> android: Clear adapter uuids during initialization
> android: Add support for getting UUIDs property
>
> Szymon Janc (2):
> android: Remove not needed include
> android: Register DeviceID record when adapter is initialized
>
> android/adapter.c | 202 ++++++++++++++++++++++++++++++++++++++++++++++++++----
> android/adapter.h | 3 +
> 2 files changed, 192 insertions(+), 13 deletions(-)
All five patches have been applied. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH_v2 3/4] android/pan: Add notify method to PAN notifications
From: Johan Hedberg @ 2013-11-12 17:06 UTC (permalink / raw)
To: Ravi kumar Veeramally; +Cc: linux-bluetooth
In-Reply-To: <1384266042-6344-4-git-send-email-ravikumar.veeramally@linux.intel.com>
Hi Ravi,
On Tue, Nov 12, 2013, Ravi kumar Veeramally wrote:
> ---
> android/hal-pan.c | 6 ++++++
> android/hal.h | 1 +
> 2 files changed, 7 insertions(+)
I've applied the first two patches, but there's one issue with this one:
> +void bt_notify_pan(uint16_t opcode, void *buf, uint16_t len)
> +{
> + if (!interface_ready())
> + return;
> +}
Why is opcode uint16_t instead of uint8_t? Haven't we defined it as
uint8_t in our IPC document?
Johan
^ permalink raw reply
* Re: [RFC BlueZ v1] doc: Add GATT API
From: Claudio Takahasi @ 2013-11-12 18:49 UTC (permalink / raw)
To: Scott James Remnant; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <CAHZ1yCmTdG_ynyfXj0CYhRsPWdM5MBeySvG1Wd5Xb+nEvCVH0A@mail.gmail.com>
Hi Scott,
On Mon, Nov 11, 2013 at 3:56 PM, Scott James Remnant <keybuk@google.com> wrote:
> On Tue, Oct 15, 2013 at 11:39 AM, Claudio Takahasi
> <claudio.takahasi@openbossa.org> wrote:
>
>> +GATT local and remote services share the same high-level D-Bus API. Local
>> +refers to local GATT based service exported by a BlueZ plugin or an external
>> +application. Remote refers to GATT services exported by the peer.
>
> If this object format also be used to describe the services and
> characteristics of a remote device, how will those be handled? I
> assume that we don't want to get the value of every single
> characteristic on connection - that seems wasteful, and would quite
> rapidly drain the batteries of smaller devices.
Declarations are stored/cached. All attributes are discovered only
once in the first connection or after bonding.
When re-connecting, value is read on demand when the user calls
Properties Get (if value is not cached).
Another point is: Notification or Indication are automatically enabled
after the discovery procedure.
>
>
> How will service changed be handled? How will BlueZ track the set of
> applications, and the set of services etc. defined by those
> applications in a manner that keeps handles consistent? How will it
> handle generating the Services Changed notification in the cases where
> the set of applications and/or services change, or the handles change?
We implemented a hash of declarations. Using the "Id" provided in the
options dictionary (see RegisterAgent) we are able to identity if the
external service changed its attributes.
However, I don' t think we will upstream this approach soon, Marcel
wants a simpler approach: always send ServiceChanged.
If you want to understand more details of the implementation see:
https://db.tt/FkWob6jw
>
>
>> +Characteristic hierarchy
>> +========================
> :
>> +Service org.bluez
>> +Interface org.bluez.Characteristic1 [Experimental]
>> +Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY
>
> This would also need a "Permissions" property akin to the one you have
> for Descriptors - characteristics can be "not accessible", read-only,
> write-only, read/write - and can also require authorization,
> authentication, encryption and minimum encryption key sizes - as with
> descriptors.
It is implemented already, there is an optional "Flags" property :
"array{string} Flags [read-only, optional]"
But this is not enough, there are some cases that the permissions are
defined by the external application.
>
>> + array{byte} Value [read-write]
>> +
>> + Cached Value of the characteristic. If present, the
>> + value will be cached by bluetoothd and updated when the
>> + PropertiesChanged signal is emitted.
>> +
>> + External services must emit this signal when the
>> + characteristic supports notification/indication, so
>> + that clients can be notified of the new value.
>
> The PropertiesChanged signal explains how Notification will be handled
> - but how will Indication? How will a service receive the Indication
> Confirmation from the remote devices?
The bluetoothd core manages the Confirmation. In my opinion clients
listening for PropertiesChanged don' t need to know the difference
between notification and indication.
Allow an external client to manage the Confirmation will insert
additional complexity without giving real benefits.
>
>
>> +Application Manager hierarchy
>> +=============================
> :
>> +Service org.bluez
>> +Interface org.bluez.ApplicationManager1 [Experimental]
>> +Object path /org/bluez
>> +
>> +Methods RegisterAgent(object application, dict options)
>
> Shouldn't this be "RegisterApplication" ?
>
> I assume that the object path is the one to which D-Bus Object Manager
> queries are sent, allowing a single process to implement multiple
> "applications"?
The name is still open, but remember that this method might be used to
register client and servers.
At the moment "object path" together with DBus BUS id are used for
identification only. Multiple GATT services can be registered
independently of the application object path.
Application object path can be used to manage *groups* of services
exposed by the single process.
>
>> + UnregisterAgent(object application)
>
> Likewise, "UnregisterApplication" ?
>
>> +Application Agent hierarchy
>> +===========================
>> +
>> +Service unique name
>> +Interface org.bluez.ApplicationAgent1 [Experimental]
>> +Object path freely definable
>> +
>
> "Agent" seems unnnecessary here - if the object is an Application,
> then org.bluez.Application1 would be a decent enough name. Thus an
> "Application" consists of multiple Services, each of which consists of
> multiple Characteristics, each of which has multiple Descriptors
IMO "Agent" gives a better association with its functionality, it
reminds me org.bluez.Agent1.
Let's wait the opinion of the others developers...
Regards,
Claudio
^ permalink raw reply
* Re: [PATCH_v2 3/4] android/pan: Add notify method to PAN notifications
From: Ravi kumar Veeramally @ 2013-11-12 19:33 UTC (permalink / raw)
To: linux-bluetooth, johan.hedberg
In-Reply-To: <20131112170623.GA5058@x220.p-661hnu-f1>
Hi Johan,
On 12.11.2013 19:06, Johan Hedberg wrote:
> Hi Ravi,
>
> On Tue, Nov 12, 2013, Ravi kumar Veeramally wrote:
>> ---
>> android/hal-pan.c | 6 ++++++
>> android/hal.h | 1 +
>> 2 files changed, 7 insertions(+)
> I've applied the first two patches, but there's one issue with this one:
>
>> +void bt_notify_pan(uint16_t opcode, void *buf, uint16_t len)
>> +{
>> + if (!interface_ready())
>> + return;
>> +}
> Why is opcode uint16_t instead of uint8_t? Haven't we defined it as
> uint8_t in our IPC document?
>
There are few other places like adapter and hid it is declared as uint16_t.
I will fix that too and send you v3 of these two.
Thanks,
Ravi.
^ permalink raw reply
* [PATCH] Bluetooth: Add support for Intel Bluetooth device [8087:0a2a]
From: Tedd Ho-Jeong An @ 2013-11-12 21:10 UTC (permalink / raw)
To: linux-bluetooth; +Cc: don.fry, tedd.an, marcel
From: Tedd Ho-Jeong An <tedd.an@intel.com>
This patch adds support for new Intel Bluetooth device.
T: Bus=02 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 4 Spd=12 MxCh= 0
D: Ver= 2.01 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
P: Vendor=8087 ProdID=0a2a Rev= 0.01
C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA
I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=81(I) Atr=03(Int.) MxPS= 64 Ivl=1ms
E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms
E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms
I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms
E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms
I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms
E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms
I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms
E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms
I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms
E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms
I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms
E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
Signed-off-by: Tedd Ho-Jeong An <tedd.an@intel.com>
---
drivers/bluetooth/btusb.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index c206091..0263997 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -225,6 +225,7 @@ static const struct usb_device_id blacklist_table[] = {
/* Intel Bluetooth device */
{ USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL },
+ { USB_DEVICE(0x8087, 0x0a2a), .driver_info = BTUSB_INTEL },
{ } /* Terminating entry */
};
--
1.7.9.5
^ permalink raw reply related
* Re: shutdown(3) and bluetooth.
From: David Miller @ 2013-11-12 21:13 UTC (permalink / raw)
To: davej; +Cc: netdev, linux-bluetooth, linux-wireless
In-Reply-To: <20131112211125.GA2912@redhat.com>
From: Dave Jones <davej@redhat.com>
Date: Tue, 12 Nov 2013 16:11:25 -0500
> Is shutdown() allowed to block indefinitely ? The man page doesn't say either way,
> and I've noticed that my fuzz tester occasionally hangs for days spinning in bt_sock_wait_state()
>
> Is there something I should be doing to guarantee that this operation
> will either time out, or return instantly ?
>
> In this specific case, I doubt anything is on the "sender" end of the socket, so
> it's going to be waiting forever for a state change that won't arrive.
Adding bluetooth and wireless lists. Dave, please consult MAINTAINERS when
asking questions like this, thanks!
^ permalink raw reply
* [PATCH] Enable autosuspend for Intel Bluetooth device
From: Tedd Ho-Jeong An @ 2013-11-12 21:14 UTC (permalink / raw)
To: linux-bluetooth; +Cc: don.fry
From: Tedd Ho-Jeong An <tedd.an@intel.com>
This patch enables autosuspend for Intel Bluetooth device.
After btusb is loaded for Intel Bluetooth device, the power/control
attribute contains "on" value by default which disables the autosuspend.
Based on the USB PM document(Documentation/usb/power-management.txt),
kernel disabled the autosuspend for all devices other than hub by default.
"The USB specification states that all USB devices must support power
management. Nevertheless, the sad fact is that many devices do not
support it very well. You can suspend them all right, but when you
try to resume them they disconnect themselves from the USB bus or
they stop working entirely. This seems to be especially prevalent
among printers and scanners, but plenty of other types of device have
the same deficiency.
For this reason, by default the kernel disables autosuspend (the
power/control attribute is initialized to "on") for all devices other
than hubs. Hubs, at least, appear to be reasonably well-behaved in
this regard."
This document also described how the driver can enables the autosuspend
by using an USB api.
"Drivers can enable autosuspend for their devices by calling
usb_enable_autosuspend(struct usb_device *udev);
in their probe() routine, if they know that the device is capable of
suspending and resuming correctly. This is exactly equivalent to
writing "auto" to the device's power/control attribute."
For Intel Bluetooth device, the autosuspend needs to be enabled so the
device can transit to LPM(Low Power Mode) and ULPM(Ultra LPM) states after
receiving suspend message from the host.
Signed-off-by: Tedd Ho-Jeong An <tedd.an@intel.com>
---
drivers/bluetooth/btusb.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index c206091..0dc9409 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -1437,8 +1437,10 @@ static int btusb_probe(struct usb_interface *intf,
if (id->driver_info & BTUSB_BCM92035)
hdev->setup = btusb_setup_bcm92035;
- if (id->driver_info & BTUSB_INTEL)
+ if (id->driver_info & BTUSB_INTEL) {
+ usb_enable_autosuspend(data->udev);
hdev->setup = btusb_setup_intel;
+ }
/* Interface numbers are hardcoded in the specification */
data->isoc = usb_ifnum_to_if(data->udev, 1);
--
1.7.9.5
^ permalink raw reply related
* [PATCH] Enable autosuspend for Intel Bluetooth device
From: Tedd Ho-Jeong An @ 2013-11-12 21:16 UTC (permalink / raw)
To: linux-bluetooth; +Cc: don.fry, marcel, tedd.an
From: Tedd Ho-Jeong An <tedd.an@intel.com>
This patch enables autosuspend for Intel Bluetooth device.
After btusb is loaded for Intel Bluetooth device, the power/control
attribute contains "on" value by default which disables the autosuspend.
Based on the USB PM document(Documentation/usb/power-management.txt),
kernel disabled the autosuspend for all devices other than hub by default.
"The USB specification states that all USB devices must support power
management. Nevertheless, the sad fact is that many devices do not
support it very well. You can suspend them all right, but when you
try to resume them they disconnect themselves from the USB bus or
they stop working entirely. This seems to be especially prevalent
among printers and scanners, but plenty of other types of device have
the same deficiency.
For this reason, by default the kernel disables autosuspend (the
power/control attribute is initialized to "on") for all devices other
than hubs. Hubs, at least, appear to be reasonably well-behaved in
this regard."
This document also described how the driver can enables the autosuspend
by using an USB api.
"Drivers can enable autosuspend for their devices by calling
usb_enable_autosuspend(struct usb_device *udev);
in their probe() routine, if they know that the device is capable of
suspending and resuming correctly. This is exactly equivalent to
writing "auto" to the device's power/control attribute."
For Intel Bluetooth device, the autosuspend needs to be enabled so the
device can transit to LPM(Low Power Mode) and ULPM(Ultra LPM) states after
receiving suspend message from the host.
Signed-off-by: Tedd Ho-Jeong An <tedd.an@intel.com>
---
drivers/bluetooth/btusb.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index c206091..0dc9409 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -1437,8 +1437,10 @@ static int btusb_probe(struct usb_interface *intf,
if (id->driver_info & BTUSB_BCM92035)
hdev->setup = btusb_setup_bcm92035;
- if (id->driver_info & BTUSB_INTEL)
+ if (id->driver_info & BTUSB_INTEL) {
+ usb_enable_autosuspend(data->udev);
hdev->setup = btusb_setup_intel;
+ }
/* Interface numbers are hardcoded in the specification */
data->isoc = usb_ifnum_to_if(data->udev, 1);
--
1.7.9.5
^ permalink raw reply related
* Re: shutdown(3) and bluetooth.
From: Marcel Holtmann @ 2013-11-12 21:56 UTC (permalink / raw)
To: Dave Jones; +Cc: netdev, linux-bluetooth@vger.kernel.org development
In-Reply-To: <20131112211125.GA2912@redhat.com>
Hi Dave,
> Is shutdown() allowed to block indefinitely ? The man page doesn't say either way,
> and I've noticed that my fuzz tester occasionally hangs for days spinning in bt_sock_wait_state()
>
> Is there something I should be doing to guarantee that this operation
> will either time out, or return instantly ?
>
> In this specific case, I doubt anything is on the "sender" end of the socket, so
> it's going to be waiting forever for a state change that won't arrive.
can you give us some extra information here. What kind of Bluetooth socket is this actually. From the top of my head, I have no idea why we would even wait forever. Normally when all low-level links are gone, the socket will shut down anyway.
Regards
Marcel
^ permalink raw reply
* Re: shutdown(3) and bluetooth.
From: Dave Jones @ 2013-11-12 22:10 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: netdev, linux-bluetooth@vger.kernel.org development
In-Reply-To: <DF4C2B40-BD87-4E88-911D-E3E5F488CAE4@holtmann.org>
On Wed, Nov 13, 2013 at 06:56:23AM +0900, Marcel Holtmann wrote:
> Hi Dave,
>
> > Is shutdown() allowed to block indefinitely ? The man page doesn't say either way,
> > and I've noticed that my fuzz tester occasionally hangs for days spinning in bt_sock_wait_state()
> >
> > Is there something I should be doing to guarantee that this operation
> > will either time out, or return instantly ?
> >
> > In this specific case, I doubt anything is on the "sender" end of the socket, so
> > it's going to be waiting forever for a state change that won't arrive.
>
> can you give us some extra information here. What kind of Bluetooth socket is this actually. From the top of my head, I have no idea why we would even wait forever. Normally when all low-level links are gone, the socket will shut down anyway.
Here's the info I found in the logs, it looks like this was the only bluetooth socket.
fd[195] = domain:31 (PF_BLUETOOTH) type:0x5 protocol:2
Setsockopt(1 d 2134000 8) on fd 195
it doesn't look like any further operations were done on this fd during the fuzzers runtime.
Quick way to reproduce:
./trinity -P PF_BLUETOOTH -l off -c setsockopt
let it run a few seconds, and then ctrl-c. The main process will never exit.
5814 pts/6 Ss 0:00 | \_ bash
5876 pts/6 S+ 0:00 | | \_ ./trinity -P PF_BLUETOOTH -l off -c setsockopt
5877 pts/6 Z+ 0:00 | | \_ [trinity] <defunct>
5878 pts/6 S+ 0:01 | | \_ [trinity-main]
$ sudo cat /proc/5878/stack
[<ffffffffa04397a2>] bt_sock_wait_state+0xc2/0x190 [bluetooth]
[<ffffffffa0847a75>] rfcomm_sock_shutdown+0x85/0xb0 [rfcomm]
[<ffffffffa0847ad9>] rfcomm_sock_release+0x39/0xb0 [rfcomm]
[<ffffffff81532fcf>] sock_release+0x1f/0x80
[<ffffffff81533042>] sock_close+0x12/0x20
[<ffffffff811a9ac1>] __fput+0xe1/0x230
[<ffffffff811a9c5e>] ____fput+0xe/0x10
[<ffffffff8108534c>] task_work_run+0xbc/0xe0
[<ffffffff8106944c>] do_exit+0x2bc/0xa20
[<ffffffff81069c2f>] do_group_exit+0x3f/0xa0
[<ffffffff81069ca4>] SyS_exit_group+0x14/0x20
[<ffffffff81656b27>] tracesys+0xdd/0xe2
[<ffffffffffffffff>] 0xffffffffffffffff
Dave
^ permalink raw reply
* Re: shutdown(3) and bluetooth.
From: Marcel Holtmann @ 2013-11-12 22:32 UTC (permalink / raw)
To: Dave Jones; +Cc: netdev, linux-bluetooth@vger.kernel.org development
In-Reply-To: <20131112221038.GA6689@redhat.com>
Hi Dave,
>>> Is shutdown() allowed to block indefinitely ? The man page doesn't say either way,
>>> and I've noticed that my fuzz tester occasionally hangs for days spinning in bt_sock_wait_state()
>>>
>>> Is there something I should be doing to guarantee that this operation
>>> will either time out, or return instantly ?
>>>
>>> In this specific case, I doubt anything is on the "sender" end of the socket, so
>>> it's going to be waiting forever for a state change that won't arrive.
>>
>> can you give us some extra information here. What kind of Bluetooth socket is this actually. From the top of my head, I have no idea why we would even wait forever. Normally when all low-level links are gone, the socket will shut down anyway.
>
> Here's the info I found in the logs, it looks like this was the only bluetooth socket.
>
> fd[195] = domain:31 (PF_BLUETOOTH) type:0x5 protocol:2
> Setsockopt(1 d 2134000 8) on fd 195
this is a bit confusing. Protocol 2 is actually SCO, but the stack trace shows RFCOMM.
> it doesn't look like any further operations were done on this fd during the fuzzers runtime.
>
> Quick way to reproduce:
>
> ./trinity -P PF_BLUETOOTH -l off -c setsockopt
>
> let it run a few seconds, and then ctrl-c. The main process will never exit.
>
> 5814 pts/6 Ss 0:00 | \_ bash
> 5876 pts/6 S+ 0:00 | | \_ ./trinity -P PF_BLUETOOTH -l off -c setsockopt
> 5877 pts/6 Z+ 0:00 | | \_ [trinity] <defunct>
> 5878 pts/6 S+ 0:01 | | \_ [trinity-main]
>
> $ sudo cat /proc/5878/stack
> [<ffffffffa04397a2>] bt_sock_wait_state+0xc2/0x190 [bluetooth]
> [<ffffffffa0847a75>] rfcomm_sock_shutdown+0x85/0xb0 [rfcomm]
> [<ffffffffa0847ad9>] rfcomm_sock_release+0x39/0xb0 [rfcomm]
> [<ffffffff81532fcf>] sock_release+0x1f/0x80
> [<ffffffff81533042>] sock_close+0x12/0x20
> [<ffffffff811a9ac1>] __fput+0xe1/0x230
> [<ffffffff811a9c5e>] ____fput+0xe/0x10
> [<ffffffff8108534c>] task_work_run+0xbc/0xe0
> [<ffffffff8106944c>] do_exit+0x2bc/0xa20
> [<ffffffff81069c2f>] do_group_exit+0x3f/0xa0
> [<ffffffff81069ca4>] SyS_exit_group+0x14/0x20
> [<ffffffff81656b27>] tracesys+0xdd/0xe2
> [<ffffffffffffffff>] 0xffffffffffffffff
What kernel did you run this against? It is a shot in the dark, but can you try linux-next quickly. There was a socket related fix for the socket options where we confused RFCOMM vs L2CAP struct sock.
Regards
Marcel
^ permalink raw reply
* Re: shutdown(3) and bluetooth.
From: Dave Jones @ 2013-11-12 22:48 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: netdev, linux-bluetooth@vger.kernel.org development
In-Reply-To: <FC5CE013-B077-4EA5-81C1-A7D8B4A5EF85@holtmann.org>
On Wed, Nov 13, 2013 at 07:32:09AM +0900, Marcel Holtmann wrote:
> > Here's the info I found in the logs, it looks like this was the only bluetooth socket.
> >
> > fd[195] = domain:31 (PF_BLUETOOTH) type:0x5 protocol:2
> > Setsockopt(1 d 2134000 8) on fd 195
>
> this is a bit confusing. Protocol 2 is actually SCO, but the stack trace shows RFCOMM.
Sorry, mixed up two separate runs. In the log above, the stack trace is actually..
[<ffffffffa0492dca>] bt_sock_wait_state+0xda/0x240 [bluetooth]
[<ffffffffa04c86d8>] sco_sock_release+0xb8/0xf0 [bluetooth]
[<ffffffff815cb1ff>] sock_release+0x1f/0x90
[<ffffffff815cb282>] sock_close+0x12/0x20
> > ./trinity -P PF_BLUETOOTH -l off -c setsockopt
> >
> > let it run a few seconds, and then ctrl-c. The main process will never exit.
> >
> > 5814 pts/6 Ss 0:00 | \_ bash
> > 5876 pts/6 S+ 0:00 | | \_ ./trinity -P PF_BLUETOOTH -l off -c setsockopt
> > 5877 pts/6 Z+ 0:00 | | \_ [trinity] <defunct>
> > 5878 pts/6 S+ 0:01 | | \_ [trinity-main]
> >
> > $ sudo cat /proc/5878/stack
> > [<ffffffffa04397a2>] bt_sock_wait_state+0xc2/0x190 [bluetooth]
> > [<ffffffffa0847a75>] rfcomm_sock_shutdown+0x85/0xb0 [rfcomm]
> > [<ffffffffa0847ad9>] rfcomm_sock_release+0x39/0xb0 [rfcomm]
So it seems it affects both SCO and RFCOMM.
> What kernel did you run this against? It is a shot in the dark, but can you try linux-next quickly.
> There was a socket related fix for the socket options where we confused RFCOMM vs L2CAP struct sock.
first noticed it on Linus' latest HEAD, and then reproduced it on 3.11.6
I'll look at linux-next tomorrow.
thanks,
Dave
^ permalink raw reply
* Re: shutdown(3) and bluetooth.
From: Marcel Holtmann @ 2013-11-12 23:37 UTC (permalink / raw)
To: Dave Jones; +Cc: netdev, linux-bluetooth@vger.kernel.org development
In-Reply-To: <20131112224819.GE9057@redhat.com>
Hi Dave,
>>> Here's the info I found in the logs, it looks like this was the only bluetooth socket.
>>>
>>> fd[195] = domain:31 (PF_BLUETOOTH) type:0x5 protocol:2
>>> Setsockopt(1 d 2134000 8) on fd 195
>>
>> this is a bit confusing. Protocol 2 is actually SCO, but the stack trace shows RFCOMM.
>
> Sorry, mixed up two separate runs. In the log above, the stack trace is actually..
>
> [<ffffffffa0492dca>] bt_sock_wait_state+0xda/0x240 [bluetooth]
> [<ffffffffa04c86d8>] sco_sock_release+0xb8/0xf0 [bluetooth]
> [<ffffffff815cb1ff>] sock_release+0x1f/0x90
> [<ffffffff815cb282>] sock_close+0x12/0x20
>
>
>>> ./trinity -P PF_BLUETOOTH -l off -c setsockopt
>>>
>>> let it run a few seconds, and then ctrl-c. The main process will never exit.
>>>
>>> 5814 pts/6 Ss 0:00 | \_ bash
>>> 5876 pts/6 S+ 0:00 | | \_ ./trinity -P PF_BLUETOOTH -l off -c setsockopt
>>> 5877 pts/6 Z+ 0:00 | | \_ [trinity] <defunct>
>>> 5878 pts/6 S+ 0:01 | | \_ [trinity-main]
>>>
>>> $ sudo cat /proc/5878/stack
>>> [<ffffffffa04397a2>] bt_sock_wait_state+0xc2/0x190 [bluetooth]
>>> [<ffffffffa0847a75>] rfcomm_sock_shutdown+0x85/0xb0 [rfcomm]
>>> [<ffffffffa0847ad9>] rfcomm_sock_release+0x39/0xb0 [rfcomm]
>
> So it seems it affects both SCO and RFCOMM.
>
>> What kernel did you run this against? It is a shot in the dark, but can you try linux-next quickly.
>> There was a socket related fix for the socket options where we confused RFCOMM vs L2CAP struct sock.
>
> first noticed it on Linus' latest HEAD, and then reproduced it on 3.11.6
> I'll look at linux-next tomorrow.
I looked through the code and only call bt_sock_wait_state when SOCK_LINGER and sk_lingertime is set. In that case we actually block until the socket state changes to BT_CLOSED.
The only way I see this could happen is if you have a huge linger timeout and confused the socket state before. What is actually the list of system calls that you are throwing at this socket.
Regards
Marcel
^ permalink raw reply
* [PATCH v2 0/8] android: Some adapter and mgmt handling code cleanup
From: Szymon Janc @ 2013-11-12 23:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
Hi,
v2:
- addressed Johan comments about using static adapter structure instead of
bunch of static adapter_* variables
- Added a patch for utilizing mgmt library for passing adapter ready callback
(patch 3)
v1:
This patchset moves mgmt initalization handling from main.c to adapter.c so
now all mgmt handling is done from adaper.c. Adapter.c is also renamed to
bluetooth.c to match service name implemented by it.
Startup and shutdown timeouts are still handled in main.c (mostly due to
both resulting in mainloop shutdown so extra callback are avoided).
IO handling and commands dispatch is still done in main.c
Comments are welcome.
--
BR
Szymon Janc
Szymon Janc (8):
android: Make adapter static
android: Move adapter initialization to adapter.c
android: Don't use static pointer for storing adapter_ready callback
android/hidhost: Use adapter address provided on register
android: Report adapter address in adapter_ready callback
android: Remove not needed bt_adapter_get_address function
android: Rename adapter.c to bluetooth.c
android: Rename bluetooth service functions to match service name
android/Android.mk | 2 +-
android/Makefile.am | 4 +-
android/adapter.c | 2008 -----------------------------------------------
android/adapter.h | 37 -
android/bluetooth.c | 2177 +++++++++++++++++++++++++++++++++++++++++++++++++++
android/bluetooth.h | 38 +
android/hidhost.c | 21 +-
android/main.c | 314 ++------
8 files changed, 2287 insertions(+), 2314 deletions(-)
delete mode 100644 android/adapter.c
delete mode 100644 android/adapter.h
create mode 100644 android/bluetooth.c
create mode 100644 android/bluetooth.h
--
1.8.4.3
^ permalink raw reply
* [PATCH v2 1/8] android: Make adapter static
From: Szymon Janc @ 2013-11-12 23:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1384300100-8941-1-git-send-email-szymon.janc@tieto.com>
Only one controller is used so there is no need to keep it as allocable
structure. This will also make memory management simpler and more
correct eg. adapter was never free.
Elements not directly related to adapter are kept outside of adapter
structure.
---
android/adapter.c | 307 +++++++++++++++++++++++++++---------------------------
1 file changed, 152 insertions(+), 155 deletions(-)
diff --git a/android/adapter.c b/android/adapter.c
index 9690861..f8bfb36 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -59,26 +59,36 @@
+ (sizeof(struct hal_property))
static int notification_sk = -1;
+
/* This list contains addresses which are asked for records */
static GSList *browse_reqs;
-struct bt_adapter {
- uint16_t index;
- struct mgmt *mgmt;
+static bt_adapter_ready adapter_ready = NULL;
- bt_adapter_ready ready;
+static struct mgmt *mgmt_if = NULL;
+
+static struct {
+ uint16_t index;
bdaddr_t bdaddr;
uint32_t dev_class;
char *name;
- uint32_t supported_settings;
uint32_t current_settings;
bool discovering;
uint32_t discoverable_timeout;
+
GSList *uuids;
+} adapter = {
+ .index = MGMT_INDEX_NONE,
+ .dev_class = 0,
+ .name = NULL,
+ .current_settings = 0,
+ .discovering = false,
+ .discoverable_timeout = DEFAULT_DISCOVERABLE_TIMEOUT,
+ .uuids = NULL,
};
struct browse_req {
@@ -95,7 +105,6 @@ static const uint16_t uuid_list[] = {
0
};
-static struct bt_adapter *adapter;
static GSList *found_devices = NULL;
static void adapter_name_changed(const uint8_t *name)
@@ -120,13 +129,13 @@ static void adapter_name_changed(const uint8_t *name)
static void adapter_set_name(const uint8_t *name)
{
- if (!g_strcmp0(adapter->name, (const char *) name))
+ if (!g_strcmp0(adapter.name, (const char *) name))
return;
DBG("%s", name);
- g_free(adapter->name);
- adapter->name = g_strdup((const char *) name);
+ g_free(adapter.name);
+ adapter.name = g_strdup((const char *) name);
adapter_name_changed(name);
}
@@ -150,7 +159,7 @@ static void powered_changed(void)
{
struct hal_ev_adapter_state_changed ev;
- ev.state = (adapter->current_settings & MGMT_SETTING_POWERED) ?
+ ev.state = (adapter.current_settings & MGMT_SETTING_POWERED) ?
HAL_POWER_ON : HAL_POWER_OFF;
DBG("%u", ev.state);
@@ -163,8 +172,8 @@ static uint8_t settings2scan_mode(void)
{
bool connectable, discoverable;
- connectable = adapter->current_settings & MGMT_SETTING_CONNECTABLE;
- discoverable = adapter->current_settings & MGMT_SETTING_DISCOVERABLE;
+ connectable = adapter.current_settings & MGMT_SETTING_CONNECTABLE;
+ discoverable = adapter.current_settings & MGMT_SETTING_DISCOVERABLE;
if (connectable && discoverable)
return HAL_ADAPTER_SCAN_MODE_CONN_DISC;
@@ -206,7 +215,7 @@ static void adapter_class_changed(void)
ev->props[0].type = HAL_PROP_ADAPTER_CLASS;
ev->props[0].len = sizeof(uint32_t);
- memcpy(ev->props->val, &adapter->dev_class, sizeof(uint32_t));
+ memcpy(ev->props->val, &adapter.dev_class, sizeof(uint32_t));
ipc_send(notification_sk, HAL_SERVICE_ID_BLUETOOTH,
HAL_EV_ADAPTER_PROPS_CHANGED, sizeof(buf), buf, -1);
@@ -217,9 +226,9 @@ static void settings_changed(uint32_t settings)
uint32_t changed_mask;
uint32_t scan_mode_mask;
- changed_mask = adapter->current_settings ^ settings;
+ changed_mask = adapter.current_settings ^ settings;
- adapter->current_settings = settings;
+ adapter.current_settings = settings;
DBG("0x%08x", changed_mask);
@@ -234,7 +243,7 @@ static void settings_changed(uint32_t settings)
* Only when powered, the connectable and discoverable
* state changes should be communicated.
*/
- if (adapter->current_settings & MGMT_SETTING_POWERED)
+ if (adapter.current_settings & MGMT_SETTING_POWERED)
if (changed_mask & scan_mode_mask)
scan_mode_changed();
}
@@ -251,10 +260,10 @@ static void new_settings_callback(uint16_t index, uint16_t length,
settings = bt_get_le32(param);
- DBG("settings: 0x%8.8x -> 0x%8.8x", adapter->current_settings,
+ DBG("settings: 0x%8.8x -> 0x%8.8x", adapter.current_settings,
settings);
- if (settings == adapter->current_settings)
+ if (settings == adapter.current_settings)
return;
settings_changed(settings);
@@ -273,12 +282,12 @@ static void mgmt_dev_class_changed_event(uint16_t index, uint16_t length,
dev_class = rp->val[0] | (rp->val[1] << 8) | (rp->val[2] << 16);
- if (dev_class == adapter->dev_class)
+ if (dev_class == adapter.dev_class)
return;
DBG("Class: 0x%06x", dev_class);
- adapter->dev_class = dev_class;
+ adapter.dev_class = dev_class;
adapter_class_changed();
@@ -415,7 +424,7 @@ static void browse_cb(sdp_list_t *recs, int err, gpointer user_data)
/* Search for mandatory uuids */
if (uuid_list[req->search_uuid]) {
sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
- bt_search_service(&adapter->bdaddr, &req->bdaddr, &uuid,
+ bt_search_service(&adapter.bdaddr, &req->bdaddr, &uuid,
browse_cb, user_data, NULL);
return;
}
@@ -447,7 +456,7 @@ static uint8_t browse_remote_sdp(const bdaddr_t *addr)
bacpy(&req->bdaddr, addr);
sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
- if (bt_search_service(&adapter->bdaddr,
+ if (bt_search_service(&adapter.bdaddr,
&req->bdaddr, &uuid, browse_cb, req, NULL) < 0) {
browse_req_free(req);
return false;
@@ -602,17 +611,17 @@ static void mgmt_discovering_event(uint16_t index, uint16_t length,
return;
}
- DBG("hci%u type %u discovering %u", adapter->index, ev->type,
+ DBG("hci%u type %u discovering %u", index, ev->type,
ev->discovering);
- if (adapter->discovering == !!ev->discovering)
+ if (adapter.discovering == !!ev->discovering)
return;
- adapter->discovering = !!ev->discovering;
+ adapter.discovering = !!ev->discovering;
DBG("new discovering state %u", ev->discovering);
- if (adapter->discovering) {
+ if (adapter.discovering) {
cp.state = HAL_DISCOVERY_STATE_STARTED;
} else {
g_slist_free_full(found_devices, g_free);
@@ -633,8 +642,8 @@ static void confirm_device_name(const bdaddr_t *addr, uint8_t addr_type)
bacpy(&cp.addr.bdaddr, addr);
cp.addr.type = addr_type;
- if (mgmt_reply(adapter->mgmt, MGMT_OP_CONFIRM_NAME, adapter->index,
- sizeof(cp), &cp, NULL, NULL, NULL) == 0)
+ if (mgmt_reply(mgmt_if, MGMT_OP_CONFIRM_NAME, adapter.index,
+ sizeof(cp), &cp, NULL, NULL, NULL) == 0)
error("Failed to send confirm name request");
}
@@ -880,56 +889,49 @@ static void mgmt_device_unpaired_event(uint16_t index, uint16_t length,
static void register_mgmt_handlers(void)
{
- mgmt_register(adapter->mgmt, MGMT_EV_NEW_SETTINGS, adapter->index,
+ mgmt_register(mgmt_if, MGMT_EV_NEW_SETTINGS, adapter.index,
new_settings_callback, NULL, NULL);
- mgmt_register(adapter->mgmt, MGMT_EV_CLASS_OF_DEV_CHANGED,
- adapter->index, mgmt_dev_class_changed_event,
- NULL, NULL);
+ mgmt_register(mgmt_if, MGMT_EV_CLASS_OF_DEV_CHANGED, adapter.index,
+ mgmt_dev_class_changed_event, NULL, NULL);
- mgmt_register(adapter->mgmt, MGMT_EV_LOCAL_NAME_CHANGED,
- adapter->index, mgmt_local_name_changed_event,
- NULL, NULL);
+ mgmt_register(mgmt_if, MGMT_EV_LOCAL_NAME_CHANGED, adapter.index,
+ mgmt_local_name_changed_event, NULL, NULL);
- mgmt_register(adapter->mgmt, MGMT_EV_NEW_LINK_KEY, adapter->index,
+ mgmt_register(mgmt_if, MGMT_EV_NEW_LINK_KEY, adapter.index,
new_link_key_callback, NULL, NULL);
- mgmt_register(adapter->mgmt, MGMT_EV_PIN_CODE_REQUEST, adapter->index,
+ mgmt_register(mgmt_if, MGMT_EV_PIN_CODE_REQUEST, adapter.index,
pin_code_request_callback, NULL, NULL);
- mgmt_register(adapter->mgmt, MGMT_EV_USER_CONFIRM_REQUEST,
- adapter->index, user_confirm_request_callback,
- NULL, NULL);
+ mgmt_register(mgmt_if, MGMT_EV_USER_CONFIRM_REQUEST, adapter.index,
+ user_confirm_request_callback, NULL, NULL);
- mgmt_register(adapter->mgmt, MGMT_EV_USER_PASSKEY_REQUEST,
- adapter->index, user_passkey_request_callback,
- NULL, NULL);
+ mgmt_register(mgmt_if, MGMT_EV_USER_PASSKEY_REQUEST, adapter.index,
+ user_passkey_request_callback, NULL, NULL);
- mgmt_register(adapter->mgmt, MGMT_EV_PASSKEY_NOTIFY, adapter->index,
+ mgmt_register(mgmt_if, MGMT_EV_PASSKEY_NOTIFY, adapter.index,
user_passkey_notify_callback, NULL, NULL);
- mgmt_register(adapter->mgmt, MGMT_EV_DISCOVERING, adapter->index,
- mgmt_discovering_event,
- NULL, NULL);
+ mgmt_register(mgmt_if, MGMT_EV_DISCOVERING, adapter.index,
+ mgmt_discovering_event, NULL, NULL);
- mgmt_register(adapter->mgmt, MGMT_EV_DEVICE_FOUND,
- adapter->index, mgmt_device_found_event,
- NULL, NULL);
+ mgmt_register(mgmt_if, MGMT_EV_DEVICE_FOUND, adapter.index,
+ mgmt_device_found_event, NULL, NULL);
- mgmt_register(adapter->mgmt, MGMT_EV_DEVICE_CONNECTED, adapter->index,
+ mgmt_register(mgmt_if, MGMT_EV_DEVICE_CONNECTED, adapter.index,
mgmt_device_connected_event, NULL, NULL);
- mgmt_register(adapter->mgmt, MGMT_EV_DEVICE_DISCONNECTED,
- adapter->index, mgmt_device_disconnected_event,
- NULL, NULL);
+ mgmt_register(mgmt_if, MGMT_EV_DEVICE_DISCONNECTED, adapter.index,
+ mgmt_device_disconnected_event, NULL, NULL);
- mgmt_register(adapter->mgmt, MGMT_EV_CONNECT_FAILED, adapter->index,
- mgmt_connect_failed_event, NULL, NULL);
+ mgmt_register(mgmt_if, MGMT_EV_CONNECT_FAILED, adapter.index,
+ mgmt_connect_failed_event, NULL, NULL);
- mgmt_register(adapter->mgmt, MGMT_EV_AUTH_FAILED, adapter->index,
- mgmt_auth_failed_event, NULL, NULL);
+ mgmt_register(mgmt_if, MGMT_EV_AUTH_FAILED, adapter.index,
+ mgmt_auth_failed_event, NULL, NULL);
- mgmt_register(adapter->mgmt, MGMT_EV_DEVICE_UNPAIRED, adapter->index,
+ mgmt_register(mgmt_if, MGMT_EV_DEVICE_UNPAIRED, adapter.index,
mgmt_device_unpaired_event, NULL, NULL);
}
@@ -940,18 +942,18 @@ static void load_link_keys_complete(uint8_t status, uint16_t length,
if (status) {
error("Failed to load link keys for index %u: %s (0x%02x)",
- adapter->index, mgmt_errstr(status), status);
+ adapter.index, mgmt_errstr(status), status);
err = -EIO;
goto failed;
}
DBG("status %u", status);
- adapter->ready(0);
+ adapter_ready(0);
return;
failed:
- adapter->ready(err);
+ adapter_ready(err);
}
static void load_link_keys(GSList *keys)
@@ -979,14 +981,14 @@ static void load_link_keys(GSList *keys)
for (key = cp->keys; keys != NULL; keys = g_slist_next(keys), key++)
memcpy(key, keys->data, sizeof(*key));
- id = mgmt_send(adapter->mgmt, MGMT_OP_LOAD_LINK_KEYS, adapter->index,
+ id = mgmt_send(mgmt_if, MGMT_OP_LOAD_LINK_KEYS, adapter.index,
cp_size, cp, load_link_keys_complete, NULL, NULL);
g_free(cp);
if (id == 0) {
error("Failed to load link keys");
- adapter->ready(-EIO);
+ adapter_ready(-EIO);
}
}
@@ -1004,7 +1006,7 @@ static void uuid16_to_uint128(uint16_t uuid, uint128_t *u128)
static bool get_uuids(void)
{
struct hal_ev_adapter_props_changed *ev;
- GSList *list = adapter->uuids;
+ GSList *list = adapter.uuids;
unsigned int uuid_count = g_slist_length(list);
int len = uuid_count * sizeof(uint128_t);
uint8_t buf[BASELEN_PROP_CHANGED + len];
@@ -1049,7 +1051,7 @@ static void remove_uuid_complete(uint8_t status, uint16_t length,
return;
}
- mgmt_dev_class_changed_event(adapter->index, length, param, NULL);
+ mgmt_dev_class_changed_event(adapter.index, length, param, NULL);
/* send notification only if bluetooth service is registered */
if (notification_sk >= 0)
@@ -1064,9 +1066,8 @@ static void remove_uuid(uint16_t uuid)
uuid16_to_uint128(uuid, &uint128);
htob128(&uint128, (uint128_t *) cp.uuid);
- mgmt_send(adapter->mgmt, MGMT_OP_REMOVE_UUID,
- adapter->index, sizeof(cp), &cp,
- remove_uuid_complete, NULL, NULL);
+ mgmt_send(mgmt_if, MGMT_OP_REMOVE_UUID, adapter.index, sizeof(cp), &cp,
+ remove_uuid_complete, NULL, NULL);
}
static void add_uuid_complete(uint8_t status, uint16_t length,
@@ -1078,7 +1079,7 @@ static void add_uuid_complete(uint8_t status, uint16_t length,
return;
}
- mgmt_dev_class_changed_event(adapter->index, length, param, NULL);
+ mgmt_dev_class_changed_event(adapter.index, length, param, NULL);
/* send notification only if bluetooth service is registered */
if (notification_sk >= 0)
@@ -1095,9 +1096,8 @@ static void add_uuid(uint8_t svc_hint, uint16_t uuid)
htob128(&uint128, (uint128_t *) cp.uuid);
cp.svc_hint = svc_hint;
- mgmt_send(adapter->mgmt, MGMT_OP_ADD_UUID,
- adapter->index, sizeof(cp), &cp,
- add_uuid_complete, NULL, NULL);
+ mgmt_send(mgmt_if, MGMT_OP_ADD_UUID, adapter.index, sizeof(cp), &cp,
+ add_uuid_complete, NULL, NULL);
}
int bt_adapter_add_record(sdp_record_t *rec, uint8_t svc_hint)
@@ -1112,17 +1112,16 @@ int bt_adapter_add_record(sdp_record_t *rec, uint8_t svc_hint)
uuid = rec->svclass.value.uuid16;
- if (g_slist_find(adapter->uuids, GUINT_TO_POINTER(uuid))) {
+ if (g_slist_find(adapter.uuids, GUINT_TO_POINTER(uuid))) {
DBG("UUID 0x%x already added", uuid);
return -EALREADY;
}
- adapter->uuids = g_slist_prepend(adapter->uuids,
- GUINT_TO_POINTER(uuid));
+ adapter.uuids = g_slist_prepend(adapter.uuids, GUINT_TO_POINTER(uuid));
add_uuid(svc_hint, uuid);
- return add_record_to_server(&adapter->bdaddr, rec);
+ return add_record_to_server(&adapter.bdaddr, rec);
}
void bt_adapter_remove_record(uint32_t handle)
@@ -1137,11 +1136,11 @@ void bt_adapter_remove_record(uint32_t handle)
uuid = rec->svclass.value.uuid16;
- uuid_found = g_slist_find(adapter->uuids, GUINT_TO_POINTER(uuid));
+ uuid_found = g_slist_find(adapter.uuids, GUINT_TO_POINTER(uuid));
if (uuid_found) {
remove_uuid(uuid);
- adapter->uuids = g_slist_remove(adapter->uuids,
+ adapter.uuids = g_slist_remove(adapter.uuids,
uuid_found->data);
}
@@ -1162,7 +1161,7 @@ static void set_mode_complete(uint8_t status, uint16_t length,
* required in both cases. So it is safe to just call the
* event handling functions here.
*/
- new_settings_callback(adapter->index, length, param, NULL);
+ new_settings_callback(adapter.index, length, param, NULL);
}
static bool set_mode(uint16_t opcode, uint8_t mode)
@@ -1174,7 +1173,7 @@ static bool set_mode(uint16_t opcode, uint8_t mode)
DBG("opcode=0x%x mode=0x%x", opcode, mode);
- if (mgmt_send(adapter->mgmt, opcode, adapter->index, sizeof(cp), &cp,
+ if (mgmt_send(mgmt_if, opcode, adapter.index, sizeof(cp), &cp,
set_mode_complete, NULL, NULL) > 0)
return true;
@@ -1190,9 +1189,8 @@ static void set_io_capability(void)
memset(&cp, 0, sizeof(cp));
cp.io_capability = DEFAULT_IO_CAPABILITY;
- if (mgmt_send(adapter->mgmt, MGMT_OP_SET_IO_CAPABILITY,
- adapter->index, sizeof(cp), &cp,
- NULL, NULL, NULL) == 0)
+ if (mgmt_send(mgmt_if, MGMT_OP_SET_IO_CAPABILITY, adapter.index,
+ sizeof(cp), &cp, NULL, NULL, NULL) == 0)
error("Failed to set IO capability");
}
@@ -1213,9 +1211,8 @@ static void set_device_id(void)
cp.product = htobs(DEVICE_ID_PRODUCT);
cp.version = htobs(version);
- if (mgmt_send(adapter->mgmt, MGMT_OP_SET_DEVICE_ID,
- adapter->index, sizeof(cp), &cp,
- NULL, NULL, NULL) == 0)
+ if (mgmt_send(mgmt_if, MGMT_OP_SET_DEVICE_ID, adapter.index,
+ sizeof(cp), &cp, NULL, NULL, NULL) == 0)
error("Failed to set device id");
register_device_id(DEVICE_ID_SOURCE, DEVICE_ID_VENDOR,
@@ -1245,9 +1242,9 @@ static uint8_t set_adapter_name(uint8_t *name, uint16_t len)
memset(&cp, 0, sizeof(cp));
memcpy(cp.name, name, len);
- if (mgmt_send(adapter->mgmt, MGMT_OP_SET_LOCAL_NAME, adapter->index,
- sizeof(cp), &cp, set_adapter_name_complete, NULL,
- NULL) > 0)
+ if (mgmt_send(mgmt_if, MGMT_OP_SET_LOCAL_NAME, adapter.index,
+ sizeof(cp), &cp, set_adapter_name_complete,
+ NULL, NULL) > 0)
return HAL_STATUS_SUCCESS;
error("Failed to set name");
@@ -1262,7 +1259,7 @@ static uint8_t set_discoverable_timeout(uint8_t *timeout)
* Just need to store this value here */
/* TODO: This should be in some storage */
- memcpy(&adapter->discoverable_timeout, timeout, sizeof(uint32_t));
+ memcpy(&adapter.discoverable_timeout, timeout, sizeof(uint32_t));
return HAL_STATUS_SUCCESS;
}
@@ -1273,7 +1270,7 @@ static void clear_uuids(void)
memset(&cp, 0, sizeof(cp));
- mgmt_send(adapter->mgmt, MGMT_OP_REMOVE_UUID, adapter->index,
+ mgmt_send(mgmt_if, MGMT_OP_REMOVE_UUID, adapter.index,
sizeof(cp), &cp, NULL, NULL, NULL);
}
@@ -1281,14 +1278,14 @@ static void read_info_complete(uint8_t status, uint16_t length, const void *para
void *user_data)
{
const struct mgmt_rp_read_info *rp = param;
- uint32_t missing_settings;
+ uint32_t missing_settings, supported_settings;
int err;
DBG("");
if (status) {
error("Failed to read info for index %u: %s (0x%02x)",
- adapter->index, mgmt_errstr(status), status);
+ adapter.index, mgmt_errstr(status), status);
err = -EIO;
goto failed;
}
@@ -1306,13 +1303,15 @@ static void read_info_complete(uint8_t status, uint16_t length, const void *para
}
/* Store adapter information */
- bacpy(&adapter->bdaddr, &rp->bdaddr);
- adapter->dev_class = rp->dev_class[0] | (rp->dev_class[1] << 8) |
+ bacpy(&adapter.bdaddr, &rp->bdaddr);
+ adapter.dev_class = rp->dev_class[0] | (rp->dev_class[1] << 8) |
(rp->dev_class[2] << 16);
- adapter->name = g_strdup((const char *) rp->name);
+ adapter.name = g_strdup((const char *) rp->name);
- adapter->supported_settings = btohs(rp->supported_settings);
- adapter->current_settings = btohs(rp->current_settings);
+ supported_settings = btohs(rp->supported_settings);
+ adapter.current_settings = btohs(rp->current_settings);
+
+ /* TODO: Read discoverable timeout from storage here */
/* TODO: Register all event notification handlers */
register_mgmt_handlers();
@@ -1324,8 +1323,7 @@ static void read_info_complete(uint8_t status, uint16_t length, const void *para
set_io_capability();
set_device_id();
- missing_settings = adapter->current_settings ^
- adapter->supported_settings;
+ missing_settings = adapter.current_settings ^ supported_settings;
if (missing_settings & MGMT_SETTING_SSP)
set_mode(MGMT_OP_SET_SSP, 0x01);
@@ -1336,26 +1334,29 @@ static void read_info_complete(uint8_t status, uint16_t length, const void *para
return;
failed:
- adapter->ready(err);
+ adapter_ready(err);
}
void bt_adapter_init(uint16_t index, struct mgmt *mgmt, bt_adapter_ready cb)
{
- adapter = g_new0(struct bt_adapter, 1);
+ mgmt_if = mgmt_ref(mgmt);
+
+ adapter.index = index;
+
+ adapter_ready = cb;
- adapter->mgmt = mgmt_ref(mgmt);
- adapter->index = index;
- adapter->discovering = false;
- adapter->ready = cb;
- /* TODO: Read it from some storage */
- adapter->discoverable_timeout = DEFAULT_DISCOVERABLE_TIMEOUT;
+ /* TODO: Read discoverable timeout from some storage */
if (mgmt_send(mgmt, MGMT_OP_READ_INFO, index, 0, NULL,
read_info_complete, NULL, NULL) > 0)
return;
- mgmt_unref(adapter->mgmt);
- adapter->ready(-EIO);
+ mgmt_unref(mgmt_if);
+ mgmt_if = NULL;
+
+ adapter.index = MGMT_INDEX_NONE;
+
+ adapter_ready(-EIO);
}
static bool set_discoverable(uint8_t mode, uint16_t timeout)
@@ -1368,9 +1369,8 @@ static bool set_discoverable(uint8_t mode, uint16_t timeout)
DBG("mode %u timeout %u", mode, timeout);
- if (mgmt_send(adapter->mgmt, MGMT_OP_SET_DISCOVERABLE,
- adapter->index, sizeof(cp), &cp,
- set_mode_complete, adapter, NULL) > 0)
+ if (mgmt_send(mgmt_if, MGMT_OP_SET_DISCOVERABLE, adapter.index,
+ sizeof(cp), &cp, set_mode_complete, NULL, NULL) > 0)
return true;
error("Failed to set mode discoverable");
@@ -1388,7 +1388,7 @@ static void get_address(void)
ev->props[0].type = HAL_PROP_ADAPTER_ADDR;
ev->props[0].len = sizeof(bdaddr_t);
- bdaddr2android(&adapter->bdaddr, ev->props[0].val);
+ bdaddr2android(&adapter.bdaddr, ev->props[0].val);
ipc_send(notification_sk, HAL_SERVICE_ID_BLUETOOTH,
HAL_EV_ADAPTER_PROPS_CHANGED, sizeof(buf), buf, -1);
@@ -1396,10 +1396,10 @@ static void get_address(void)
static bool get_name(void)
{
- if (!adapter->name)
+ if (!adapter.name)
return false;
- adapter_name_changed((uint8_t *) adapter->name);
+ adapter_name_changed((uint8_t *) adapter.name);
return true;
}
@@ -1463,7 +1463,7 @@ static bool get_discoverable_timeout(void)
ev->props[0].type = HAL_PROP_ADAPTER_DISC_TIMEOUT;
ev->props[0].len = sizeof(uint32_t);
- memcpy(&ev->props[0].val, &adapter->discoverable_timeout,
+ memcpy(&ev->props[0].val, &adapter.discoverable_timeout,
sizeof(uint32_t));
ipc_send(notification_sk, HAL_SERVICE_ID_BLUETOOTH,
@@ -1519,15 +1519,15 @@ static bool start_discovery(void)
struct mgmt_cp_start_discovery cp;
uint8_t type = 1 << BDADDR_BREDR;
- if (adapter->current_settings & type)
+ if (adapter.current_settings & type)
cp.type = type;
else
cp.type = 0;
DBG("type=0x%x", type);
- if (mgmt_send(adapter->mgmt, MGMT_OP_START_DISCOVERY, adapter->index,
- sizeof(cp), &cp, NULL, NULL, NULL) > 0)
+ if (mgmt_send(mgmt_if, MGMT_OP_START_DISCOVERY, adapter.index,
+ sizeof(cp), &cp, NULL, NULL, NULL) > 0)
return true;
error("Failed to start discovery");
@@ -1539,15 +1539,15 @@ static bool stop_discovery(void)
struct mgmt_cp_stop_discovery cp;
uint8_t type = 1 << BDADDR_BREDR;
- if (adapter->current_settings & type)
+ if (adapter.current_settings & type)
cp.type = type;
else
cp.type = 0;
DBG("type=0x%x", type);
- if (mgmt_send(adapter->mgmt, MGMT_OP_STOP_DISCOVERY, adapter->index,
- sizeof(cp), &cp, NULL, NULL, NULL) > 0)
+ if (mgmt_send(mgmt_if, MGMT_OP_STOP_DISCOVERY, adapter.index,
+ sizeof(cp), &cp, NULL, NULL, NULL) > 0)
return true;
error("Failed to start discovery");
@@ -1559,8 +1559,8 @@ static uint8_t set_scan_mode(void *buf, uint16_t len)
uint8_t *mode = buf;
bool conn, disc, cur_conn, cur_disc;
- cur_conn = adapter->current_settings & MGMT_SETTING_CONNECTABLE;
- cur_disc = adapter->current_settings & MGMT_SETTING_DISCOVERABLE;
+ cur_conn = adapter.current_settings & MGMT_SETTING_CONNECTABLE;
+ cur_disc = adapter.current_settings & MGMT_SETTING_DISCOVERABLE;
DBG("connectable %u discoverable %d mode %u", cur_conn, cur_disc,
*mode);
@@ -1674,9 +1674,8 @@ static bool create_bond(void *buf, uint16_t len)
cp.addr.type = BDADDR_BREDR;
android2bdaddr(cmd->bdaddr, &cp.addr.bdaddr);
- if (mgmt_send(adapter->mgmt, MGMT_OP_PAIR_DEVICE, adapter->index,
- sizeof(cp), &cp, pair_device_complete, NULL,
- NULL) == 0)
+ if (mgmt_send(mgmt_if, MGMT_OP_PAIR_DEVICE, adapter.index, sizeof(cp),
+ &cp, pair_device_complete, NULL, NULL) == 0)
return false;
send_bond_state_change(&cp.addr.bdaddr, HAL_STATUS_SUCCESS,
@@ -1693,9 +1692,8 @@ static bool cancel_bond(void *buf, uint16_t len)
cp.type = BDADDR_BREDR;
android2bdaddr(cmd->bdaddr, &cp.bdaddr);
- return mgmt_reply(adapter->mgmt, MGMT_OP_CANCEL_PAIR_DEVICE,
- adapter->index, sizeof(cp), &cp, NULL, NULL,
- NULL) > 0;
+ return mgmt_reply(mgmt_if, MGMT_OP_CANCEL_PAIR_DEVICE, adapter.index,
+ sizeof(cp), &cp, NULL, NULL, NULL) > 0;
}
static void unpair_device_complete(uint8_t status, uint16_t length,
@@ -1721,9 +1719,9 @@ static bool remove_bond(void *buf, uint16_t len)
cp.addr.type = BDADDR_BREDR;
android2bdaddr(cmd->bdaddr, &cp.addr.bdaddr);
- return mgmt_send(adapter->mgmt, MGMT_OP_UNPAIR_DEVICE,
- adapter->index, sizeof(cp), &cp,
- unpair_device_complete, NULL, NULL) > 0;
+ return mgmt_send(mgmt_if, MGMT_OP_UNPAIR_DEVICE, adapter.index,
+ sizeof(cp), &cp, unpair_device_complete,
+ NULL, NULL) > 0;
}
static uint8_t pin_reply(void *buf, uint16_t len)
@@ -1750,9 +1748,8 @@ static uint8_t pin_reply(void *buf, uint16_t len)
rp.pin_len = cmd->pin_len;
memcpy(rp.pin_code, cmd->pin_code, rp.pin_len);
- if (mgmt_reply(adapter->mgmt, MGMT_OP_PIN_CODE_REPLY,
- adapter->index, sizeof(rp), &rp,
- NULL, NULL, NULL) == 0)
+ if (mgmt_reply(mgmt_if, MGMT_OP_PIN_CODE_REPLY, adapter.index,
+ sizeof(rp), &rp, NULL, NULL, NULL) == 0)
return HAL_STATUS_FAILED;
} else {
struct mgmt_cp_pin_code_neg_reply rp;
@@ -1760,9 +1757,9 @@ static uint8_t pin_reply(void *buf, uint16_t len)
bacpy(&rp.addr.bdaddr, &bdaddr);
rp.addr.type = BDADDR_BREDR;
- if (mgmt_reply(adapter->mgmt, MGMT_OP_PIN_CODE_NEG_REPLY,
- adapter->index, sizeof(rp), &rp,
- NULL, NULL, NULL) == 0)
+ if (mgmt_reply(mgmt_if, MGMT_OP_PIN_CODE_NEG_REPLY,
+ adapter.index, sizeof(rp), &rp,
+ NULL, NULL, NULL) == 0)
return HAL_STATUS_FAILED;
}
@@ -1782,7 +1779,7 @@ static uint8_t user_confirm_reply(const bdaddr_t *bdaddr, bool accept)
bacpy(&cp.bdaddr, bdaddr);
cp.type = BDADDR_BREDR;
- if (mgmt_reply(adapter->mgmt, opcode, adapter->index, sizeof(cp), &cp,
+ if (mgmt_reply(mgmt_if, opcode, adapter.index, sizeof(cp), &cp,
NULL, NULL, NULL) > 0)
return HAL_STATUS_SUCCESS;
@@ -1802,9 +1799,9 @@ static uint8_t user_passkey_reply(const bdaddr_t *bdaddr, bool accept,
cp.addr.type = BDADDR_BREDR;
cp.passkey = htobl(passkey);
- id = mgmt_reply(adapter->mgmt, MGMT_OP_USER_PASSKEY_REPLY,
- adapter->index, sizeof(cp), &cp,
- NULL, NULL, NULL);
+ id = mgmt_reply(mgmt_if, MGMT_OP_USER_PASSKEY_REPLY,
+ adapter.index, sizeof(cp), &cp,
+ NULL, NULL, NULL);
} else {
struct mgmt_cp_user_passkey_neg_reply cp;
@@ -1812,9 +1809,9 @@ static uint8_t user_passkey_reply(const bdaddr_t *bdaddr, bool accept,
bacpy(&cp.addr.bdaddr, bdaddr);
cp.addr.type = BDADDR_BREDR;
- id = mgmt_reply(adapter->mgmt, MGMT_OP_USER_PASSKEY_NEG_REPLY,
- adapter->index, sizeof(cp), &cp,
- NULL, NULL, NULL);
+ id = mgmt_reply(mgmt_if, MGMT_OP_USER_PASSKEY_NEG_REPLY,
+ adapter.index, sizeof(cp), &cp,
+ NULL, NULL, NULL);
}
if (id == 0)
@@ -1877,7 +1874,7 @@ void bt_adapter_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
* enabling adapter */
get_properties();
- if (adapter->current_settings & MGMT_SETTING_POWERED) {
+ if (adapter.current_settings & MGMT_SETTING_POWERED) {
status = HAL_STATUS_DONE;
goto error;
}
@@ -1887,7 +1884,7 @@ void bt_adapter_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
break;
case HAL_OP_DISABLE:
- if (!(adapter->current_settings & MGMT_SETTING_POWERED)) {
+ if (!(adapter.current_settings & MGMT_SETTING_POWERED)) {
status = HAL_STATUS_DONE;
goto error;
}
@@ -1938,12 +1935,12 @@ void bt_adapter_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
goto error;
break;
case HAL_OP_START_DISCOVERY:
- if (adapter->discovering) {
+ if (adapter.discovering) {
status = HAL_STATUS_DONE;
goto error;
}
- if (!(adapter->current_settings & MGMT_SETTING_POWERED)) {
+ if (!(adapter.current_settings & MGMT_SETTING_POWERED)) {
status = HAL_STATUS_NOT_READY;
goto error;
}
@@ -1953,12 +1950,12 @@ void bt_adapter_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
break;
case HAL_OP_CANCEL_DISCOVERY:
- if (!adapter->discovering) {
+ if (!adapter.discovering) {
status = HAL_STATUS_DONE;
goto error;
}
- if (!(adapter->current_settings & MGMT_SETTING_POWERED)) {
+ if (!(adapter.current_settings & MGMT_SETTING_POWERED)) {
status = HAL_STATUS_NOT_READY;
goto error;
}
@@ -1988,7 +1985,7 @@ error:
const bdaddr_t *bt_adapter_get_address(void)
{
- return &adapter->bdaddr;
+ return &adapter.bdaddr;
}
bool bt_adapter_register(int sk)
--
1.8.4.3
^ permalink raw reply related
* [PATCH v2 2/8] android: Move adapter initialization to adapter.c
From: Szymon Janc @ 2013-11-12 23:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1384300100-8941-1-git-send-email-szymon.janc@tieto.com>
There is no need to handle that in main.c. Also this removes mgmt
interface dependency from adapter API as all mgmt commands are handled
from adapter code.
Startup and shutdown timeouts handling is left in main.c.
---
android/adapter.c | 195 +++++++++++++++++++++++++++++++++--
android/adapter.h | 7 +-
android/main.c | 300 +++++++++---------------------------------------------
3 files changed, 240 insertions(+), 262 deletions(-)
diff --git a/android/adapter.c b/android/adapter.c
index f8bfb36..1d628c8 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -58,6 +58,8 @@
#define BASELEN_PROP_CHANGED sizeof(struct hal_ev_adapter_props_changed) \
+ (sizeof(struct hal_property))
+static uint16_t option_index = MGMT_INDEX_NONE;
+
static int notification_sk = -1;
/* This list contains addresses which are asked for records */
@@ -1337,28 +1339,201 @@ failed:
adapter_ready(err);
}
-void bt_adapter_init(uint16_t index, struct mgmt *mgmt, bt_adapter_ready cb)
+static void mgmt_index_added_event(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
{
- mgmt_if = mgmt_ref(mgmt);
+ DBG("index %u", index);
- adapter.index = index;
+ if (adapter.index != MGMT_INDEX_NONE) {
+ DBG("skip event for index %u", index);
+ return;
+ }
- adapter_ready = cb;
+ if (option_index != MGMT_INDEX_NONE && option_index != index) {
+ DBG("skip event for index %u (option %u)", index, option_index);
+ return;
+ }
- /* TODO: Read discoverable timeout from some storage */
+ if (mgmt_send(mgmt_if, MGMT_OP_READ_INFO, index, 0, NULL,
+ read_info_complete, NULL, NULL) == 0) {
+ adapter_ready(-EIO);
+ return;
+ }
+}
- if (mgmt_send(mgmt, MGMT_OP_READ_INFO, index, 0, NULL,
- read_info_complete, NULL, NULL) > 0)
+static void mgmt_index_removed_event(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ DBG("index %u", index);
+
+ if (index != adapter.index)
return;
- mgmt_unref(mgmt_if);
- mgmt_if = NULL;
+ error("Adapter was removed. Exiting.");
+ raise(SIGTERM);
+}
+
+static void read_index_list_complete(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ const struct mgmt_rp_read_index_list *rp = param;
+ uint16_t num;
+ int i;
+
+ DBG("");
+
+ if (status) {
+ error("%s: Failed to read index list: %s (0x%02x)",
+ __func__, mgmt_errstr(status), status);
+ goto failed;
+ }
+
+ if (length < sizeof(*rp)) {
+ error("%s: Wrong size of read index list response", __func__);
+ goto failed;
+ }
+
+ num = btohs(rp->num_controllers);
+
+ DBG("Number of controllers: %u", num);
+
+ if (num * sizeof(uint16_t) + sizeof(*rp) != length) {
+ error("%s: Incorrect pkt size for index list rsp", __func__);
+ goto failed;
+ }
+
+ if (adapter.index != MGMT_INDEX_NONE)
+ return;
+
+ for (i = 0; i < num; i++) {
+ uint16_t index = btohs(rp->index[i]);
+
+ if (option_index != MGMT_INDEX_NONE && option_index != index)
+ continue;
+
+ if (mgmt_send(mgmt_if, MGMT_OP_READ_INFO, index, 0, NULL,
+ read_info_complete, NULL, NULL) == 0)
+ goto failed;
+
+ adapter.index = index;
+ return;
+ }
+
+ return;
+
+failed:
+ adapter_ready(-EIO);
+}
+
+static void read_version_complete(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ const struct mgmt_rp_read_version *rp = param;
+ uint8_t mgmt_version, mgmt_revision;
+
+ DBG("");
+
+ if (status) {
+ error("Failed to read version information: %s (0x%02x)",
+ mgmt_errstr(status), status);
+ goto failed;
+ }
+
+ if (length < sizeof(*rp)) {
+ error("Wrong size response");
+ goto failed;
+ }
- adapter.index = MGMT_INDEX_NONE;
+ mgmt_version = rp->version;
+ mgmt_revision = btohs(rp->revision);
+
+ info("Bluetooth management interface %u.%u initialized",
+ mgmt_version, mgmt_revision);
+
+ if (MGMT_VERSION(mgmt_version, mgmt_revision) < MGMT_VERSION(1, 3)) {
+ error("Version 1.3 or later of management interface required");
+ goto failed;
+ }
+
+ mgmt_register(mgmt_if, MGMT_EV_INDEX_ADDED, MGMT_INDEX_NONE,
+ mgmt_index_added_event, NULL, NULL);
+ mgmt_register(mgmt_if, MGMT_EV_INDEX_REMOVED, MGMT_INDEX_NONE,
+ mgmt_index_removed_event, NULL, NULL);
+
+ if (mgmt_send(mgmt_if, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0,
+ NULL, read_index_list_complete, NULL, NULL) > 0)
+ return;
+ error("Failed to read controller index list");
+
+failed:
adapter_ready(-EIO);
}
+bool bt_adapter_start(int index, bt_adapter_ready cb)
+{
+ DBG("index %d", index);
+
+ mgmt_if = mgmt_new_default();
+ if (!mgmt_if) {
+ error("Failed to access management interface");
+ return false;
+ }
+
+ if (mgmt_send(mgmt_if, MGMT_OP_READ_VERSION, MGMT_INDEX_NONE, 0, NULL,
+ read_version_complete, NULL, NULL) == 0) {
+ error("Error sending READ_VERSION mgmt command");
+
+ mgmt_unref(mgmt_if);
+ mgmt_if = NULL;
+
+ return false;
+ }
+
+ if (index >= 0)
+ option_index = index;
+
+ adapter_ready = cb;
+
+ return true;
+}
+
+static void shutdown_complete(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ bt_adapter_stopped cb = user_data;
+
+ if (status != MGMT_STATUS_SUCCESS)
+ error("Clean controller shutdown failed");
+
+ cb();
+}
+
+bool bt_adapter_stop(bt_adapter_stopped cb)
+{
+ struct mgmt_mode cp;
+
+ if (adapter.index == MGMT_INDEX_NONE)
+ return false;
+
+ info("Switching controller off");
+
+ memset(&cp, 0, sizeof(cp));
+
+ return mgmt_send(mgmt_if, MGMT_OP_SET_POWERED, adapter.index,
+ sizeof(cp), &cp, shutdown_complete, (void *)cb,
+ NULL) > 0;
+}
+
+void bt_adapter_cleanup(void)
+{
+ g_free(adapter.name);
+ adapter.name = NULL;
+
+ mgmt_unref(mgmt_if);
+ mgmt_if = NULL;
+}
+
static bool set_discoverable(uint8_t mode, uint16_t timeout)
{
struct mgmt_cp_set_discoverable cp;
diff --git a/android/adapter.h b/android/adapter.h
index 0e84cb0..e8993f2 100644
--- a/android/adapter.h
+++ b/android/adapter.h
@@ -22,9 +22,12 @@
*/
typedef void (*bt_adapter_ready)(int err);
+bool bt_adapter_start(int index, bt_adapter_ready cb);
-void bt_adapter_init(uint16_t index, struct mgmt *mgmt_if,
- bt_adapter_ready cb);
+typedef void (*bt_adapter_stopped)(void);
+bool bt_adapter_stop(bt_adapter_stopped cb);
+
+void bt_adapter_cleanup(void);
void bt_adapter_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len);
diff --git a/android/main.c b/android/main.c
index 36cc8aa..f82e6d8 100644
--- a/android/main.c
+++ b/android/main.c
@@ -45,8 +45,6 @@
#include "src/sdpd.h"
#include "lib/bluetooth.h"
-#include "lib/mgmt.h"
-#include "src/shared/mgmt.h"
#include "adapter.h"
#include "socket.h"
@@ -65,11 +63,9 @@
#define STARTUP_GRACE_SECONDS 5
#define SHUTDOWN_GRACE_SECONDS 10
-static GMainLoop *event_loop;
-static struct mgmt *mgmt_if = NULL;
+static guint bluetooth_start_timeout = 0;
-static uint16_t adapter_index = MGMT_INDEX_NONE;
-static guint adapter_timeout = 0;
+static GMainLoop *event_loop;
static GIOChannel *hal_cmd_io = NULL;
static GIOChannel *hal_notif_io = NULL;
@@ -186,35 +182,32 @@ static void handle_service_core(uint8_t opcode, void *buf, uint16_t len)
}
}
-static void shutdown_complete(uint8_t status, uint16_t length,
- const void *param, void *user_data)
+static void bluetooth_stopped(void)
{
- if (status != MGMT_STATUS_SUCCESS)
- error("Clean controller shutdown failed");
+ g_main_loop_quit(event_loop);
+}
+static gboolean quit_eventloop(gpointer user_data)
+{
g_main_loop_quit(event_loop);
+ return FALSE;
}
-static void shutdown_controller(void)
+static void stop_bluetooth(void)
{
- static bool __shutdown = false;
- struct mgmt_mode cp;
+ static bool __stop = false;
- if (__shutdown)
+ if (__stop)
return;
- __shutdown = true;
-
- info("Switching controller off");
+ __stop = true;
- memset(&cp, 0, sizeof(cp));
- cp.val = 0x00;
-
- if (mgmt_send(mgmt_if, MGMT_OP_SET_POWERED, adapter_index,
- sizeof(cp), &cp, shutdown_complete, NULL, NULL) > 0)
+ if (!bt_adapter_stop(bluetooth_stopped)) {
+ g_main_loop_quit(event_loop);
return;
+ }
- g_main_loop_quit(event_loop);
+ g_timeout_add_seconds(SHUTDOWN_GRACE_SECONDS, quit_eventloop, NULL);
}
static gboolean cmd_watch_cb(GIOChannel *io, GIOCondition cond,
@@ -279,7 +272,7 @@ static gboolean cmd_watch_cb(GIOChannel *io, GIOCondition cond,
return TRUE;
fail:
- shutdown_controller();
+ stop_bluetooth();
return FALSE;
}
@@ -287,7 +280,7 @@ static gboolean notif_watch_cb(GIOChannel *io, GIOCondition cond,
gpointer user_data)
{
info("HAL notification socket closed, terminating");
- shutdown_controller();
+ stop_bluetooth();
return FALSE;
}
@@ -336,7 +329,7 @@ static gboolean notif_connect_cb(GIOChannel *io, GIOCondition cond,
DBG("");
if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
- g_main_loop_quit(event_loop);
+ stop_bluetooth();
return FALSE;
}
@@ -359,23 +352,38 @@ static gboolean cmd_connect_cb(GIOChannel *io, GIOCondition cond,
DBG("");
if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
- g_main_loop_quit(event_loop);
+ stop_bluetooth();
return FALSE;
}
hal_notif_io = connect_hal(notif_connect_cb);
if (!hal_notif_io) {
error("Cannot connect to HAL, terminating");
- g_main_loop_quit(event_loop);
+ stop_bluetooth();
}
return FALSE;
}
-static gboolean quit_eventloop(gpointer user_data)
+static void adapter_ready(int err)
{
- g_main_loop_quit(event_loop);
- return FALSE;
+ if (err < 0) {
+ error("Adapter initialization failed: %s", strerror(-err));
+ exit(EXIT_FAILURE);
+ }
+
+ if (bluetooth_start_timeout > 0) {
+ g_source_remove(bluetooth_start_timeout);
+ bluetooth_start_timeout = 0;
+ }
+
+ info("Adapter initialized");
+
+ hal_cmd_io = connect_hal(cmd_connect_cb);
+ if (!hal_cmd_io) {
+ error("Cannot connect to HAL, terminating");
+ stop_bluetooth();
+ }
}
static gboolean signal_handler(GIOChannel *channel, GIOCondition cond,
@@ -400,12 +408,7 @@ static gboolean signal_handler(GIOChannel *channel, GIOCondition cond,
case SIGTERM:
if (!__terminated) {
info("Terminating");
- if (adapter_index != MGMT_INDEX_NONE) {
- g_timeout_add_seconds(SHUTDOWN_GRACE_SECONDS,
- quit_eventloop, NULL);
- shutdown_controller();
- } else
- g_main_loop_quit(event_loop);
+ stop_bluetooth();
}
__terminated = true;
@@ -453,7 +456,7 @@ static guint setup_signalfd(void)
}
static gboolean option_version = FALSE;
-static gint option_index = MGMT_INDEX_NONE;
+static gint option_index = -1;
static GOptionEntry options[] = {
{ "version", 'v', 0, G_OPTION_ARG_NONE, &option_version,
@@ -463,216 +466,6 @@ static GOptionEntry options[] = {
{ NULL }
};
-static void adapter_ready(int err)
-{
- if (err < 0) {
- error("Adapter initialization failed: %s", strerror(-err));
- exit(EXIT_FAILURE);
- }
-
- info("Adapter initialized");
-
- hal_cmd_io = connect_hal(cmd_connect_cb);
- if (!hal_cmd_io) {
- error("Cannot connect to HAL, terminating");
- g_main_loop_quit(event_loop);
- }
-}
-
-static void mgmt_index_added_event(uint16_t index, uint16_t length,
- const void *param, void *user_data)
-{
- uint16_t opt_index = option_index;
-
- DBG("index %u", index);
-
- if (adapter_index != MGMT_INDEX_NONE) {
- DBG("skip event for index %u", index);
- return;
- }
-
- if (opt_index != MGMT_INDEX_NONE && opt_index != index) {
- DBG("skip event for index %u (option %u)", index, opt_index);
- return;
- }
-
- if (adapter_timeout > 0) {
- g_source_remove(adapter_timeout);
- adapter_timeout = 0;
- }
-
- adapter_index = index;
- bt_adapter_init(index, mgmt_if, adapter_ready);
-}
-
-static void mgmt_index_removed_event(uint16_t index, uint16_t length,
- const void *param, void *user_data)
-{
- DBG("index %u", index);
-
- if (index != adapter_index)
- return;
-
- error("Adapter was removed. Exiting.");
- g_main_loop_quit(event_loop);
-}
-
-static gboolean adapter_timeout_handler(gpointer user_data)
-{
- adapter_timeout = 0;
- g_main_loop_quit(event_loop);
-
- return FALSE;
-}
-
-static void read_index_list_complete(uint8_t status, uint16_t length,
- const void *param, void *user_data)
-{
- const struct mgmt_rp_read_index_list *rp = param;
- uint16_t opt_index = option_index;
- uint16_t num;
- int i;
-
- DBG("");
-
- if (status) {
- error("%s: Failed to read index list: %s (0x%02x)",
- __func__, mgmt_errstr(status), status);
- goto failed;
- }
-
- if (length < sizeof(*rp)) {
- error("%s: Wrong size of read index list response", __func__);
- goto failed;
- }
-
- num = btohs(rp->num_controllers);
-
- DBG("Number of controllers: %u", num);
-
- if (num * sizeof(uint16_t) + sizeof(*rp) != length) {
- error("%s: Incorrect pkt size for index list rsp", __func__);
- goto failed;
- }
-
- if (adapter_index != MGMT_INDEX_NONE)
- return;
-
- for (i = 0; i < num; i++) {
- uint16_t index = btohs(rp->index[i]);
-
- if (opt_index != MGMT_INDEX_NONE && opt_index != index)
- continue;
-
- adapter_index = index;
- bt_adapter_init(adapter_index, mgmt_if, adapter_ready);
- return;
- }
-
- if (adapter_index != MGMT_INDEX_NONE)
- return;
-
- adapter_timeout = g_timeout_add_seconds(STARTUP_GRACE_SECONDS,
- adapter_timeout_handler, NULL);
- if (adapter_timeout > 0)
- return;
-
- error("%s: Failed init timeout", __func__);
-
-failed:
- g_main_loop_quit(event_loop);
-}
-
-static void read_commands_complete(uint8_t status, uint16_t length,
- const void *param, void *user_data)
-{
- const struct mgmt_rp_read_commands *rp = param;
-
- DBG("");
-
- if (status) {
- error("Failed to read supported commands: %s (0x%02x)",
- mgmt_errstr(status), status);
- return;
- }
-
- if (length < sizeof(*rp)) {
- error("Wrong size response");
- return;
- }
-}
-
-static void read_version_complete(uint8_t status, uint16_t length,
- const void *param, void *user_data)
-{
- const struct mgmt_rp_read_version *rp = param;
- uint8_t mgmt_version, mgmt_revision;
-
- DBG("");
-
- if (status) {
- error("Failed to read version information: %s (0x%02x)",
- mgmt_errstr(status), status);
- goto failed;
- }
-
- if (length < sizeof(*rp)) {
- error("Wrong size response");
- goto failed;
- }
-
- mgmt_version = rp->version;
- mgmt_revision = btohs(rp->revision);
-
- info("Bluetooth management interface %u.%u initialized",
- mgmt_version, mgmt_revision);
-
- if (MGMT_VERSION(mgmt_version, mgmt_revision) < MGMT_VERSION(1, 3)) {
- error("Version 1.3 or later of management interface required");
- goto failed;
- }
-
- mgmt_send(mgmt_if, MGMT_OP_READ_COMMANDS, MGMT_INDEX_NONE, 0, NULL,
- read_commands_complete, NULL, NULL);
-
- mgmt_register(mgmt_if, MGMT_EV_INDEX_ADDED, MGMT_INDEX_NONE,
- mgmt_index_added_event, NULL, NULL);
- mgmt_register(mgmt_if, MGMT_EV_INDEX_REMOVED, MGMT_INDEX_NONE,
- mgmt_index_removed_event, NULL, NULL);
-
- if (mgmt_send(mgmt_if, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0,
- NULL, read_index_list_complete, NULL, NULL) > 0)
- return;
-
- error("Failed to read controller index list");
-
-failed:
- g_main_loop_quit(event_loop);
-}
-
-static bool init_mgmt_interface(void)
-{
- mgmt_if = mgmt_new_default();
- if (!mgmt_if) {
- error("Failed to access management interface");
- return false;
- }
-
- if (mgmt_send(mgmt_if, MGMT_OP_READ_VERSION, MGMT_INDEX_NONE, 0, NULL,
- read_version_complete, NULL, NULL) == 0) {
- error("Error sending READ_VERSION mgmt command");
- return false;
- }
-
- return true;
-}
-
-static void cleanup_mgmt_interface(void)
-{
- mgmt_unref(mgmt_if);
- mgmt_if = NULL;
-}
-
static void cleanup_hal_connection(void)
{
if (hal_cmd_io) {
@@ -757,7 +550,14 @@ int main(int argc, char *argv[])
if (!set_capabilities())
return EXIT_FAILURE;
- if (!init_mgmt_interface())
+ bluetooth_start_timeout = g_timeout_add_seconds(STARTUP_GRACE_SECONDS,
+ quit_eventloop, NULL);
+ if (bluetooth_start_timeout == 0) {
+ error("Failed to init startup timeout");
+ return EXIT_FAILURE;
+ }
+
+ if (!bt_adapter_start(option_index, adapter_ready))
return EXIT_FAILURE;
/* Use params: mtu = 0, flags = 0 */
@@ -771,7 +571,7 @@ int main(int argc, char *argv[])
cleanup_hal_connection();
stop_sdp_server();
- cleanup_mgmt_interface();
+ bt_adapter_cleanup();
g_main_loop_unref(event_loop);
info("Exit");
--
1.8.4.3
^ permalink raw reply related
* [PATCH v2 3/8] android: Don't use static pointer for storing adapter_ready callback
From: Szymon Janc @ 2013-11-12 23:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1384300100-8941-1-git-send-email-szymon.janc@tieto.com>
There is no need to keep ready callback for daemon lifetime as it is
not used after reporting adapter being ready. Use mgmt library feature
for passing user data so that static pointer is not needed.
---
android/adapter.c | 40 +++++++++++++++++++++-------------------
1 file changed, 21 insertions(+), 19 deletions(-)
diff --git a/android/adapter.c b/android/adapter.c
index 1d628c8..001059a 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -65,8 +65,6 @@ static int notification_sk = -1;
/* This list contains addresses which are asked for records */
static GSList *browse_reqs;
-static bt_adapter_ready adapter_ready = NULL;
-
static struct mgmt *mgmt_if = NULL;
static struct {
@@ -940,6 +938,7 @@ static void register_mgmt_handlers(void)
static void load_link_keys_complete(uint8_t status, uint16_t length,
const void *param, void *user_data)
{
+ bt_adapter_ready cb = user_data;
int err;
if (status) {
@@ -951,14 +950,14 @@ static void load_link_keys_complete(uint8_t status, uint16_t length,
DBG("status %u", status);
- adapter_ready(0);
+ cb(0);
return;
failed:
- adapter_ready(err);
+ cb(err);
}
-static void load_link_keys(GSList *keys)
+static void load_link_keys(GSList *keys, bt_adapter_ready cb)
{
struct mgmt_cp_load_link_keys *cp;
struct mgmt_link_key_info *key;
@@ -984,13 +983,13 @@ static void load_link_keys(GSList *keys)
memcpy(key, keys->data, sizeof(*key));
id = mgmt_send(mgmt_if, MGMT_OP_LOAD_LINK_KEYS, adapter.index,
- cp_size, cp, load_link_keys_complete, NULL, NULL);
+ cp_size, cp, load_link_keys_complete, cb, NULL);
g_free(cp);
if (id == 0) {
error("Failed to load link keys");
- adapter_ready(-EIO);
+ cb(-EIO);
}
}
@@ -1280,6 +1279,7 @@ static void read_info_complete(uint8_t status, uint16_t length, const void *para
void *user_data)
{
const struct mgmt_rp_read_info *rp = param;
+ bt_adapter_ready cb = user_data;
uint32_t missing_settings, supported_settings;
int err;
@@ -1320,7 +1320,7 @@ static void read_info_complete(uint8_t status, uint16_t length, const void *para
clear_uuids();
- load_link_keys(NULL);
+ load_link_keys(NULL, cb);
set_io_capability();
set_device_id();
@@ -1336,12 +1336,14 @@ static void read_info_complete(uint8_t status, uint16_t length, const void *para
return;
failed:
- adapter_ready(err);
+ cb(err);
}
static void mgmt_index_added_event(uint16_t index, uint16_t length,
const void *param, void *user_data)
{
+ bt_adapter_ready cb = user_data;
+
DBG("index %u", index);
if (adapter.index != MGMT_INDEX_NONE) {
@@ -1355,8 +1357,8 @@ static void mgmt_index_added_event(uint16_t index, uint16_t length,
}
if (mgmt_send(mgmt_if, MGMT_OP_READ_INFO, index, 0, NULL,
- read_info_complete, NULL, NULL) == 0) {
- adapter_ready(-EIO);
+ read_info_complete, cb, NULL) == 0) {
+ cb(-EIO);
return;
}
}
@@ -1377,6 +1379,7 @@ static void read_index_list_complete(uint8_t status, uint16_t length,
const void *param, void *user_data)
{
const struct mgmt_rp_read_index_list *rp = param;
+ bt_adapter_ready cb = user_data;
uint16_t num;
int i;
@@ -1412,7 +1415,7 @@ static void read_index_list_complete(uint8_t status, uint16_t length,
continue;
if (mgmt_send(mgmt_if, MGMT_OP_READ_INFO, index, 0, NULL,
- read_info_complete, NULL, NULL) == 0)
+ read_info_complete, cb, NULL) == 0)
goto failed;
adapter.index = index;
@@ -1422,7 +1425,7 @@ static void read_index_list_complete(uint8_t status, uint16_t length,
return;
failed:
- adapter_ready(-EIO);
+ cb(-EIO);
}
static void read_version_complete(uint8_t status, uint16_t length,
@@ -1430,6 +1433,7 @@ static void read_version_complete(uint8_t status, uint16_t length,
{
const struct mgmt_rp_read_version *rp = param;
uint8_t mgmt_version, mgmt_revision;
+ bt_adapter_ready cb = user_data;
DBG("");
@@ -1456,18 +1460,18 @@ static void read_version_complete(uint8_t status, uint16_t length,
}
mgmt_register(mgmt_if, MGMT_EV_INDEX_ADDED, MGMT_INDEX_NONE,
- mgmt_index_added_event, NULL, NULL);
+ mgmt_index_added_event, cb, NULL);
mgmt_register(mgmt_if, MGMT_EV_INDEX_REMOVED, MGMT_INDEX_NONE,
mgmt_index_removed_event, NULL, NULL);
if (mgmt_send(mgmt_if, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0,
- NULL, read_index_list_complete, NULL, NULL) > 0)
+ NULL, read_index_list_complete, cb, NULL) > 0)
return;
error("Failed to read controller index list");
failed:
- adapter_ready(-EIO);
+ cb(-EIO);
}
bool bt_adapter_start(int index, bt_adapter_ready cb)
@@ -1481,7 +1485,7 @@ bool bt_adapter_start(int index, bt_adapter_ready cb)
}
if (mgmt_send(mgmt_if, MGMT_OP_READ_VERSION, MGMT_INDEX_NONE, 0, NULL,
- read_version_complete, NULL, NULL) == 0) {
+ read_version_complete, cb, NULL) == 0) {
error("Error sending READ_VERSION mgmt command");
mgmt_unref(mgmt_if);
@@ -1493,8 +1497,6 @@ bool bt_adapter_start(int index, bt_adapter_ready cb)
if (index >= 0)
option_index = index;
- adapter_ready = cb;
-
return true;
}
--
1.8.4.3
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox