* [PATCH 2/4] sdp: Move spd_init_services_list to adapter
From: Grzegorz Kolodziejczyk @ 2013-08-26 13:07 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1377522441-28671-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>
Make sdp_init_services_list to be runned in adapter instead of
sdp-database. sdp_init_service is invoked by adapter_register function.
Change-Id: Iddf5afbe410608ca96df727a7c9bb791e457ca77
---
src/adapter.c | 27 ++++++++++++++++++++++++++-
src/adapter.h | 2 ++
src/sdpd-database.c | 31 ++++++++-----------------------
src/sdpd.h | 3 +--
4 files changed, 37 insertions(+), 26 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index 723e3a8..fd20d61 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -5603,7 +5603,7 @@ static int adapter_register(struct btd_adapter *adapter)
agent_unref(agent);
}
- sdp_init_services_list(&adapter->bdaddr);
+ adapter_sdp_init_services_list(&adapter->bdaddr);
btd_adapter_gatt_server_start(adapter);
@@ -6306,3 +6306,28 @@ void adapter_start_sdp_server(uint16_t sdp_mtu, uint32_t sdp_flags) {
for (; services; services = services->next)
adapter_foreach(adapter_service_insert, services->data);
}
+
+void adapter_sdp_init_services_list(bdaddr_t *device)
+{
+ sdp_list_t *p;
+
+ p = sdp_get_access_list();
+
+ DBG("");
+
+ for (; p != NULL; p = p->next) {
+ sdp_access_t *access = p->data;
+ sdp_record_t *rec;
+
+ if (bacmp(BDADDR_ANY, &access->device))
+ continue;
+
+ rec = sdp_record_find(access->handle);
+ if (rec == NULL)
+ continue;
+
+ SDPDBG("adding record with handle %x", access->handle);
+
+ adapter_foreach(adapter_service_insert, rec);
+ }
+}
diff --git a/src/adapter.h b/src/adapter.h
index a60a29f..ad01710 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -214,3 +214,5 @@ gboolean btd_adapter_check_oob_handler(struct btd_adapter *adapter);
void btd_adapter_for_each_device(struct btd_adapter *adapter,
void (*cb)(struct btd_device *device, void *data),
void *data);
+
+void adapter_sdp_init_services_list(bdaddr_t *device);
diff --git a/src/sdpd-database.c b/src/sdpd-database.c
index cf33f19..7228cd7 100644
--- a/src/sdpd-database.c
+++ b/src/sdpd-database.c
@@ -285,6 +285,14 @@ sdp_list_t *sdp_get_record_list(void)
return service_db;
}
+/*
+ * Return a pointer to the linked list containing the access db in sorted order
+ */
+sdp_list_t *sdp_get_access_list(void)
+{
+ return access_db;
+}
+
int sdp_check_access(uint32_t handle, bdaddr_t *device)
{
sdp_list_t *p = access_locate(handle);
@@ -314,26 +322,3 @@ uint32_t sdp_next_handle(void)
return handle;
}
-
-void sdp_init_services_list(bdaddr_t *device)
-{
- sdp_list_t *p;
-
- DBG("");
-
- for (p = access_db; p != NULL; p = p->next) {
- sdp_access_t *access = p->data;
- sdp_record_t *rec;
-
- if (bacmp(BDADDR_ANY, &access->device))
- continue;
-
- rec = sdp_record_find(access->handle);
- if (rec == NULL)
- continue;
-
- SDPDBG("adding record with handle %x", access->handle);
-
- adapter_foreach(adapter_service_insert, rec);
- }
-}
diff --git a/src/sdpd.h b/src/sdpd.h
index 9a0e1e9..ad384bd 100644
--- a/src/sdpd.h
+++ b/src/sdpd.h
@@ -68,6 +68,7 @@ sdp_record_t *sdp_record_find(uint32_t handle);
void sdp_record_add(const bdaddr_t *device, sdp_record_t *rec);
int sdp_record_remove(uint32_t handle);
sdp_list_t *sdp_get_record_list(void);
+sdp_list_t *sdp_get_access_list(void);
int sdp_check_access(uint32_t handle, bdaddr_t *device);
uint32_t sdp_next_handle(void);
@@ -81,5 +82,3 @@ void stop_sdp_server(void);
int add_record_to_server(const bdaddr_t *src, sdp_record_t *rec);
int remove_record_from_server(uint32_t handle);
-
-void sdp_init_services_list(bdaddr_t *device);
--
1.7.9.5
^ permalink raw reply related
* [PATCH 1/4] sdp: Move sdp server init to adapter
From: Grzegorz Kolodziejczyk @ 2013-08-26 13:07 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1377522441-28671-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>
Change-Id: Ie8440d59a00750f3d8aec49924d6b209bc6ebe2f
---
src/adapter.c | 11 +++++++++++
src/adapter.h | 1 +
src/main.c | 2 +-
3 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/src/adapter.c b/src/adapter.c
index 17f5508..723e3a8 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -6295,3 +6295,14 @@ void adapter_shutdown(void)
if (!adapter_remaining)
btd_exit();
}
+
+void adapter_start_sdp_server(uint16_t sdp_mtu, uint32_t sdp_flags) {
+ sdp_list_t *services;
+
+ info("Start sdp server");
+ start_sdp_server(sdp_mtu, sdp_flags);
+
+ services = sdp_get_record_list();
+ for (; services; services = services->next)
+ adapter_foreach(adapter_service_insert, services->data);
+}
diff --git a/src/adapter.h b/src/adapter.h
index 32b12c0..a60a29f 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -79,6 +79,7 @@ struct smp_ltk_info {
int adapter_init(void);
void adapter_cleanup(void);
void adapter_shutdown(void);
+void adapter_start_sdp_server(uint16_t sdp_mtu, uint32_t sdp_flags);
struct btd_adapter *adapter_find(const bdaddr_t *sba);
struct btd_adapter *adapter_find_by_id(int id);
diff --git a/src/main.c b/src/main.c
index dc0478e..7e68d1e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -548,7 +548,7 @@ int main(int argc, char *argv[])
if (option_compat == TRUE)
sdp_flags |= SDP_SERVER_COMPAT;
- start_sdp_server(sdp_mtu, sdp_flags);
+ adapter_start_sdp_server(sdp_mtu, sdp_flags);
/* Loading plugins has to be done after D-Bus has been setup since
* the plugins might wanna expose some paths on the bus. However the
--
1.7.9.5
^ permalink raw reply related
* [PATCH 0/4] *** Make sdp independent from adapter ***
From: Grzegorz Kolodziejczyk @ 2013-08-26 13:07 UTC (permalink / raw)
To: linux-bluetooth
Solutions to consider:
- Access db has been expanded via sdp_get_access_list
- sdp_access_t moved to sdpd.h
Grzegorz Kolodziejczyk (4):
sdp: Move sdp server init to adapter
sdp: Move spd_init_services_list to adapter
sdp: Make sdp_record_add to be handled by adapter
sdp: Make sdp_record_remove to be handled by adapter
profiles/audio/a2dp.c | 10 ++--
profiles/audio/avrcp.c | 8 ++--
profiles/health/hdp.c | 2 +-
profiles/health/hdp_util.c | 4 +-
profiles/network/server.c | 6 +--
profiles/sap/server.c | 4 +-
src/adapter.c | 109 +++++++++++++++++++++++++++++++++++++++++++-
src/adapter.h | 6 +++
src/attrib-server.c | 8 ++--
src/main.c | 2 +-
src/profile.c | 4 +-
src/sdpd-database.c | 52 ++++-----------------
src/sdpd.h | 8 +++-
13 files changed, 152 insertions(+), 71 deletions(-)
--
1.7.9.5
^ permalink raw reply
* Re: [PATCH 1/2] obexd: Use g_dbus_get_properties when parsing MAP-msg-listing
From: Luiz Augusto von Dentz @ 2013-08-26 12:34 UTC (permalink / raw)
To: Christian Fetzer; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1377187721-3758-1-git-send-email-christian.fetzer@oss.bmw-carit.de>
Hi Christian,
On Thu, Aug 22, 2013 at 7:08 PM, Christian Fetzer
<christian.fetzer@oss.bmw-carit.de> wrote:
> From: Christian Fetzer <christian.fetzer@bmw-carit.de>
>
> Currently the message D-Bus properties for the ListMessages response are put
> together manually in the parse_* functions unsing obex_dbus_dict_append.
> This patch simplifies it by calling g_dbus_get_properties for every message.
> ---
> obexd/client/map.c | 84 ++++++++++++++----------------------------------------
> 1 file changed, 21 insertions(+), 63 deletions(-)
>
> diff --git a/obexd/client/map.c b/obexd/client/map.c
> index 3d8acc4..8864a54 100644
> --- a/obexd/client/map.c
> +++ b/obexd/client/map.c
> @@ -790,81 +790,60 @@ static struct map_msg *map_msg_create(struct map_data *data, const char *handle)
> return msg;
> }
>
> -static void parse_subject(struct map_msg *msg, const char *value,
> - DBusMessageIter *iter)
> +static void parse_subject(struct map_msg *msg, const char *value)
> {
> g_free(msg->subject);
> msg->subject = g_strdup(value);
> - obex_dbus_dict_append(iter, "Subject", DBUS_TYPE_STRING, &value);
> }
>
> -static void parse_datetime(struct map_msg *msg, const char *value,
> - DBusMessageIter *iter)
> +static void parse_datetime(struct map_msg *msg, const char *value)
> {
> g_free(msg->timestamp);
> msg->timestamp = g_strdup(value);
> - obex_dbus_dict_append(iter, "Timestamp", DBUS_TYPE_STRING, &value);
> }
>
> -static void parse_sender(struct map_msg *msg, const char *value,
> - DBusMessageIter *iter)
> +static void parse_sender(struct map_msg *msg, const char *value)
> {
> g_free(msg->sender);
> msg->sender = g_strdup(value);
> - obex_dbus_dict_append(iter, "Sender", DBUS_TYPE_STRING, &value);
> }
>
> -static void parse_sender_address(struct map_msg *msg, const char *value,
> - DBusMessageIter *iter)
> +static void parse_sender_address(struct map_msg *msg, const char *value)
> {
> g_free(msg->sender_address);
> msg->sender_address = g_strdup(value);
> - obex_dbus_dict_append(iter, "SenderAddress", DBUS_TYPE_STRING,
> - &value);
> }
>
> -static void parse_replyto(struct map_msg *msg, const char *value,
> - DBusMessageIter *iter)
> +static void parse_replyto(struct map_msg *msg, const char *value)
> {
> g_free(msg->replyto);
> msg->replyto = g_strdup(value);
> - obex_dbus_dict_append(iter, "ReplyTo", DBUS_TYPE_STRING, &value);
> }
>
> -static void parse_recipient(struct map_msg *msg, const char *value,
> - DBusMessageIter *iter)
> +static void parse_recipient(struct map_msg *msg, const char *value)
> {
> g_free(msg->recipient);
> msg->recipient = g_strdup(value);
> - obex_dbus_dict_append(iter, "Recipient", DBUS_TYPE_STRING, &value);
> }
>
> -static void parse_recipient_address(struct map_msg *msg, const char *value,
> - DBusMessageIter *iter)
> +static void parse_recipient_address(struct map_msg *msg, const char *value)
> {
> g_free(msg->recipient_address);
> msg->recipient_address = g_strdup(value);
> - obex_dbus_dict_append(iter, "RecipientAddress", DBUS_TYPE_STRING,
> - &value);
> }
>
> -static void parse_type(struct map_msg *msg, const char *value,
> - DBusMessageIter *iter)
> +static void parse_type(struct map_msg *msg, const char *value)
> {
> g_free(msg->type);
> msg->type = g_strdup(value);
> - obex_dbus_dict_append(iter, "Type", DBUS_TYPE_STRING, &value);
> }
>
> -static void parse_size(struct map_msg *msg, const char *value,
> - DBusMessageIter *iter)
> +static void parse_size(struct map_msg *msg, const char *value)
> {
> msg->size = g_ascii_strtoll(value, NULL, 10);
> - obex_dbus_dict_append(iter, "Size", DBUS_TYPE_UINT64, &msg->size);
> }
>
> -static void parse_text(struct map_msg *msg, const char *value,
> - DBusMessageIter *iter)
> +static void parse_text(struct map_msg *msg, const char *value)
> {
> gboolean flag = strcasecmp(value, "no") != 0;
>
> @@ -873,27 +852,20 @@ static void parse_text(struct map_msg *msg, const char *value,
> else
> msg->flags &= ~MAP_MSG_FLAG_TEXT;
>
> - obex_dbus_dict_append(iter, "Text", DBUS_TYPE_BOOLEAN, &flag);
> }
>
> -static void parse_status(struct map_msg *msg, const char *value,
> - DBusMessageIter *iter)
> +static void parse_status(struct map_msg *msg, const char *value)
> {
> g_free(msg->status);
> msg->status = g_strdup(value);
> - obex_dbus_dict_append(iter, "Status", DBUS_TYPE_STRING, &value);
> }
>
> -static void parse_attachment_size(struct map_msg *msg, const char *value,
> - DBusMessageIter *iter)
> +static void parse_attachment_size(struct map_msg *msg, const char *value)
> {
> msg->attachment_size = g_ascii_strtoll(value, NULL, 10);
> - obex_dbus_dict_append(iter, "AttachmentSize", DBUS_TYPE_UINT64,
> - &msg->attachment_size);
> }
>
> -static void parse_priority(struct map_msg *msg, const char *value,
> - DBusMessageIter *iter)
> +static void parse_priority(struct map_msg *msg, const char *value)
> {
> gboolean flag = strcasecmp(value, "no") != 0;
>
> @@ -902,11 +874,9 @@ static void parse_priority(struct map_msg *msg, const char *value,
> else
> msg->flags &= ~MAP_MSG_FLAG_PRIORITY;
>
> - obex_dbus_dict_append(iter, "Priority", DBUS_TYPE_BOOLEAN, &flag);
> }
>
> -static void parse_read(struct map_msg *msg, const char *value,
> - DBusMessageIter *iter)
> +static void parse_read(struct map_msg *msg, const char *value)
> {
> gboolean flag = strcasecmp(value, "no") != 0;
>
> @@ -915,11 +885,9 @@ static void parse_read(struct map_msg *msg, const char *value,
> else
> msg->flags &= ~MAP_MSG_FLAG_READ;
>
> - obex_dbus_dict_append(iter, "Read", DBUS_TYPE_BOOLEAN, &flag);
> }
>
> -static void parse_sent(struct map_msg *msg, const char *value,
> - DBusMessageIter *iter)
> +static void parse_sent(struct map_msg *msg, const char *value)
> {
> gboolean flag = strcasecmp(value, "no") != 0;
>
> @@ -928,11 +896,9 @@ static void parse_sent(struct map_msg *msg, const char *value,
> else
> msg->flags &= ~MAP_MSG_FLAG_SENT;
>
> - obex_dbus_dict_append(iter, "Sent", DBUS_TYPE_BOOLEAN, &flag);
> }
>
> -static void parse_protected(struct map_msg *msg, const char *value,
> - DBusMessageIter *iter)
> +static void parse_protected(struct map_msg *msg, const char *value)
> {
> gboolean flag = strcasecmp(value, "no") != 0;
>
> @@ -941,13 +907,11 @@ static void parse_protected(struct map_msg *msg, const char *value,
> else
> msg->flags &= ~MAP_MSG_FLAG_PROTECTED;
>
> - obex_dbus_dict_append(iter, "Protected", DBUS_TYPE_BOOLEAN, &flag);
> }
>
> static struct map_msg_parser {
> const char *name;
> - void (*func) (struct map_msg *msg, const char *value,
> - DBusMessageIter *iter);
> + void (*func) (struct map_msg *msg, const char *value);
> } msg_parsers[] = {
> { "subject", parse_subject },
> { "datetime", parse_datetime },
> @@ -974,7 +938,7 @@ static void msg_element(GMarkupParseContext *ctxt, const char *element,
> {
> struct map_parser *parser = user_data;
> struct map_data *data = parser->data;
> - DBusMessageIter entry, dict, *iter = parser->iter;
> + DBusMessageIter entry, *iter = parser->iter;
> struct map_msg *msg;
> const char *key;
> int i;
> @@ -1000,25 +964,19 @@ static void msg_element(GMarkupParseContext *ctxt, const char *element,
> dbus_message_iter_append_basic(&entry, DBUS_TYPE_OBJECT_PATH,
> &msg->path);
>
> - dbus_message_iter_open_container(&entry, DBUS_TYPE_ARRAY,
> - DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
> - DBUS_TYPE_STRING_AS_STRING
> - DBUS_TYPE_VARIANT_AS_STRING
> - DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
> - &dict);
> -
> for (i = 0, key = names[i]; key; key = names[++i]) {
> struct map_msg_parser *parser;
>
> for (parser = msg_parsers; parser && parser->name; parser++) {
> if (strcasecmp(key, parser->name) == 0) {
> - parser->func(msg, values[i], &dict);
> + parser->func(msg, values[i]);
> break;
> }
> }
> }
>
> - dbus_message_iter_close_container(&entry, &dict);
> + g_dbus_get_properties(conn, msg->path, MAP_MSG_INTERFACE, &entry);
> +
> dbus_message_iter_close_container(iter, &entry);
> }
>
> --
> 1.8.3.4
Patch 1/2 applied, please modify and rebase 2/2.
--
Luiz Augusto von Dentz
^ permalink raw reply
* Re: [PATCH 1/1] obexd: Fix memleak when unregistering MAP event handler
From: Luiz Augusto von Dentz @ 2013-08-26 12:33 UTC (permalink / raw)
To: Christian Fetzer; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1377187669-3691-1-git-send-email-christian.fetzer@oss.bmw-carit.de>
Hi Christian,
On Thu, Aug 22, 2013 at 7:07 PM, Christian Fetzer
<christian.fetzer@oss.bmw-carit.de> wrote:
> From: Christian Fetzer <christian.fetzer@bmw-carit.de>
>
> 96 bytes in 3 blocks are definitely lost in loss record 217 of 310
> at 0x4C29E84: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
> by 0x5977858: g_malloc0 (in /usr/lib/libglib-2.0.so.0.3600.3)
> by 0x433A87: map_register_event_handler (map-event.c:76)
> by 0x4324C1: set_notification_registration (map.c:1722)
> by 0x4325BB: map_probe (map.c:1801)
> by 0x42D55C: obc_session_register (session.c:862)
> by 0x42BE4B: create_callback (manager.c:100)
> by 0x42CA0D: connect_cb (session.c:281)
> by 0x4191CB: handle_response (gobex.c:949)
> by 0x4196F0: incoming_data (gobex.c:1192)
> by 0x5971DA5: g_main_context_dispatch (in /usr/lib/libglib-2.0.so.0.3600.3)
> by 0x59720F7: ??? (in /usr/lib/libglib-2.0.so.0.3600.3)
> ---
> obexd/client/map-event.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/obexd/client/map-event.c b/obexd/client/map-event.c
> index 76dfb84..bbe3519 100644
> --- a/obexd/client/map-event.c
> +++ b/obexd/client/map-event.c
> @@ -97,6 +97,7 @@ void map_unregister_event_handler(struct obc_session *session, int mas_id)
> handlers = g_slist_remove(handlers, handler);
> DBG("Handler %p for %s:%d unregistered", handler,
> obc_session_get_destination(session), mas_id);
> + g_free(handler);
> }
>
> void map_dispatch_event(int mas_id, const char *device,
> --
> 1.8.3.4
Applied thanks.
--
Luiz Augusto von Dentz
^ permalink raw reply
* Re: [PATCH 1/2] obexd: Add obc_session_get_current_path function
From: Luiz Augusto von Dentz @ 2013-08-26 12:31 UTC (permalink / raw)
To: Christian Fetzer; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1377187223-3427-1-git-send-email-christian.fetzer@oss.bmw-carit.de>
Hi Christian,
On Thu, Aug 22, 2013 at 7:00 PM, Christian Fetzer
<christian.fetzer@oss.bmw-carit.de> wrote:
> From: Christian Fetzer <christian.fetzer@bmw-carit.de>
>
> This patch extends client session by the tracking of the current path.
> The current path can be accessed by obc_session_get_current_path.
>
> This allows drivers to add a folder property to browsed objects so that
> the application doesn't have to keep track of the folder an object
> belongs to.
> ---
> obexd/client/session.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
> obexd/client/session.h | 2 ++
> 2 files changed, 48 insertions(+)
>
> diff --git a/obexd/client/session.c b/obexd/client/session.c
> index 44e2bf8..293359b 100644
> --- a/obexd/client/session.c
> +++ b/obexd/client/session.c
> @@ -110,6 +110,8 @@ struct obc_session {
> guint watch;
> GQueue *queue;
> guint process_id;
> + GSList *cur_path_list;
> + char *cur_path;
> };
>
> static GSList *sessions = NULL;
> @@ -242,6 +244,8 @@ static void session_free(struct obc_session *session)
> g_free(session->owner);
> g_free(session->source);
> g_free(session->destination);
> + g_slist_free_full(session->cur_path_list, g_free);
> + g_free(session->cur_path);
> g_free(session);
> }
>
> @@ -500,6 +504,7 @@ struct obc_session *obc_session_create(const char *source,
> session->destination = g_strdup(destination);
> session->channel = channel;
> session->queue = g_queue_new();
> + session->cur_path = g_strdup("/");
>
> if (owner)
> obc_session_set_owner(session, owner, owner_disconnected);
> @@ -930,12 +935,33 @@ const char *obc_session_get_target(struct obc_session *session)
> return session->driver->target;
> }
>
> +const char *obc_session_get_current_path(struct obc_session *session)
> +{
> + GSList *l;
> + GString *strbuf;
> +
> + if (!session->cur_path) {
> + strbuf = g_string_new("/");
> + for (l = session->cur_path_list; l; l = l->next) {
> + g_string_append(strbuf, l->data);
> + if (l->next)
> + g_string_append_c(strbuf, '/');
> + }
> + session->cur_path = g_string_free(strbuf, FALSE);
> + }
> +
> + return session->cur_path;
> +}
> +
> static void setpath_complete(struct obc_session *session,
> struct obc_transfer *transfer,
> GError *err, void *user_data)
> {
> struct pending_request *p = user_data;
>
> + g_free(session->cur_path);
> + session->cur_path = NULL;
> +
> if (p->func)
> p->func(session, NULL, err, p->data);
>
> @@ -962,7 +988,9 @@ static void setpath_cb(GObex *obex, GError *err, GObexPacket *rsp,
> {
> struct pending_request *p = user_data;
> struct setpath_data *data = p->data;
> + char *prev;
> char *next;
> + GSList *last;
> guint8 code;
>
> p->req_id = 0;
> @@ -982,6 +1010,24 @@ static void setpath_cb(GObex *obex, GError *err, GObexPacket *rsp,
> return;
> }
>
> + /* Track current folder in cur_folder_list */
> + if (strlen(data->remaining[data->index-1]) == 0) {
> + g_slist_free_full(p->session->cur_path_list, g_free);
> + p->session->cur_path_list = NULL;
> + } else {
> + prev = data->remaining[data->index-1];
> + if (strcmp(prev, "..") == 0) {
> + if (p->session->cur_path_list) {
> + last = g_slist_last(p->session->cur_path_list);
> + g_free(last->data);
> + p->session->cur_path_list = g_slist_delete_link(
> + p->session->cur_path_list, last);
> + }
> + } else
> + p->session->cur_path_list = g_slist_append(
> + p->session->cur_path_list, g_strdup(prev));
> + }
> +
> /* Ignore empty folder names to avoid resetting the current path */
> while ((next = data->remaining[data->index]) && strlen(next) == 0)
> data->index++;
> diff --git a/obexd/client/session.h b/obexd/client/session.h
> index 319d529..01034b5 100644
> --- a/obexd/client/session.h
> +++ b/obexd/client/session.h
> @@ -58,6 +58,8 @@ const char *obc_session_register(struct obc_session *session,
> const void *obc_session_get_attribute(struct obc_session *session,
> int attribute_id);
>
> +const char *obc_session_get_current_path(struct obc_session *session);
> +
> guint obc_session_queue(struct obc_session *session,
> struct obc_transfer *transfer,
> session_callback_t func, void *user_data,
> --
> 1.8.3.4
Please use path or folder instead of cur_path/current_path to make it
a bit shorter, also I don't think you should really needs to have 2
fields for tracking this.
--
Luiz Augusto von Dentz
^ permalink raw reply
* Re: [PATCH 2/2] obexd: Add property changed signals for 'org.bluez.obex.Message1'
From: Luiz Augusto von Dentz @ 2013-08-26 12:08 UTC (permalink / raw)
To: Christian Fetzer; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1377187721-3758-2-git-send-email-christian.fetzer@oss.bmw-carit.de>
Hi Christian,
On Thu, Aug 22, 2013 at 7:08 PM, Christian Fetzer
<christian.fetzer@oss.bmw-carit.de> wrote:
> From: Christian Fetzer <christian.fetzer@bmw-carit.de>
>
> This patch adds property changed signal emissions in case message properties
> change on the server.
> ---
> obexd/client/map.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 92 insertions(+), 2 deletions(-)
>
> diff --git a/obexd/client/map.c b/obexd/client/map.c
> index 8864a54..a9a9bcd 100644
> --- a/obexd/client/map.c
> +++ b/obexd/client/map.c
> @@ -792,121 +792,211 @@ static struct map_msg *map_msg_create(struct map_data *data, const char *handle)
>
> static void parse_subject(struct map_msg *msg, const char *value)
> {
> + if (g_strcmp0(msg->subject, value) == 0)
> + return;
> +
> g_free(msg->subject);
> msg->subject = g_strdup(value);
> +
> + g_dbus_emit_property_changed(conn, msg->path,
> + MAP_MSG_INTERFACE, "Subject");
> }
>
> static void parse_datetime(struct map_msg *msg, const char *value)
> {
> + if (g_strcmp0(msg->timestamp, value) == 0)
> + return;
> +
> g_free(msg->timestamp);
> msg->timestamp = g_strdup(value);
> +
> + g_dbus_emit_property_changed(conn, msg->path,
> + MAP_MSG_INTERFACE, "Timestamp");
> }
>
> static void parse_sender(struct map_msg *msg, const char *value)
> {
> + if (g_strcmp0(msg->sender, value) == 0)
> + return;
> +
> g_free(msg->sender);
> msg->sender = g_strdup(value);
> +
> + g_dbus_emit_property_changed(conn, msg->path,
> + MAP_MSG_INTERFACE, "Sender");
> }
>
> static void parse_sender_address(struct map_msg *msg, const char *value)
> {
> + if (g_strcmp0(msg->sender_address, value) == 0)
> + return;
> +
> g_free(msg->sender_address);
> msg->sender_address = g_strdup(value);
> +
> + g_dbus_emit_property_changed(conn, msg->path,
> + MAP_MSG_INTERFACE, "SenderAddress");
> }
>
> static void parse_replyto(struct map_msg *msg, const char *value)
> {
> + if (g_strcmp0(msg->replyto, value) == 0)
> + return;
> +
> g_free(msg->replyto);
> msg->replyto = g_strdup(value);
> +
> + g_dbus_emit_property_changed(conn, msg->path,
> + MAP_MSG_INTERFACE, "ReplyTo");
> }
>
> static void parse_recipient(struct map_msg *msg, const char *value)
> {
> + if (g_strcmp0(msg->recipient, value) == 0)
> + return;
> +
> g_free(msg->recipient);
> msg->recipient = g_strdup(value);
> +
> + g_dbus_emit_property_changed(conn, msg->path,
> + MAP_MSG_INTERFACE, "Recipient");
> }
>
> static void parse_recipient_address(struct map_msg *msg, const char *value)
> {
> + if (g_strcmp0(msg->recipient_address, value) == 0)
> + return;
> +
> g_free(msg->recipient_address);
> msg->recipient_address = g_strdup(value);
> +
> + g_dbus_emit_property_changed(conn, msg->path,
> + MAP_MSG_INTERFACE, "RecipientAddress");
> }
>
> static void parse_type(struct map_msg *msg, const char *value)
> {
> + if (g_strcmp0(msg->type, value) == 0)
> + return;
> +
> g_free(msg->type);
> msg->type = g_strdup(value);
> +
> + g_dbus_emit_property_changed(conn, msg->path,
> + MAP_MSG_INTERFACE, "Type");
> }
>
> static void parse_size(struct map_msg *msg, const char *value)
> {
> - msg->size = g_ascii_strtoll(value, NULL, 10);
> + uint64_t size = g_ascii_strtoll(value, NULL, 10);
> +
> + if (msg->size == size)
> + return;
> +
> + msg->size = size;
> +
> + g_dbus_emit_property_changed(conn, msg->path,
> + MAP_MSG_INTERFACE, "Size");
> }
>
> static void parse_text(struct map_msg *msg, const char *value)
> {
> gboolean flag = strcasecmp(value, "no") != 0;
>
> + uint8_t oldflags = msg->flags;
> if (flag)
> msg->flags |= MAP_MSG_FLAG_TEXT;
> else
> msg->flags &= ~MAP_MSG_FLAG_TEXT;
>
> + if (msg->flags != oldflags)
> + g_dbus_emit_property_changed(conn, msg->path,
> + MAP_MSG_INTERFACE, "Text");
> }
>
> static void parse_status(struct map_msg *msg, const char *value)
> {
> + if (g_strcmp0(msg->status, value) == 0)
> + return;
> +
> g_free(msg->status);
> msg->status = g_strdup(value);
> +
> + g_dbus_emit_property_changed(conn, msg->path,
> + MAP_MSG_INTERFACE, "Status");
> }
>
> static void parse_attachment_size(struct map_msg *msg, const char *value)
> {
> - msg->attachment_size = g_ascii_strtoll(value, NULL, 10);
> + uint64_t attachment_size = g_ascii_strtoll(value, NULL, 10);
> +
> + if (msg->attachment_size == attachment_size)
> + return;
> +
> + msg->attachment_size = attachment_size;
> +
> + g_dbus_emit_property_changed(conn, msg->path,
> + MAP_MSG_INTERFACE, "AttachmentSize");
> }
>
> static void parse_priority(struct map_msg *msg, const char *value)
> {
> gboolean flag = strcasecmp(value, "no") != 0;
>
> + uint8_t oldflags = msg->flags;
> if (flag)
> msg->flags |= MAP_MSG_FLAG_PRIORITY;
> else
> msg->flags &= ~MAP_MSG_FLAG_PRIORITY;
>
> + if (msg->flags != oldflags)
> + g_dbus_emit_property_changed(conn, msg->path,
> + MAP_MSG_INTERFACE, "Priority");
> }
>
> static void parse_read(struct map_msg *msg, const char *value)
> {
> gboolean flag = strcasecmp(value, "no") != 0;
>
> + uint8_t oldflags = msg->flags;
> if (flag)
> msg->flags |= MAP_MSG_FLAG_READ;
> else
> msg->flags &= ~MAP_MSG_FLAG_READ;
>
> + if (msg->flags != oldflags)
> + g_dbus_emit_property_changed(conn, msg->path,
> + MAP_MSG_INTERFACE, "Read");
> }
>
> static void parse_sent(struct map_msg *msg, const char *value)
> {
> gboolean flag = strcasecmp(value, "no") != 0;
>
> + uint8_t oldflags = msg->flags;
> if (flag)
> msg->flags |= MAP_MSG_FLAG_SENT;
> else
> msg->flags &= ~MAP_MSG_FLAG_SENT;
>
> + if (msg->flags != oldflags)
> + g_dbus_emit_property_changed(conn, msg->path,
> + MAP_MSG_INTERFACE, "Sent");
> }
>
> static void parse_protected(struct map_msg *msg, const char *value)
> {
> gboolean flag = strcasecmp(value, "no") != 0;
>
> + uint8_t oldflags = msg->flags;
> if (flag)
> msg->flags |= MAP_MSG_FLAG_PROTECTED;
> else
> msg->flags &= ~MAP_MSG_FLAG_PROTECTED;
>
> + if (msg->flags != oldflags)
> + g_dbus_emit_property_changed(conn, msg->path,
> + MAP_MSG_INTERFACE, "Protected");
> }
>
> static struct map_msg_parser {
> --
> 1.8.3.4
Does this make us emit signals when creating the objects? That should
probably not be necessary, only emit signals once the value really
changes.
--
Luiz Augusto von Dentz
^ permalink raw reply
* [PATCH] Bluetooth: Fix handling of getsockname() for HCI sockets
From: Marcel Holtmann @ 2013-08-26 7:20 UTC (permalink / raw)
To: linux-bluetooth
The hci_dev check is not protected and so move it into the socket lock. In
addition return the HCI channel identifier instead of always 0 channel.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
net/bluetooth/hci_sock.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index d858941..49c5c62 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -695,25 +695,30 @@ static int hci_sock_getname(struct socket *sock, struct sockaddr *addr,
{
struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
struct sock *sk = sock->sk;
- struct hci_dev *hdev = hci_pi(sk)->hdev;
+ struct hci_dev *hdev;
+ int err = 0;
BT_DBG("sock %p sk %p", sock, sk);
if (peer)
return -EOPNOTSUPP;
- if (!hdev)
- return -EBADFD;
-
lock_sock(sk);
+ hdev = hci_pi(sk)->hdev;
+ if (!hdev) {
+ err = -EBADFD;
+ goto done;
+ }
+
*addr_len = sizeof(*haddr);
haddr->hci_family = AF_BLUETOOTH;
haddr->hci_dev = hdev->id;
- haddr->hci_channel= 0;
+ haddr->hci_channel= hci_pi(sk)->channel;
+done:
release_sock(sk);
- return 0;
+ return err;
}
static void hci_sock_cmsg(struct sock *sk, struct msghdr *msg,
--
1.8.3.1
^ permalink raw reply related
* [PATCH] Bluetooth: Fix handling of getpeername() for HCI sockets
From: Marcel Holtmann @ 2013-08-26 7:06 UTC (permalink / raw)
To: linux-bluetooth
The HCI sockets do not have a peer associated with it and so make sure
that getpeername() returns EOPNOTSUPP since this operation is actually
not supported on HCI sockets.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
net/bluetooth/hci_sock.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index c45ec25..d858941 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -699,6 +699,9 @@ static int hci_sock_getname(struct socket *sock, struct sockaddr *addr,
BT_DBG("sock %p sk %p", sock, sk);
+ if (peer)
+ return -EOPNOTSUPP;
+
if (!hdev)
return -EBADFD;
--
1.8.3.1
^ permalink raw reply related
* [PATCH] Bluetooth: Refactor raw socket filter into more readable code
From: Marcel Holtmann @ 2013-08-26 6:25 UTC (permalink / raw)
To: linux-bluetooth
The handling of the raw socket filter is rather obscure code and it gets
in the way of future extensions. Instead of inline filtering in the raw
socket packet routine, refactor it into its own function.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
net/bluetooth/hci_sock.c | 64 +++++++++++++++++++++++++++++++-----------------
1 file changed, 41 insertions(+), 23 deletions(-)
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 9bd7d95..c45ec25 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -66,6 +66,46 @@ static struct bt_sock_list hci_sk_list = {
.lock = __RW_LOCK_UNLOCKED(hci_sk_list.lock)
};
+static bool is_filtered_packet(struct sock *sk, struct sk_buff *skb)
+{
+ struct hci_filter *flt;
+ int flt_type, flt_event;
+
+ /* Apply filter */
+ flt = &hci_pi(sk)->filter;
+
+ if (bt_cb(skb)->pkt_type == HCI_VENDOR_PKT)
+ flt_type = 0;
+ else
+ flt_type = bt_cb(skb)->pkt_type & HCI_FLT_TYPE_BITS;
+
+ if (!test_bit(flt_type, &flt->type_mask))
+ return true;
+
+ /* Extra filter for event packets only */
+ if (bt_cb(skb)->pkt_type != HCI_EVENT_PKT)
+ return false;
+
+ flt_event = (*(__u8 *)skb->data & HCI_FLT_EVENT_BITS);
+
+ if (!hci_test_bit(flt_event, &flt->event_mask))
+ return true;
+
+ /* Check filter only when opcode is set */
+ if (!flt->opcode)
+ return false;
+
+ if (flt_event == HCI_EV_CMD_COMPLETE &&
+ flt->opcode != get_unaligned((__le16 *)(skb->data + 3)))
+ return true;
+
+ if (flt_event == HCI_EV_CMD_STATUS &&
+ flt->opcode != get_unaligned((__le16 *)(skb->data + 4)))
+ return true;
+
+ return false;
+}
+
/* Send frame to RAW socket */
void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
{
@@ -77,7 +117,6 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
read_lock(&hci_sk_list.lock);
sk_for_each(sk, &hci_sk_list.head) {
- struct hci_filter *flt;
struct sk_buff *nskb;
if (sk->sk_state != BT_BOUND || hci_pi(sk)->hdev != hdev)
@@ -90,30 +129,9 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
if (hci_pi(sk)->channel != HCI_CHANNEL_RAW)
continue;
- /* Apply filter */
- flt = &hci_pi(sk)->filter;
-
- if (!test_bit((bt_cb(skb)->pkt_type == HCI_VENDOR_PKT) ?
- 0 : (bt_cb(skb)->pkt_type & HCI_FLT_TYPE_BITS),
- &flt->type_mask))
+ if (is_filtered_packet(sk, skb))
continue;
- if (bt_cb(skb)->pkt_type == HCI_EVENT_PKT) {
- int evt = (*(__u8 *)skb->data & HCI_FLT_EVENT_BITS);
-
- if (!hci_test_bit(evt, &flt->event_mask))
- continue;
-
- if (flt->opcode &&
- ((evt == HCI_EV_CMD_COMPLETE &&
- flt->opcode !=
- get_unaligned((__le16 *)(skb->data + 3))) ||
- (evt == HCI_EV_CMD_STATUS &&
- flt->opcode !=
- get_unaligned((__le16 *)(skb->data + 4)))))
- continue;
- }
-
if (!skb_copy) {
/* Create a private copy with headroom */
skb_copy = __pskb_copy(skb, 1, GFP_ATOMIC);
--
1.8.3.1
^ permalink raw reply related
* [PATCH v2 5/5] Bluetooth: Export LE connection parameters to debugfs
From: Andre Guedes @ 2013-08-23 20:01 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1377288071-3664-1-git-send-email-andre.guedes@openbossa.org>
This patch exports LE connection parameters under hciX directory if
controller is LE capable. All parameter files have read and write
permissions. This means, we are able to change LE connection parameters
by writing new values into the files. For instance, to change the
default value for supervision_timeout we can run:
$ echo 0x0040 > /sys/kernel/debug/bluetooth/hci0/le_conn_supervision_timeout
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
net/bluetooth/hci_sysfs.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 78ef738..ba4f7c7 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -546,6 +546,7 @@ void hci_init_sysfs(struct hci_dev *hdev)
void hci_sysfs_export_info(struct hci_dev *hdev)
{
struct discovery_param *discov = &hdev->discovery_param;
+ struct le_conn_param *conn = &hdev->le_conn_param;
if (lmp_bredr_capable(hdev)) {
debugfs_create_file("inquiry_cache", 0444, hdev->debugfs,
@@ -558,6 +559,7 @@ void hci_sysfs_export_info(struct hci_dev *hdev)
}
if (lmp_le_capable(hdev)) {
+ /* Discovery parameters */
debugfs_create_x8("discov_scan_type", S_IRUSR|S_IWUSR,
hdev->debugfs, &discov->scan_type);
debugfs_create_x16("discov_scan_interval", S_IRUSR|S_IWUSR,
@@ -566,6 +568,25 @@ void hci_sysfs_export_info(struct hci_dev *hdev)
hdev->debugfs, &discov->scan_window);
debugfs_create_u16("discov_le_scan_timeout", S_IRUSR|S_IWUSR,
hdev->debugfs, &discov->le_scan_timeout);
+
+ /* Connection parameters */
+ debugfs_create_x16("le_conn_scan_interval", S_IRUSR|S_IWUSR,
+ hdev->debugfs, &conn->scan_interval);
+ debugfs_create_x16("le_conn_scan_window", S_IRUSR|S_IWUSR,
+ hdev->debugfs, &conn->scan_window);
+ debugfs_create_x16("le_conn_interval_min", S_IRUSR|S_IWUSR,
+ hdev->debugfs, &conn->conn_interval_min);
+ debugfs_create_x16("le_conn_interval_max", S_IRUSR|S_IWUSR,
+ hdev->debugfs, &conn->conn_interval_max);
+ debugfs_create_x16("le_conn_supervision_timeout",
+ S_IRUSR|S_IWUSR, hdev->debugfs,
+ &conn->supervision_timeout);
+ debugfs_create_x16("le_conn_min_ce_lentgh", S_IRUSR|S_IWUSR,
+ hdev->debugfs, &conn->min_ce_lentgh);
+ debugfs_create_x16("le_conn_max_ce_lentgh", S_IRUSR|S_IWUSR,
+ hdev->debugfs, &conn->max_ce_lentgh);
+ debugfs_create_x16("le_conn_latency", S_IRUSR|S_IWUSR,
+ hdev->debugfs, &conn->conn_latency);
}
if (lmp_le_capable(hdev) && lmp_bredr_capable(hdev)) {
--
1.8.3.4
^ permalink raw reply related
* [PATCH v2 4/5] Bluetooth: Keep the LE connection parameters in its own structure
From: Andre Guedes @ 2013-08-23 20:01 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Vinicius Costa Gomes
In-Reply-To: <1377288071-3664-1-git-send-email-andre.guedes@openbossa.org>
From: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
This will allow for easier parameterization of these fields. This is
the first step for allowing to change the parameters during runtime.
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
include/net/bluetooth/hci_core.h | 13 +++++++++++++
net/bluetooth/hci_conn.c | 16 +++++++++-------
net/bluetooth/hci_core.c | 11 +++++++++++
3 files changed, 33 insertions(+), 7 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 20dae6d..b354211 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -117,6 +117,17 @@ struct oob_data {
u8 randomizer[16];
};
+struct le_conn_param {
+ u16 scan_interval;
+ u16 scan_window;
+ u16 conn_interval_min;
+ u16 conn_interval_max;
+ u16 supervision_timeout;
+ u16 min_ce_lentgh;
+ u16 max_ce_lentgh;
+ u16 conn_latency;
+};
+
#define HCI_MAX_SHORT_NAME_LENGTH 10
struct amp_assoc {
@@ -287,6 +298,8 @@ struct hci_dev {
struct delayed_work le_scan_disable;
+ struct le_conn_param le_conn_param;
+
__s8 adv_tx_power;
__u8 adv_data[HCI_MAX_AD_LENGTH];
__u8 adv_data_len;
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index f081712..97fc61b 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -52,6 +52,7 @@ static const struct sco_param sco_param_wideband[] = {
static void hci_le_create_connection(struct hci_conn *conn)
{
struct hci_dev *hdev = conn->hdev;
+ struct le_conn_param *param = &hdev->le_conn_param;
struct hci_cp_le_create_conn cp;
conn->state = BT_CONNECT;
@@ -60,15 +61,16 @@ static void hci_le_create_connection(struct hci_conn *conn)
conn->sec_level = BT_SECURITY_LOW;
memset(&cp, 0, sizeof(cp));
- cp.scan_interval = __constant_cpu_to_le16(0x0060);
- cp.scan_window = __constant_cpu_to_le16(0x0030);
+ cp.scan_interval = __cpu_to_le16(param->scan_interval);
+ cp.scan_window = __cpu_to_le16(param->scan_window);
bacpy(&cp.peer_addr, &conn->dst);
cp.peer_addr_type = conn->dst_type;
- cp.conn_interval_min = __constant_cpu_to_le16(0x0028);
- cp.conn_interval_max = __constant_cpu_to_le16(0x0038);
- cp.supervision_timeout = __constant_cpu_to_le16(0x002a);
- cp.min_ce_len = __constant_cpu_to_le16(0x0000);
- cp.max_ce_len = __constant_cpu_to_le16(0x0000);
+ cp.conn_interval_min = __cpu_to_le16(param->conn_interval_min);
+ cp.conn_interval_max = __cpu_to_le16(param->conn_interval_max);
+ cp.supervision_timeout = __cpu_to_le16(param->supervision_timeout);
+ cp.min_ce_len = __constant_cpu_to_le16(param->min_ce_lentgh);
+ cp.max_ce_len = __constant_cpu_to_le16(param->max_ce_lentgh);
+ cp.conn_latency = __constant_cpu_to_le16(param->conn_latency);
hci_send_cmd(hdev, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp);
}
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index e6d1350..eac6709 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2098,6 +2098,7 @@ struct hci_dev *hci_alloc_dev(void)
{
struct hci_dev *hdev;
struct discovery_param *discov;
+ struct le_conn_param *conn_param;
hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
if (!hdev)
@@ -2153,6 +2154,16 @@ struct hci_dev *hci_alloc_dev(void)
discov->interleaved_inquiry_length = DISCOV_INTERLEAVED_INQUIRY_LEN;
discov->bredr_inquiry_length = DISCOV_BREDR_INQUIRY_LEN;
+ conn_param = &hdev->le_conn_param;
+ conn_param->scan_interval = 0x0060;
+ conn_param->scan_window = 0x0030;
+ conn_param->conn_interval_min = 0x0028;
+ conn_param->conn_interval_max = 0x0038;
+ conn_param->supervision_timeout = 0x002a;
+ conn_param->min_ce_lentgh = 0x0000;
+ conn_param->max_ce_lentgh = 0x0000;
+ conn_param->conn_latency = 0x0000;
+
return hdev;
}
EXPORT_SYMBOL(hci_alloc_dev);
--
1.8.3.4
^ permalink raw reply related
* [PATCH v2 3/5] Bluetooth: Export discovery parameters to debugfs
From: Andre Guedes @ 2013-08-23 20:01 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1377288071-3664-1-git-send-email-andre.guedes@openbossa.org>
This patch exports discovery parameters under hciX directory. All
parameter files have read and write permissions. This means, we
are able to change discovery parameters by writing new values into
the files. For instance, to change the default value for the scanning
interval we can run:
$ echo 0x0016 > /sys/kernel/debug/bluetooth/hci0/discov_scan_interval
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
net/bluetooth/hci_sysfs.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index c89032c..78ef738 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -545,11 +545,36 @@ void hci_init_sysfs(struct hci_dev *hdev)
/* This function expects hdev has been already intialized */
void hci_sysfs_export_info(struct hci_dev *hdev)
{
+ struct discovery_param *discov = &hdev->discovery_param;
+
if (lmp_bredr_capable(hdev)) {
debugfs_create_file("inquiry_cache", 0444, hdev->debugfs,
hdev, &inquiry_cache_fops);
debugfs_create_file("auto_accept_delay", 0444, hdev->debugfs,
hdev, &auto_accept_delay_fops);
+ debugfs_create_x8("discov_bredr_inq_len", S_IRUSR|S_IWUSR,
+ hdev->debugfs,
+ &discov->bredr_inquiry_length);
+ }
+
+ if (lmp_le_capable(hdev)) {
+ debugfs_create_x8("discov_scan_type", S_IRUSR|S_IWUSR,
+ hdev->debugfs, &discov->scan_type);
+ debugfs_create_x16("discov_scan_interval", S_IRUSR|S_IWUSR,
+ hdev->debugfs, &discov->scan_interval);
+ debugfs_create_x16("discov_scan_window", S_IRUSR|S_IWUSR,
+ hdev->debugfs, &discov->scan_window);
+ debugfs_create_u16("discov_le_scan_timeout", S_IRUSR|S_IWUSR,
+ hdev->debugfs, &discov->le_scan_timeout);
+ }
+
+ if (lmp_le_capable(hdev) && lmp_bredr_capable(hdev)) {
+ debugfs_create_x8("discov_interleaved_inq_len",
+ S_IRUSR|S_IWUSR, hdev->debugfs,
+ &discov->interleaved_inquiry_length);
+ debugfs_create_u16("discov_interleaved_scan_timeout",
+ S_IRUSR|S_IWUSR, hdev->debugfs,
+ &discov->interleaved_scan_timeout);
}
}
--
1.8.3.4
^ permalink raw reply related
* [PATCH v2 2/5] Bluetooth: Discovery parameters per hci_dev
From: Andre Guedes @ 2013-08-23 20:01 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1377288071-3664-1-git-send-email-andre.guedes@openbossa.org>
This patch adds discovery parameters to struct hci_dev. This way, we
will be able to configure the discovery parameters per hci device.
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
include/net/bluetooth/hci_core.h | 13 +++++++++++++
net/bluetooth/hci_core.c | 13 ++++++++++++-
net/bluetooth/mgmt.c | 15 +++++++++------
3 files changed, 34 insertions(+), 7 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 879bf45..20dae6d 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -127,6 +127,17 @@ struct amp_assoc {
__u8 data[HCI_MAX_AMP_ASSOC_SIZE];
};
+struct discovery_param {
+ u8 scan_type;
+ u16 scan_interval;
+ u16 scan_window;
+ u16 le_scan_timeout;
+ u16 interleaved_scan_timeout;
+
+ u8 interleaved_inquiry_length;
+ u8 bredr_inquiry_length;
+};
+
#define HCI_MAX_PAGES 3
#define NUM_REASSEMBLY 4
@@ -280,6 +291,8 @@ struct hci_dev {
__u8 adv_data[HCI_MAX_AD_LENGTH];
__u8 adv_data_len;
+ struct discovery_param discovery_param;
+
int (*open)(struct hci_dev *hdev);
int (*close)(struct hci_dev *hdev);
int (*flush)(struct hci_dev *hdev);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index e8be6ec..e6d1350 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2032,6 +2032,7 @@ static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status)
{
/* General inquiry access code (GIAC) */
u8 lap[3] = { 0x33, 0x8b, 0x9e };
+ struct discovery_param *discov = &hdev->discovery_param;
struct hci_request req;
struct hci_cp_inquiry cp;
int err;
@@ -2053,7 +2054,7 @@ static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status)
memset(&cp, 0, sizeof(cp));
memcpy(&cp.lap, lap, sizeof(cp.lap));
- cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN;
+ cp.length = discov->interleaved_inquiry_length;
hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp);
hci_dev_lock(hdev);
@@ -2096,6 +2097,7 @@ static void le_scan_disable_work(struct work_struct *work)
struct hci_dev *hci_alloc_dev(void)
{
struct hci_dev *hdev;
+ struct discovery_param *discov;
hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
if (!hdev)
@@ -2142,6 +2144,15 @@ struct hci_dev *hci_alloc_dev(void)
hci_init_sysfs(hdev);
discovery_init(hdev);
+ discov = &hdev->discovery_param;
+ discov->scan_type = LE_SCAN_ACTIVE;
+ discov->scan_interval = DISCOV_LE_SCAN_INT;
+ discov->scan_window = DISCOV_LE_SCAN_WIN;
+ discov->le_scan_timeout = DISCOV_LE_TIMEOUT;
+ discov->interleaved_scan_timeout = DISCOV_INTERLEAVED_TIMEOUT;
+ discov->interleaved_inquiry_length = DISCOV_INTERLEAVED_INQUIRY_LEN;
+ discov->bredr_inquiry_length = DISCOV_BREDR_INQUIRY_LEN;
+
return hdev;
}
EXPORT_SYMBOL(hci_alloc_dev);
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index fedc539..b9b14c6 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2642,6 +2642,8 @@ static int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status)
static void start_discovery_complete(struct hci_dev *hdev, u8 status)
{
+ struct discovery_param *discov = &hdev->discovery_param;
+
BT_DBG("status %d", status);
if (status) {
@@ -2658,12 +2660,12 @@ static void start_discovery_complete(struct hci_dev *hdev, u8 status)
switch (hdev->discovery.type) {
case DISCOV_TYPE_LE:
queue_delayed_work(hdev->workqueue, &hdev->le_scan_disable,
- DISCOV_LE_TIMEOUT);
+ discov->le_scan_timeout);
break;
case DISCOV_TYPE_INTERLEAVED:
queue_delayed_work(hdev->workqueue, &hdev->le_scan_disable,
- DISCOV_INTERLEAVED_TIMEOUT);
+ discov->interleaved_scan_timeout);
break;
case DISCOV_TYPE_BREDR:
@@ -2678,6 +2680,7 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
void *data, u16 len)
{
struct mgmt_cp_start_discovery *cp = data;
+ struct discovery_param *discov = &hdev->discovery_param;
struct pending_cmd *cmd;
struct hci_cp_le_set_scan_param param_cp;
struct hci_cp_le_set_scan_enable enable_cp;
@@ -2739,7 +2742,7 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
memset(&inq_cp, 0, sizeof(inq_cp));
memcpy(&inq_cp.lap, lap, sizeof(inq_cp.lap));
- inq_cp.length = DISCOV_BREDR_INQUIRY_LEN;
+ inq_cp.length = discov->bredr_inquiry_length;
hci_req_add(&req, HCI_OP_INQUIRY, sizeof(inq_cp), &inq_cp);
break;
@@ -2775,9 +2778,9 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
}
memset(¶m_cp, 0, sizeof(param_cp));
- param_cp.type = LE_SCAN_ACTIVE;
- param_cp.interval = cpu_to_le16(DISCOV_LE_SCAN_INT);
- param_cp.window = cpu_to_le16(DISCOV_LE_SCAN_WIN);
+ param_cp.type = discov->scan_type;
+ param_cp.interval = cpu_to_le16(discov->scan_interval);
+ param_cp.window = cpu_to_le16(discov->scan_window);
hci_req_add(&req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp),
¶m_cp);
--
1.8.3.4
^ permalink raw reply related
* [PATCH v2 1/5] Bluetooth: Fix hci_add_sysfs
From: Andre Guedes @ 2013-08-23 20:01 UTC (permalink / raw)
To: linux-bluetooth
The inquiry_cache and auto_accept_delay files should be added to
debugfs only if controller is BR/EDR capable.
Since in hci_register_dev() hdev has not been initialized yet,
we are not able to check if the controller is BR/EDR capable.
Thus, we postpone exporting those two files to just after
controller's initialization.
Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
---
include/net/bluetooth/hci_core.h | 1 +
net/bluetooth/hci_core.c | 17 ++++++++++++-----
net/bluetooth/hci_sysfs.c | 16 +++++++++++-----
3 files changed, 24 insertions(+), 10 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 3ede820..879bf45 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -775,6 +775,7 @@ int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count);
void hci_init_sysfs(struct hci_dev *hdev);
int hci_add_sysfs(struct hci_dev *hdev);
void hci_del_sysfs(struct hci_dev *hdev);
+void hci_sysfs_export_info(struct hci_dev *hdev);
void hci_conn_init_sysfs(struct hci_conn *conn);
void hci_conn_add_sysfs(struct hci_conn *conn);
void hci_conn_del_sysfs(struct hci_conn *conn);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 8d9b87d..e8be6ec 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1184,11 +1184,18 @@ int hci_dev_open(__u16 dev)
hci_dev_hold(hdev);
set_bit(HCI_UP, &hdev->flags);
hci_notify(hdev, HCI_DEV_UP);
- if (!test_bit(HCI_SETUP, &hdev->dev_flags) &&
- mgmt_valid_hdev(hdev)) {
- hci_dev_lock(hdev);
- mgmt_powered(hdev, 1);
- hci_dev_unlock(hdev);
+ if (mgmt_valid_hdev(hdev)) {
+ /* If we are in HCI_SETUP phase, meaning the device
+ * has just been registered, we should export the
+ * remaining infos to debugfs.
+ */
+ if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
+ hci_sysfs_export_info(hdev);
+ } else {
+ hci_dev_lock(hdev);
+ mgmt_powered(hdev, 1);
+ hci_dev_unlock(hdev);
+ }
}
} else {
/* Init failed, cleanup */
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 7ad6ecf..c89032c 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -542,6 +542,17 @@ void hci_init_sysfs(struct hci_dev *hdev)
device_initialize(dev);
}
+/* This function expects hdev has been already intialized */
+void hci_sysfs_export_info(struct hci_dev *hdev)
+{
+ if (lmp_bredr_capable(hdev)) {
+ debugfs_create_file("inquiry_cache", 0444, hdev->debugfs,
+ hdev, &inquiry_cache_fops);
+ debugfs_create_file("auto_accept_delay", 0444, hdev->debugfs,
+ hdev, &auto_accept_delay_fops);
+ }
+}
+
int hci_add_sysfs(struct hci_dev *hdev)
{
struct device *dev = &hdev->dev;
@@ -562,16 +573,11 @@ int hci_add_sysfs(struct hci_dev *hdev)
if (!hdev->debugfs)
return 0;
- debugfs_create_file("inquiry_cache", 0444, hdev->debugfs,
- hdev, &inquiry_cache_fops);
-
debugfs_create_file("blacklist", 0444, hdev->debugfs,
hdev, &blacklist_fops);
debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops);
- debugfs_create_file("auto_accept_delay", 0444, hdev->debugfs, hdev,
- &auto_accept_delay_fops);
return 0;
}
--
1.8.3.4
^ permalink raw reply related
* [PATCH] Bluetooth: Add Intel Bluetooth Bootloader driver
From: Tedd Ho-Jeong An @ 2013-08-23 16:21 UTC (permalink / raw)
To: linux-bluetooth; +Cc: don.fry, marcel, johan.hedberg
From: Tedd Ho-Jeong An <tedd.an@intel.com>
This patch adds Intel Bluetooth Bootloader driver for Intel BT device.
It downloads the full FW image file from firmware/intel to the device.
Once downloading is done successfully, the device reset and bootup as
Bluetooth class device.
Signed-off-by: Tedd Ho-Jeong An <tedd.an@intel.com>
Tested-by: Don Fry <don.fry@intel.com>
---
drivers/bluetooth/Kconfig | 13 ++
drivers/bluetooth/Makefile | 1 +
drivers/bluetooth/intel_bl.c | 370 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 384 insertions(+)
create mode 100644 drivers/bluetooth/intel_bl.c
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
index fdfd61a..060dd10 100644
--- a/drivers/bluetooth/Kconfig
+++ b/drivers/bluetooth/Kconfig
@@ -242,4 +242,17 @@ config BT_WILINK
Say Y here to compile support for Texas Instrument's WiLink7 driver
into the kernel or say M to compile it as module.
+
+config BT_INTEL_BL
+ tristate "Intel firmware download driver"
+ depends on USB
+ select FW_LOADER
+ help
+ Intel Bluetooth firmware download driver.
+ This driver loads the full firmware into the Intel Bluetooth
+ chipset.
+
+ Say Y here to compile support for "Intel firmware download driver"
+ into the kernel or say M to compile it as module.
+
endmenu
diff --git a/drivers/bluetooth/Makefile b/drivers/bluetooth/Makefile
index 4afae20..edfcdb5 100644
--- a/drivers/bluetooth/Makefile
+++ b/drivers/bluetooth/Makefile
@@ -19,6 +19,7 @@ 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
+obj-$(CONFIG_BT_INTEL_BL) += intel_bl.o
btmrvl-y := btmrvl_main.o
btmrvl-$(CONFIG_DEBUG_FS) += btmrvl_debugfs.o
diff --git a/drivers/bluetooth/intel_bl.c b/drivers/bluetooth/intel_bl.c
new file mode 100644
index 0000000..4c8296b
--- /dev/null
+++ b/drivers/bluetooth/intel_bl.c
@@ -0,0 +1,387 @@
+/*
+ *
+ * Intel Bluetooth BootLoader driver
+ *
+ * Copyright (C) 2012 Intel Corporation
+ *
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/usb.h>
+#include <linux/firmware.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+#define VERSION "1.0"
+
+static struct usb_driver intel_bl_driver;
+
+static const struct usb_device_id intel_bl_table[] = {
+ /* Intel Bluetooth USB BootLoader(RAM module) */
+ { USB_DEVICE(0x8087, 0x0A5A) },
+
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, intel_bl_table);
+
+#define MAX_DATA_SIZE 260
+
+#define CMD_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */
+
+struct intel_version {
+ u8 status;
+ u8 hw_platform;
+ u8 hw_variant;
+ u8 hw_revision;
+ u8 fw_variant;
+ u8 fw_revision;
+ u8 fw_build_num;
+ u8 fw_build_ww;
+ u8 fw_build_yy;
+ u8 fw_patch_num;
+} __packed;
+
+struct intel_bl_data {
+ struct usb_device *udev;
+
+ u8 evt_buff[MAX_DATA_SIZE];
+ int evt_len;
+
+ struct work_struct work;
+ atomic_t shutdown;
+};
+
+static int intel_bl_send_cmd_sync(struct intel_bl_data *data,
+ const u8 *cmd_buff, int cmd_len, u32 timeout)
+{
+ u8 *buff;
+ int err;
+
+ BT_DBG("send cmd len %d", cmd_len);
+
+ buff = kmalloc(cmd_len, GFP_KERNEL);
+ if (!buff)
+ return -ENOMEM;
+
+ memcpy(buff, cmd_buff, cmd_len);
+
+ err = usb_control_msg(data->udev, usb_sndctrlpipe(data->udev, 0x00),
+ 0, USB_TYPE_CLASS, 0, 0,
+ buff, cmd_len, USB_CTRL_SET_TIMEOUT);
+ if (err < 0) {
+ BT_ERR("failed to send control message (%d)", err);
+ goto exit_error;
+ }
+
+ err = usb_interrupt_msg(data->udev, usb_rcvintpipe(data->udev, 0x81),
+ data->evt_buff, MAX_DATA_SIZE, &data->evt_len,
+ 5000);
+ if (err < 0) {
+ BT_ERR("failed to receive interrupt message (%d)", err);
+ goto exit_error;
+ }
+
+ BT_DBG("received event(%d): %02x %02x %02x %02x %02x %02x",
+ data->evt_len, data->evt_buff[0], data->evt_buff[1],
+ data->evt_buff[2], data->evt_buff[3], data->evt_buff[4],
+ data->evt_buff[5]);
+
+exit_error:
+ kfree(buff);
+
+ return err;
+}
+
+static const struct firmware *intel_bl_get_fw(struct intel_bl_data *data,
+ struct intel_version *ver)
+{
+ const struct firmware *fw;
+ char fwname[64];
+ int err;
+
+ snprintf(fwname, sizeof(fwname),
+ "intel/ibt-hw-%x.%x.%x-fw-%x.%x.%x.%x.%x.bseq",
+ ver->hw_platform, ver->hw_variant, ver->hw_revision,
+ ver->fw_variant, ver->fw_revision, ver->fw_build_num,
+ ver->fw_build_ww, ver->fw_build_yy);
+
+ BT_INFO("Intel Bluetooth firmware file: %s", fwname);
+
+ err = request_firmware(&fw, fwname, &data->udev->dev);
+ if (err < 0) {
+ BT_ERR("failed to open the Intel firmware file (%d)", err);
+ return NULL;
+ }
+
+ return fw;
+}
+
+static int intel_bl_downloading(struct intel_bl_data *data,
+ const struct firmware *fw,
+ const u8 **fw_ptr)
+{
+ struct hci_command_hdr *cmd;
+ const u8 *cmd_ptr;
+ struct hci_event_hdr *evt = NULL;
+ const u8 *evt_ptr = NULL;
+ int err;
+
+ int remain = fw->size - (*fw_ptr - fw->data);
+
+ if (atomic_read(&data->shutdown)) {
+ BT_ERR("firmware download aborted.");
+ return -EFAULT;
+ }
+
+ BT_DBG("downloading fw data: remain %d", remain);
+
+
+ if (remain <= HCI_COMMAND_HDR_SIZE || *fw_ptr[0] != 0x01) {
+ BT_ERR("fw file is corrupted: invalid cmd read");
+ return -EINVAL;
+ }
+ (*fw_ptr)++;
+ remain--;
+
+ cmd = (struct hci_command_hdr *)(*fw_ptr);
+ cmd_ptr = *fw_ptr;
+
+ /* push HCI command header */
+ *fw_ptr += sizeof(*cmd);
+ remain -= sizeof(*cmd);
+
+ if (remain < cmd->plen) {
+ BT_ERR("fw file is corrupted. invalid cmd len");
+ return -EFAULT;
+ }
+
+ /* push HCI command parameter */
+ *fw_ptr += cmd->plen;
+ remain -= cmd->plen;
+
+ /* read event */
+ if (remain <= HCI_EVENT_HDR_SIZE || *fw_ptr[0] != 0x02) {
+ BT_ERR("fw file is corrupted: invalid evt read");
+ return -EINVAL;
+ }
+
+ (*fw_ptr)++;
+ remain--;
+
+ evt = (struct hci_event_hdr *)(*fw_ptr);
+ evt_ptr = *fw_ptr;
+
+ /* push HCI event header */
+ *fw_ptr += sizeof(*evt);
+ remain -= sizeof(*evt);
+
+ if (remain < evt->plen) {
+ BT_ERR("fw file is corrupted: invalid evt len");
+ return -EFAULT;
+ }
+
+ *fw_ptr += evt->plen;
+ remain -= evt->plen;
+
+ err = intel_bl_send_cmd_sync(data, cmd_ptr, cmd->plen + 3, CMD_TIMEOUT);
+ if (err) {
+ BT_ERR("failed to send patch command %d", err);
+ return -EFAULT;
+ }
+
+ if (evt->plen + 2 != data->evt_len) {
+ BT_ERR("mismatch event length");
+ return -EFAULT;
+ }
+
+ if (memcmp(data->evt_buff, evt_ptr, evt->plen + 2)) {
+ BT_ERR("mismatch event parameter");
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+static void intel_bl_setup(struct work_struct *work)
+{
+ struct intel_bl_data *data =
+ container_of(work, struct intel_bl_data, work);
+ const struct firmware *fw;
+ const u8 *fw_ptr;
+ struct intel_version *ver;
+ int err;
+
+ const u8 get_version[] = { 0x05, 0xFC, 0x00 };
+ const u8 mfg_enable[] = { 0x11, 0xFC, 0x02, 0x01, 0x00 };
+ const u8 mfg_reset_deactivate[] = { 0x11, 0xFC, 0x02, 0x00, 0x01 };
+ const u8 mfg_reset_activate[] = { 0x11, 0xFC, 0x02, 0x00, 0x02 };
+
+ BT_DBG("start Intel fw setup: data %p", data);
+
+ /* get version */
+ err = intel_bl_send_cmd_sync(data, get_version, 3, CMD_TIMEOUT);
+ if (err < 0) {
+ BT_ERR("failed to send get_version command (%d)", err);
+ return;
+ }
+
+ BT_DBG("received get_version event");
+ if (data->evt_len != 15) {
+ BT_ERR("received invalid get_version event: (%d)",
+ data->evt_len);
+ return;
+ }
+
+ ver = (struct intel_version *)&data->evt_buff[5];
+ if (ver->status) {
+ BT_ERR("get_version event failed (%02x)", ver->status);
+ return;
+ }
+
+ BT_DBG("Intel fw version: %02x%02x%02x%02x%02x%02x%02x%02x%02x",
+ ver->hw_platform, ver->hw_variant, ver->hw_revision,
+ ver->fw_variant, ver->fw_revision, ver->fw_build_num,
+ ver->fw_build_ww, ver->fw_build_yy, ver->fw_patch_num);
+
+ if (ver->fw_patch_num) {
+ BT_INFO("fw is already loaded. skip the downloading");
+ return;
+ }
+
+ fw = intel_bl_get_fw(data, ver);
+ if (!fw)
+ return;
+
+ fw_ptr = fw->data;
+
+ /* make sure the first byte is FF */
+ if (fw->data[0] != 0xFF) {
+ BT_ERR("invalid fw image file: %02x", fw->data[0]);
+ release_firmware(fw);
+ return;
+ }
+ fw_ptr++;
+
+ /* enter mfg mode */
+ err = intel_bl_send_cmd_sync(data, mfg_enable, 5, CMD_TIMEOUT);
+ if (err < 0) {
+ BT_ERR("failed to enable mfg mode (%d)", err);
+ release_firmware(fw);
+ return;
+ }
+
+ while (fw->size > fw_ptr - fw->data) {
+ err = intel_bl_downloading(data, fw, &fw_ptr);
+ if (err < 0) {
+ release_firmware(fw);
+ goto exit_mfg_deactivate;
+ }
+ }
+
+ release_firmware(fw);
+
+ /* patching success */
+ err = intel_bl_send_cmd_sync(data, mfg_reset_activate, 5, CMD_TIMEOUT);
+ if (err < 0) {
+ BT_ERR("failed to disable mfg mode: (%d)", err);
+ return;
+ }
+
+ BT_INFO("Intel fw downloading is completed");
+
+ return;
+
+exit_mfg_deactivate:
+ err = intel_bl_send_cmd_sync(data, mfg_reset_deactivate, 5,
+ CMD_TIMEOUT);
+ if (err < 0) {
+ BT_ERR("failed to disable mfg mode(deactivate fw): (%d)", err);
+ return;
+ }
+
+ BT_INFO("device is reset without enabling fw");
+ return;
+
+}
+
+static int intel_bl_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct intel_bl_data *data;
+ int err;
+
+ BT_DBG("intf %p id %p", intf, id);
+
+ /* interface numbers are hardcoded in the spec */
+ if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
+ return -ENODEV;
+
+ data = devm_kzalloc(&intf->dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->udev = interface_to_usbdev(intf);
+
+ usb_set_intfdata(intf, data);
+
+ /* There is a bug in the bootloader that interrupt interface is only
+ * enabled after receiving SetInterface(0, AltSetting=0).
+ */
+ err = usb_set_interface(data->udev, 0, 0);
+ if (err < 0) {
+ BT_ERR("failed to set interface 0, alt 0 %d", err);
+ return err;
+ }
+
+ INIT_WORK(&data->work, intel_bl_setup);
+
+ /* use workqueue to have a small delay */
+ schedule_work(&data->work);
+
+ return 0;
+}
+
+static void intel_bl_disconnect(struct usb_interface *intf)
+{
+ struct intel_bl_data *data = usb_get_intfdata(intf);
+
+ BT_DBG("intf %p", intf);
+
+ atomic_inc(&data->shutdown);
+ cancel_work_sync(&data->work);
+
+ BT_DBG("intel_bl_disconnect");
+
+ usb_set_intfdata(intf, NULL);
+}
+
+static struct usb_driver intel_bl_driver = {
+ .name = "intel_bl",
+ .probe = intel_bl_probe,
+ .disconnect = intel_bl_disconnect,
+ .id_table = intel_bl_table,
+ .disable_hub_initiated_lpm = 1,
+};
+
+module_usb_driver(intel_bl_driver);
+
+MODULE_AUTHOR("Tedd Ho-Jeong An <tedd.an@intel.com>");
+MODULE_DESCRIPTION("Intel Bluetooth USB Bootloader driver ver " VERSION);
+MODULE_VERSION(VERSION);
+MODULE_LICENSE("GPL");
--
1.7.9.5
--
Regards
Tedd Ho-Jeong An
Intel Corporation
^ permalink raw reply related
* Re: [PATCH 3/6] Bluetooth: Set discovery parameters
From: Andre Guedes @ 2013-08-22 20:01 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <345ED8A3-63AC-4F6A-8D42-D1CCA6532D97@holtmann.org>
Hi Marcel,
On Wed, Aug 21, 2013 at 7:56 PM, Marcel Holtmann <marcel@holtmann.org> wrot=
e:
> Hi Andre,
>
>>>> This patch adds support for setting discovery parameters through
>>>> debugfs filesystem.
>>>>
>>>> Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
>>>> ---
>>>> net/bluetooth/hci_sysfs.c | 45 +++++++++++++++++++++++++++++++++++++++=
+++++-
>>>> 1 file changed, 44 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
>>>> index 90cb53b..17ebc4a 100644
>>>> --- a/net/bluetooth/hci_sysfs.c
>>>> +++ b/net/bluetooth/hci_sysfs.c
>>>> @@ -553,9 +553,52 @@ static int discovery_parameters_open(struct inode=
*inode, struct file *file)
>>>> return single_open(file, discovery_parameters_show, inode->i_priv=
ate);
>>>> }
>>>>
>>>> +static ssize_t discovery_parameters_write(struct file *file,
>>>> + const char __user *data,
>>>> + size_t count, loff_t *offset)
>>>> +{
>>>> + struct seq_file *sfile =3D file->private_data;
>>>> + struct hci_dev *hdev =3D sfile->private;
>>>> + struct discovery_param param;
>>>> + char *buf;
>>>> + int n;
>>>> + ssize_t res =3D 0;
>>>> +
>>>> + /* We don't allow partial writes */
>>>> + if (*offset !=3D 0)
>>>> + return 0;
>>>> +
>>>> + buf =3D kzalloc(count, GFP_KERNEL);
>>>> + if (!buf)
>>>> + return 0;
>>>> +
>>>> + if (copy_from_user(buf, data, count))
>>>> + goto out;
>>>> +
>>>> + memset(¶m, 0, sizeof(param));
>>>> +
>>>> + n =3D sscanf(buf, "%hhx %hx %hx %u %u %hhx %hhx",
>>>> + ¶m.scan_type, ¶m.scan_interval, ¶m.scan_w=
indow,
>>>> + ¶m.le_scan_duration, ¶m.interleaved_scan_dura=
tion,
>>>> + ¶m.interleaved_inquiry_length,
>>>> + ¶m.bredr_inquiry_length);
>>>
>>> I am not a huge fan of this crazy. I need a manual to know exactly what=
to do here. That is just silly. Unless things are a bit self-explanatory o=
n how you can tweak things, I am not really interested here.
>>
>> What do you think about having the following hierarchy:
>>
>> hciX/
>> |
>> |--> discovery_param/
>> | |--> scan_type
>> | |--> scan_window
>> | |--> scan_interval
>> | |--> le_scan_timeout
>> | |--> interleaved_scan_timeout
>> | |--> interleaved_inquiry_length
>> | |--> bredr_inquiry_length
>> |
>> |--> le_conn_param/
>> |--> scan_window
>> |--> scan_interval
>> |--> min_conn_interval
>> |--> max_conn_interval
>> |--> min_ce_length
>> |--> max_ce_length
>> |--> supervision_timeout
>> |--> conn_latency
>>
>> It sounds much self-explanatory to me.
>
> don't go crazy with the nesting here. Toplevel directory entries are just=
fine. The one tricky part you will run into is that things like the scan_w=
indow for connections suppose to be per device and not just global. Since y=
ou can learn many of these parameters from AD or GATT. And when connecting =
to one specific device, you suppose to use these ones and not some global c=
ommon value.
Ok, so I'll place them all in hciX/ and add the prefix "discov_" for
the discovery files and "le_conn_" for the LE connection ones.
About scan_window and scan_interval parameters, you are right, they
are supposed to be per device. That feature should be addressed in the
new LE connection approach we've discussed a while ago (which, BTW, I
already started the implementation). These exported parameters, on the
other hand, are the default values the kernel uses in case specific
parameters were not set for a given device.
The idea behind exporting LE connection parameters via debugfs is to
facilitate the implementation of experiments. Today the parameters are
hard coded in kernel and we have to recompile it each time we want
experiment new values. IMO, we should export scan_window and
scan_interval since they are very useful for running experiments.
>>> Also intermixing LE with BR/EDR is a bit pointless here. I would prefer=
if they are separate and not that BR/EDR only controller exports LE knobs =
and and LE only controller exports BR/EDR knobs.
>>
>> Sure. I'll fix this in the v2 patchset. We can also extend this to
>> others debugfs entries (e.g. inquiry_cache and auto_accept_delay files
>> should not be exported if controller is LE-only).
>
> Of course they should be separated.
I'll fix it.
>> In the current code, hdev is exported during device registration
>> (hci_register_dev). However, in hci_register_dev(), hdev has not been
>> initialized yet so we are not able to know is controller is BR/EDR, LE
>> or dual mode. In order to fix this, we need to postpone exporting hdev
>> by moving hci_add_sysfs call from hci_register_dev() to
>> hci_dev_open().
>>
>> As a side effect, the hciX/ directory will be added to debugfs once
>> the adapter is powered on and it will be removed once the adapter is
>> powered off. Do you see any problem with that?
>
> That is not acceptable and also not how the kernel actually works. We are=
initializing the adapter no matter what. So the information is available b=
efore power on.
Fair enough, let's forget about this approach.
I just realized we can fix this by exporting BR/EDR and LE specific
information once hdev is initialized. All we need to do is checking if
HCI_SETUP flag is set just after __hci_init call in hci_open_dev().
Thanks for your feedback,
Andre
^ permalink raw reply
* Re: pull request: bluetooth-next 2013-08-21
From: John W. Linville @ 2013-08-22 18:28 UTC (permalink / raw)
To: Gustavo Padovan, linux-wireless, linux-bluetooth, linux-kernel
In-Reply-To: <20130821161218.GH14645@joana>
On Wed, Aug 21, 2013 at 06:12:18PM +0200, Gustavo Padovan wrote:
> Hi John,
>
> Patches to 3.12, here we have:
>
> * implementation of a proper tty_port for RFCOMM devices, this fixes some
> issues people were seeing lately in the kernel.
> * Add voice_setting option for SCO, it is used for SCO Codec selection
> * bugfixes, small improvements and clean ups
>
> Please pull, Thanks.
>
> Gustavo
>
> --
> The following changes since commit 72bb2f2678878dd4a758e628957f29ce28000d88:
>
> bgmac: make bgmac depend on bcm47xx (2013-07-24 11:05:19 -0400)
>
> are available in the git repository at:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next master
>
> for you to fetch changes up to 2dea632f9acad076370fe871d4ccc93868621403:
>
> Bluetooth: Add SCO connection fallback (2013-08-21 16:47:13 +0200)
Pulling now...
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
^ permalink raw reply
* [PATCH 2/2] obexd: Add property changed signals for 'org.bluez.obex.Message1'
From: Christian Fetzer @ 2013-08-22 16:08 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1377187721-3758-1-git-send-email-christian.fetzer@oss.bmw-carit.de>
From: Christian Fetzer <christian.fetzer@bmw-carit.de>
This patch adds property changed signal emissions in case message properties
change on the server.
---
obexd/client/map.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 92 insertions(+), 2 deletions(-)
diff --git a/obexd/client/map.c b/obexd/client/map.c
index 8864a54..a9a9bcd 100644
--- a/obexd/client/map.c
+++ b/obexd/client/map.c
@@ -792,121 +792,211 @@ static struct map_msg *map_msg_create(struct map_data *data, const char *handle)
static void parse_subject(struct map_msg *msg, const char *value)
{
+ if (g_strcmp0(msg->subject, value) == 0)
+ return;
+
g_free(msg->subject);
msg->subject = g_strdup(value);
+
+ g_dbus_emit_property_changed(conn, msg->path,
+ MAP_MSG_INTERFACE, "Subject");
}
static void parse_datetime(struct map_msg *msg, const char *value)
{
+ if (g_strcmp0(msg->timestamp, value) == 0)
+ return;
+
g_free(msg->timestamp);
msg->timestamp = g_strdup(value);
+
+ g_dbus_emit_property_changed(conn, msg->path,
+ MAP_MSG_INTERFACE, "Timestamp");
}
static void parse_sender(struct map_msg *msg, const char *value)
{
+ if (g_strcmp0(msg->sender, value) == 0)
+ return;
+
g_free(msg->sender);
msg->sender = g_strdup(value);
+
+ g_dbus_emit_property_changed(conn, msg->path,
+ MAP_MSG_INTERFACE, "Sender");
}
static void parse_sender_address(struct map_msg *msg, const char *value)
{
+ if (g_strcmp0(msg->sender_address, value) == 0)
+ return;
+
g_free(msg->sender_address);
msg->sender_address = g_strdup(value);
+
+ g_dbus_emit_property_changed(conn, msg->path,
+ MAP_MSG_INTERFACE, "SenderAddress");
}
static void parse_replyto(struct map_msg *msg, const char *value)
{
+ if (g_strcmp0(msg->replyto, value) == 0)
+ return;
+
g_free(msg->replyto);
msg->replyto = g_strdup(value);
+
+ g_dbus_emit_property_changed(conn, msg->path,
+ MAP_MSG_INTERFACE, "ReplyTo");
}
static void parse_recipient(struct map_msg *msg, const char *value)
{
+ if (g_strcmp0(msg->recipient, value) == 0)
+ return;
+
g_free(msg->recipient);
msg->recipient = g_strdup(value);
+
+ g_dbus_emit_property_changed(conn, msg->path,
+ MAP_MSG_INTERFACE, "Recipient");
}
static void parse_recipient_address(struct map_msg *msg, const char *value)
{
+ if (g_strcmp0(msg->recipient_address, value) == 0)
+ return;
+
g_free(msg->recipient_address);
msg->recipient_address = g_strdup(value);
+
+ g_dbus_emit_property_changed(conn, msg->path,
+ MAP_MSG_INTERFACE, "RecipientAddress");
}
static void parse_type(struct map_msg *msg, const char *value)
{
+ if (g_strcmp0(msg->type, value) == 0)
+ return;
+
g_free(msg->type);
msg->type = g_strdup(value);
+
+ g_dbus_emit_property_changed(conn, msg->path,
+ MAP_MSG_INTERFACE, "Type");
}
static void parse_size(struct map_msg *msg, const char *value)
{
- msg->size = g_ascii_strtoll(value, NULL, 10);
+ uint64_t size = g_ascii_strtoll(value, NULL, 10);
+
+ if (msg->size == size)
+ return;
+
+ msg->size = size;
+
+ g_dbus_emit_property_changed(conn, msg->path,
+ MAP_MSG_INTERFACE, "Size");
}
static void parse_text(struct map_msg *msg, const char *value)
{
gboolean flag = strcasecmp(value, "no") != 0;
+ uint8_t oldflags = msg->flags;
if (flag)
msg->flags |= MAP_MSG_FLAG_TEXT;
else
msg->flags &= ~MAP_MSG_FLAG_TEXT;
+ if (msg->flags != oldflags)
+ g_dbus_emit_property_changed(conn, msg->path,
+ MAP_MSG_INTERFACE, "Text");
}
static void parse_status(struct map_msg *msg, const char *value)
{
+ if (g_strcmp0(msg->status, value) == 0)
+ return;
+
g_free(msg->status);
msg->status = g_strdup(value);
+
+ g_dbus_emit_property_changed(conn, msg->path,
+ MAP_MSG_INTERFACE, "Status");
}
static void parse_attachment_size(struct map_msg *msg, const char *value)
{
- msg->attachment_size = g_ascii_strtoll(value, NULL, 10);
+ uint64_t attachment_size = g_ascii_strtoll(value, NULL, 10);
+
+ if (msg->attachment_size == attachment_size)
+ return;
+
+ msg->attachment_size = attachment_size;
+
+ g_dbus_emit_property_changed(conn, msg->path,
+ MAP_MSG_INTERFACE, "AttachmentSize");
}
static void parse_priority(struct map_msg *msg, const char *value)
{
gboolean flag = strcasecmp(value, "no") != 0;
+ uint8_t oldflags = msg->flags;
if (flag)
msg->flags |= MAP_MSG_FLAG_PRIORITY;
else
msg->flags &= ~MAP_MSG_FLAG_PRIORITY;
+ if (msg->flags != oldflags)
+ g_dbus_emit_property_changed(conn, msg->path,
+ MAP_MSG_INTERFACE, "Priority");
}
static void parse_read(struct map_msg *msg, const char *value)
{
gboolean flag = strcasecmp(value, "no") != 0;
+ uint8_t oldflags = msg->flags;
if (flag)
msg->flags |= MAP_MSG_FLAG_READ;
else
msg->flags &= ~MAP_MSG_FLAG_READ;
+ if (msg->flags != oldflags)
+ g_dbus_emit_property_changed(conn, msg->path,
+ MAP_MSG_INTERFACE, "Read");
}
static void parse_sent(struct map_msg *msg, const char *value)
{
gboolean flag = strcasecmp(value, "no") != 0;
+ uint8_t oldflags = msg->flags;
if (flag)
msg->flags |= MAP_MSG_FLAG_SENT;
else
msg->flags &= ~MAP_MSG_FLAG_SENT;
+ if (msg->flags != oldflags)
+ g_dbus_emit_property_changed(conn, msg->path,
+ MAP_MSG_INTERFACE, "Sent");
}
static void parse_protected(struct map_msg *msg, const char *value)
{
gboolean flag = strcasecmp(value, "no") != 0;
+ uint8_t oldflags = msg->flags;
if (flag)
msg->flags |= MAP_MSG_FLAG_PROTECTED;
else
msg->flags &= ~MAP_MSG_FLAG_PROTECTED;
+ if (msg->flags != oldflags)
+ g_dbus_emit_property_changed(conn, msg->path,
+ MAP_MSG_INTERFACE, "Protected");
}
static struct map_msg_parser {
--
1.8.3.4
^ permalink raw reply related
* [PATCH 1/2] obexd: Use g_dbus_get_properties when parsing MAP-msg-listing
From: Christian Fetzer @ 2013-08-22 16:08 UTC (permalink / raw)
To: linux-bluetooth
From: Christian Fetzer <christian.fetzer@bmw-carit.de>
Currently the message D-Bus properties for the ListMessages response are put
together manually in the parse_* functions unsing obex_dbus_dict_append.
This patch simplifies it by calling g_dbus_get_properties for every message.
---
obexd/client/map.c | 84 ++++++++++++++----------------------------------------
1 file changed, 21 insertions(+), 63 deletions(-)
diff --git a/obexd/client/map.c b/obexd/client/map.c
index 3d8acc4..8864a54 100644
--- a/obexd/client/map.c
+++ b/obexd/client/map.c
@@ -790,81 +790,60 @@ static struct map_msg *map_msg_create(struct map_data *data, const char *handle)
return msg;
}
-static void parse_subject(struct map_msg *msg, const char *value,
- DBusMessageIter *iter)
+static void parse_subject(struct map_msg *msg, const char *value)
{
g_free(msg->subject);
msg->subject = g_strdup(value);
- obex_dbus_dict_append(iter, "Subject", DBUS_TYPE_STRING, &value);
}
-static void parse_datetime(struct map_msg *msg, const char *value,
- DBusMessageIter *iter)
+static void parse_datetime(struct map_msg *msg, const char *value)
{
g_free(msg->timestamp);
msg->timestamp = g_strdup(value);
- obex_dbus_dict_append(iter, "Timestamp", DBUS_TYPE_STRING, &value);
}
-static void parse_sender(struct map_msg *msg, const char *value,
- DBusMessageIter *iter)
+static void parse_sender(struct map_msg *msg, const char *value)
{
g_free(msg->sender);
msg->sender = g_strdup(value);
- obex_dbus_dict_append(iter, "Sender", DBUS_TYPE_STRING, &value);
}
-static void parse_sender_address(struct map_msg *msg, const char *value,
- DBusMessageIter *iter)
+static void parse_sender_address(struct map_msg *msg, const char *value)
{
g_free(msg->sender_address);
msg->sender_address = g_strdup(value);
- obex_dbus_dict_append(iter, "SenderAddress", DBUS_TYPE_STRING,
- &value);
}
-static void parse_replyto(struct map_msg *msg, const char *value,
- DBusMessageIter *iter)
+static void parse_replyto(struct map_msg *msg, const char *value)
{
g_free(msg->replyto);
msg->replyto = g_strdup(value);
- obex_dbus_dict_append(iter, "ReplyTo", DBUS_TYPE_STRING, &value);
}
-static void parse_recipient(struct map_msg *msg, const char *value,
- DBusMessageIter *iter)
+static void parse_recipient(struct map_msg *msg, const char *value)
{
g_free(msg->recipient);
msg->recipient = g_strdup(value);
- obex_dbus_dict_append(iter, "Recipient", DBUS_TYPE_STRING, &value);
}
-static void parse_recipient_address(struct map_msg *msg, const char *value,
- DBusMessageIter *iter)
+static void parse_recipient_address(struct map_msg *msg, const char *value)
{
g_free(msg->recipient_address);
msg->recipient_address = g_strdup(value);
- obex_dbus_dict_append(iter, "RecipientAddress", DBUS_TYPE_STRING,
- &value);
}
-static void parse_type(struct map_msg *msg, const char *value,
- DBusMessageIter *iter)
+static void parse_type(struct map_msg *msg, const char *value)
{
g_free(msg->type);
msg->type = g_strdup(value);
- obex_dbus_dict_append(iter, "Type", DBUS_TYPE_STRING, &value);
}
-static void parse_size(struct map_msg *msg, const char *value,
- DBusMessageIter *iter)
+static void parse_size(struct map_msg *msg, const char *value)
{
msg->size = g_ascii_strtoll(value, NULL, 10);
- obex_dbus_dict_append(iter, "Size", DBUS_TYPE_UINT64, &msg->size);
}
-static void parse_text(struct map_msg *msg, const char *value,
- DBusMessageIter *iter)
+static void parse_text(struct map_msg *msg, const char *value)
{
gboolean flag = strcasecmp(value, "no") != 0;
@@ -873,27 +852,20 @@ static void parse_text(struct map_msg *msg, const char *value,
else
msg->flags &= ~MAP_MSG_FLAG_TEXT;
- obex_dbus_dict_append(iter, "Text", DBUS_TYPE_BOOLEAN, &flag);
}
-static void parse_status(struct map_msg *msg, const char *value,
- DBusMessageIter *iter)
+static void parse_status(struct map_msg *msg, const char *value)
{
g_free(msg->status);
msg->status = g_strdup(value);
- obex_dbus_dict_append(iter, "Status", DBUS_TYPE_STRING, &value);
}
-static void parse_attachment_size(struct map_msg *msg, const char *value,
- DBusMessageIter *iter)
+static void parse_attachment_size(struct map_msg *msg, const char *value)
{
msg->attachment_size = g_ascii_strtoll(value, NULL, 10);
- obex_dbus_dict_append(iter, "AttachmentSize", DBUS_TYPE_UINT64,
- &msg->attachment_size);
}
-static void parse_priority(struct map_msg *msg, const char *value,
- DBusMessageIter *iter)
+static void parse_priority(struct map_msg *msg, const char *value)
{
gboolean flag = strcasecmp(value, "no") != 0;
@@ -902,11 +874,9 @@ static void parse_priority(struct map_msg *msg, const char *value,
else
msg->flags &= ~MAP_MSG_FLAG_PRIORITY;
- obex_dbus_dict_append(iter, "Priority", DBUS_TYPE_BOOLEAN, &flag);
}
-static void parse_read(struct map_msg *msg, const char *value,
- DBusMessageIter *iter)
+static void parse_read(struct map_msg *msg, const char *value)
{
gboolean flag = strcasecmp(value, "no") != 0;
@@ -915,11 +885,9 @@ static void parse_read(struct map_msg *msg, const char *value,
else
msg->flags &= ~MAP_MSG_FLAG_READ;
- obex_dbus_dict_append(iter, "Read", DBUS_TYPE_BOOLEAN, &flag);
}
-static void parse_sent(struct map_msg *msg, const char *value,
- DBusMessageIter *iter)
+static void parse_sent(struct map_msg *msg, const char *value)
{
gboolean flag = strcasecmp(value, "no") != 0;
@@ -928,11 +896,9 @@ static void parse_sent(struct map_msg *msg, const char *value,
else
msg->flags &= ~MAP_MSG_FLAG_SENT;
- obex_dbus_dict_append(iter, "Sent", DBUS_TYPE_BOOLEAN, &flag);
}
-static void parse_protected(struct map_msg *msg, const char *value,
- DBusMessageIter *iter)
+static void parse_protected(struct map_msg *msg, const char *value)
{
gboolean flag = strcasecmp(value, "no") != 0;
@@ -941,13 +907,11 @@ static void parse_protected(struct map_msg *msg, const char *value,
else
msg->flags &= ~MAP_MSG_FLAG_PROTECTED;
- obex_dbus_dict_append(iter, "Protected", DBUS_TYPE_BOOLEAN, &flag);
}
static struct map_msg_parser {
const char *name;
- void (*func) (struct map_msg *msg, const char *value,
- DBusMessageIter *iter);
+ void (*func) (struct map_msg *msg, const char *value);
} msg_parsers[] = {
{ "subject", parse_subject },
{ "datetime", parse_datetime },
@@ -974,7 +938,7 @@ static void msg_element(GMarkupParseContext *ctxt, const char *element,
{
struct map_parser *parser = user_data;
struct map_data *data = parser->data;
- DBusMessageIter entry, dict, *iter = parser->iter;
+ DBusMessageIter entry, *iter = parser->iter;
struct map_msg *msg;
const char *key;
int i;
@@ -1000,25 +964,19 @@ static void msg_element(GMarkupParseContext *ctxt, const char *element,
dbus_message_iter_append_basic(&entry, DBUS_TYPE_OBJECT_PATH,
&msg->path);
- dbus_message_iter_open_container(&entry, DBUS_TYPE_ARRAY,
- DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
- DBUS_TYPE_STRING_AS_STRING
- DBUS_TYPE_VARIANT_AS_STRING
- DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
- &dict);
-
for (i = 0, key = names[i]; key; key = names[++i]) {
struct map_msg_parser *parser;
for (parser = msg_parsers; parser && parser->name; parser++) {
if (strcasecmp(key, parser->name) == 0) {
- parser->func(msg, values[i], &dict);
+ parser->func(msg, values[i]);
break;
}
}
}
- dbus_message_iter_close_container(&entry, &dict);
+ g_dbus_get_properties(conn, msg->path, MAP_MSG_INTERFACE, &entry);
+
dbus_message_iter_close_container(iter, &entry);
}
--
1.8.3.4
^ permalink raw reply related
* [PATCH 1/1] obexd: Fix memleak when unregistering MAP event handler
From: Christian Fetzer @ 2013-08-22 16:07 UTC (permalink / raw)
To: linux-bluetooth
From: Christian Fetzer <christian.fetzer@bmw-carit.de>
96 bytes in 3 blocks are definitely lost in loss record 217 of 310
at 0x4C29E84: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x5977858: g_malloc0 (in /usr/lib/libglib-2.0.so.0.3600.3)
by 0x433A87: map_register_event_handler (map-event.c:76)
by 0x4324C1: set_notification_registration (map.c:1722)
by 0x4325BB: map_probe (map.c:1801)
by 0x42D55C: obc_session_register (session.c:862)
by 0x42BE4B: create_callback (manager.c:100)
by 0x42CA0D: connect_cb (session.c:281)
by 0x4191CB: handle_response (gobex.c:949)
by 0x4196F0: incoming_data (gobex.c:1192)
by 0x5971DA5: g_main_context_dispatch (in /usr/lib/libglib-2.0.so.0.3600.3)
by 0x59720F7: ??? (in /usr/lib/libglib-2.0.so.0.3600.3)
---
obexd/client/map-event.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/obexd/client/map-event.c b/obexd/client/map-event.c
index 76dfb84..bbe3519 100644
--- a/obexd/client/map-event.c
+++ b/obexd/client/map-event.c
@@ -97,6 +97,7 @@ void map_unregister_event_handler(struct obc_session *session, int mas_id)
handlers = g_slist_remove(handlers, handler);
DBG("Handler %p for %s:%d unregistered", handler,
obc_session_get_destination(session), mas_id);
+ g_free(handler);
}
void map_dispatch_event(int mas_id, const char *device,
--
1.8.3.4
^ permalink raw reply related
* [PATCH 2/2] obexd: Add property Folder to MAP message
From: Christian Fetzer @ 2013-08-22 16:00 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1377187223-3427-1-git-send-email-christian.fetzer@oss.bmw-carit.de>
From: Christian Fetzer <christian.fetzer@bmw-carit.de>
diff --git a/obexd/client/map.c b/obexd/client/map.c
index 3d8acc4..83da09b 100644
--- a/obexd/client/map.c
+++ b/obexd/client/map.c
@@ -123,6 +123,7 @@ struct map_msg {
char *status;
uint64_t attachment_size;
uint8_t flags;
+ char *folder;
GDBusPendingPropertySet pending;
};
@@ -379,6 +380,7 @@ static void map_msg_free(void *data)
g_free(msg->path);
g_free(msg->subject);
g_free(msg->handle);
+ g_free(msg->folder);
g_free(msg->timestamp);
g_free(msg->sender);
g_free(msg->sender_address);
@@ -451,6 +453,16 @@ done:
msg->pending = 0;
}
+static gboolean get_folder(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data)
+{
+ struct map_msg *msg = data;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &msg->folder);
+
+ return TRUE;
+}
+
static gboolean subject_exists(const GDBusPropertyTable *property, void *data)
{
struct map_msg *msg = data;
@@ -744,6 +756,7 @@ static const GDBusMethodTable map_msg_methods[] = {
};
static const GDBusPropertyTable map_msg_properties[] = {
+ { "Folder", "s", get_folder },
{ "Subject", "s", get_subject, NULL, subject_exists },
{ "Timestamp", "s", get_timestamp, NULL, timestamp_exists },
{ "Sender", "s", get_sender, NULL, sender_exists },
@@ -766,7 +779,8 @@ static const GDBusPropertyTable map_msg_properties[] = {
{ }
};
-static struct map_msg *map_msg_create(struct map_data *data, const char *handle)
+static struct map_msg *map_msg_create(struct map_data *data, const char *handle,
+ const char *folder)
{
struct map_msg *msg;
@@ -775,6 +789,7 @@ static struct map_msg *map_msg_create(struct map_data *data, const char *handle)
msg->path = g_strdup_printf("%s/message%s",
obc_session_get_path(data->session),
handle);
+ msg->folder = g_strdup(folder);
if (!g_dbus_register_interface(conn, msg->path, MAP_MSG_INTERFACE,
map_msg_methods, NULL,
@@ -989,7 +1004,8 @@ static void msg_element(GMarkupParseContext *ctxt, const char *element,
msg = g_hash_table_lookup(data->messages, values[i]);
if (msg == NULL) {
- msg = map_msg_create(data, values[i]);
+ msg = map_msg_create(data, values[i],
+ obc_session_get_current_path(data->session));
if (msg == NULL)
return;
}
--
1.8.3.4
^ permalink raw reply related
* [PATCH 1/2] obexd: Add obc_session_get_current_path function
From: Christian Fetzer @ 2013-08-22 16:00 UTC (permalink / raw)
To: linux-bluetooth
From: Christian Fetzer <christian.fetzer@bmw-carit.de>
This patch extends client session by the tracking of the current path.
The current path can be accessed by obc_session_get_current_path.
This allows drivers to add a folder property to browsed objects so that
the application doesn't have to keep track of the folder an object
belongs to.
---
obexd/client/session.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
obexd/client/session.h | 2 ++
2 files changed, 48 insertions(+)
diff --git a/obexd/client/session.c b/obexd/client/session.c
index 44e2bf8..293359b 100644
--- a/obexd/client/session.c
+++ b/obexd/client/session.c
@@ -110,6 +110,8 @@ struct obc_session {
guint watch;
GQueue *queue;
guint process_id;
+ GSList *cur_path_list;
+ char *cur_path;
};
static GSList *sessions = NULL;
@@ -242,6 +244,8 @@ static void session_free(struct obc_session *session)
g_free(session->owner);
g_free(session->source);
g_free(session->destination);
+ g_slist_free_full(session->cur_path_list, g_free);
+ g_free(session->cur_path);
g_free(session);
}
@@ -500,6 +504,7 @@ struct obc_session *obc_session_create(const char *source,
session->destination = g_strdup(destination);
session->channel = channel;
session->queue = g_queue_new();
+ session->cur_path = g_strdup("/");
if (owner)
obc_session_set_owner(session, owner, owner_disconnected);
@@ -930,12 +935,33 @@ const char *obc_session_get_target(struct obc_session *session)
return session->driver->target;
}
+const char *obc_session_get_current_path(struct obc_session *session)
+{
+ GSList *l;
+ GString *strbuf;
+
+ if (!session->cur_path) {
+ strbuf = g_string_new("/");
+ for (l = session->cur_path_list; l; l = l->next) {
+ g_string_append(strbuf, l->data);
+ if (l->next)
+ g_string_append_c(strbuf, '/');
+ }
+ session->cur_path = g_string_free(strbuf, FALSE);
+ }
+
+ return session->cur_path;
+}
+
static void setpath_complete(struct obc_session *session,
struct obc_transfer *transfer,
GError *err, void *user_data)
{
struct pending_request *p = user_data;
+ g_free(session->cur_path);
+ session->cur_path = NULL;
+
if (p->func)
p->func(session, NULL, err, p->data);
@@ -962,7 +988,9 @@ static void setpath_cb(GObex *obex, GError *err, GObexPacket *rsp,
{
struct pending_request *p = user_data;
struct setpath_data *data = p->data;
+ char *prev;
char *next;
+ GSList *last;
guint8 code;
p->req_id = 0;
@@ -982,6 +1010,24 @@ static void setpath_cb(GObex *obex, GError *err, GObexPacket *rsp,
return;
}
+ /* Track current folder in cur_folder_list */
+ if (strlen(data->remaining[data->index-1]) == 0) {
+ g_slist_free_full(p->session->cur_path_list, g_free);
+ p->session->cur_path_list = NULL;
+ } else {
+ prev = data->remaining[data->index-1];
+ if (strcmp(prev, "..") == 0) {
+ if (p->session->cur_path_list) {
+ last = g_slist_last(p->session->cur_path_list);
+ g_free(last->data);
+ p->session->cur_path_list = g_slist_delete_link(
+ p->session->cur_path_list, last);
+ }
+ } else
+ p->session->cur_path_list = g_slist_append(
+ p->session->cur_path_list, g_strdup(prev));
+ }
+
/* Ignore empty folder names to avoid resetting the current path */
while ((next = data->remaining[data->index]) && strlen(next) == 0)
data->index++;
diff --git a/obexd/client/session.h b/obexd/client/session.h
index 319d529..01034b5 100644
--- a/obexd/client/session.h
+++ b/obexd/client/session.h
@@ -58,6 +58,8 @@ const char *obc_session_register(struct obc_session *session,
const void *obc_session_get_attribute(struct obc_session *session,
int attribute_id);
+const char *obc_session_get_current_path(struct obc_session *session);
+
guint obc_session_queue(struct obc_session *session,
struct obc_transfer *transfer,
session_callback_t func, void *user_data,
--
1.8.3.4
^ permalink raw reply related
* Re: [PATCH v1 24/49] BT: btusb: prepare for enabling irq in complete()
From: Ming Lei @ 2013-08-22 12:23 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: linux-usb, Oliver Neukum, Alan Stern, Ming Lei, Marcel Holtmann,
Gustavo Padovan, Johan Hedberg, linux-bluetooth
In-Reply-To: <1376756714-25479-25-git-send-email-ming.lei@canonical.com>
On Sun, Aug 18, 2013 at 12:24 AM, Ming Lei <ming.lei@canonical.com> wrote:
> Complete() will be run with interrupt enabled, so change to
> spin_lock_irqsave().
>
> Cc: Marcel Holtmann <marcel@holtmann.org>
> Cc: Gustavo Padovan <gustavo@padovan.org>
> Cc: Johan Hedberg <johan.hedberg@gmail.com>
> Cc: linux-bluetooth@vger.kernel.org
> Signed-off-by: Ming Lei <ming.lei@canonical.com>
Marcel, Gustavo and Johan, could you review and give an Ack if
this one and 25/49 are OK so they can be merged via Greg's USB
tree?
Thanks,
--
Ming Lei
^ permalink raw reply
* Re: [PATCH 3/6] Bluetooth: Set discovery parameters
From: Marcel Holtmann @ 2013-08-21 22:56 UTC (permalink / raw)
To: Andre Guedes; +Cc: linux-bluetooth
In-Reply-To: <CACJA=fVmvqJu0YxfAZ9A8a-08z6NUvT-J97O3db9ii0vQVKsFg@mail.gmail.com>
Hi Andre,
>>> This patch adds support for setting discovery parameters through
>>> debugfs filesystem.
>>>
>>> Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
>>> ---
>>> net/bluetooth/hci_sysfs.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
>>> 1 file changed, 44 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
>>> index 90cb53b..17ebc4a 100644
>>> --- a/net/bluetooth/hci_sysfs.c
>>> +++ b/net/bluetooth/hci_sysfs.c
>>> @@ -553,9 +553,52 @@ static int discovery_parameters_open(struct inode *inode, struct file *file)
>>> return single_open(file, discovery_parameters_show, inode->i_private);
>>> }
>>>
>>> +static ssize_t discovery_parameters_write(struct file *file,
>>> + const char __user *data,
>>> + size_t count, loff_t *offset)
>>> +{
>>> + struct seq_file *sfile = file->private_data;
>>> + struct hci_dev *hdev = sfile->private;
>>> + struct discovery_param param;
>>> + char *buf;
>>> + int n;
>>> + ssize_t res = 0;
>>> +
>>> + /* We don't allow partial writes */
>>> + if (*offset != 0)
>>> + return 0;
>>> +
>>> + buf = kzalloc(count, GFP_KERNEL);
>>> + if (!buf)
>>> + return 0;
>>> +
>>> + if (copy_from_user(buf, data, count))
>>> + goto out;
>>> +
>>> + memset(¶m, 0, sizeof(param));
>>> +
>>> + n = sscanf(buf, "%hhx %hx %hx %u %u %hhx %hhx",
>>> + ¶m.scan_type, ¶m.scan_interval, ¶m.scan_window,
>>> + ¶m.le_scan_duration, ¶m.interleaved_scan_duration,
>>> + ¶m.interleaved_inquiry_length,
>>> + ¶m.bredr_inquiry_length);
>>
>> I am not a huge fan of this crazy. I need a manual to know exactly what to do here. That is just silly. Unless things are a bit self-explanatory on how you can tweak things, I am not really interested here.
>
> What do you think about having the following hierarchy:
>
> hciX/
> |
> |--> discovery_param/
> | |--> scan_type
> | |--> scan_window
> | |--> scan_interval
> | |--> le_scan_timeout
> | |--> interleaved_scan_timeout
> | |--> interleaved_inquiry_length
> | |--> bredr_inquiry_length
> |
> |--> le_conn_param/
> |--> scan_window
> |--> scan_interval
> |--> min_conn_interval
> |--> max_conn_interval
> |--> min_ce_length
> |--> max_ce_length
> |--> supervision_timeout
> |--> conn_latency
>
> It sounds much self-explanatory to me.
don't go crazy with the nesting here. Toplevel directory entries are just fine. The one tricky part you will run into is that things like the scan_window for connections suppose to be per device and not just global. Since you can learn many of these parameters from AD or GATT. And when connecting to one specific device, you suppose to use these ones and not some global common value.
>> Also intermixing LE with BR/EDR is a bit pointless here. I would prefer if they are separate and not that BR/EDR only controller exports LE knobs and and LE only controller exports BR/EDR knobs.
>
> Sure. I'll fix this in the v2 patchset. We can also extend this to
> others debugfs entries (e.g. inquiry_cache and auto_accept_delay files
> should not be exported if controller is LE-only).
Of course they should be separated.
> In the current code, hdev is exported during device registration
> (hci_register_dev). However, in hci_register_dev(), hdev has not been
> initialized yet so we are not able to know is controller is BR/EDR, LE
> or dual mode. In order to fix this, we need to postpone exporting hdev
> by moving hci_add_sysfs call from hci_register_dev() to
> hci_dev_open().
>
> As a side effect, the hciX/ directory will be added to debugfs once
> the adapter is powered on and it will be removed once the adapter is
> powered off. Do you see any problem with that?
That is not acceptable and also not how the kernel actually works. We are initializing the adapter no matter what. So the information is available before power on.
Regards
Marcel
^ 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