* [PATCH v3 3/7] Create helper functions to deal with handles on interactive gatttool
From: Sheldon Demario @ 2011-02-23 14:20 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Sheldon Demario
In-Reply-To: <20110223030903.GB16014@jh-x301>
---
attrib/interactive.c | 48 +++++++++++++++++++++++++++++++-----------------
1 files changed, 31 insertions(+), 17 deletions(-)
diff --git a/attrib/interactive.c b/attrib/interactive.c
index 7cc03bc..ed45894 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -238,36 +238,50 @@ static void cmd_primary(int argcp, char **argvp)
gatt_discover_primary(attrib, &uuid, primary_by_uuid_cb, NULL);
}
-static void cmd_char(int argcp, char **argvp)
+static int strtohandle(int *dst, const char *src)
{
- int start = 0x0001;
- int end = 0xffff;
+ char *e;
- if (conn_state != STATE_CONNECTED) {
- printf("Command failed: disconnected\n");
- return;
- }
+ errno = 0;
+ *dst = strtoll(src, &e, 16);
+ if (errno != 0 || *e != '\0')
+ return -1;
- if (argcp > 1) {
- char *e;
+ return 0;
+}
- start = strtoll(argvp[1], &e, 16);
- if (errno != 0 || *e != '\0') {
+static int set_handles(int *start, int *end, int argcp, char **argvp)
+{
+ if (argcp > 1) {
+ if (strtohandle(start, argvp[1])) {
printf("Invalid start handle: %s\n", argvp[1]);
- return;
+ return -1;
}
}
if (argcp > 2) {
- char *e;
-
- end = strtoll(argvp[2], &e, 16);
- if (errno != 0 || *e != '\0') {
+ if (strtohandle(end, argvp[2])) {
printf("Invalid end handle: %s\n", argvp[2]);
- return;
+ return -1;
}
}
+ return 0;
+}
+
+static void cmd_char(int argcp, char **argvp)
+{
+ int start = 0x0001;
+ int end = 0xffff;
+
+ if (conn_state != STATE_CONNECTED) {
+ printf("Command failed: disconnected\n");
+ return;
+ }
+
+ if (set_handles(&start, &end, argcp, argvp))
+ return;
+
gatt_discover_char(attrib, start, end, char_cb, NULL);
return;
--
1.7.1
^ permalink raw reply related
* [PATCH 2/2 v3] Implement generic descriptor access to Attribute API
From: Elvis Pfützenreuter @ 2011-02-23 13:49 UTC (permalink / raw)
To: linux-bluetooth; +Cc: epx
In-Reply-To: <1298468980-2215-1-git-send-email-epx@signove.com>
This patch implements the proposed API changes.
Client Characteristic Configuration automatic update upon Watcher
registering will be handled by another series.
---
attrib/client.c | 367 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 356 insertions(+), 11 deletions(-)
diff --git a/attrib/client.c b/attrib/client.c
index 0f9ba3e..711813b 100644
--- a/attrib/client.c
+++ b/attrib/client.c
@@ -79,6 +79,15 @@ struct primary {
GSList *watchers;
};
+struct descriptor {
+ char *path;
+ uint16_t handle;
+ uuid_t uuid;
+ char type[MAX_LEN_UUID_STR + 1];
+ uint8_t *value;
+ size_t vlen;
+};
+
struct characteristic {
struct primary *prim;
char *path;
@@ -91,12 +100,14 @@ struct characteristic {
struct format *format;
uint8_t *value;
size_t vlen;
+ GSList *descriptors;
};
struct query_data {
struct primary *prim;
struct characteristic *chr;
uint16_t handle;
+ struct descriptor *descr;
};
struct watcher {
@@ -110,10 +121,22 @@ static GSList *gatt_services = NULL;
static DBusConnection *connection;
+static void descriptor_free(void *user_data)
+{
+ struct descriptor *descr = user_data;
+
+ g_free(descr->path);
+ g_free(descr->value);
+
+ g_free(descr);
+}
+
static void characteristic_free(void *user_data)
{
struct characteristic *chr = user_data;
+ g_slist_foreach(chr->descriptors, (GFunc) descriptor_free, NULL);
+
g_free(chr->path);
g_free(chr->desc);
g_free(chr->format);
@@ -188,11 +211,90 @@ static int watcher_cmp(gconstpointer a, gconstpointer b)
return g_strcmp0(watcher->path, match->path);
}
+static void add_descriptor_dict(DBusMessageIter *entry,
+ struct descriptor *descr)
+{
+ DBusMessageIter descr_dict_var;
+ DBusMessageIter descr_dict;
+ const char *uuid;
+ const uint8_t *value;
+ size_t vlen;
+
+ value = descr->value;
+ vlen = descr->vlen;
+ uuid = descr->type;
+
+ dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT,
+ DBUS_TYPE_ARRAY_AS_STRING
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+ &descr_dict_var);
+
+ dbus_message_iter_open_container(&descr_dict_var, 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,
+ &descr_dict);
+
+ dict_append_entry(&descr_dict, "UUID", DBUS_TYPE_STRING, &uuid);
+
+ if (value)
+ dict_append_array(&descr_dict, "Value", DBUS_TYPE_BYTE,
+ &value, vlen);
+
+ dbus_message_iter_close_container(&descr_dict_var, &descr_dict);
+ dbus_message_iter_close_container(entry, &descr_dict_var);
+}
+
+static void add_descriptors_dict(DBusMessageIter *outer_entry,
+ struct characteristic *chr)
+{
+ DBusMessageIter descrs_dict_var;
+ DBusMessageIter descrs_dict;
+ GSList *l;
+
+ dbus_message_iter_open_container(outer_entry, DBUS_TYPE_VARIANT,
+ DBUS_TYPE_ARRAY_AS_STRING
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+ &descrs_dict_var);
+
+ dbus_message_iter_open_container(&descrs_dict_var, 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,
+ &descrs_dict);
+
+ for (l = chr->descriptors; l; l = l->next) {
+ struct descriptor *descr = l->data;
+ const char *key;
+ DBusMessageIter entry;
+
+ key = descr->path;
+
+ dbus_message_iter_open_container(&descrs_dict,
+ DBUS_TYPE_DICT_ENTRY, NULL, &entry);
+
+ dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
+
+ add_descriptor_dict(&entry, descr);
+
+ dbus_message_iter_close_container(&descrs_dict, &entry);
+ }
+
+ dbus_message_iter_close_container(&descrs_dict_var, &descrs_dict);
+ dbus_message_iter_close_container(outer_entry, &descrs_dict_var);
+}
+
static void append_char_dict(DBusMessageIter *iter, struct characteristic *chr)
{
DBusMessageIter dict;
+ DBusMessageIter entry;
const char *name = "";
char *uuid;
+ const char *key;
dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
@@ -214,6 +316,19 @@ static void append_char_dict(DBusMessageIter *iter, struct characteristic *chr)
dict_append_array(&dict, "Value", DBUS_TYPE_BYTE, &chr->value,
chr->vlen);
+ /* Descriptors entry */
+
+ dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY,
+ NULL, &entry);
+
+ key = "Descriptors";
+
+ dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
+
+ add_descriptors_dict(&entry, chr);
+
+ dbus_message_iter_close_container(&dict, &entry);
+
/* FIXME: Missing Format, Value and Representation */
dbus_message_iter_close_container(iter, &dict);
@@ -245,6 +360,19 @@ static int characteristic_set_value(struct characteristic *chr,
return 0;
}
+static int descriptor_set_value(struct descriptor *descr,
+ const uint8_t *value, size_t vlen)
+{
+ descr->value = g_try_realloc(descr->value, vlen);
+ if (descr->value == NULL)
+ return -ENOMEM;
+
+ memcpy(descr->value, value, vlen);
+ descr->vlen = vlen;
+
+ return 0;
+}
+
static void update_watchers(gpointer data, gpointer user_data)
{
struct watcher *w = data;
@@ -483,6 +611,172 @@ static DBusMessage *set_value(DBusConnection *conn, DBusMessage *msg,
return dbus_message_new_method_return(msg);
}
+static int descriptor_path_cmp(gconstpointer a, gconstpointer b)
+{
+ const struct descriptor *descr = a;
+ const char *path = b;
+
+ return strcmp(descr->path, path);
+}
+
+static struct descriptor *find_descriptor_by_path(struct characteristic *chr,
+ const char *path)
+{
+ GSList *ldescr;
+
+ ldescr = g_slist_find_custom(chr->descriptors, path,
+ descriptor_path_cmp);
+
+ if (ldescr)
+ return ldescr->data;
+
+ return NULL;
+}
+
+static int descriptor_handle_cmp(gconstpointer a, gconstpointer b)
+{
+ const struct descriptor *descr = a;
+ uint16_t handle = GPOINTER_TO_UINT(b);
+
+ return descr->handle - handle;
+}
+
+static struct descriptor *find_descriptor_by_handle(struct characteristic *chr,
+ guint handle)
+{
+ GSList *ldescr;
+
+ ldescr = g_slist_find_custom(chr->descriptors, GUINT_TO_POINTER(handle),
+ descriptor_handle_cmp);
+
+ if (ldescr)
+ return ldescr->data;
+
+ return NULL;
+}
+
+static DBusMessage *set_descriptor(DBusConnection *conn, DBusMessage *msg,
+ struct characteristic *chr, const char *path,
+ uint8_t *value, int len)
+{
+ struct gatt_service *gatt = chr->prim->gatt;
+ GError *gerr = NULL;
+ struct descriptor *descr;
+
+ descr = find_descriptor_by_path(chr, path);
+
+ if (!descr)
+ return btd_error_invalid_args(msg);
+
+ if (l2cap_connect(gatt, &gerr, FALSE) < 0) {
+ DBusMessage *reply = btd_error_failed(msg, gerr->message);
+ g_error_free(gerr);
+ return reply;
+ }
+
+ gatt_write_cmd(gatt->attrib, descr->handle, value, len, NULL, NULL);
+
+ descriptor_set_value(descr, value, len);
+
+ return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *set_descriptor_front(DBusConnection *conn,
+ DBusMessage *msg, DBusMessageIter *iter,
+ struct characteristic *chr)
+{
+ DBusMessageIter dict, entry;
+ DBusMessageIter descr_iter, descr_dict, descr_entry, sub;
+ int ctype;
+ const char *descriptor_path;
+ const char *key;
+ uint8_t *value;
+ int len;
+
+ if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
+ return btd_error_invalid_args(msg);
+
+ dbus_message_iter_recurse(iter, &dict);
+
+ if (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_DICT_ENTRY)
+ return btd_error_invalid_args(msg);
+
+ /* Unpack descriptor entry */
+
+ dbus_message_iter_recurse(&dict, &entry);
+ ctype = dbus_message_iter_get_arg_type(&entry);
+
+ if (ctype != DBUS_TYPE_OBJECT_PATH && ctype != DBUS_TYPE_STRING)
+ return btd_error_invalid_args(msg);
+
+ /* Got descriptor path */
+
+ dbus_message_iter_get_basic(&entry, &descriptor_path);
+
+ dbus_message_iter_next(&entry);
+
+ /* Get descriptor dict */
+
+ if (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_VARIANT)
+ dbus_message_iter_recurse(&entry, &descr_iter);
+ else
+ descr_iter = entry;
+
+ if (dbus_message_iter_get_arg_type(&descr_iter) != DBUS_TYPE_ARRAY)
+ return btd_error_invalid_args(msg);
+
+ /* Unpack descriptor dict */
+
+ dbus_message_iter_recurse(&descr_iter, &descr_dict);
+
+ while ((ctype = dbus_message_iter_get_arg_type(&descr_dict)) !=
+ DBUS_TYPE_INVALID) {
+ if (ctype != DBUS_TYPE_DICT_ENTRY)
+ return btd_error_invalid_args(msg);
+
+ /* Interpret descriptor dict's entry */
+
+ dbus_message_iter_recurse(&descr_dict, &descr_entry);
+
+ ctype = dbus_message_iter_get_arg_type(&descr_entry);
+ if (ctype != DBUS_TYPE_STRING)
+ return btd_error_invalid_args(msg);
+
+ dbus_message_iter_get_basic(&descr_entry, &key);
+
+ if (!g_str_equal(key, "Value")) {
+ dbus_message_iter_next(&descr_dict);
+ continue;
+ }
+
+ /* Key is Value, get array of bytes */
+
+ dbus_message_iter_next(&descr_entry);
+
+ ctype = dbus_message_iter_get_arg_type(&descr_entry);
+ if (ctype != DBUS_TYPE_ARRAY)
+ return btd_error_invalid_args(msg);
+
+ ctype = dbus_message_iter_get_element_type(&descr_entry);
+ if (ctype != DBUS_TYPE_BYTE)
+ return btd_error_invalid_args(msg);
+
+ dbus_message_iter_recurse(&descr_entry, &sub);
+ dbus_message_iter_get_fixed_array(&sub, &value, &len);
+
+ dbus_message_iter_next(&descr_dict);
+ }
+
+ /* Just one descriptor entry per SetProperty() call */
+
+ dbus_message_iter_next(&dict);
+
+ if (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID)
+ return btd_error_invalid_args(msg);
+
+ return set_descriptor(conn, msg, chr, descriptor_path, value, len);
+}
+
static DBusMessage *get_properties(DBusConnection *conn, DBusMessage *msg,
void *data)
{
@@ -525,6 +819,8 @@ static DBusMessage *set_property(DBusConnection *conn,
if (g_str_equal("Value", property))
return set_value(conn, msg, &sub, chr);
+ else if (g_str_equal("Descriptors", property))
+ return set_descriptor_front(conn, msg, &sub, chr);
return btd_error_invalid_args(msg);
}
@@ -737,6 +1033,26 @@ done:
g_free(current);
}
+static void update_descriptor(guint8 status, const guint8 *pdu, guint16 len,
+ gpointer user_data)
+{
+ struct query_data *current = user_data;
+ struct gatt_service *gatt = current->prim->gatt;
+ struct descriptor *descr = current->descr;
+
+ if (status != 0)
+ goto done;
+
+ if (len < 2)
+ goto done;
+
+ descriptor_set_value(descr, pdu + 1, len - 1);
+
+done:
+ g_attrib_unref(gatt->attrib);
+ g_free(current);
+}
+
static void update_char_value(guint8 status, const guint8 *pdu,
guint16 len, gpointer user_data)
{
@@ -762,6 +1078,31 @@ static void update_char_value(guint8 status, const guint8 *pdu,
g_free(current);
}
+static struct descriptor *char_add_descriptor(struct characteristic *chr,
+ uint16_t handle, uuid_t uuid)
+{
+ struct descriptor *descr;
+
+ descr = find_descriptor_by_handle(chr, handle);
+
+ if (!descr) {
+ descr = g_new0(struct descriptor, 1);
+ descr->path = g_strdup_printf("%s/descriptor%04x",
+ chr->path, handle);
+ descr->handle = handle;
+ chr->descriptors = g_slist_append(chr->descriptors, descr);
+ }
+
+ if (sdp_uuid_cmp(&uuid, &descr->uuid) != 0) {
+ char *uuidstr = bt_uuid2string(&uuid);
+ strcpy(descr->type, uuidstr);
+ g_free(uuidstr);
+ descr->uuid = uuid;
+ }
+
+ return descr;
+}
+
static int uuid_desc16_cmp(uuid_t *uuid, guint16 desc)
{
uuid_t u16;
@@ -783,7 +1124,7 @@ static void descriptor_cb(guint8 status, const guint8 *pdu, guint16 plen,
if (status != 0)
goto done;
- DBG("Find Information Response received");
+ DBG("Discover Descriptors Response received");
list = dec_find_info_resp(pdu, plen, &format);
if (list == NULL)
@@ -797,15 +1138,14 @@ static void descriptor_cb(guint8 status, const guint8 *pdu, guint16 plen,
handle = att_get_u16(info);
- if (format == 0x01) {
+ if (format == 0x01)
sdp_uuid16_create(&uuid, att_get_u16(&info[2]));
- } else {
- /* Currently, only "user description" and "presentation
- * format" descriptors are used, and both have 16-bit
- * UUIDs. Therefore there is no need to support format
- * 0x02 yet. */
+ else if (format == 0x02)
+ // FIXME use att_get_u128
+ sdp_uuid128_create(&uuid, &info[2]);
+ else
continue;
- }
+
qfmt = g_new0(struct query_data, 1);
qfmt->prim = current->prim;
qfmt->chr = current->chr;
@@ -819,8 +1159,13 @@ static void descriptor_cb(guint8 status, const guint8 *pdu, guint16 plen,
gatt->attrib = g_attrib_ref(gatt->attrib);
gatt_read_char(gatt->attrib, handle,
update_char_format, qfmt);
- } else
- g_free(qfmt);
+ } else {
+ qfmt->descr = char_add_descriptor(current->chr, handle,
+ uuid);
+ gatt->attrib = g_attrib_ref(gatt->attrib);
+ gatt_read_char(gatt->attrib, handle, update_descriptor,
+ qfmt);
+ }
}
att_data_list_free(list);
@@ -888,7 +1233,7 @@ static void char_discovered_cb(GSList *characteristics, guint8 status,
strncpy(chr->type, current_chr->uuid, sizeof(chr->type));
if (previous_end)
- *previous_end = current_chr->handle;
+ *previous_end = current_chr->handle - 1;
previous_end = &chr->end;
--
1.7.1
^ permalink raw reply related
* [PATCH 1/2 v3] Add generic descriptor support to Attribute API document
From: Elvis Pfützenreuter @ 2011-02-23 13:49 UTC (permalink / raw)
To: linux-bluetooth; +Cc: epx
This patch proposes extensions to Attribute API, giving access to all
characteristic descriptors (beyond 'Description' and 'Format').
Client Characteristic Configuration automatic update upon Watcher
registering will be handled by another patch series.
---
doc/attribute-api.txt | 30 ++++++++++++++++++++++++++++++
1 files changed, 30 insertions(+), 0 deletions(-)
diff --git a/doc/attribute-api.txt b/doc/attribute-api.txt
index 23808e6..bb7cbfa 100644
--- a/doc/attribute-api.txt
+++ b/doc/attribute-api.txt
@@ -104,6 +104,7 @@ Methods dict GetProperties()
Possible Errors: org.bluez.Error.InvalidArguments
+
Properties string UUID [readonly]
UUID128 of this characteristic.
@@ -143,6 +144,35 @@ Properties string UUID [readonly]
Friendly representation of the Characteristic Value
based on the format attribute.
+ dict Descriptors [readwrite]
+
+ Dict of descriptors for this characteristic.
+
+ This dict contains only the descriptors not already
+ covered by other properties (v.g. Description, Format).
+
+ Each descriptor is mapped to an unique object path,
+ which is the dict key.
+
+ Each dict value is, in turn, a dict with at least
+ the following keys:
+
+ {
+ "UUID": string. Descriptor UUID, always present
+ "Value": array of bytes. Raw descriptor value,
+ present only when/if descriptor value
+ has been fetched.
+ }
+
+ When updating a descriptor value using SetProperty(),
+ only one descriptor at a time may be updated in order
+ to guarantee unambiguous error reporting. In other
+ words, when calling SetProperty('Descriptors', dict),
+ dict must have exactly one entry.
+
+ Descriptor's UUID may not be updated. If present, it is
+ ignored by SetProperty().
+
Characteristic Watcher hierarchy
===============================
--
1.7.1
^ permalink raw reply related
* Re: [PATCH 2/3] Bluetooth: Move index to common header in management interface
From: Anderson Lizardo @ 2011-02-23 13:49 UTC (permalink / raw)
To: Szymon Janc
Cc: linux-bluetooth@vger.kernel.org,
par-gunnar.p.hjalmdahl@stericsson.com,
henrik.possung@stericsson.com
In-Reply-To: <201102231437.10401.szymon.janc@tieto.com>
Hi Szymon,
On Wed, Feb 23, 2011 at 10:37 AM, Szymon Janc <szymon.janc@tieto.com> wrote:
>> In general, I think all commands which used to have controller index
>> as parameters (both cp and rp), would need to be modified because
>> index is already part of the header.
>
> Actually all commands were modified, just missed to null parameters.
Just to make it clear, there are other occurrences which should be
changed to null parameters as well:
set_dev_class()
set_service_cache()
set_io_capability()
Regards,
--
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil
^ permalink raw reply
* Re: [PATCH 2/3] Bluetooth: Move index to common header in management interface
From: Szymon Janc @ 2011-02-23 13:37 UTC (permalink / raw)
To: Anderson Lizardo
Cc: linux-bluetooth@vger.kernel.org,
par-gunnar.p.hjalmdahl@stericsson.com,
henrik.possung@stericsson.com
In-Reply-To: <AANLkTin=5B6E26nzSkGad0W7FfTc+3S0_7F7ErsBLbbp@mail.gmail.com>
> > - err = cmd_complete(sk, MGMT_OP_ADD_UUID, &dev_id, sizeof(dev_id));
> > + err = cmd_complete(sk, index, MGMT_OP_ADD_UUID, &index, sizeof(index));
>
> Is index still required to be passed as return parameter, now that it
> is part of the header? This is the case for various other commands.
I've missed that, should be cmd_complete(sk, index, MGMT_OP_ADD_UUID, NULL, 0);
Will send fixed version.
> > - err = cmd_complete(sk, MGMT_OP_REMOVE_UUID, &dev_id, sizeof(dev_id));
> > + err = cmd_complete(sk, index, MGMT_OP_REMOVE_UUID, NULL, 0);
>
> Here controller index is not being passed as return parameter anymore,
> so it looks inconsistent to me.
This one is correct.
> In general, I think all commands which used to have controller index
> as parameters (both cp and rp), would need to be modified because
> index is already part of the header.
Actually all commands were modified, just missed to null parameters.
> Also be sure to update doc/mgmt-api.txt from BlueZ.
Sure.
> Regards,
>
BR
Szymon
^ permalink raw reply
* [PATCH] Drop trailing newline from DBG() calls
From: Anderson Lizardo @ 2011-02-23 13:28 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
---
audio/telephony-ofono.c | 2 +-
plugins/service.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/audio/telephony-ofono.c b/audio/telephony-ofono.c
index 0a7f0bd..b9fb0f1 100644
--- a/audio/telephony-ofono.c
+++ b/audio/telephony-ofono.c
@@ -1116,7 +1116,7 @@ static void get_modems_reply(DBusPendingCall *call, void *user_data)
DBusMessage *reply;
DBusMessageIter iter, entry;
- DBG("list_modem_reply is called\n");
+ DBG("list_modem_reply is called");
reply = dbus_pending_call_steal_reply(call);
dbus_error_init(&err);
diff --git a/plugins/service.c b/plugins/service.c
index f44aa92..4e4db81 100644
--- a/plugins/service.c
+++ b/plugins/service.c
@@ -172,13 +172,13 @@ static void element_end(GMarkupParseContext *context,
int ret = sdp_attr_add(ctx_data->record, ctx_data->attr_id,
ctx_data->stack_head->data);
if (ret == -1)
- DBG("Trouble adding attribute\n");
+ DBG("Trouble adding attribute");
ctx_data->stack_head->data = NULL;
sdp_xml_data_free(ctx_data->stack_head);
ctx_data->stack_head = NULL;
} else {
- DBG("No data for attribute 0x%04x\n", ctx_data->attr_id);
+ DBG("No data for attribute 0x%04x", ctx_data->attr_id);
}
return;
}
--
1.7.0.4
^ permalink raw reply related
* Re: [PATCH v2 3/7] Create helper functions to deal with handles on interactive gatttool
From: Sheldon Demario @ 2011-02-23 13:23 UTC (permalink / raw)
To: Sheldon Demario, linux-bluetooth; +Cc: Johan Hedberg
In-Reply-To: <20110223030903.GB16014@jh-x301>
Hi Johan
On Wed, Feb 23, 2011 at 12:09 AM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> Hi Sheldon,
>
> On Tue, Feb 22, 2011, Sheldon Demario wrote:
>> + *dst = strtoll(src, &e, 16);
>> + if (errno != 0 || *e != '\0') {
>> + return -1;
>> }
>
> Firstly, you've got a coding style issue here: no {} for one-line
> scopes. Secondly, are you sure that this is the right way to check for
> strtoll failure? If there was some earlier libc function that failed
> errno might be set to != 0 even if strtoll succeeds, right? Or are all
> errno using libc functions guaranteed to set errno to 0 on success?
> Reading the man-page of strtoll it seems you should be checking for
> LLONG_MIN and LLONG_MAX return values.
If strtoll() returns LLONG_MIN or LLONG_MAX the errno is set to ERANGE
so it is not need to check for these returning values. However, as
Lizardo said, the errno must be set to 0 before strtoll() be called,
so will send this fix.
Sheldon.
^ permalink raw reply
* Re: [PATCH 2/3] Bluetooth: Move index to common header in management interface
From: Anderson Lizardo @ 2011-02-23 13:14 UTC (permalink / raw)
To: Szymon Janc; +Cc: linux-bluetooth, par-gunnar.p.hjalmdahl, henrik.possung
In-Reply-To: <1298456785-1572-2-git-send-email-szymon.janc@tieto.com>
Hi,
On Wed, Feb 23, 2011 at 7:26 AM, Szymon Janc <szymon.janc@tieto.com> wrote:
> @@ -567,22 +558,20 @@ static int update_class(struct hci_dev *hdev)
> return hci_send_cmd(hdev, HCI_OP_WRITE_CLASS_OF_DEV, sizeof(cod), cod);
> }
>
> -static int add_uuid(struct sock *sk, unsigned char *data, u16 len)
> +static int add_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len)
> {
> struct mgmt_cp_add_uuid *cp;
> struct hci_dev *hdev;
> struct bt_uuid *uuid;
> - u16 dev_id;
> int err;
>
> cp = (void *) data;
> - dev_id = get_unaligned_le16(&cp->index);
>
> - BT_DBG("request for hci%u", dev_id);
> + BT_DBG("request for hci%u", index);
>
> - hdev = hci_dev_get(dev_id);
> + hdev = hci_dev_get(index);
> if (!hdev)
> - return cmd_status(sk, MGMT_OP_ADD_UUID, ENODEV);
> + return cmd_status(sk, index, MGMT_OP_ADD_UUID, ENODEV);
>
> hci_dev_lock_bh(hdev);
>
> @@ -601,7 +590,7 @@ static int add_uuid(struct sock *sk, unsigned char *data, u16 len)
> if (err < 0)
> goto failed;
>
> - err = cmd_complete(sk, MGMT_OP_ADD_UUID, &dev_id, sizeof(dev_id));
> + err = cmd_complete(sk, index, MGMT_OP_ADD_UUID, &index, sizeof(index));
Is index still required to be passed as return parameter, now that it
is part of the header? This is the case for various other commands.
>
> failed:
> hci_dev_unlock_bh(hdev);
> @@ -610,23 +599,21 @@ failed:
> return err;
> }
>
> -static int remove_uuid(struct sock *sk, unsigned char *data, u16 len)
> +static int remove_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len)
> {
> struct list_head *p, *n;
> struct mgmt_cp_remove_uuid *cp;
> struct hci_dev *hdev;
> u8 bt_uuid_any[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
> - u16 dev_id;
> int err, found;
>
> cp = (void *) data;
> - dev_id = get_unaligned_le16(&cp->index);
>
> - BT_DBG("request for hci%u", dev_id);
> + BT_DBG("request for hci%u", index);
>
> - hdev = hci_dev_get(dev_id);
> + hdev = hci_dev_get(index);
> if (!hdev)
> - return cmd_status(sk, MGMT_OP_REMOVE_UUID, ENODEV);
> + return cmd_status(sk, index, MGMT_OP_REMOVE_UUID, ENODEV);
>
> hci_dev_lock_bh(hdev);
>
> @@ -648,7 +635,7 @@ static int remove_uuid(struct sock *sk, unsigned char *data, u16 len)
> }
>
> if (found == 0) {
> - err = cmd_status(sk, MGMT_OP_REMOVE_UUID, ENOENT);
> + err = cmd_status(sk, index, MGMT_OP_REMOVE_UUID, ENOENT);
> goto unlock;
> }
>
> @@ -656,7 +643,7 @@ static int remove_uuid(struct sock *sk, unsigned char *data, u16 len)
> if (err < 0)
> goto unlock;
>
> - err = cmd_complete(sk, MGMT_OP_REMOVE_UUID, &dev_id, sizeof(dev_id));
> + err = cmd_complete(sk, index, MGMT_OP_REMOVE_UUID, NULL, 0);
Here controller index is not being passed as return parameter anymore,
so it looks inconsistent to me.
>
> unlock:
> hci_dev_unlock_bh(hdev);
> @@ -665,21 +652,20 @@ unlock:
In general, I think all commands which used to have controller index
as parameters (both cp and rp), would need to be modified because
index is already part of the header.
Also be sure to update doc/mgmt-api.txt from BlueZ.
Regards,
--
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil
^ permalink raw reply
* [PATCH] Add GStreamer version check in acinclude.m4
From: Szymon Janc @ 2011-02-23 13:13 UTC (permalink / raw)
To: linux-bluetooth; +Cc: par-gunnar.p.hjalmdahl, henrik.possung, Szymon Janc
Since commit cc04c6a2f7500f3d29d56634e645130ff3bd80fb compilation fails with
GStreamer 0.10.28 or older.
---
acinclude.m4 | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/acinclude.m4 b/acinclude.m4
index 91e0956..6aaa885 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -115,7 +115,8 @@ AC_DEFUN([AC_PATH_GLIB], [
])
AC_DEFUN([AC_PATH_GSTREAMER], [
- PKG_CHECK_MODULES(GSTREAMER, gstreamer-0.10 gstreamer-plugins-base-0.10, gstreamer_found=yes, gstreamer_found=no)
+ PKG_CHECK_MODULES(GSTREAMER, gstreamer-0.10 >= 0.10.30 gstreamer-plugins-base-0.10, gstreamer_found=yes,
+ AC_MSG_WARN(GStreamer library version 0.10.30 or later is required);gstreamer_found=no)
AC_SUBST(GSTREAMER_CFLAGS)
AC_SUBST(GSTREAMER_LIBS)
GSTREAMER_PLUGINSDIR=`$PKG_CONFIG --variable=pluginsdir gstreamer-0.10`
--
1.7.0.4
on behalf of ST-Ericsson
^ permalink raw reply related
* Re: [PATCH 1/4] HCI command to add device in LE White List
From: Claudio Takahasi @ 2011-02-23 12:44 UTC (permalink / raw)
To: Arun Kumar SINGH; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <AFCDDB4A3EA003429EEF1E7B211FDBBA334C047D5A@EXDCVYMBSTM005.EQ1STM.local>
Hi Arun,
patch doesn't not apply. Please rebase and send the patch series again.
On Wed, Feb 23, 2011 at 7:07 AM, Arun Kumar SINGH
<arunkr.singh@stericsson.com> wrote:
> From fd4e7d6f3b9b33c7b75f7da5600c6fc0fb947b06 Mon Sep 17 00:00:00 2001
> From: ArunKumarSingh <arunkr.singh@stericsson.com>
> Date: Wed, 23 Feb 2011 11:24:58 +0530
> Subject: [PATCH] Commands to add device to White-list
>
> ---
> lib/hci.c | 29 +++++++++++++++++++++++++++++
> lib/hci.h | 5 +++++
> lib/hci_lib.h | 1 +
> tools/hcitool.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 82 insertions(+), 0 deletions(-)
> mode change 100644 => 100755 lib/hci.c
> mode change 100644 => 100755 lib/hci.h
> mode change 100644 => 100755 lib/hci_lib.h
> mode change 100644 => 100755 tools/hcitool.c
>
> diff --git a/lib/hci.c b/lib/hci.c
> old mode 100644
> new mode 100755
> index 048fda4..a85f193
> --- a/lib/hci.c
> +++ b/lib/hci.c
> @@ -1291,6 +1291,35 @@ int hci_disconnect(int dd, uint16_t handle, uint8_t reason, int to)
> return 0;
> }
>
> +int hci_le_add_to_white_list(int dd, const bdaddr_t *bdaddr, uint8_t type)
use the enum that you added instead of uint8_t
> +{
> + struct hci_request rq;
> + le_add_device_to_white_list_cp cp;
> + uint8_t status;
> +
> + memset(&cp, 0, sizeof(cp));
> + cp.bdaddr_type = type;
> + bacpy(&cp.bdaddr, bdaddr);
> +
> + memset(&rq, 0, sizeof(rq));
> + rq.ogf = OGF_LE_CTL;
> + rq.ocf = OCF_LE_ADD_DEVICE_TO_WHITE_LIST;
> + rq.cparam = &cp;
> + rq.clen = LE_ADD_DEVICE_TO_WHITE_LIST_CP_SIZE;
> + rq.rparam = &status;
> + rq.rlen = 1;
> +
> + if (hci_send_req(dd, &rq, 1000) < 0)
> + return -1;
Pass the timeout as parameter to this function to follow the same
standard of the other hci_* functions
> +
> + if (status) {
> + errno = EIO;
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> int hci_read_local_name(int dd, int len, char *name, int to)
> {
> read_local_name_rp rp;
> diff --git a/lib/hci.h b/lib/hci.h
> old mode 100644
> new mode 100755
> index 9b5388b..06d0b35
> --- a/lib/hci.h
> +++ b/lib/hci.h
> @@ -1523,6 +1523,11 @@ typedef struct {
>
> #define OCF_LE_CREATE_CONN_CANCEL 0x000E
>
> +typedef enum {
> + LE_PUBLIC_DEVICE_ADDR = 0x00,
> + LE_RANDOM_DEVICE_ADDR = 0x01,
> +}le_device_addr_type;
In BlueZ we use "device" to refer to remote devices and "adapter" to
represent the local adapter. If the same constant will be used in
other hci commands related to the local adapter you could simply call
it le_address_type. One example is cmd_lecc() which uses a hardcode
value to "own address type".
BR,
Claudio
> +
> #define OCF_LE_READ_WHITE_LIST_SIZE 0x000F
> typedef struct {
> uint8_t status;
> diff --git a/lib/hci_lib.h b/lib/hci_lib.h
> old mode 100644
> new mode 100755
> index b63a2a4..7127d70
> --- a/lib/hci_lib.h
> +++ b/lib/hci_lib.h
> @@ -127,6 +127,7 @@ int hci_le_create_conn(int dd, uint16_t interval, uint16_t window,
> uint16_t latency, uint16_t supervision_timeout,
> uint16_t min_ce_length, uint16_t max_ce_length,
> uint16_t *handle, int to);
> +int hci_le_add_to_white_list(int dd, const bdaddr_t *bdaddr, uint8_t type);
>
> int hci_for_each_dev(int flag, int(*func)(int dd, int dev_id, long arg), long arg);
> int hci_get_route(bdaddr_t *bdaddr);
> diff --git a/tools/hcitool.c b/tools/hcitool.c
> old mode 100644
> new mode 100755
> index d7a82cc..b5109b8
> --- a/tools/hcitool.c
> +++ b/tools/hcitool.c
> @@ -2487,6 +2487,52 @@ static void cmd_lecc(int dev_id, int argc, char **argv)
> hci_close_dev(dd);
> }
>
> +static struct option leaddwl_options[] = {
> + { "help", 0, 0, 'h' },
> + { 0, 0, 0, 0 }
> +};
> +
> +static const char *leaddwl_help =
> + "Usage:\n"
> + "\tleaddwl\n";
> +
> +static void cmd_leaddwl(int dev_id, int argc, char **argv)
> +{
> + int err, opt, dd;
> + bdaddr_t bdaddr;
> + le_device_addr_type bdaddr_type;
> +
> + for_each_opt(opt, leaddwl_options, NULL) {
> + switch (opt) {
> + default:
> + printf("%s", leaddwl_help);
> + return;
> + }
> + }
> +
> + helper_arg(1, 1, &argc, &argv, leaddwl_help);
> +
> + if (dev_id < 0)
> + dev_id = hci_get_route(NULL);
> +
> + dd = hci_open_dev(dev_id);
> + if (dd < 0) {
> + perror("Could not open device");
> + exit(1);
> + }
> +
> + str2ba(argv[0], &bdaddr);
> + bdaddr_type = LE_PUBLIC_DEVICE_ADDR;
> +
> + err = hci_le_add_to_white_list(dd, &bdaddr, bdaddr_type);
> + hci_close_dev(dd);
> +
> + if (err < 0) {
> + perror("Cant add to white list");
> + exit(1);
> + }
> +}
> +
> static struct option ledc_options[] = {
> { "help", 0, 0, 'h' },
> { 0, 0, 0, 0 }
> @@ -2563,6 +2609,7 @@ static struct {
> { "clkoff", cmd_clkoff, "Read clock offset" },
> { "clock", cmd_clock, "Read local or remote clock" },
> { "lescan", cmd_lescan, "Start LE scan" },
> + { "leaddwl", cmd_leaddwl, "Add this device to white list" },
> { "lecc", cmd_lecc, "Create a LE Connection", },
> { "ledc", cmd_ledc, "Disconnect a LE Connection", },
> { NULL, NULL, 0 }
> --
> 1.7.0.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* [PATCH] Fix typo on DBG() string format
From: Anderson Lizardo @ 2011-02-23 12:27 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
---
attrib/client.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/attrib/client.c b/attrib/client.c
index 0f9ba3e..4635c75 100644
--- a/attrib/client.c
+++ b/attrib/client.c
@@ -299,7 +299,7 @@ static void events_handler(const uint8_t *pdu, uint16_t len,
NULL, NULL, NULL);
case ATT_OP_HANDLE_NOTIFY:
if (characteristic_set_value(chr, &pdu[3], len - 3) < 0)
- DBG("Can't change Characteristic %0x02x", handle);
+ DBG("Can't change Characteristic 0x%02x", handle);
g_slist_foreach(prim->watchers, update_watchers, chr);
break;
--
1.7.0.4
^ permalink raw reply related
* Re: [PATCH v2 3/7] Create helper functions to deal with handles on interactive gatttool
From: Anderson Lizardo @ 2011-02-23 12:21 UTC (permalink / raw)
To: Sheldon Demario, linux-bluetooth; +Cc: Johan Hedberg
In-Reply-To: <20110223030903.GB16014@jh-x301>
Hi Johan,
On Wed, Feb 23, 2011 at 12:09 AM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> Hi Sheldon,
>
> On Tue, Feb 22, 2011, Sheldon Demario wrote:
>> + *dst = strtoll(src, &e, 16);
>> + if (errno != 0 || *e != '\0') {
>> + return -1;
>> }
>
> Firstly, you've got a coding style issue here: no {} for one-line
> scopes. Secondly, are you sure that this is the right way to check for
> strtoll failure? If there was some earlier libc function that failed
> errno might be set to != 0 even if strtoll succeeds, right? Or are all
> errno using libc functions guaranteed to set errno to 0 on success?
> Reading the man-page of strtoll it seems you should be checking for
> LLONG_MIN and LLONG_MAX return values.
Looking at "man errno", it is not guaranteed for errno to be set to
zero on success, therefore the recommended way is to set it to zero
prior to calling the function to be checked.
The NOTES section from "man strtoll" recommends using errno when
checking for errors:
"Since strtol() can legitimately return 0, LONG_MAX, or LONG_MIN
(LLONG_MAX or LLONG_MIN for strtoll()) on both success and failure,
the calling program should set errno to 0 before the call, and then
determine if an error occurred by checking whether errno has a
non-zero value after the call."
So I think the only missing bit here it to set errno to zero prior to
calling strtoll()
Regards,
--
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil
^ permalink raw reply
* [PATCH v2] Check malformed notification/indication PDU
From: Elvis Pfützenreuter @ 2011-02-23 12:16 UTC (permalink / raw)
To: linux-bluetooth; +Cc: epx
This patch implements discard of obviously malformed
GATT notification/indication PDUs.
---
attrib/client.c | 10 +++++++++-
1 files changed, 9 insertions(+), 1 deletions(-)
diff --git a/attrib/client.c b/attrib/client.c
index 0f9ba3e..2a5436b 100644
--- a/attrib/client.c
+++ b/attrib/client.c
@@ -272,9 +272,17 @@ static void events_handler(const uint8_t *pdu, uint16_t len,
struct primary *prim;
GSList *lprim, *lchr;
uint8_t opdu[ATT_MAX_MTU];
- guint handle = att_get_u16(&pdu[1]);
+ guint handle;
uint16_t olen;
+ if (len < 3) {
+ DBG("Malformed notification/indication packet (opcode 0x%02x)",
+ pdu[0]);
+ return;
+ }
+
+ handle = att_get_u16(&pdu[1]);
+
for (lprim = gatt->primary, prim = NULL, chr = NULL; lprim;
lprim = lprim->next) {
prim = lprim->data;
--
1.7.1
^ permalink raw reply related
* Re: [PATCH] Check malformed notification/indication PDU
From: Anderson Lizardo @ 2011-02-23 12:09 UTC (permalink / raw)
To: Elvis Pfützenreuter; +Cc: linux-bluetooth
In-Reply-To: <1298462180-17737-1-git-send-email-epx@signove.com>
Hi Elvis,
On Wed, Feb 23, 2011 at 8:56 AM, Elvis Pfützenreuter <epx@signove.com> wrote:
> This patch implements discard of obviously malformed
> GATT notification/indication PDUs.
> ---
> attrib/client.c | 9 ++++++++-
> 1 files changed, 8 insertions(+), 1 deletions(-)
>
> diff --git a/attrib/client.c b/attrib/client.c
> index 0f9ba3e..dc7ee8b 100644
> --- a/attrib/client.c
> +++ b/attrib/client.c
> @@ -272,9 +272,16 @@ static void events_handler(const uint8_t *pdu, uint16_t len,
> struct primary *prim;
> GSList *lprim, *lchr;
> uint8_t opdu[ATT_MAX_MTU];
> - guint handle = att_get_u16(&pdu[1]);
> + guint handle;
> uint16_t olen;
>
> + if (len < 3) {
> + DBG("Malformed notif/indic packet (opcode %x)", pdu[0]);
> + return;
> + }
> +
> + handle = att_get_u16(&pdu[1]);
> +
Patch looks fine, I'd only like to suggest using
"notification/indication" instead of abbreviations, and "0x%02x" for
the opcode format.
Regards,
--
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil
^ permalink raw reply
* [PATCH] Check malformed notification/indication PDU
From: Elvis Pfützenreuter @ 2011-02-23 11:56 UTC (permalink / raw)
To: linux-bluetooth; +Cc: epx
This patch implements discard of obviously malformed
GATT notification/indication PDUs.
---
attrib/client.c | 9 ++++++++-
1 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/attrib/client.c b/attrib/client.c
index 0f9ba3e..dc7ee8b 100644
--- a/attrib/client.c
+++ b/attrib/client.c
@@ -272,9 +272,16 @@ static void events_handler(const uint8_t *pdu, uint16_t len,
struct primary *prim;
GSList *lprim, *lchr;
uint8_t opdu[ATT_MAX_MTU];
- guint handle = att_get_u16(&pdu[1]);
+ guint handle;
uint16_t olen;
+ if (len < 3) {
+ DBG("Malformed notif/indic packet (opcode %x)", pdu[0]);
+ return;
+ }
+
+ handle = att_get_u16(&pdu[1]);
+
for (lprim = gatt->primary, prim = NULL, chr = NULL; lprim;
lprim = lprim->next) {
prim = lprim->data;
--
1.7.1
^ permalink raw reply related
* [PATCH 3/3] Bluetooth: Validate data size before accessing mgmt commands
From: Szymon Janc @ 2011-02-23 10:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: par-gunnar.p.hjalmdahl, henrik.possung, Szymon Janc
In-Reply-To: <1298456785-1572-1-git-send-email-szymon.janc@tieto.com>
Crafted (too small) data buffer could result in reading data outside of buffer.
Validate buffer size and return EINVAL if size is wrong..
Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
---
net/bluetooth/mgmt.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 53 insertions(+), 0 deletions(-)
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 3639dfb..621d5b2 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -302,6 +302,9 @@ static int set_powered(struct sock *sk, u16 index, unsigned char *data, u16 len)
BT_DBG("request for hci%u", index);
+ if (len != sizeof(*cp))
+ return cmd_status(sk, index, MGMT_OP_SET_POWERED, EINVAL);
+
hdev = hci_dev_get(index);
if (!hdev)
return cmd_status(sk, index, MGMT_OP_SET_POWERED, ENODEV);
@@ -351,6 +354,9 @@ static int set_discoverable(struct sock *sk, u16 index, unsigned char *data,
BT_DBG("request for hci%u", index);
+ if (len != sizeof(*cp))
+ return cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, EINVAL);
+
hdev = hci_dev_get(index);
if (!hdev)
return cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, ENODEV);
@@ -409,6 +415,9 @@ static int set_connectable(struct sock *sk, u16 index, unsigned char *data,
BT_DBG("request for hci%u", index);
+ if (len != sizeof(*cp))
+ return cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, EINVAL);
+
hdev = hci_dev_get(index);
if (!hdev)
return cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, ENODEV);
@@ -499,6 +508,9 @@ static int set_pairable(struct sock *sk, u16 index, unsigned char *data,
BT_DBG("request for hci%u", index);
+ if (len != sizeof(*cp))
+ return cmd_status(sk, index, MGMT_OP_SET_PAIRABLE, EINVAL);
+
hdev = hci_dev_get(index);
if (!hdev)
return cmd_status(sk, index, MGMT_OP_SET_PAIRABLE, ENODEV);
@@ -569,6 +581,9 @@ static int add_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len)
BT_DBG("request for hci%u", index);
+ if (len != sizeof(*cp))
+ return cmd_status(sk, index, MGMT_OP_ADD_UUID, EINVAL);
+
hdev = hci_dev_get(index);
if (!hdev)
return cmd_status(sk, index, MGMT_OP_ADD_UUID, ENODEV);
@@ -611,6 +626,9 @@ static int remove_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len)
BT_DBG("request for hci%u", index);
+ if (len != sizeof(*cp))
+ return cmd_status(sk, index, MGMT_OP_REMOVE_UUID, EINVAL);
+
hdev = hci_dev_get(index);
if (!hdev)
return cmd_status(sk, index, MGMT_OP_REMOVE_UUID, ENODEV);
@@ -663,6 +681,9 @@ static int set_dev_class(struct sock *sk, u16 index, unsigned char *data,
BT_DBG("request for hci%u", index);
+ if (len != sizeof(*cp))
+ return cmd_status(sk, index, MGMT_OP_SET_DEV_CLASS, EINVAL);
+
hdev = hci_dev_get(index);
if (!hdev)
return cmd_status(sk, index, MGMT_OP_SET_DEV_CLASS, ENODEV);
@@ -693,6 +714,10 @@ static int set_service_cache(struct sock *sk, u16 index, unsigned char *data,
cp = (void *) data;
+ if (len != sizeof(*cp))
+ return cmd_status(sk, index, MGMT_OP_SET_SERVICE_CACHE,
+ EINVAL);
+
hdev = hci_dev_get(index);
if (!hdev)
return cmd_status(sk, index, MGMT_OP_SET_SERVICE_CACHE, ENODEV);
@@ -727,6 +752,10 @@ static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len)
int i;
cp = (void *) data;
+
+ if (len < sizeof(*cp))
+ return -EINVAL;
+
key_count = get_unaligned_le16(&cp->key_count);
expected_len = sizeof(*cp) + key_count * sizeof(struct mgmt_key_info);
@@ -776,6 +805,9 @@ static int remove_key(struct sock *sk, u16 index, unsigned char *data, u16 len)
cp = (void *) data;
+ if (len != sizeof(*cp))
+ return cmd_status(sk, index, MGMT_OP_REMOVE_KEY, EINVAL);
+
hdev = hci_dev_get(index);
if (!hdev)
return cmd_status(sk, index, MGMT_OP_REMOVE_KEY, ENODEV);
@@ -822,6 +854,9 @@ static int disconnect(struct sock *sk, u16 index, unsigned char *data, u16 len)
cp = (void *) data;
+ if (len != sizeof(*cp))
+ return cmd_status(sk, index, MGMT_OP_DISCONNECT, EINVAL);
+
hdev = hci_dev_get(index);
if (!hdev)
return cmd_status(sk, index, MGMT_OP_DISCONNECT, ENODEV);
@@ -932,6 +967,9 @@ static int pin_code_reply(struct sock *sk, u16 index, unsigned char *data,
cp = (void *) data;
+ if (len != sizeof(*cp))
+ return cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, EINVAL);
+
hdev = hci_dev_get(index);
if (!hdev)
return cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, ENODEV);
@@ -976,6 +1014,10 @@ static int pin_code_neg_reply(struct sock *sk, u16 index, unsigned char *data,
cp = (void *) data;
+ if (len != sizeof(*cp))
+ return cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY,
+ EINVAL);
+
hdev = hci_dev_get(index);
if (!hdev)
return cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY,
@@ -1018,6 +1060,10 @@ static int set_io_capability(struct sock *sk, u16 index, unsigned char *data,
cp = (void *) data;
+ if (len != sizeof(*cp))
+ return cmd_status(sk, index, MGMT_OP_SET_IO_CAPABILITY,
+ EINVAL);
+
hdev = hci_dev_get(index);
if (!hdev)
return cmd_status(sk, index, MGMT_OP_SET_IO_CAPABILITY, ENODEV);
@@ -1109,6 +1155,9 @@ static int pair_device(struct sock *sk, u16 index, unsigned char *data, u16 len)
cp = (void *) data;
+ if (len != sizeof(*cp))
+ return cmd_status(sk, index, MGMT_OP_PAIR_DEVICE, EINVAL);
+
hdev = hci_dev_get(index);
if (!hdev)
return cmd_status(sk, index, MGMT_OP_PAIR_DEVICE, ENODEV);
@@ -1172,6 +1221,10 @@ static int user_confirm_reply(struct sock *sk, u16 index, unsigned char *data,
BT_DBG("");
+ if (len != sizeof(*cp))
+ return cmd_status(sk, index, MGMT_OP_USER_CONFIRM_REPLY,
+ EINVAL);
+
if (success) {
mgmt_op = MGMT_OP_USER_CONFIRM_REPLY;
hci_op = HCI_OP_USER_CONFIRM_REPLY;
--
1.7.0.4
^ permalink raw reply related
* [PATCH 2/3] Bluetooth: Move index to common header in management interface
From: Szymon Janc @ 2011-02-23 10:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: par-gunnar.p.hjalmdahl, henrik.possung, Szymon Janc
In-Reply-To: <1298456785-1572-1-git-send-email-szymon.janc@tieto.com>
Most mgmt commands and event are related to hci adapter. Moving index to
common header allow to easily use it in command status while reporting errors.
For those not related to adapter use MGMT_INDEX_NONE (0xFFFF) as index.
Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
---
include/net/bluetooth/mgmt.h | 43 +----
net/bluetooth/mgmt.c | 407 +++++++++++++++++++-----------------------
2 files changed, 184 insertions(+), 266 deletions(-)
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 1e63c31..5fabfa8 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -21,11 +21,13 @@
SOFTWARE IS DISCLAIMED.
*/
+#define MGMT_INDEX_NONE 0xFFFF
+
struct mgmt_hdr {
__le16 opcode;
+ __le16 index;
__le16 len;
} __packed;
-#define MGMT_HDR_SIZE 4
#define MGMT_OP_READ_VERSION 0x0001
struct mgmt_rp_read_version {
@@ -40,11 +42,7 @@ struct mgmt_rp_read_index_list {
} __packed;
#define MGMT_OP_READ_INFO 0x0004
-struct mgmt_cp_read_info {
- __le16 index;
-} __packed;
struct mgmt_rp_read_info {
- __le16 index;
__u8 type;
__u8 powered;
__u8 connectable;
@@ -60,7 +58,6 @@ struct mgmt_rp_read_info {
} __packed;
struct mgmt_mode {
- __le16 index;
__u8 val;
} __packed;
@@ -74,27 +71,23 @@ struct mgmt_mode {
#define MGMT_OP_ADD_UUID 0x0009
struct mgmt_cp_add_uuid {
- __le16 index;
__u8 uuid[16];
__u8 svc_hint;
} __packed;
#define MGMT_OP_REMOVE_UUID 0x000A
struct mgmt_cp_remove_uuid {
- __le16 index;
__u8 uuid[16];
} __packed;
#define MGMT_OP_SET_DEV_CLASS 0x000B
struct mgmt_cp_set_dev_class {
- __le16 index;
__u8 major;
__u8 minor;
} __packed;
#define MGMT_OP_SET_SERVICE_CACHE 0x000C
struct mgmt_cp_set_service_cache {
- __le16 index;
__u8 enable;
} __packed;
@@ -107,7 +100,6 @@ struct mgmt_key_info {
#define MGMT_OP_LOAD_KEYS 0x000D
struct mgmt_cp_load_keys {
- __le16 index;
__u8 debug_keys;
__le16 key_count;
struct mgmt_key_info keys[0];
@@ -115,75 +107,60 @@ struct mgmt_cp_load_keys {
#define MGMT_OP_REMOVE_KEY 0x000E
struct mgmt_cp_remove_key {
- __le16 index;
bdaddr_t bdaddr;
__u8 disconnect;
} __packed;
#define MGMT_OP_DISCONNECT 0x000F
struct mgmt_cp_disconnect {
- __le16 index;
bdaddr_t bdaddr;
} __packed;
struct mgmt_rp_disconnect {
- __le16 index;
bdaddr_t bdaddr;
} __packed;
#define MGMT_OP_GET_CONNECTIONS 0x0010
-struct mgmt_cp_get_connections {
- __le16 index;
-} __packed;
struct mgmt_rp_get_connections {
- __le16 index;
__le16 conn_count;
bdaddr_t conn[0];
} __packed;
#define MGMT_OP_PIN_CODE_REPLY 0x0011
struct mgmt_cp_pin_code_reply {
- __le16 index;
bdaddr_t bdaddr;
__u8 pin_len;
__u8 pin_code[16];
} __packed;
struct mgmt_rp_pin_code_reply {
- __le16 index;
bdaddr_t bdaddr;
uint8_t status;
} __packed;
#define MGMT_OP_PIN_CODE_NEG_REPLY 0x0012
struct mgmt_cp_pin_code_neg_reply {
- __le16 index;
bdaddr_t bdaddr;
} __packed;
#define MGMT_OP_SET_IO_CAPABILITY 0x0013
struct mgmt_cp_set_io_capability {
- __le16 index;
__u8 io_capability;
} __packed;
#define MGMT_OP_PAIR_DEVICE 0x0014
struct mgmt_cp_pair_device {
- __le16 index;
bdaddr_t bdaddr;
__u8 io_cap;
} __packed;
struct mgmt_rp_pair_device {
- __le16 index;
bdaddr_t bdaddr;
__u8 status;
} __packed;
#define MGMT_OP_USER_CONFIRM_REPLY 0x0015
struct mgmt_cp_user_confirm_reply {
- __le16 index;
bdaddr_t bdaddr;
} __packed;
struct mgmt_rp_user_confirm_reply {
- __le16 index;
bdaddr_t bdaddr;
__u8 status;
} __packed;
@@ -204,19 +181,12 @@ struct mgmt_ev_cmd_status {
#define MGMT_EV_CONTROLLER_ERROR 0x0003
struct mgmt_ev_controller_error {
- __le16 index;
__u8 error_code;
} __packed;
#define MGMT_EV_INDEX_ADDED 0x0004
-struct mgmt_ev_index_added {
- __le16 index;
-} __packed;
#define MGMT_EV_INDEX_REMOVED 0x0005
-struct mgmt_ev_index_removed {
- __le16 index;
-} __packed;
#define MGMT_EV_POWERED 0x0006
@@ -228,46 +198,39 @@ struct mgmt_ev_index_removed {
#define MGMT_EV_NEW_KEY 0x000A
struct mgmt_ev_new_key {
- __le16 index;
struct mgmt_key_info key;
__u8 old_key_type;
} __packed;
#define MGMT_EV_CONNECTED 0x000B
struct mgmt_ev_connected {
- __le16 index;
bdaddr_t bdaddr;
} __packed;
#define MGMT_EV_DISCONNECTED 0x000C
struct mgmt_ev_disconnected {
- __le16 index;
bdaddr_t bdaddr;
} __packed;
#define MGMT_EV_CONNECT_FAILED 0x000D
struct mgmt_ev_connect_failed {
- __le16 index;
bdaddr_t bdaddr;
__u8 status;
} __packed;
#define MGMT_EV_PIN_CODE_REQUEST 0x000E
struct mgmt_ev_pin_code_request {
- __le16 index;
bdaddr_t bdaddr;
} __packed;
#define MGMT_EV_USER_CONFIRM_REQUEST 0x000F
struct mgmt_ev_user_confirm_request {
- __le16 index;
bdaddr_t bdaddr;
__le32 value;
} __packed;
#define MGMT_EV_AUTH_FAILED 0x0010
struct mgmt_ev_auth_failed {
- __le16 index;
bdaddr_t bdaddr;
__u8 status;
} __packed;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 4543ede..3639dfb 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -43,7 +43,7 @@ struct pending_cmd {
LIST_HEAD(cmd_list);
-static int cmd_status(struct sock *sk, u16 cmd, u8 status)
+static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status)
{
struct sk_buff *skb;
struct mgmt_hdr *hdr;
@@ -58,6 +58,7 @@ static int cmd_status(struct sock *sk, u16 cmd, u8 status)
hdr = (void *) skb_put(skb, sizeof(*hdr));
hdr->opcode = cpu_to_le16(MGMT_EV_CMD_STATUS);
+ hdr->index = cpu_to_le16(index);
hdr->len = cpu_to_le16(sizeof(*ev));
ev = (void *) skb_put(skb, sizeof(*ev));
@@ -70,7 +71,8 @@ static int cmd_status(struct sock *sk, u16 cmd, u8 status)
return 0;
}
-static int cmd_complete(struct sock *sk, u16 cmd, void *rp, size_t rp_len)
+static int cmd_complete(struct sock *sk, u16 index, u16 cmd, void *rp,
+ size_t rp_len)
{
struct sk_buff *skb;
struct mgmt_hdr *hdr;
@@ -85,6 +87,7 @@ static int cmd_complete(struct sock *sk, u16 cmd, void *rp, size_t rp_len)
hdr = (void *) skb_put(skb, sizeof(*hdr));
hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE);
+ hdr->index = cpu_to_le16(index);
hdr->len = cpu_to_le16(sizeof(*ev) + rp_len);
ev = (void *) skb_put(skb, sizeof(*ev) + rp_len);
@@ -106,7 +109,8 @@ static int read_version(struct sock *sk)
rp.version = MGMT_VERSION;
put_unaligned_le16(MGMT_REVISION, &rp.revision);
- return cmd_complete(sk, MGMT_OP_READ_VERSION, &rp, sizeof(rp));
+ return cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_VERSION, &rp,
+ sizeof(rp));
}
static int read_index_list(struct sock *sk)
@@ -152,32 +156,24 @@ static int read_index_list(struct sock *sk)
read_unlock(&hci_dev_list_lock);
- err = cmd_complete(sk, MGMT_OP_READ_INDEX_LIST, rp, rp_len);
+ err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_INDEX_LIST, rp,
+ rp_len);
kfree(rp);
return err;
}
-static int read_controller_info(struct sock *sk, unsigned char *data, u16 len)
+static int read_controller_info(struct sock *sk, u16 index)
{
struct mgmt_rp_read_info rp;
- struct mgmt_cp_read_info *cp = (void *) data;
struct hci_dev *hdev;
- u16 dev_id;
- BT_DBG("sock %p", sk);
-
- if (len != 2)
- return cmd_status(sk, MGMT_OP_READ_INFO, EINVAL);
-
- dev_id = get_unaligned_le16(&cp->index);
+ BT_DBG("sock %p hci%u", sk, index);
- BT_DBG("request for hci%u", dev_id);
-
- hdev = hci_dev_get(dev_id);
+ hdev = hci_dev_get(index);
if (!hdev)
- return cmd_status(sk, MGMT_OP_READ_INFO, ENODEV);
+ return cmd_status(sk, index, MGMT_OP_READ_INFO, ENODEV);
hci_del_off_timer(hdev);
@@ -185,7 +181,6 @@ static int read_controller_info(struct sock *sk, unsigned char *data, u16 len)
set_bit(HCI_MGMT, &hdev->flags);
- put_unaligned_le16(hdev->id, &rp.index);
rp.type = hdev->dev_type;
rp.powered = test_bit(HCI_UP, &hdev->flags);
@@ -210,7 +205,7 @@ static int read_controller_info(struct sock *sk, unsigned char *data, u16 len)
hci_dev_unlock_bh(hdev);
hci_dev_put(hdev);
- return cmd_complete(sk, MGMT_OP_READ_INFO, &rp, sizeof(rp));
+ return cmd_complete(sk, index, MGMT_OP_READ_INFO, &rp, sizeof(rp));
}
static void mgmt_pending_free(struct pending_cmd *cmd)
@@ -296,37 +291,35 @@ static void mgmt_pending_remove(struct pending_cmd *cmd)
mgmt_pending_free(cmd);
}
-static int set_powered(struct sock *sk, unsigned char *data, u16 len)
+static int set_powered(struct sock *sk, u16 index, unsigned char *data, u16 len)
{
struct mgmt_mode *cp;
struct hci_dev *hdev;
struct pending_cmd *cmd;
- u16 dev_id;
int err, up;
cp = (void *) data;
- dev_id = get_unaligned_le16(&cp->index);
- BT_DBG("request for hci%u", dev_id);
+ BT_DBG("request for hci%u", index);
- hdev = hci_dev_get(dev_id);
+ hdev = hci_dev_get(index);
if (!hdev)
- return cmd_status(sk, MGMT_OP_SET_POWERED, ENODEV);
+ return cmd_status(sk, index, MGMT_OP_SET_POWERED, ENODEV);
hci_dev_lock_bh(hdev);
up = test_bit(HCI_UP, &hdev->flags);
if ((cp->val && up) || (!cp->val && !up)) {
- err = cmd_status(sk, MGMT_OP_SET_POWERED, EALREADY);
+ err = cmd_status(sk, index, MGMT_OP_SET_POWERED, EALREADY);
goto failed;
}
- if (mgmt_pending_find(MGMT_OP_SET_POWERED, dev_id)) {
- err = cmd_status(sk, MGMT_OP_SET_POWERED, EBUSY);
+ if (mgmt_pending_find(MGMT_OP_SET_POWERED, index)) {
+ err = cmd_status(sk, index, MGMT_OP_SET_POWERED, EBUSY);
goto failed;
}
- cmd = mgmt_pending_add(sk, MGMT_OP_SET_POWERED, dev_id, data, len);
+ cmd = mgmt_pending_add(sk, MGMT_OP_SET_POWERED, index, data, len);
if (!cmd) {
err = -ENOMEM;
goto failed;
@@ -345,44 +338,43 @@ failed:
return err;
}
-static int set_discoverable(struct sock *sk, unsigned char *data, u16 len)
+static int set_discoverable(struct sock *sk, u16 index, unsigned char *data,
+ u16 len)
{
struct mgmt_mode *cp;
struct hci_dev *hdev;
struct pending_cmd *cmd;
- u16 dev_id;
u8 scan;
int err;
cp = (void *) data;
- dev_id = get_unaligned_le16(&cp->index);
- BT_DBG("request for hci%u", dev_id);
+ BT_DBG("request for hci%u", index);
- hdev = hci_dev_get(dev_id);
+ hdev = hci_dev_get(index);
if (!hdev)
- return cmd_status(sk, MGMT_OP_SET_DISCOVERABLE, ENODEV);
+ return cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, ENODEV);
hci_dev_lock_bh(hdev);
if (!test_bit(HCI_UP, &hdev->flags)) {
- err = cmd_status(sk, MGMT_OP_SET_DISCOVERABLE, ENETDOWN);
+ err = cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, ENETDOWN);
goto failed;
}
- if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, dev_id) ||
- mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, dev_id)) {
- err = cmd_status(sk, MGMT_OP_SET_DISCOVERABLE, EBUSY);
+ if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, index) ||
+ mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, index)) {
+ err = cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, EBUSY);
goto failed;
}
if (cp->val == test_bit(HCI_ISCAN, &hdev->flags) &&
test_bit(HCI_PSCAN, &hdev->flags)) {
- err = cmd_status(sk, MGMT_OP_SET_DISCOVERABLE, EALREADY);
+ err = cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, EALREADY);
goto failed;
}
- cmd = mgmt_pending_add(sk, MGMT_OP_SET_DISCOVERABLE, dev_id, data, len);
+ cmd = mgmt_pending_add(sk, MGMT_OP_SET_DISCOVERABLE, index, data, len);
if (!cmd) {
err = -ENOMEM;
goto failed;
@@ -404,43 +396,42 @@ failed:
return err;
}
-static int set_connectable(struct sock *sk, unsigned char *data, u16 len)
+static int set_connectable(struct sock *sk, u16 index, unsigned char *data,
+ u16 len)
{
struct mgmt_mode *cp;
struct hci_dev *hdev;
struct pending_cmd *cmd;
- u16 dev_id;
u8 scan;
int err;
cp = (void *) data;
- dev_id = get_unaligned_le16(&cp->index);
- BT_DBG("request for hci%u", dev_id);
+ BT_DBG("request for hci%u", index);
- hdev = hci_dev_get(dev_id);
+ hdev = hci_dev_get(index);
if (!hdev)
- return cmd_status(sk, MGMT_OP_SET_CONNECTABLE, ENODEV);
+ return cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, ENODEV);
hci_dev_lock_bh(hdev);
if (!test_bit(HCI_UP, &hdev->flags)) {
- err = cmd_status(sk, MGMT_OP_SET_CONNECTABLE, ENETDOWN);
+ err = cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, ENETDOWN);
goto failed;
}
- if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, dev_id) ||
- mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, dev_id)) {
- err = cmd_status(sk, MGMT_OP_SET_CONNECTABLE, EBUSY);
+ if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, index) ||
+ mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, index)) {
+ err = cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, EBUSY);
goto failed;
}
if (cp->val == test_bit(HCI_PSCAN, &hdev->flags)) {
- err = cmd_status(sk, MGMT_OP_SET_CONNECTABLE, EALREADY);
+ err = cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, EALREADY);
goto failed;
}
- cmd = mgmt_pending_add(sk, MGMT_OP_SET_CONNECTABLE, dev_id, data, len);
+ cmd = mgmt_pending_add(sk, MGMT_OP_SET_CONNECTABLE, index, data, len);
if (!cmd) {
err = -ENOMEM;
goto failed;
@@ -462,7 +453,8 @@ failed:
return err;
}
-static int mgmt_event(u16 event, void *data, u16 data_len, struct sock *skip_sk)
+static int mgmt_event(u16 event, u16 index, void *data, u16 data_len,
+ struct sock *skip_sk)
{
struct sk_buff *skb;
struct mgmt_hdr *hdr;
@@ -475,9 +467,11 @@ static int mgmt_event(u16 event, void *data, u16 data_len, struct sock *skip_sk)
hdr = (void *) skb_put(skb, sizeof(*hdr));
hdr->opcode = cpu_to_le16(event);
+ hdr->index = cpu_to_le16(index);
hdr->len = cpu_to_le16(data_len);
- memcpy(skb_put(skb, data_len), data, data_len);
+ if (data)
+ memcpy(skb_put(skb, data_len), data, data_len);
hci_send_to_sock(NULL, skb, skip_sk);
kfree_skb(skb);
@@ -489,27 +483,25 @@ static int send_mode_rsp(struct sock *sk, u16 opcode, u16 index, u8 val)
{
struct mgmt_mode rp;
- put_unaligned_le16(index, &rp.index);
rp.val = val;
- return cmd_complete(sk, opcode, &rp, sizeof(rp));
+ return cmd_complete(sk, index, opcode, &rp, sizeof(rp));
}
-static int set_pairable(struct sock *sk, unsigned char *data, u16 len)
+static int set_pairable(struct sock *sk, u16 index, unsigned char *data,
+ u16 len)
{
struct mgmt_mode *cp, ev;
struct hci_dev *hdev;
- u16 dev_id;
int err;
cp = (void *) data;
- dev_id = get_unaligned_le16(&cp->index);
- BT_DBG("request for hci%u", dev_id);
+ BT_DBG("request for hci%u", index);
- hdev = hci_dev_get(dev_id);
+ hdev = hci_dev_get(index);
if (!hdev)
- return cmd_status(sk, MGMT_OP_SET_PAIRABLE, ENODEV);
+ return cmd_status(sk, index, MGMT_OP_SET_PAIRABLE, ENODEV);
hci_dev_lock_bh(hdev);
@@ -518,14 +510,13 @@ static int set_pairable(struct sock *sk, unsigned char *data, u16 len)
else
clear_bit(HCI_PAIRABLE, &hdev->flags);
- err = send_mode_rsp(sk, MGMT_OP_SET_PAIRABLE, dev_id, cp->val);
+ err = send_mode_rsp(sk, MGMT_OP_SET_PAIRABLE, index, cp->val);
if (err < 0)
goto failed;
- put_unaligned_le16(dev_id, &ev.index);
ev.val = cp->val;
- err = mgmt_event(MGMT_EV_PAIRABLE, &ev, sizeof(ev), sk);
+ err = mgmt_event(MGMT_EV_PAIRABLE, index, &ev, sizeof(ev), sk);
failed:
hci_dev_unlock_bh(hdev);
@@ -567,22 +558,20 @@ static int update_class(struct hci_dev *hdev)
return hci_send_cmd(hdev, HCI_OP_WRITE_CLASS_OF_DEV, sizeof(cod), cod);
}
-static int add_uuid(struct sock *sk, unsigned char *data, u16 len)
+static int add_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len)
{
struct mgmt_cp_add_uuid *cp;
struct hci_dev *hdev;
struct bt_uuid *uuid;
- u16 dev_id;
int err;
cp = (void *) data;
- dev_id = get_unaligned_le16(&cp->index);
- BT_DBG("request for hci%u", dev_id);
+ BT_DBG("request for hci%u", index);
- hdev = hci_dev_get(dev_id);
+ hdev = hci_dev_get(index);
if (!hdev)
- return cmd_status(sk, MGMT_OP_ADD_UUID, ENODEV);
+ return cmd_status(sk, index, MGMT_OP_ADD_UUID, ENODEV);
hci_dev_lock_bh(hdev);
@@ -601,7 +590,7 @@ static int add_uuid(struct sock *sk, unsigned char *data, u16 len)
if (err < 0)
goto failed;
- err = cmd_complete(sk, MGMT_OP_ADD_UUID, &dev_id, sizeof(dev_id));
+ err = cmd_complete(sk, index, MGMT_OP_ADD_UUID, &index, sizeof(index));
failed:
hci_dev_unlock_bh(hdev);
@@ -610,23 +599,21 @@ failed:
return err;
}
-static int remove_uuid(struct sock *sk, unsigned char *data, u16 len)
+static int remove_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len)
{
struct list_head *p, *n;
struct mgmt_cp_remove_uuid *cp;
struct hci_dev *hdev;
u8 bt_uuid_any[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- u16 dev_id;
int err, found;
cp = (void *) data;
- dev_id = get_unaligned_le16(&cp->index);
- BT_DBG("request for hci%u", dev_id);
+ BT_DBG("request for hci%u", index);
- hdev = hci_dev_get(dev_id);
+ hdev = hci_dev_get(index);
if (!hdev)
- return cmd_status(sk, MGMT_OP_REMOVE_UUID, ENODEV);
+ return cmd_status(sk, index, MGMT_OP_REMOVE_UUID, ENODEV);
hci_dev_lock_bh(hdev);
@@ -648,7 +635,7 @@ static int remove_uuid(struct sock *sk, unsigned char *data, u16 len)
}
if (found == 0) {
- err = cmd_status(sk, MGMT_OP_REMOVE_UUID, ENOENT);
+ err = cmd_status(sk, index, MGMT_OP_REMOVE_UUID, ENOENT);
goto unlock;
}
@@ -656,7 +643,7 @@ static int remove_uuid(struct sock *sk, unsigned char *data, u16 len)
if (err < 0)
goto unlock;
- err = cmd_complete(sk, MGMT_OP_REMOVE_UUID, &dev_id, sizeof(dev_id));
+ err = cmd_complete(sk, index, MGMT_OP_REMOVE_UUID, NULL, 0);
unlock:
hci_dev_unlock_bh(hdev);
@@ -665,21 +652,20 @@ unlock:
return err;
}
-static int set_dev_class(struct sock *sk, unsigned char *data, u16 len)
+static int set_dev_class(struct sock *sk, u16 index, unsigned char *data,
+ u16 len)
{
struct hci_dev *hdev;
struct mgmt_cp_set_dev_class *cp;
- u16 dev_id;
int err;
cp = (void *) data;
- dev_id = get_unaligned_le16(&cp->index);
- BT_DBG("request for hci%u", dev_id);
+ BT_DBG("request for hci%u", index);
- hdev = hci_dev_get(dev_id);
+ hdev = hci_dev_get(index);
if (!hdev)
- return cmd_status(sk, MGMT_OP_SET_DEV_CLASS, ENODEV);
+ return cmd_status(sk, index, MGMT_OP_SET_DEV_CLASS, ENODEV);
hci_dev_lock_bh(hdev);
@@ -689,8 +675,8 @@ static int set_dev_class(struct sock *sk, unsigned char *data, u16 len)
err = update_class(hdev);
if (err == 0)
- err = cmd_complete(sk, MGMT_OP_SET_DEV_CLASS, &dev_id,
- sizeof(dev_id));
+ err = cmd_complete(sk, index, MGMT_OP_SET_DEV_CLASS, &index,
+ sizeof(index));
hci_dev_unlock_bh(hdev);
hci_dev_put(hdev);
@@ -698,23 +684,22 @@ static int set_dev_class(struct sock *sk, unsigned char *data, u16 len)
return err;
}
-static int set_service_cache(struct sock *sk, unsigned char *data, u16 len)
+static int set_service_cache(struct sock *sk, u16 index, unsigned char *data,
+ u16 len)
{
struct hci_dev *hdev;
struct mgmt_cp_set_service_cache *cp;
- u16 dev_id;
int err;
cp = (void *) data;
- dev_id = get_unaligned_le16(&cp->index);
- hdev = hci_dev_get(dev_id);
+ hdev = hci_dev_get(index);
if (!hdev)
- return cmd_status(sk, MGMT_OP_SET_SERVICE_CACHE, ENODEV);
+ return cmd_status(sk, index, MGMT_OP_SET_SERVICE_CACHE, ENODEV);
hci_dev_lock_bh(hdev);
- BT_DBG("hci%u enable %d", dev_id, cp->enable);
+ BT_DBG("hci%u enable %d", index, cp->enable);
if (cp->enable) {
set_bit(HCI_SERVICE_CACHE, &hdev->flags);
@@ -725,8 +710,8 @@ static int set_service_cache(struct sock *sk, unsigned char *data, u16 len)
}
if (err == 0)
- err = cmd_complete(sk, MGMT_OP_SET_SERVICE_CACHE, &dev_id,
- sizeof(dev_id));
+ err = cmd_complete(sk, index, MGMT_OP_SET_SERVICE_CACHE, &index,
+ sizeof(index));
hci_dev_unlock_bh(hdev);
hci_dev_put(hdev);
@@ -734,15 +719,14 @@ static int set_service_cache(struct sock *sk, unsigned char *data, u16 len)
return err;
}
-static int load_keys(struct sock *sk, unsigned char *data, u16 len)
+static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len)
{
struct hci_dev *hdev;
struct mgmt_cp_load_keys *cp;
- u16 dev_id, key_count, expected_len;
+ u16 key_count, expected_len;
int i;
cp = (void *) data;
- dev_id = get_unaligned_le16(&cp->index);
key_count = get_unaligned_le16(&cp->key_count);
expected_len = sizeof(*cp) + key_count * sizeof(struct mgmt_key_info);
@@ -752,11 +736,11 @@ static int load_keys(struct sock *sk, unsigned char *data, u16 len)
return -EINVAL;
}
- hdev = hci_dev_get(dev_id);
+ hdev = hci_dev_get(index);
if (!hdev)
- return cmd_status(sk, MGMT_OP_LOAD_KEYS, ENODEV);
+ return cmd_status(sk, index, MGMT_OP_LOAD_KEYS, ENODEV);
- BT_DBG("hci%u debug_keys %u key_count %u", dev_id, cp->debug_keys,
+ BT_DBG("hci%u debug_keys %u key_count %u", index, cp->debug_keys,
key_count);
hci_dev_lock_bh(hdev);
@@ -783,26 +767,24 @@ static int load_keys(struct sock *sk, unsigned char *data, u16 len)
return 0;
}
-static int remove_key(struct sock *sk, unsigned char *data, u16 len)
+static int remove_key(struct sock *sk, u16 index, unsigned char *data, u16 len)
{
struct hci_dev *hdev;
struct mgmt_cp_remove_key *cp;
struct hci_conn *conn;
- u16 dev_id;
int err;
cp = (void *) data;
- dev_id = get_unaligned_le16(&cp->index);
- hdev = hci_dev_get(dev_id);
+ hdev = hci_dev_get(index);
if (!hdev)
- return cmd_status(sk, MGMT_OP_REMOVE_KEY, ENODEV);
+ return cmd_status(sk, index, MGMT_OP_REMOVE_KEY, ENODEV);
hci_dev_lock_bh(hdev);
err = hci_remove_link_key(hdev, &cp->bdaddr);
if (err < 0) {
- err = cmd_status(sk, MGMT_OP_REMOVE_KEY, -err);
+ err = cmd_status(sk, index, MGMT_OP_REMOVE_KEY, -err);
goto unlock;
}
@@ -827,44 +809,42 @@ unlock:
return err;
}
-static int disconnect(struct sock *sk, unsigned char *data, u16 len)
+static int disconnect(struct sock *sk, u16 index, unsigned char *data, u16 len)
{
struct hci_dev *hdev;
struct mgmt_cp_disconnect *cp;
struct hci_cp_disconnect dc;
struct pending_cmd *cmd;
struct hci_conn *conn;
- u16 dev_id;
int err;
BT_DBG("");
cp = (void *) data;
- dev_id = get_unaligned_le16(&cp->index);
- hdev = hci_dev_get(dev_id);
+ hdev = hci_dev_get(index);
if (!hdev)
- return cmd_status(sk, MGMT_OP_DISCONNECT, ENODEV);
+ return cmd_status(sk, index, MGMT_OP_DISCONNECT, ENODEV);
hci_dev_lock_bh(hdev);
if (!test_bit(HCI_UP, &hdev->flags)) {
- err = cmd_status(sk, MGMT_OP_DISCONNECT, ENETDOWN);
+ err = cmd_status(sk, index, MGMT_OP_DISCONNECT, ENETDOWN);
goto failed;
}
- if (mgmt_pending_find(MGMT_OP_DISCONNECT, dev_id)) {
- err = cmd_status(sk, MGMT_OP_DISCONNECT, EBUSY);
+ if (mgmt_pending_find(MGMT_OP_DISCONNECT, index)) {
+ err = cmd_status(sk, index, MGMT_OP_DISCONNECT, EBUSY);
goto failed;
}
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
if (!conn) {
- err = cmd_status(sk, MGMT_OP_DISCONNECT, ENOTCONN);
+ err = cmd_status(sk, index, MGMT_OP_DISCONNECT, ENOTCONN);
goto failed;
}
- cmd = mgmt_pending_add(sk, MGMT_OP_DISCONNECT, dev_id, data, len);
+ cmd = mgmt_pending_add(sk, MGMT_OP_DISCONNECT, index, data, len);
if (!cmd) {
err = -ENOMEM;
goto failed;
@@ -884,24 +864,24 @@ failed:
return err;
}
-static int get_connections(struct sock *sk, unsigned char *data, u16 len)
+static int get_connections(struct sock *sk, u16 index, unsigned char *data,
+ u16 len)
{
struct mgmt_cp_get_connections *cp;
struct mgmt_rp_get_connections *rp;
struct hci_dev *hdev;
struct list_head *p;
size_t rp_len;
- u16 dev_id, count;
+ u16 count;
int i, err;
BT_DBG("");
cp = (void *) data;
- dev_id = get_unaligned_le16(&cp->index);
- hdev = hci_dev_get(dev_id);
+ hdev = hci_dev_get(index);
if (!hdev)
- return cmd_status(sk, MGMT_OP_GET_CONNECTIONS, ENODEV);
+ return cmd_status(sk, index, MGMT_OP_GET_CONNECTIONS, ENODEV);
hci_dev_lock_bh(hdev);
@@ -917,7 +897,6 @@ static int get_connections(struct sock *sk, unsigned char *data, u16 len)
goto unlock;
}
- put_unaligned_le16(dev_id, &rp->index);
put_unaligned_le16(count, &rp->conn_count);
read_lock(&hci_dev_list_lock);
@@ -931,7 +910,7 @@ static int get_connections(struct sock *sk, unsigned char *data, u16 len)
read_unlock(&hci_dev_list_lock);
- err = cmd_complete(sk, MGMT_OP_GET_CONNECTIONS, rp, rp_len);
+ err = cmd_complete(sk, index, MGMT_OP_GET_CONNECTIONS, rp, rp_len);
unlock:
kfree(rp);
@@ -940,32 +919,31 @@ unlock:
return err;
}
-static int pin_code_reply(struct sock *sk, unsigned char *data, u16 len)
+static int pin_code_reply(struct sock *sk, u16 index, unsigned char *data,
+ u16 len)
{
struct hci_dev *hdev;
struct mgmt_cp_pin_code_reply *cp;
struct hci_cp_pin_code_reply reply;
struct pending_cmd *cmd;
- u16 dev_id;
int err;
BT_DBG("");
cp = (void *) data;
- dev_id = get_unaligned_le16(&cp->index);
- hdev = hci_dev_get(dev_id);
+ hdev = hci_dev_get(index);
if (!hdev)
- return cmd_status(sk, MGMT_OP_PIN_CODE_REPLY, ENODEV);
+ return cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, ENODEV);
hci_dev_lock_bh(hdev);
if (!test_bit(HCI_UP, &hdev->flags)) {
- err = cmd_status(sk, MGMT_OP_PIN_CODE_REPLY, ENETDOWN);
+ err = cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, ENETDOWN);
goto failed;
}
- cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_REPLY, dev_id, data, len);
+ cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_REPLY, index, data, len);
if (!cmd) {
err = -ENOMEM;
goto failed;
@@ -986,31 +964,32 @@ failed:
return err;
}
-static int pin_code_neg_reply(struct sock *sk, unsigned char *data, u16 len)
+static int pin_code_neg_reply(struct sock *sk, u16 index, unsigned char *data,
+ u16 len)
{
struct hci_dev *hdev;
struct mgmt_cp_pin_code_neg_reply *cp;
struct pending_cmd *cmd;
- u16 dev_id;
int err;
BT_DBG("");
cp = (void *) data;
- dev_id = get_unaligned_le16(&cp->index);
- hdev = hci_dev_get(dev_id);
+ hdev = hci_dev_get(index);
if (!hdev)
- return cmd_status(sk, MGMT_OP_PIN_CODE_NEG_REPLY, ENODEV);
+ return cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY,
+ ENODEV);
hci_dev_lock_bh(hdev);
if (!test_bit(HCI_UP, &hdev->flags)) {
- err = cmd_status(sk, MGMT_OP_PIN_CODE_NEG_REPLY, ENETDOWN);
+ err = cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY,
+ ENETDOWN);
goto failed;
}
- cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_NEG_REPLY, dev_id,
+ cmd = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_NEG_REPLY, index,
data, len);
if (!cmd) {
err = -ENOMEM;
@@ -1029,20 +1008,19 @@ failed:
return err;
}
-static int set_io_capability(struct sock *sk, unsigned char *data, u16 len)
+static int set_io_capability(struct sock *sk, u16 index, unsigned char *data,
+ u16 len)
{
struct hci_dev *hdev;
struct mgmt_cp_set_io_capability *cp;
- u16 dev_id;
BT_DBG("");
cp = (void *) data;
- dev_id = get_unaligned_le16(&cp->index);
- hdev = hci_dev_get(dev_id);
+ hdev = hci_dev_get(index);
if (!hdev)
- return cmd_status(sk, MGMT_OP_SET_IO_CAPABILITY, ENODEV);
+ return cmd_status(sk, index, MGMT_OP_SET_IO_CAPABILITY, ENODEV);
hci_dev_lock_bh(hdev);
@@ -1054,8 +1032,8 @@ static int set_io_capability(struct sock *sk, unsigned char *data, u16 len)
hci_dev_unlock_bh(hdev);
hci_dev_put(hdev);
- return cmd_complete(sk, MGMT_OP_SET_IO_CAPABILITY,
- &dev_id, sizeof(dev_id));
+ return cmd_complete(sk, index, MGMT_OP_SET_IO_CAPABILITY,
+ &index, sizeof(index));
}
static inline struct pending_cmd *find_pairing(struct hci_conn *conn)
@@ -1088,11 +1066,10 @@ static void pairing_complete(struct pending_cmd *cmd, u8 status)
struct mgmt_rp_pair_device rp;
struct hci_conn *conn = cmd->user_data;
- rp.index = cmd->index;
bacpy(&rp.bdaddr, &conn->dst);
rp.status = status;
- cmd_complete(cmd->sk, MGMT_OP_PAIR_DEVICE, &rp, sizeof(rp));
+ cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE, &rp, sizeof(rp));
/* So we don't get further callbacks for this connection */
conn->connect_cfm_cb = NULL;
@@ -1119,24 +1096,22 @@ static void pairing_complete_cb(struct hci_conn *conn, u8 status)
pairing_complete(cmd, status);
}
-static int pair_device(struct sock *sk, unsigned char *data, u16 len)
+static int pair_device(struct sock *sk, u16 index, unsigned char *data, u16 len)
{
struct hci_dev *hdev;
struct mgmt_cp_pair_device *cp;
struct pending_cmd *cmd;
u8 sec_level, auth_type;
struct hci_conn *conn;
- u16 dev_id;
int err;
BT_DBG("");
cp = (void *) data;
- dev_id = get_unaligned_le16(&cp->index);
- hdev = hci_dev_get(dev_id);
+ hdev = hci_dev_get(index);
if (!hdev)
- return cmd_status(sk, MGMT_OP_PAIR_DEVICE, ENODEV);
+ return cmd_status(sk, index, MGMT_OP_PAIR_DEVICE, ENODEV);
hci_dev_lock_bh(hdev);
@@ -1156,11 +1131,11 @@ static int pair_device(struct sock *sk, unsigned char *data, u16 len)
if (conn->connect_cfm_cb) {
hci_conn_put(conn);
- err = cmd_status(sk, MGMT_OP_PAIR_DEVICE, EBUSY);
+ err = cmd_status(sk, index, MGMT_OP_PAIR_DEVICE, EBUSY);
goto unlock;
}
- cmd = mgmt_pending_add(sk, MGMT_OP_PAIR_DEVICE, dev_id, data, len);
+ cmd = mgmt_pending_add(sk, MGMT_OP_PAIR_DEVICE, index, data, len);
if (!cmd) {
err = -ENOMEM;
hci_conn_put(conn);
@@ -1186,19 +1161,17 @@ unlock:
return err;
}
-static int user_confirm_reply(struct sock *sk, unsigned char *data, u16 len,
- int success)
+static int user_confirm_reply(struct sock *sk, u16 index, unsigned char *data,
+ u16 len, int success)
{
struct mgmt_cp_user_confirm_reply *cp = (void *) data;
- u16 dev_id, mgmt_op, hci_op;
+ u16 mgmt_op, hci_op;
struct pending_cmd *cmd;
struct hci_dev *hdev;
int err;
BT_DBG("");
- dev_id = get_unaligned_le16(&cp->index);
-
if (success) {
mgmt_op = MGMT_OP_USER_CONFIRM_REPLY;
hci_op = HCI_OP_USER_CONFIRM_REPLY;
@@ -1207,16 +1180,16 @@ static int user_confirm_reply(struct sock *sk, unsigned char *data, u16 len,
hci_op = HCI_OP_USER_CONFIRM_NEG_REPLY;
}
- hdev = hci_dev_get(dev_id);
+ hdev = hci_dev_get(index);
if (!hdev)
- return cmd_status(sk, mgmt_op, ENODEV);
+ return cmd_status(sk, index, mgmt_op, ENODEV);
if (!test_bit(HCI_UP, &hdev->flags)) {
- err = cmd_status(sk, mgmt_op, ENETDOWN);
+ err = cmd_status(sk, index, mgmt_op, ENETDOWN);
goto failed;
}
- cmd = mgmt_pending_add(sk, mgmt_op, dev_id, data, len);
+ cmd = mgmt_pending_add(sk, mgmt_op, index, data, len);
if (!cmd) {
err = -ENOMEM;
goto failed;
@@ -1237,7 +1210,7 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
{
unsigned char *buf;
struct mgmt_hdr *hdr;
- u16 opcode, len;
+ u16 opcode, index, len;
int err;
BT_DBG("got %zu bytes", msglen);
@@ -1256,6 +1229,7 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
hdr = (struct mgmt_hdr *) buf;
opcode = get_unaligned_le16(&hdr->opcode);
+ index = get_unaligned_le16(&hdr->index);
len = get_unaligned_le16(&hdr->len);
if (len != msglen - sizeof(*hdr)) {
@@ -1271,65 +1245,65 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
err = read_index_list(sk);
break;
case MGMT_OP_READ_INFO:
- err = read_controller_info(sk, buf + sizeof(*hdr), len);
+ err = read_controller_info(sk, index);
break;
case MGMT_OP_SET_POWERED:
- err = set_powered(sk, buf + sizeof(*hdr), len);
+ err = set_powered(sk, index, buf + sizeof(*hdr), len);
break;
case MGMT_OP_SET_DISCOVERABLE:
- err = set_discoverable(sk, buf + sizeof(*hdr), len);
+ err = set_discoverable(sk, index, buf + sizeof(*hdr), len);
break;
case MGMT_OP_SET_CONNECTABLE:
- err = set_connectable(sk, buf + sizeof(*hdr), len);
+ err = set_connectable(sk, index, buf + sizeof(*hdr), len);
break;
case MGMT_OP_SET_PAIRABLE:
- err = set_pairable(sk, buf + sizeof(*hdr), len);
+ err = set_pairable(sk, index, buf + sizeof(*hdr), len);
break;
case MGMT_OP_ADD_UUID:
- err = add_uuid(sk, buf + sizeof(*hdr), len);
+ err = add_uuid(sk, index, buf + sizeof(*hdr), len);
break;
case MGMT_OP_REMOVE_UUID:
- err = remove_uuid(sk, buf + sizeof(*hdr), len);
+ err = remove_uuid(sk, index, buf + sizeof(*hdr), len);
break;
case MGMT_OP_SET_DEV_CLASS:
- err = set_dev_class(sk, buf + sizeof(*hdr), len);
+ err = set_dev_class(sk, index, buf + sizeof(*hdr), len);
break;
case MGMT_OP_SET_SERVICE_CACHE:
- err = set_service_cache(sk, buf + sizeof(*hdr), len);
+ err = set_service_cache(sk, index, buf + sizeof(*hdr), len);
break;
case MGMT_OP_LOAD_KEYS:
- err = load_keys(sk, buf + sizeof(*hdr), len);
+ err = load_keys(sk, index, buf + sizeof(*hdr), len);
break;
case MGMT_OP_REMOVE_KEY:
- err = remove_key(sk, buf + sizeof(*hdr), len);
+ err = remove_key(sk, index, buf + sizeof(*hdr), len);
break;
case MGMT_OP_DISCONNECT:
- err = disconnect(sk, buf + sizeof(*hdr), len);
+ err = disconnect(sk, index, buf + sizeof(*hdr), len);
break;
case MGMT_OP_GET_CONNECTIONS:
- err = get_connections(sk, buf + sizeof(*hdr), len);
+ err = get_connections(sk, index, buf + sizeof(*hdr), len);
break;
case MGMT_OP_PIN_CODE_REPLY:
- err = pin_code_reply(sk, buf + sizeof(*hdr), len);
+ err = pin_code_reply(sk, index, buf + sizeof(*hdr), len);
break;
case MGMT_OP_PIN_CODE_NEG_REPLY:
- err = pin_code_neg_reply(sk, buf + sizeof(*hdr), len);
+ err = pin_code_neg_reply(sk, index, buf + sizeof(*hdr), len);
break;
case MGMT_OP_SET_IO_CAPABILITY:
- err = set_io_capability(sk, buf + sizeof(*hdr), len);
+ err = set_io_capability(sk, index, buf + sizeof(*hdr), len);
break;
case MGMT_OP_PAIR_DEVICE:
- err = pair_device(sk, buf + sizeof(*hdr), len);
+ err = pair_device(sk, index, buf + sizeof(*hdr), len);
break;
case MGMT_OP_USER_CONFIRM_REPLY:
- err = user_confirm_reply(sk, buf + sizeof(*hdr), len, 1);
+ err = user_confirm_reply(sk, index, buf + sizeof(*hdr), len, 1);
break;
case MGMT_OP_USER_CONFIRM_NEG_REPLY:
- err = user_confirm_reply(sk, buf + sizeof(*hdr), len, 0);
+ err = user_confirm_reply(sk, index, buf + sizeof(*hdr), len, 0);
break;
default:
BT_DBG("Unknown op %u", opcode);
- err = cmd_status(sk, opcode, 0x01);
+ err = cmd_status(sk, index, opcode, 0x01);
break;
}
@@ -1345,20 +1319,12 @@ done:
int mgmt_index_added(u16 index)
{
- struct mgmt_ev_index_added ev;
-
- put_unaligned_le16(index, &ev.index);
-
- return mgmt_event(MGMT_EV_INDEX_ADDED, &ev, sizeof(ev), NULL);
+ return mgmt_event(MGMT_EV_INDEX_ADDED, index, NULL, 0, NULL);
}
int mgmt_index_removed(u16 index)
{
- struct mgmt_ev_index_added ev;
-
- put_unaligned_le16(index, &ev.index);
-
- return mgmt_event(MGMT_EV_INDEX_REMOVED, &ev, sizeof(ev), NULL);
+ return mgmt_event(MGMT_EV_INDEX_REMOVED, index, NULL, 0, NULL);
}
struct cmd_lookup {
@@ -1394,10 +1360,9 @@ int mgmt_powered(u16 index, u8 powered)
mgmt_pending_foreach(MGMT_OP_SET_POWERED, index, mode_rsp, &match);
- put_unaligned_le16(index, &ev.index);
ev.val = powered;
- ret = mgmt_event(MGMT_EV_POWERED, &ev, sizeof(ev), match.sk);
+ ret = mgmt_event(MGMT_EV_POWERED, index, &ev, sizeof(ev), match.sk);
if (match.sk)
sock_put(match.sk);
@@ -1414,10 +1379,10 @@ int mgmt_discoverable(u16 index, u8 discoverable)
mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, index,
mode_rsp, &match);
- put_unaligned_le16(index, &ev.index);
ev.val = discoverable;
- ret = mgmt_event(MGMT_EV_DISCOVERABLE, &ev, sizeof(ev), match.sk);
+ ret = mgmt_event(MGMT_EV_DISCOVERABLE, index, &ev, sizeof(ev),
+ match.sk);
if (match.sk)
sock_put(match.sk);
@@ -1433,10 +1398,9 @@ int mgmt_connectable(u16 index, u8 connectable)
mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, index, mode_rsp, &match);
- put_unaligned_le16(index, &ev.index);
ev.val = connectable;
- ret = mgmt_event(MGMT_EV_CONNECTABLE, &ev, sizeof(ev), match.sk);
+ ret = mgmt_event(MGMT_EV_CONNECTABLE, index, &ev, sizeof(ev), match.sk);
if (match.sk)
sock_put(match.sk);
@@ -1450,25 +1414,22 @@ int mgmt_new_key(u16 index, struct link_key *key, u8 old_key_type)
memset(&ev, 0, sizeof(ev));
- put_unaligned_le16(index, &ev.index);
-
bacpy(&ev.key.bdaddr, &key->bdaddr);
ev.key.type = key->type;
memcpy(ev.key.val, key->val, 16);
ev.key.pin_len = key->pin_len;
ev.old_key_type = old_key_type;
- return mgmt_event(MGMT_EV_NEW_KEY, &ev, sizeof(ev), NULL);
+ return mgmt_event(MGMT_EV_NEW_KEY, index, &ev, sizeof(ev), NULL);
}
int mgmt_connected(u16 index, bdaddr_t *bdaddr)
{
struct mgmt_ev_connected ev;
- put_unaligned_le16(index, &ev.index);
bacpy(&ev.bdaddr, bdaddr);
- return mgmt_event(MGMT_EV_CONNECTED, &ev, sizeof(ev), NULL);
+ return mgmt_event(MGMT_EV_CONNECTED, index, &ev, sizeof(ev), NULL);
}
static void disconnect_rsp(struct pending_cmd *cmd, void *data)
@@ -1477,10 +1438,9 @@ static void disconnect_rsp(struct pending_cmd *cmd, void *data)
struct sock **sk = data;
struct mgmt_rp_disconnect rp;
- put_unaligned_le16(cmd->index, &rp.index);
bacpy(&rp.bdaddr, &cp->bdaddr);
- cmd_complete(cmd->sk, MGMT_OP_DISCONNECT, &rp, sizeof(rp));
+ cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT, &rp, sizeof(rp));
*sk = cmd->sk;
sock_hold(*sk);
@@ -1496,10 +1456,9 @@ int mgmt_disconnected(u16 index, bdaddr_t *bdaddr)
mgmt_pending_foreach(MGMT_OP_DISCONNECT, index, disconnect_rsp, &sk);
- put_unaligned_le16(index, &ev.index);
bacpy(&ev.bdaddr, bdaddr);
- err = mgmt_event(MGMT_EV_DISCONNECTED, &ev, sizeof(ev), sk);
+ err = mgmt_event(MGMT_EV_DISCONNECTED, index, &ev, sizeof(ev), sk);
if (sk)
sock_put(sk);
@@ -1516,7 +1475,7 @@ int mgmt_disconnect_failed(u16 index)
if (!cmd)
return -ENOENT;
- err = cmd_status(cmd->sk, MGMT_OP_DISCONNECT, EIO);
+ err = cmd_status(cmd->sk, index, MGMT_OP_DISCONNECT, EIO);
mgmt_pending_remove(cmd);
@@ -1527,21 +1486,20 @@ int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status)
{
struct mgmt_ev_connect_failed ev;
- put_unaligned_le16(index, &ev.index);
bacpy(&ev.bdaddr, bdaddr);
ev.status = status;
- return mgmt_event(MGMT_EV_CONNECT_FAILED, &ev, sizeof(ev), NULL);
+ return mgmt_event(MGMT_EV_CONNECT_FAILED, index, &ev, sizeof(ev), NULL);
}
int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr)
{
struct mgmt_ev_pin_code_request ev;
- put_unaligned_le16(index, &ev.index);
bacpy(&ev.bdaddr, bdaddr);
- return mgmt_event(MGMT_EV_PIN_CODE_REQUEST, &ev, sizeof(ev), NULL);
+ return mgmt_event(MGMT_EV_PIN_CODE_REQUEST, index, &ev, sizeof(ev),
+ NULL);
}
int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
@@ -1554,11 +1512,11 @@ int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
if (!cmd)
return -ENOENT;
- put_unaligned_le16(index, &rp.index);
bacpy(&rp.bdaddr, bdaddr);
rp.status = status;
- err = cmd_complete(cmd->sk, MGMT_OP_PIN_CODE_REPLY, &rp, sizeof(rp));
+ err = cmd_complete(cmd->sk, index, MGMT_OP_PIN_CODE_REPLY, &rp,
+ sizeof(rp));
mgmt_pending_remove(cmd);
@@ -1575,11 +1533,10 @@ int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
if (!cmd)
return -ENOENT;
- put_unaligned_le16(index, &rp.index);
bacpy(&rp.bdaddr, bdaddr);
rp.status = status;
- err = cmd_complete(cmd->sk, MGMT_OP_PIN_CODE_NEG_REPLY,
+ err = cmd_complete(cmd->sk, index, MGMT_OP_PIN_CODE_NEG_REPLY,
&rp, sizeof(rp));
mgmt_pending_remove(cmd);
@@ -1593,11 +1550,11 @@ int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value)
BT_DBG("hci%u", index);
- put_unaligned_le16(index, &ev.index);
bacpy(&ev.bdaddr, bdaddr);
put_unaligned_le32(value, &ev.value);
- return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, &ev, sizeof(ev), NULL);
+ return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, index, &ev, sizeof(ev),
+ NULL);
}
static int confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status,
@@ -1611,10 +1568,9 @@ static int confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status,
if (!cmd)
return -ENOENT;
- put_unaligned_le16(index, &rp.index);
bacpy(&rp.bdaddr, bdaddr);
rp.status = status;
- err = cmd_complete(cmd->sk, opcode, &rp, sizeof(rp));
+ err = cmd_complete(cmd->sk, index, opcode, &rp, sizeof(rp));
mgmt_pending_remove(cmd);
@@ -1638,9 +1594,8 @@ int mgmt_auth_failed(u16 index, bdaddr_t *bdaddr, u8 status)
{
struct mgmt_ev_auth_failed ev;
- put_unaligned_le16(index, &ev.index);
bacpy(&ev.bdaddr, bdaddr);
ev.status = status;
- return mgmt_event(MGMT_EV_AUTH_FAILED, &ev, sizeof(ev), NULL);
+ return mgmt_event(MGMT_EV_AUTH_FAILED, index, &ev, sizeof(ev), NULL);
}
--
1.7.0.4
^ permalink raw reply related
* [PATCH 1/3] Bluetooth: Use proper command structure in remove_uuid
From: Szymon Janc @ 2011-02-23 10:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: par-gunnar.p.hjalmdahl, henrik.possung, Szymon Janc
The structure used for command was wrong (probably copy-paste mistake).
Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
---
net/bluetooth/mgmt.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 982becd..4543ede 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -613,7 +613,7 @@ failed:
static int remove_uuid(struct sock *sk, unsigned char *data, u16 len)
{
struct list_head *p, *n;
- struct mgmt_cp_add_uuid *cp;
+ struct mgmt_cp_remove_uuid *cp;
struct hci_dev *hdev;
u8 bt_uuid_any[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
u16 dev_id;
--
1.7.0.4
^ permalink raw reply related
* [PATCH 6/6] Remove redundante check for server when checking for usb
From: Luiz Augusto von Dentz @ 2011-02-23 9:54 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1298454881-7941-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
There is a check for this already on Makefile.am
---
configure.ac | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/configure.ac b/configure.ac
index a17d0ca..9194843 100644
--- a/configure.ac
+++ b/configure.ac
@@ -155,8 +155,7 @@ AC_ARG_ENABLE(usb, AC_HELP_STRING([--enable-usb],
[enable usb plugin]), [
enable_usb=${enableval}
])
-AM_CONDITIONAL(USB, test "${enable_usb}" = "yes" &&
- test "${enable_server}" != "no")
+AM_CONDITIONAL(USB, test "${enable_usb}" = "yes")
AC_ARG_ENABLE(pcsuite, AC_HELP_STRING([--enable-pcsuite],
[enable Nokia PcSuite plugin]), [
--
1.7.1
^ permalink raw reply related
* [PATCH 5/6] Move pcsuite drivers to its own plugin
From: Luiz Augusto von Dentz @ 2011-02-23 9:54 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1298454881-7941-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
This make it easier to enable/disable this funcionality as a whole.
---
Makefile.am | 6 +-
configure.ac | 9 +-
plugins/ftp.c | 165 ++------------------------
plugins/nokia-backup.c | 309 ------------------------------------------------
4 files changed, 16 insertions(+), 473 deletions(-)
delete mode 100644 plugins/nokia-backup.c
diff --git a/Makefile.am b/Makefile.am
index fc996ec..d32d613 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -43,9 +43,9 @@ endif
builtin_modules += filesystem
builtin_sources += plugins/filesystem.c plugins/filesystem.h
-if NOKIA_BACKUP
-builtin_modules += backup
-builtin_sources += plugins/nokia-backup.c
+if NOKIA_PCSUITE
+builtin_modules += pcsuite
+builtin_sources += plugins/pcsuite.c
endif
builtin_modules += opp
diff --git a/configure.ac b/configure.ac
index da8fb64..a17d0ca 100644
--- a/configure.ac
+++ b/configure.ac
@@ -158,12 +158,11 @@ AC_ARG_ENABLE(usb, AC_HELP_STRING([--enable-usb],
AM_CONDITIONAL(USB, test "${enable_usb}" = "yes" &&
test "${enable_server}" != "no")
-AC_ARG_ENABLE(nokia_backup, AC_HELP_STRING([--enable-nokia-backup],
- [enable nokia-backup plugin]), [
- enable_nokia_backup=${enableval}
+AC_ARG_ENABLE(pcsuite, AC_HELP_STRING([--enable-pcsuite],
+ [enable Nokia PcSuite plugin]), [
+ enable_pcsuite=${enableval}
])
-AM_CONDITIONAL(NOKIA_BACKUP, test "${enable_nokia_backup}" = "yes" &&
- test "${enable_server}" != "no")
+AM_CONDITIONAL(NOKIA_PCSUITE, test "${enable_pcsuite}" = "yes")
AC_ARG_ENABLE(client, AC_HELP_STRING([--disable-client],
[disable compilation of OBEX client]), [
diff --git a/plugins/ftp.c b/plugins/ftp.c
index 633abf3..79223bf 100644
--- a/plugins/ftp.c
+++ b/plugins/ftp.c
@@ -50,6 +50,7 @@
#include "dbus.h"
#include "mimetype.h"
#include "service.h"
+#include "ftp.h"
#define LST_TYPE "x-obex/folder-listing"
#define CAP_TYPE "x-obex/capability"
@@ -189,7 +190,7 @@ static int get_by_type(struct ftp_session *ftp, const char *type)
return err;
}
-static void *ftp_connect(struct obex_session *os, int *err)
+void *ftp_connect(struct obex_session *os, int *err)
{
struct ftp_session *ftp;
const char *root_folder;
@@ -212,8 +213,8 @@ static void *ftp_connect(struct obex_session *os, int *err)
return ftp;
}
-static int ftp_get(struct obex_session *os, obex_object_t *obj,
- gboolean *stream, void *user_data)
+int ftp_get(struct obex_session *os, obex_object_t *obj, gboolean *stream,
+ void *user_data)
{
struct ftp_session *ftp = user_data;
const char *type = obex_get_type(os);
@@ -254,7 +255,7 @@ static int ftp_delete(struct ftp_session *ftp, const char *name)
return ret;
}
-static int ftp_chkput(struct obex_session *os, void *user_data)
+int ftp_chkput(struct obex_session *os, void *user_data)
{
struct ftp_session *ftp = user_data;
const char *name = obex_get_name(os);
@@ -278,8 +279,7 @@ static int ftp_chkput(struct obex_session *os, void *user_data)
return ret;
}
-static int ftp_put(struct obex_session *os, obex_object_t *obj,
- void *user_data)
+int ftp_put(struct obex_session *os, obex_object_t *obj, void *user_data)
{
struct ftp_session *ftp = user_data;
const char *name = obex_get_name(os);
@@ -299,8 +299,7 @@ static int ftp_put(struct obex_session *os, obex_object_t *obj,
return 0;
}
-static int ftp_setpath(struct obex_session *os, obex_object_t *obj,
- void *user_data)
+int ftp_setpath(struct obex_session *os, obex_object_t *obj, void *user_data)
{
struct ftp_session *ftp = user_data;
const char *root_folder, *name;
@@ -404,7 +403,7 @@ done:
return err;
}
-static void ftp_disconnect(struct obex_session *os, void *user_data)
+void ftp_disconnect(struct obex_session *os, void *user_data)
{
struct ftp_session *ftp = user_data;
@@ -416,145 +415,6 @@ static void ftp_disconnect(struct obex_session *os, void *user_data)
g_free(ftp);
}
-static void *pcsuite_connect(struct obex_session *os, int *err)
-{
- struct pcsuite_session *pcsuite;
- struct ftp_session *ftp;
- int fd;
- char *filename;
-
- DBG("");
-
- ftp = ftp_connect(os, err);
- if (ftp == NULL)
- return NULL;
-
- filename = g_build_filename(g_get_home_dir(), ".pcsuite", NULL);
-
- fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0644);
- if (fd < 0 && errno != EEXIST) {
- error("open(%s): %s(%d)", filename, strerror(errno), errno);
- goto fail;
- }
-
- /* Try to remove the file before retrying since it could be
- that some process left/crash without removing it */
- if (fd < 0) {
- if (remove(filename) < 0) {
- error("remove(%s): %s(%d)", filename, strerror(errno),
- errno);
- goto fail;
- }
-
- fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0644);
- if (fd < 0) {
- error("open(%s): %s(%d)", filename, strerror(errno),
- errno);
- goto fail;
- }
- }
-
- DBG("%s created", filename);
-
- pcsuite = g_new0(struct pcsuite_session, 1);
- pcsuite->ftp = ftp;
- pcsuite->lock_file = filename;
- pcsuite->fd = fd;
-
- DBG("session %p created", pcsuite);
-
- if (err)
- *err = 0;
-
- return pcsuite;
-
-fail:
- if (ftp)
- ftp_disconnect(os, ftp);
- if (err)
- *err = -errno;
-
- g_free(filename);
-
- return NULL;
-}
-
-static int pcsuite_get(struct obex_session *os, obex_object_t *obj,
- gboolean *stream, void *user_data)
-{
- struct pcsuite_session *pcsuite = user_data;
-
- DBG("%p", pcsuite);
-
- return ftp_get(os, obj, stream, pcsuite->ftp);
-}
-
-static int pcsuite_chkput(struct obex_session *os, void *user_data)
-{
- struct pcsuite_session *pcsuite = user_data;
-
- DBG("%p", pcsuite);
-
- return ftp_chkput(os, pcsuite->ftp);
-}
-
-static int pcsuite_put(struct obex_session *os, obex_object_t *obj,
- void *user_data)
-{
- struct pcsuite_session *pcsuite = user_data;
-
- DBG("%p", pcsuite);
-
- return ftp_put(os, obj, pcsuite->ftp);
-}
-
-static int pcsuite_setpath(struct obex_session *os, obex_object_t *obj,
- void *user_data)
-{
- struct pcsuite_session *pcsuite = user_data;
-
- DBG("%p", pcsuite);
-
- return ftp_setpath(os, obj, pcsuite->ftp);
-}
-
-static void pcsuite_disconnect(struct obex_session *os, void *user_data)
-{
- struct pcsuite_session *pcsuite = user_data;
-
- DBG("%p", pcsuite);
-
- if (pcsuite->fd >= 0)
- close(pcsuite->fd);
-
- if (pcsuite->lock_file) {
- remove(pcsuite->lock_file);
- g_free(pcsuite->lock_file);
- }
-
- if (pcsuite->ftp)
- ftp_disconnect(os, pcsuite->ftp);
-
- g_free(pcsuite);
-}
-
-static struct obex_service_driver pcsuite = {
- .name = "Nokia OBEX PC Suite Services",
- .service = OBEX_PCSUITE,
- .channel = PCSUITE_CHANNEL,
- .record = PCSUITE_RECORD,
- .target = FTP_TARGET,
- .target_size = TARGET_SIZE,
- .who = PCSUITE_WHO,
- .who_size = PCSUITE_WHO_SIZE,
- .connect = pcsuite_connect,
- .get = pcsuite_get,
- .put = pcsuite_put,
- .chkput = pcsuite_chkput,
- .setpath = pcsuite_setpath,
- .disconnect = pcsuite_disconnect
-};
-
static struct obex_service_driver ftp = {
.name = "File Transfer server",
.service = OBEX_FTP,
@@ -572,19 +432,12 @@ static struct obex_service_driver ftp = {
static int ftp_init(void)
{
- int err;
-
- err = obex_service_driver_register(&ftp);
- if (err < 0)
- return err;
-
- return obex_service_driver_register(&pcsuite);
+ return obex_service_driver_register(&ftp);
}
static void ftp_exit(void)
{
obex_service_driver_unregister(&ftp);
- obex_service_driver_unregister(&pcsuite);
}
OBEX_PLUGIN_DEFINE(ftp, ftp_init, ftp_exit)
diff --git a/plugins/nokia-backup.c b/plugins/nokia-backup.c
deleted file mode 100644
index cf17e16..0000000
--- a/plugins/nokia-backup.c
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- *
- * OBEX Server
- *
- * Copyright (C) 2010 Nokia Corporation
- * Copyright (C) 2010 Marcel Holtmann <marcel@holtmann.org>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/statvfs.h>
-#include <fcntl.h>
-#include <wait.h>
-
-#include <glib.h>
-#include "gdbus.h"
-
-
-#include <openobex/obex.h>
-#include <openobex/obex_const.h>
-
-#include "plugin.h"
-#include "log.h"
-#include "obex.h"
-#include "mimetype.h"
-#include "service.h"
-
-#define BACKUP_BUS_NAME "com.nokia.backup.plugin"
-#define BACKUP_PATH "/com/nokia/backup"
-#define BACKUP_PLUGIN_INTERFACE "com.nokia.backup.plugin"
-#define BACKUP_DBUS_TIMEOUT (1000 * 60 * 15)
-
-static const uint8_t FTP_TARGET[TARGET_SIZE] = {
- 0xF9, 0xEC, 0x7B, 0xC4, 0x95, 0x3C, 0x11, 0xD2,
- 0x98, 0x4E, 0x52, 0x54, 0x00, 0xDC, 0x9E, 0x09 };
-
-struct backup_object{
- gchar *cmd;
- int fd;
- int oflag;
- int error_code;
- mode_t mode;
- DBusPendingCall *pending_call;
- DBusConnection *conn;
-};
-
-static void on_backup_dbus_notify(DBusPendingCall *pending_call,
- void *user_data)
-{
- struct backup_object *obj = user_data;
- DBusMessage *reply;
- const char *filename;
- int error_code;
-
- DBG("Notification received for pending call - %s", obj->cmd);
-
- reply = dbus_pending_call_steal_reply(pending_call);
-
- if (reply && dbus_message_get_args(reply, NULL, DBUS_TYPE_INT32,
- &error_code, DBUS_TYPE_STRING,
- &filename, DBUS_TYPE_INVALID)) {
-
- obj->error_code = error_code;
-
- if (filename) {
- DBG("Notification - file path = %s, error_code = %d",
- filename, error_code);
- if (error_code == 0)
- obj->fd = open(filename,obj->oflag,obj->mode);
- }
-
- } else
- DBG("Notification timed out or connection got closed");
-
- if (reply)
- dbus_message_unref(reply);
-
- dbus_pending_call_unref(pending_call);
- obj->pending_call = NULL;
- dbus_connection_unref(obj->conn);
- obj->conn = NULL;
-
- if (obj->fd >= 0) {
- DBG("File opened, setting io flags, cmd = %s",
- obj->cmd);
- if (obj->oflag == O_RDONLY)
- obex_object_set_io_flags(user_data, G_IO_IN, 0);
- else
- obex_object_set_io_flags(user_data, G_IO_OUT, 0);
- } else {
- DBG("File open error, setting io error, cmd = %s",
- obj->cmd);
- obex_object_set_io_flags(user_data, G_IO_ERR, -EPERM);
- }
-}
-
-static gboolean send_backup_dbus_message(const char *oper,
- struct backup_object *obj,
- size_t *size)
-{
- DBusConnection *conn;
- DBusMessage *msg;
- DBusPendingCall *pending_call;
- gboolean ret = FALSE;
- dbus_uint32_t file_size;
-
- file_size = size ? *size : 0;
-
- conn = g_dbus_setup_bus(DBUS_BUS_SESSION, NULL, NULL);
-
- if (conn == NULL)
- return FALSE;
-
- msg = dbus_message_new_method_call(BACKUP_BUS_NAME, BACKUP_PATH,
- BACKUP_PLUGIN_INTERFACE,
- "request");
- if (msg == NULL) {
- dbus_connection_unref(conn);
- return FALSE;
- }
-
- dbus_message_append_args(msg, DBUS_TYPE_STRING, &oper,
- DBUS_TYPE_STRING, &obj->cmd,
- DBUS_TYPE_INT32, &file_size,
- DBUS_TYPE_INVALID);
-
- if (strcmp(oper, "open") == 0) {
- ret = dbus_connection_send_with_reply(conn, msg, &pending_call,
- BACKUP_DBUS_TIMEOUT);
- dbus_message_unref(msg);
- if (ret) {
- obj->conn = conn;
- obj->pending_call = pending_call;
- ret = dbus_pending_call_set_notify(pending_call,
- on_backup_dbus_notify,
- obj, NULL);
- } else
- dbus_connection_unref(conn);
- } else {
- ret = dbus_connection_send(conn, msg, NULL);
- dbus_message_unref(msg);
- dbus_connection_unref(conn);
- }
-
- return ret;
-}
-
-static void *backup_open(const char *name, int oflag, mode_t mode,
- void *context, size_t *size, int *err)
-{
- struct backup_object *obj = g_new0(struct backup_object, 1);
-
- DBG("cmd = %s", name);
-
- obj->cmd = g_path_get_basename(name);
- obj->oflag = oflag;
- obj->mode = mode;
- obj->fd = -1;
- obj->pending_call = NULL;
- obj->conn = NULL;
- obj->error_code = 0;
-
- if (send_backup_dbus_message("open", obj, size) == FALSE) {
- g_free(obj);
- obj = NULL;
- }
-
- if (err)
- *err = 0;
-
- return obj;
-}
-
-static int backup_close(void *object)
-{
- struct backup_object *obj = object;
- size_t size = 0;
-
- DBG("cmd = %s", obj->cmd);
-
- if (obj->fd != -1)
- close(obj->fd);
-
- if (obj->pending_call) {
- dbus_pending_call_cancel(obj->pending_call);
- dbus_pending_call_unref(obj->pending_call);
- dbus_connection_unref(obj->conn);
- }
-
- send_backup_dbus_message("close", obj, &size);
-
- g_free(obj->cmd);
- g_free(obj);
-
- return 0;
-}
-
-static ssize_t backup_read(void *object, void *buf, size_t count,
- uint8_t *hi, unsigned int *flags)
-{
- struct backup_object *obj = object;
- ssize_t ret = 0;
-
- *hi = OBEX_HDR_BODY;
-
- if (flags)
- *flags = 0;
-
- if (obj->pending_call) {
- DBG("cmd = %s, IN WAITING STAGE", obj->cmd);
- return -EAGAIN;
- }
-
- if (obj->fd != -1) {
- DBG("cmd = %s, READING DATA", obj->cmd);
- ret = read(obj->fd, buf, count);
- if (ret < 0)
- ret = -errno;
- } else {
- DBG("cmd = %s, PERMANENT FAILURE", obj->cmd);
- ret = obj->error_code ? -obj->error_code : -ENOENT;
- }
-
- return ret;
-}
-
-static ssize_t backup_write(void *object, const void *buf, size_t count)
-{
- struct backup_object *obj = object;
- ssize_t ret = 0;
-
- if (obj->pending_call) {
- DBG("cmd = %s, IN WAITING STAGE", obj->cmd);
- return -EAGAIN;
- }
-
- if (obj->fd != -1) {
- ret = write(obj->fd, buf, count);
-
- DBG("cmd = %s, WRITTING", obj->cmd);
-
- if (ret < 0) {
- error("backup: cmd = %s", obj->cmd);
- ret = -errno;
- }
- } else {
- error("backup: cmd = %s", obj->cmd);
- ret = obj->error_code ? -obj->error_code : -ENOENT;
- }
-
- return ret;
-}
-
-static int backup_flush(void *object)
-{
- DBG("%p", object);
-
- return 0;
-}
-
-static struct obex_mime_type_driver backup = {
- .target = FTP_TARGET,
- .target_size = TARGET_SIZE,
- .mimetype = "application/vnd.nokia-backup",
- .open = backup_open,
- .close = backup_close,
- .read = backup_read,
- .write = backup_write,
- .flush = backup_flush,
-};
-
-static int backup_init(void)
-{
- return obex_mime_type_driver_register(&backup);
-}
-
-static void backup_exit(void)
-{
- obex_mime_type_driver_unregister(&backup);
-}
-
-OBEX_PLUGIN_DEFINE(backup, backup_init, backup_exit)
--
1.7.1
^ permalink raw reply related
* [PATCH 4/6] Add .flush callback to backup plugin
From: Luiz Augusto von Dentz @ 2011-02-23 9:54 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1298454881-7941-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
---
plugins/nokia-backup.c | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/plugins/nokia-backup.c b/plugins/nokia-backup.c
index 4a69d8f..cf17e16 100644
--- a/plugins/nokia-backup.c
+++ b/plugins/nokia-backup.c
@@ -278,6 +278,13 @@ static ssize_t backup_write(void *object, const void *buf, size_t count)
return ret;
}
+static int backup_flush(void *object)
+{
+ DBG("%p", object);
+
+ return 0;
+}
+
static struct obex_mime_type_driver backup = {
.target = FTP_TARGET,
.target_size = TARGET_SIZE,
@@ -286,6 +293,7 @@ static struct obex_mime_type_driver backup = {
.close = backup_close,
.read = backup_read,
.write = backup_write,
+ .flush = backup_flush,
};
static int backup_init(void)
--
1.7.1
^ permalink raw reply related
* [PATCH 3/6] Add flush callback to mimetype driver
From: Luiz Augusto von Dentz @ 2011-02-23 9:54 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1298454881-7941-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
This add the possibility to a driver to flush its data when final packet
is received which is specially usefull for PUT to prevent auto response
for objects with no body/body empty/size 0.
Note that it should not block like fsync, instead it is assumed to always
be asyncronous so request is suspended when .flush returns > 0, the
driver should then use obex_object_set_io_flags to indicate that it has
completed the operation.
---
src/mimetype.h | 1 +
src/obex.c | 26 ++++++++++++++++++++++++--
2 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/src/mimetype.h b/src/mimetype.h
index ff16a8c..5bf741c 100644
--- a/src/mimetype.h
+++ b/src/mimetype.h
@@ -36,6 +36,7 @@ struct obex_mime_type_driver {
ssize_t (*read) (void *object, void *buf, size_t count, uint8_t *hi,
unsigned int *flags);
ssize_t (*write) (void *object, const void *buf, size_t count);
+ int (*flush) (void *object);
int (*remove) (const char *name);
int (*set_io_watch) (void *object, obex_object_io_func func,
void *user_data);
diff --git a/src/obex.c b/src/obex.c
index f2a21b7..caba2fb 100644
--- a/src/obex.c
+++ b/src/obex.c
@@ -613,6 +613,11 @@ write:
os->pending -= w;
}
+ /* Flush on EOS */
+ if (os->size != OBJECT_SIZE_UNKNOWN && os->size == os->offset &&
+ os->driver->flush)
+ return os->driver->flush(os->object) > 0 ? -EAGAIN : 0;
+
return 0;
}
@@ -702,7 +707,7 @@ static gboolean handle_async_io(void *object, int flags, int err,
if (flags & (G_IO_IN | G_IO_PRI))
ret = obex_write_stream(os, os->obex, os->obj);
- else if (flags & G_IO_OUT)
+ else if ((flags & G_IO_OUT) && os->pending > 0)
ret = obex_read_stream(os, os->obex, os->obj);
proceed:
@@ -1089,8 +1094,25 @@ static void cmd_put(struct obex_session *os, obex_t *obex, obex_object_t *obj)
}
err = os->service->put(os, obj, os->service_data);
- if (err < 0)
+ if (err < 0) {
os_set_response(obj, err);
+ return;
+ }
+
+ /* Check if there is a body and it is not empty (size > 0), otherwise
+ openobex won't notify us with OBEX_EV_STREAMAVAIL and it gonna reply
+ right away */
+ if (os->size != 0)
+ return;
+
+ /* Flush immediatly since there is nothing to write so the driver
+ has a chance to do something before we reply */
+ if (os->object && os->driver && os->driver->flush &&
+ os->driver->flush(os->object) > 0) {
+ OBEX_SuspendRequest(obex, obj);
+ os->obj = obj;
+ os->driver->set_io_watch(os->object, handle_async_io, os);
+ }
}
static void obex_event_cb(obex_t *obex, obex_object_t *obj, int mode,
--
1.7.1
^ permalink raw reply related
* [PATCH 2/6] Add more debug logs for ftp driver
From: Luiz Augusto von Dentz @ 2011-02-23 9:54 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1298454881-7941-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
---
plugins/ftp.c | 20 ++++++++++++++++++++
1 files changed, 20 insertions(+), 0 deletions(-)
diff --git a/plugins/ftp.c b/plugins/ftp.c
index 546b58c..633abf3 100644
--- a/plugins/ftp.c
+++ b/plugins/ftp.c
@@ -158,6 +158,8 @@ struct pcsuite_session {
static void set_folder(struct ftp_session *ftp, const char *new_folder)
{
+ DBG("%p folder %s", ftp, new_folder);
+
g_free(ftp->folder);
ftp->folder = new_folder ? g_strdup(new_folder) : NULL;
@@ -171,6 +173,8 @@ static int get_by_type(struct ftp_session *ftp, const char *type)
char *path;
int err;
+ DBG("%p name %s type %s", ftp, name, type);
+
if (type == NULL && name == NULL)
return -EBADR;
@@ -190,6 +194,8 @@ static void *ftp_connect(struct obex_session *os, int *err)
struct ftp_session *ftp;
const char *root_folder;
+ DBG("");
+
root_folder = obex_get_root_folder(os);
manager_register_session(os);
@@ -201,6 +207,8 @@ static void *ftp_connect(struct obex_session *os, int *err)
if (err)
*err = 0;
+ DBG("session %p created", ftp);
+
return ftp;
}
@@ -211,6 +219,8 @@ static int ftp_get(struct obex_session *os, obex_object_t *obj,
const char *type = obex_get_type(os);
int ret;
+ DBG("%p", ftp);
+
if (ftp->folder == NULL)
return -ENOENT;
@@ -229,6 +239,8 @@ static int ftp_delete(struct ftp_session *ftp, const char *name)
char *path;
int ret = 0;
+ DBG("%p name %s", ftp, name);
+
if (!(ftp->folder && name))
return -EINVAL;
@@ -249,6 +261,8 @@ static int ftp_chkput(struct obex_session *os, void *user_data)
char *path;
int ret;
+ DBG("%p name %s", ftp, name);
+
if (name == NULL)
return -EBADR;
@@ -271,6 +285,8 @@ static int ftp_put(struct obex_session *os, obex_object_t *obj,
const char *name = obex_get_name(os);
ssize_t size = obex_get_size(os);
+ DBG("%p name %s size %zd", ftp, name, size);
+
if (ftp->folder == NULL)
return -EPERM;
@@ -303,6 +319,8 @@ static int ftp_setpath(struct obex_session *os, obex_object_t *obj,
root_folder = obex_get_root_folder(os);
root = g_str_equal(root_folder, ftp->folder);
+ DBG("%p name %s", ftp, name);
+
/* Check flag "Backup" */
if ((nonhdr[0] & 0x01) == 0x01) {
DBG("Set to parent path");
@@ -390,6 +408,8 @@ static void ftp_disconnect(struct obex_session *os, void *user_data)
{
struct ftp_session *ftp = user_data;
+ DBG("%p", ftp);
+
manager_unregister_session(os);
g_free(ftp->folder);
--
1.7.1
^ permalink raw reply related
* [PATCH 1/6] Add support for pcsuite lock file
From: Luiz Augusto von Dentz @ 2011-02-23 9:54 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
This should make others applications able to detect when pcsuite is
connected.
---
plugins/ftp.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 134 insertions(+), 6 deletions(-)
diff --git a/plugins/ftp.c b/plugins/ftp.c
index a952f64..546b58c 100644
--- a/plugins/ftp.c
+++ b/plugins/ftp.c
@@ -150,6 +150,12 @@ struct ftp_session {
char *folder;
};
+struct pcsuite_session {
+ struct ftp_session *ftp;
+ char *lock_file;
+ int fd;
+};
+
static void set_folder(struct ftp_session *ftp, const char *new_folder)
{
g_free(ftp->folder);
@@ -390,6 +396,128 @@ static void ftp_disconnect(struct obex_session *os, void *user_data)
g_free(ftp);
}
+static void *pcsuite_connect(struct obex_session *os, int *err)
+{
+ struct pcsuite_session *pcsuite;
+ struct ftp_session *ftp;
+ int fd;
+ char *filename;
+
+ DBG("");
+
+ ftp = ftp_connect(os, err);
+ if (ftp == NULL)
+ return NULL;
+
+ filename = g_build_filename(g_get_home_dir(), ".pcsuite", NULL);
+
+ fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0644);
+ if (fd < 0 && errno != EEXIST) {
+ error("open(%s): %s(%d)", filename, strerror(errno), errno);
+ goto fail;
+ }
+
+ /* Try to remove the file before retrying since it could be
+ that some process left/crash without removing it */
+ if (fd < 0) {
+ if (remove(filename) < 0) {
+ error("remove(%s): %s(%d)", filename, strerror(errno),
+ errno);
+ goto fail;
+ }
+
+ fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0644);
+ if (fd < 0) {
+ error("open(%s): %s(%d)", filename, strerror(errno),
+ errno);
+ goto fail;
+ }
+ }
+
+ DBG("%s created", filename);
+
+ pcsuite = g_new0(struct pcsuite_session, 1);
+ pcsuite->ftp = ftp;
+ pcsuite->lock_file = filename;
+ pcsuite->fd = fd;
+
+ DBG("session %p created", pcsuite);
+
+ if (err)
+ *err = 0;
+
+ return pcsuite;
+
+fail:
+ if (ftp)
+ ftp_disconnect(os, ftp);
+ if (err)
+ *err = -errno;
+
+ g_free(filename);
+
+ return NULL;
+}
+
+static int pcsuite_get(struct obex_session *os, obex_object_t *obj,
+ gboolean *stream, void *user_data)
+{
+ struct pcsuite_session *pcsuite = user_data;
+
+ DBG("%p", pcsuite);
+
+ return ftp_get(os, obj, stream, pcsuite->ftp);
+}
+
+static int pcsuite_chkput(struct obex_session *os, void *user_data)
+{
+ struct pcsuite_session *pcsuite = user_data;
+
+ DBG("%p", pcsuite);
+
+ return ftp_chkput(os, pcsuite->ftp);
+}
+
+static int pcsuite_put(struct obex_session *os, obex_object_t *obj,
+ void *user_data)
+{
+ struct pcsuite_session *pcsuite = user_data;
+
+ DBG("%p", pcsuite);
+
+ return ftp_put(os, obj, pcsuite->ftp);
+}
+
+static int pcsuite_setpath(struct obex_session *os, obex_object_t *obj,
+ void *user_data)
+{
+ struct pcsuite_session *pcsuite = user_data;
+
+ DBG("%p", pcsuite);
+
+ return ftp_setpath(os, obj, pcsuite->ftp);
+}
+
+static void pcsuite_disconnect(struct obex_session *os, void *user_data)
+{
+ struct pcsuite_session *pcsuite = user_data;
+
+ DBG("%p", pcsuite);
+
+ if (pcsuite->fd >= 0)
+ close(pcsuite->fd);
+
+ if (pcsuite->lock_file) {
+ remove(pcsuite->lock_file);
+ g_free(pcsuite->lock_file);
+ }
+
+ if (pcsuite->ftp)
+ ftp_disconnect(os, pcsuite->ftp);
+
+ g_free(pcsuite);
+}
+
static struct obex_service_driver pcsuite = {
.name = "Nokia OBEX PC Suite Services",
.service = OBEX_PCSUITE,
@@ -399,12 +527,12 @@ static struct obex_service_driver pcsuite = {
.target_size = TARGET_SIZE,
.who = PCSUITE_WHO,
.who_size = PCSUITE_WHO_SIZE,
- .connect = ftp_connect,
- .get = ftp_get,
- .put = ftp_put,
- .chkput = ftp_chkput,
- .setpath = ftp_setpath,
- .disconnect = ftp_disconnect
+ .connect = pcsuite_connect,
+ .get = pcsuite_get,
+ .put = pcsuite_put,
+ .chkput = pcsuite_chkput,
+ .setpath = pcsuite_setpath,
+ .disconnect = pcsuite_disconnect
};
static struct obex_service_driver ftp = {
--
1.7.1
^ permalink raw reply related
* [PATCH 4/4] HCI command to clear LE White List
From: Arun Kumar SINGH @ 2011-02-23 7:20 UTC (permalink / raw)
To: linux-bluetooth@vger.kernel.org
>From 1142406b33f6f279ee6913e0327e922c93c32e16 Mon Sep 17 00:00:00 2001
From: ArunKumarSingh <arunkr.singh@stericsson.com>
Date: Wed, 23 Feb 2011 12:26:39 +0530
Subject: [PATCH] HCI command to clear LE White list
Signed-off-by: ArunKumarSingh <arunkr.singh@stericsson.com>
---
lib/hci.c | 22 ++++++++++++++++++++++
lib/hci_lib.h | 1 +
tools/hcitool.c | 42 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 65 insertions(+), 0 deletions(-)
diff --git a/lib/hci.c b/lib/hci.c
index 2f36448..43f596f 100755
--- a/lib/hci.c
+++ b/lib/hci.c
@@ -1377,6 +1377,28 @@ int hci_le_read_white_list_size(int dd, int *size)
return 0;
}
+int hci_le_clear_white_list(int dd)
+{
+ struct hci_request rq;
+ uint8_t status;
+
+ memset(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_CLEAR_WHITE_LIST;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(dd, &rq, 1000) < 0)
+ return -1;
+
+ if (status) {
+ errno = EIO;
+ return -1;
+ }
+
+ return 0;
+}
+
int hci_read_local_name(int dd, int len, char *name, int to)
{
read_local_name_rp rp;
diff --git a/lib/hci_lib.h b/lib/hci_lib.h
index d5f07f6..c86b0de 100755
--- a/lib/hci_lib.h
+++ b/lib/hci_lib.h
@@ -130,6 +130,7 @@ int hci_le_create_conn(int dd, uint16_t interval, uint16_t window,
int hci_le_add_to_white_list(int dd, const bdaddr_t *bdaddr, uint8_t type);
int hci_le_remove_from_white_list(int dd, const bdaddr_t *bdaddr, uint8_t type);
int hci_le_read_white_list_size(int dd, int *size);
+int hci_le_clear_white_list(int dd);
int hci_for_each_dev(int flag, int(*func)(int dd, int dev_id, long arg), long arg);
int hci_get_route(bdaddr_t *bdaddr);
diff --git a/tools/hcitool.c b/tools/hcitool.c
index fa65c4e..8ec4c20 100755
--- a/tools/hcitool.c
+++ b/tools/hcitool.c
@@ -2620,6 +2620,47 @@ static void cmd_lerdwlsz(int dev_id, int argc, char **argv)
}
}
+static struct option leclrwl_options[] = {
+ { "help", 0, 0, 'h' },
+ { 0, 0, 0, 0 }
+};
+
+static const char *leclrwl_help =
+ "Usage:\n"
+ "\tleclrwl\n";
+
+static void cmd_leclrwl(int dev_id, int argc, char **argv)
+{
+ int err, dd, opt;
+
+ for_each_opt(opt, leclrwl_options, NULL) {
+ switch (opt) {
+ default:
+ printf("%s", leclrwl_help);
+ return;
+ }
+ }
+
+ helper_arg(0, 0, &argc, &argv, leclrwl_help);
+
+ if (dev_id < 0)
+ dev_id = hci_get_route(NULL);
+
+ dd = hci_open_dev(dev_id);
+ if (dd < 0) {
+ perror("Could not open device");
+ exit(1);
+ }
+
+ err = hci_le_clear_white_list(dd);
+ hci_close_dev(dd);
+
+ if (err < 0) {
+ perror("Cant clear white list");
+ exit(1);
+ }
+}
+
static struct option ledc_options[] = {
{ "help", 0, 0, 'h' },
{ 0, 0, 0, 0 }
@@ -2699,6 +2740,7 @@ static struct {
{ "leaddwl", cmd_leaddwl, "Add this device to white list" },
{ "lermwl", cmd_lermwl, "Remove this device from white list" },
{ "lerdwlsz", cmd_lerdwlsz, "Read white list size" },
+ { "leclrwl", cmd_leclrwl, "Clear white list" },
{ "lecc", cmd_lecc, "Create a LE Connection", },
{ "ledc", cmd_ledc, "Disconnect a LE Connection", },
{ NULL, NULL, 0 }
--
1.7.0.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox