summaryrefslogtreecommitdiff
path: root/plugins/neard.c
diff options
context:
space:
mode:
authorSzymon Janc <szymon.janc@tieto.com>2013-02-07 09:13:53 +0100
committerJohan Hedberg <johan.hedberg@intel.com>2013-02-15 10:38:49 +0200
commitfe7f8fd83acb496c76fd1255492911fb844f3bfe (patch)
tree4572cf8d4317b76f728adad5823e6171e1603948 /plugins/neard.c
parentac83286bb216ec49371d84673773f55fbc5b2127 (diff)
downloadbluez-fe7f8fd83acb496c76fd1255492911fb844f3bfe.tar.gz
neard: Add ability to parse 'State' field
This contains hint for power state of remote device Bluetooth adapter.
Diffstat (limited to 'plugins/neard.c')
-rw-r--r--plugins/neard.c125
1 files changed, 92 insertions, 33 deletions
diff --git a/plugins/neard.c b/plugins/neard.c
index 7df4544e8..668c46f53 100644
--- a/plugins/neard.c
+++ b/plugins/neard.c
@@ -55,6 +55,13 @@ static gboolean agent_register_postpone = FALSE;
/* For NFC mimetype limits max OOB EIR size */
#define NFC_OOB_EIR_MAX UINT8_MAX
+enum cps {
+ CPS_ACTIVE,
+ CPS_INACTIVE,
+ CPS_ACTIVATING,
+ CPS_UNKNOWN,
+};
+
struct oob_params {
bdaddr_t address;
uint32_t class;
@@ -64,6 +71,7 @@ struct oob_params {
uint8_t *randomizer;
uint8_t *pin;
int pin_len;
+ enum cps power_state;
};
static void free_oob_params(struct oob_params *params)
@@ -451,14 +459,24 @@ static int process_nokia_com_bt(uint8_t *data, size_t size,
}
}
+static enum cps process_state(const char *state)
+{
+ if (strcasecmp(state, "active") == 0)
+ return CPS_ACTIVE;
+
+ if (strcasecmp(state, "activating") == 0)
+ return CPS_ACTIVATING;
+
+ if (strcasecmp(state, "inactive") == 0)
+ return CPS_INACTIVE;
+
+ return CPS_UNKNOWN;
+}
+
static int process_message(DBusMessage *msg, struct oob_params *remote)
{
DBusMessageIter iter;
DBusMessageIter dict;
- DBusMessageIter value;
- DBusMessageIter entry;
- const char *key;
- int type;
dbus_message_iter_init(msg, &iter);
@@ -467,46 +485,87 @@ static int process_message(DBusMessage *msg, struct oob_params *remote)
dbus_message_iter_recurse(&iter, &dict);
- type = dbus_message_iter_get_arg_type(&dict);
- if (type != DBUS_TYPE_DICT_ENTRY) {
- if (type == DBUS_TYPE_INVALID)
- return -ENOENT;
+ while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
+ DBusMessageIter value;
+ DBusMessageIter entry;
+ const char *key;
- return -EINVAL;
- }
+ dbus_message_iter_recurse(&dict, &entry);
- dbus_message_iter_recurse(&dict, &entry);
+ if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
+ goto error;
- if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
- return -EINVAL;
+ dbus_message_iter_get_basic(&entry, &key);
+ dbus_message_iter_next(&entry);
- dbus_message_iter_get_basic(&entry, &key);
- dbus_message_iter_next(&entry);
+ dbus_message_iter_recurse(&entry, &value);
- dbus_message_iter_recurse(&entry, &value);
+ if (strcasecmp(key, "EIR") == 0) {
+ DBusMessageIter array;
+ uint8_t *eir;
+ int size;
- /* All keys have byte array type values */
- if (dbus_message_iter_get_arg_type(&value) != DBUS_TYPE_ARRAY)
- return -EINVAL;
+ /* nokia.com:bt and EIR should not be passed together */
+ if (bacmp(&remote->address, BDADDR_ANY) != 0)
+ goto error;
+
+ if (dbus_message_iter_get_arg_type(&value) !=
+ DBUS_TYPE_ARRAY)
+ goto error;
- if (strcasecmp(key, "EIR") == 0) {
- DBusMessageIter array;
- uint8_t *eir;
- int size;
+ dbus_message_iter_recurse(&value, &array);
+ dbus_message_iter_get_fixed_array(&array, &eir, &size);
- dbus_message_iter_recurse(&value, &array);
- dbus_message_iter_get_fixed_array(&array, &eir, &size);
+ if (process_eir(eir, size, remote) < 0)
+ goto error;
+ } else if (strcasecmp(key, "nokia.com:bt") == 0) {
+ DBusMessageIter array;
+ uint8_t *data;
+ int size;
- return process_eir(eir, size, remote);
- } else if (strcasecmp(key, "nokia.com:bt") == 0) {
- DBusMessageIter array;
- uint8_t *data;
- int size;
+ /* nokia.com:bt and EIR should not be passed together */
+ if (bacmp(&remote->address, BDADDR_ANY) != 0)
+ goto error;
- dbus_message_iter_recurse(&value, &array);
- dbus_message_iter_get_fixed_array(&array, &data, &size);
+ if (dbus_message_iter_get_arg_type(&value) !=
+ DBUS_TYPE_ARRAY)
+ goto error;
+
+ dbus_message_iter_recurse(&value, &array);
+ dbus_message_iter_get_fixed_array(&array, &data, &size);
+
+ if (process_nokia_com_bt(data, size, remote))
+ goto error;
+ } else if (strcasecmp(key, "State") == 0) {
+ DBusMessageIter array;
+ const char *state;
+
+ if (dbus_message_iter_get_arg_type(&value) !=
+ DBUS_TYPE_STRING)
+ goto error;
+
+ dbus_message_iter_recurse(&value, &array);
+ dbus_message_iter_get_basic(&value, &state);
+
+ remote->power_state = process_state(state);
+ if (remote->power_state == CPS_UNKNOWN)
+ goto error;
+ }
+
+ dbus_message_iter_next(&dict);
+ }
+
+ /* Check if 'State' was passed along with one of other fields */
+ if (remote->power_state != CPS_UNKNOWN
+ && bacmp(&remote->address, BDADDR_ANY) == 0)
+ return -EINVAL;
+
+ return 0;
- return process_nokia_com_bt(data, size, remote);
+error:
+ if (bacmp(&remote->address, BDADDR_ANY) != 0) {
+ free_oob_params(remote);
+ memset(remote, 0, sizeof(*remote));
}
return -EINVAL;