/* 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;
uint8_t *randomizer;
uint8_t *pin;
int pin_len;
+ enum cps power_state;
};
static void free_oob_params(struct oob_params *params)
}
}
+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);
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;