Home | History | Annotate | Download | only in dbus
      1 /*
      2  * WPA Supplicant / dbus-based control interface (WPS)
      3  * Copyright (c) 2006, Dan Williams <dcbw (at) redhat.com> and Red Hat, Inc.
      4  * Copyright (c) 2009, Witold Sowa <witold.sowa (at) gmail.com>
      5  *
      6  * This software may be distributed under the terms of the BSD license.
      7  * See README for more details.
      8  */
      9 
     10 #include "includes.h"
     11 
     12 #include "common.h"
     13 #include "../config.h"
     14 #include "../wpa_supplicant_i.h"
     15 #include "../wps_supplicant.h"
     16 #include "../driver_i.h"
     17 #include "../ap.h"
     18 #include "dbus_new_helpers.h"
     19 #include "dbus_new.h"
     20 #include "dbus_new_handlers.h"
     21 #include "dbus_dict_helpers.h"
     22 
     23 
     24 struct wps_start_params {
     25 	int role; /* 0 - not set, 1 - enrollee, 2 - registrar */
     26 	int type; /* 0 - not set, 1 - pin,      2 - pbc       */
     27 	u8 *bssid;
     28 	char *pin;
     29 	u8 *p2p_dev_addr;
     30 };
     31 
     32 
     33 static int wpas_dbus_handler_wps_role(DBusMessage *message,
     34 				      DBusMessageIter *entry_iter,
     35 				      struct wps_start_params *params,
     36 				      DBusMessage **reply)
     37 {
     38 	DBusMessageIter variant_iter;
     39 	char *val;
     40 
     41 	dbus_message_iter_recurse(entry_iter, &variant_iter);
     42 	if (dbus_message_iter_get_arg_type(&variant_iter) !=
     43 	    DBUS_TYPE_STRING) {
     44 		wpa_printf(MSG_DEBUG,
     45 			   "dbus: WPS.Start - Wrong Role type, string required");
     46 		*reply = wpas_dbus_error_invalid_args(message,
     47 						      "Role must be a string");
     48 		return -1;
     49 	}
     50 	dbus_message_iter_get_basic(&variant_iter, &val);
     51 	if (os_strcmp(val, "enrollee") == 0)
     52 		params->role = 1;
     53 	else if (os_strcmp(val, "registrar") == 0)
     54 		params->role = 2;
     55 	else {
     56 		wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Unknown role %s", val);
     57 		*reply = wpas_dbus_error_invalid_args(message, val);
     58 		return -1;
     59 	}
     60 	return 0;
     61 }
     62 
     63 
     64 static int wpas_dbus_handler_wps_type(DBusMessage *message,
     65 				      DBusMessageIter *entry_iter,
     66 				      struct wps_start_params *params,
     67 				      DBusMessage **reply)
     68 {
     69 	DBusMessageIter variant_iter;
     70 	char *val;
     71 
     72 	dbus_message_iter_recurse(entry_iter, &variant_iter);
     73 	if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_STRING) {
     74 		wpa_printf(MSG_DEBUG,
     75 			   "dbus: WPS.Start - Wrong Type type, string required");
     76 		*reply = wpas_dbus_error_invalid_args(message,
     77 						      "Type must be a string");
     78 		return -1;
     79 	}
     80 	dbus_message_iter_get_basic(&variant_iter, &val);
     81 	if (os_strcmp(val, "pin") == 0)
     82 		params->type = 1;
     83 	else if (os_strcmp(val, "pbc") == 0)
     84 		params->type = 2;
     85 	else {
     86 		wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Unknown type %s",
     87 			   val);
     88 		*reply = wpas_dbus_error_invalid_args(message, val);
     89 		return -1;
     90 	}
     91 	return 0;
     92 }
     93 
     94 
     95 static int wpas_dbus_handler_wps_bssid(DBusMessage *message,
     96 				       DBusMessageIter *entry_iter,
     97 				       struct wps_start_params *params,
     98 				       DBusMessage **reply)
     99 {
    100 	DBusMessageIter variant_iter, array_iter;
    101 	int len;
    102 
    103 	dbus_message_iter_recurse(entry_iter, &variant_iter);
    104 	if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_ARRAY ||
    105 	    dbus_message_iter_get_element_type(&variant_iter) !=
    106 	    DBUS_TYPE_BYTE) {
    107 		wpa_printf(MSG_DEBUG,
    108 			   "dbus: WPS.Start - Wrong Bssid type, byte array required");
    109 		*reply = wpas_dbus_error_invalid_args(
    110 			message, "Bssid must be a byte array");
    111 		return -1;
    112 	}
    113 	dbus_message_iter_recurse(&variant_iter, &array_iter);
    114 	dbus_message_iter_get_fixed_array(&array_iter, &params->bssid, &len);
    115 	if (len != ETH_ALEN) {
    116 		wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Wrong Bssid length %d",
    117 			   len);
    118 		*reply = wpas_dbus_error_invalid_args(message,
    119 						      "Bssid is wrong length");
    120 		return -1;
    121 	}
    122 	return 0;
    123 }
    124 
    125 
    126 static int wpas_dbus_handler_wps_pin(DBusMessage *message,
    127 				     DBusMessageIter *entry_iter,
    128 				     struct wps_start_params *params,
    129 				     DBusMessage **reply)
    130 {
    131 	DBusMessageIter variant_iter;
    132 
    133 	dbus_message_iter_recurse(entry_iter, &variant_iter);
    134 	if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_STRING) {
    135 		wpa_printf(MSG_DEBUG,
    136 			   "dbus: WPS.Start - Wrong Pin type, string required");
    137 		*reply = wpas_dbus_error_invalid_args(message,
    138 						      "Pin must be a string");
    139 		return -1;
    140 	}
    141 	dbus_message_iter_get_basic(&variant_iter, &params->pin);
    142 	return 0;
    143 }
    144 
    145 
    146 #ifdef CONFIG_P2P
    147 static int wpas_dbus_handler_wps_p2p_dev_addr(DBusMessage *message,
    148 					      DBusMessageIter *entry_iter,
    149 					      struct wps_start_params *params,
    150 					      DBusMessage **reply)
    151 {
    152 	DBusMessageIter variant_iter, array_iter;
    153 	int len;
    154 
    155 	dbus_message_iter_recurse(entry_iter, &variant_iter);
    156 	if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_ARRAY ||
    157 	    dbus_message_iter_get_element_type(&variant_iter) !=
    158 	    DBUS_TYPE_BYTE) {
    159 		wpa_printf(MSG_DEBUG,
    160 			   "dbus: WPS.Start - Wrong P2PDeviceAddress type, byte array required");
    161 		*reply = wpas_dbus_error_invalid_args(
    162 			message, "P2PDeviceAddress must be a byte array");
    163 		return -1;
    164 	}
    165 	dbus_message_iter_recurse(&variant_iter, &array_iter);
    166 	dbus_message_iter_get_fixed_array(&array_iter, &params->p2p_dev_addr,
    167 					  &len);
    168 	if (len != ETH_ALEN) {
    169 		wpa_printf(MSG_DEBUG,
    170 			   "dbus: WPS.Start - Wrong P2PDeviceAddress length %d",
    171 			   len);
    172 		*reply = wpas_dbus_error_invalid_args(
    173 			message, "P2PDeviceAddress has wrong length");
    174 		return -1;
    175 	}
    176 	return 0;
    177 }
    178 #endif /* CONFIG_P2P */
    179 
    180 
    181 static int wpas_dbus_handler_wps_start_entry(DBusMessage *message, char *key,
    182 					     DBusMessageIter *entry_iter,
    183 					     struct wps_start_params *params,
    184 					     DBusMessage **reply)
    185 {
    186 	if (os_strcmp(key, "Role") == 0)
    187 		return wpas_dbus_handler_wps_role(message, entry_iter,
    188 						  params, reply);
    189 	else if (os_strcmp(key, "Type") == 0)
    190 		return wpas_dbus_handler_wps_type(message, entry_iter,
    191 						  params, reply);
    192 	else if (os_strcmp(key, "Bssid") == 0)
    193 		return wpas_dbus_handler_wps_bssid(message, entry_iter,
    194 						   params, reply);
    195 	else if (os_strcmp(key, "Pin") == 0)
    196 		return wpas_dbus_handler_wps_pin(message, entry_iter,
    197 						 params, reply);
    198 #ifdef CONFIG_P2P
    199 	else if (os_strcmp(key, "P2PDeviceAddress") == 0)
    200 		return wpas_dbus_handler_wps_p2p_dev_addr(message, entry_iter,
    201 							  params, reply);
    202 #endif /* CONFIG_P2P */
    203 
    204 	wpa_printf(MSG_DEBUG, "dbus: WPS.Start - unknown key %s", key);
    205 	*reply = wpas_dbus_error_invalid_args(message, key);
    206 	return -1;
    207 }
    208 
    209 
    210 /**
    211  * wpas_dbus_handler_wps_start - Start WPS configuration
    212  * @message: Pointer to incoming dbus message
    213  * @wpa_s: %wpa_supplicant data structure
    214  * Returns: DBus message dictionary on success or DBus error on failure
    215  *
    216  * Handler for "Start" method call. DBus dictionary argument contains
    217  * information about role (enrollee or registrar), authorization method
    218  * (pin or push button) and optionally pin and bssid. Returned message
    219  * has a dictionary argument which may contain newly generated pin (optional).
    220  */
    221 DBusMessage * wpas_dbus_handler_wps_start(DBusMessage *message,
    222 					  struct wpa_supplicant *wpa_s)
    223 {
    224 	DBusMessage *reply = NULL;
    225 	DBusMessageIter iter, dict_iter, entry_iter;
    226 	struct wps_start_params params;
    227 	char *key;
    228 	char npin[9] = { '\0' };
    229 	int ret;
    230 
    231 	os_memset(&params, 0, sizeof(params));
    232 	dbus_message_iter_init(message, &iter);
    233 
    234 	dbus_message_iter_recurse(&iter, &dict_iter);
    235 	while (dbus_message_iter_get_arg_type(&dict_iter) ==
    236 	       DBUS_TYPE_DICT_ENTRY) {
    237 		dbus_message_iter_recurse(&dict_iter, &entry_iter);
    238 
    239 		dbus_message_iter_get_basic(&entry_iter, &key);
    240 		dbus_message_iter_next(&entry_iter);
    241 
    242 		if (wpas_dbus_handler_wps_start_entry(message, key,
    243 						      &entry_iter,
    244 						      &params, &reply))
    245 			return reply;
    246 
    247 		dbus_message_iter_next(&dict_iter);
    248 	}
    249 
    250 #ifdef CONFIG_AP
    251 	if (wpa_s->ap_iface && params.type == 1) {
    252 		if (params.pin == NULL) {
    253 			wpa_printf(MSG_DEBUG,
    254 				   "dbus: WPS.Start - Pin required for registrar role");
    255 			return wpas_dbus_error_invalid_args(
    256 				message, "Pin required for registrar role.");
    257 		}
    258 		ret = wpa_supplicant_ap_wps_pin(wpa_s,
    259 						params.bssid,
    260 						params.pin,
    261 						npin, sizeof(npin), 0);
    262 	} else if (wpa_s->ap_iface) {
    263 		ret = wpa_supplicant_ap_wps_pbc(wpa_s,
    264 						params.bssid,
    265 						params.p2p_dev_addr);
    266 	} else
    267 #endif /* CONFIG_AP */
    268 	if (params.role == 0) {
    269 		wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Role not specified");
    270 		return wpas_dbus_error_invalid_args(message,
    271 						    "Role not specified");
    272 	} else if (params.role == 2) {
    273 		if (params.pin == NULL) {
    274 			wpa_printf(MSG_DEBUG,
    275 				   "dbus: WPS.Start - Pin required for registrar role");
    276 			return wpas_dbus_error_invalid_args(
    277 				message, "Pin required for registrar role.");
    278 		}
    279 		ret = wpas_wps_start_reg(wpa_s, params.bssid, params.pin,
    280 					 NULL);
    281 	} else if (params.type == 0) {
    282 		wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Type not specified");
    283 		return wpas_dbus_error_invalid_args(message,
    284 						    "Type not specified");
    285 	} else if (params.type == 1) {
    286 		ret = wpas_wps_start_pin(wpa_s, params.bssid,
    287 					 params.pin, 0,
    288 					 DEV_PW_DEFAULT);
    289 		if (ret > 0)
    290 			os_snprintf(npin, sizeof(npin), "%08d", ret);
    291 	} else {
    292 		ret = wpas_wps_start_pbc(wpa_s, params.bssid, 0);
    293 	}
    294 
    295 	if (ret < 0) {
    296 		wpa_printf(MSG_DEBUG,
    297 			   "dbus: WPS.Start wpas_wps_failed in role %s and key %s",
    298 			   (params.role == 1 ? "enrollee" : "registrar"),
    299 			   (params.type == 0 ? "" :
    300 			    (params.type == 1 ? "pin" : "pbc")));
    301 		return wpas_dbus_error_unknown_error(message,
    302 						     "WPS start failed");
    303 	}
    304 
    305 	reply = dbus_message_new_method_return(message);
    306 	if (!reply)
    307 		return wpas_dbus_error_no_memory(message);
    308 
    309 	dbus_message_iter_init_append(reply, &iter);
    310 	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
    311 	    (os_strlen(npin) > 0 &&
    312 	     !wpa_dbus_dict_append_string(&dict_iter, "Pin", npin)) ||
    313 	    !wpa_dbus_dict_close_write(&iter, &dict_iter)) {
    314 		dbus_message_unref(reply);
    315 		return wpas_dbus_error_no_memory(message);
    316 	}
    317 
    318 	return reply;
    319 }
    320 
    321 
    322 /**
    323  * wpas_dbus_handler_wps_cancel - Cancel ongoing WPS configuration
    324  * @message: Pointer to incoming dbus message
    325  * @wpa_s: %wpa_supplicant data structure
    326  * Returns: NULL on success or DBus error on failure
    327  *
    328  * Handler for "Cancel" method call. Returns NULL if WPS cancel successful
    329  * or DBus error on WPS cancel failure
    330  */
    331 DBusMessage * wpas_dbus_handler_wps_cancel(DBusMessage *message,
    332 					   struct wpa_supplicant *wpa_s)
    333 {
    334 	if (wpas_wps_cancel(wpa_s))
    335 		return wpas_dbus_error_unknown_error(message,
    336 						     "WPS cancel failed");
    337 
    338 	return NULL;
    339 }
    340 
    341 
    342 /**
    343  * wpas_dbus_getter_process_credentials - Check if credentials are processed
    344  * @message: Pointer to incoming dbus message
    345  * @wpa_s: %wpa_supplicant data structure
    346  * Returns: TRUE on success, FALSE on failure
    347  *
    348  * Getter for "ProcessCredentials" property. Returns returned boolean will be
    349  * true if wps_cred_processing configuration field is not equal to 1 or false
    350  * if otherwise.
    351  */
    352 dbus_bool_t wpas_dbus_getter_process_credentials(
    353 	const struct wpa_dbus_property_desc *property_desc,
    354 	DBusMessageIter *iter, DBusError *error, void *user_data)
    355 {
    356 	struct wpa_supplicant *wpa_s = user_data;
    357 	dbus_bool_t process = wpa_s->conf->wps_cred_processing != 1;
    358 
    359 	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
    360 						&process, error);
    361 }
    362 
    363 
    364 /**
    365  * wpas_dbus_setter_process_credentials - Set credentials_processed conf param
    366  * @iter: Pointer to incoming dbus message iter
    367  * @error: Location to store error on failure
    368  * @user_data: Function specific data
    369  * Returns: TRUE on success, FALSE on failure
    370  *
    371  * Setter for "ProcessCredentials" property. Sets credentials_processed on 2
    372  * if boolean argument is true or on 1 if otherwise.
    373  */
    374 dbus_bool_t wpas_dbus_setter_process_credentials(
    375 	const struct wpa_dbus_property_desc *property_desc,
    376 	DBusMessageIter *iter, DBusError *error, void *user_data)
    377 {
    378 	struct wpa_supplicant *wpa_s = user_data;
    379 	dbus_bool_t process_credentials, old_pc;
    380 
    381 	if (!wpa_s->dbus_new_path)
    382 		return FALSE;
    383 	if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_BOOLEAN,
    384 					      &process_credentials))
    385 		return FALSE;
    386 
    387 	old_pc = wpa_s->conf->wps_cred_processing != 1;
    388 	wpa_s->conf->wps_cred_processing = (process_credentials ? 2 : 1);
    389 
    390 	if ((wpa_s->conf->wps_cred_processing != 1) != old_pc)
    391 		wpa_dbus_mark_property_changed(wpa_s->global->dbus,
    392 					       wpa_s->dbus_new_path,
    393 					       WPAS_DBUS_NEW_IFACE_WPS,
    394 					       "ProcessCredentials");
    395 
    396 	return TRUE;
    397 }
    398 
    399 
    400 /**
    401  * wpas_dbus_getter_config_methods - Get current WPS configuration methods
    402  * @iter: Pointer to incoming dbus message iter
    403  * @error: Location to store error on failure
    404  * @user_data: Function specific data
    405  * Returns: TRUE on success, FALSE on failure
    406  *
    407  * Getter for "ConfigMethods" property. Returned boolean will be true if
    408  * providing the relevant string worked, or false otherwise.
    409  */
    410 dbus_bool_t wpas_dbus_getter_config_methods(
    411 	const struct wpa_dbus_property_desc *property_desc,
    412 	DBusMessageIter *iter, DBusError *error, void *user_data)
    413 {
    414 	struct wpa_supplicant *wpa_s = user_data;
    415 
    416 	return wpas_dbus_string_property_getter(iter,
    417 						wpa_s->conf->config_methods,
    418 						error);
    419 }
    420 
    421 
    422 /**
    423  * wpas_dbus_setter_config_methods - Set WPS configuration methods
    424  * @iter: Pointer to incoming dbus message iter
    425  * @error: Location to store error on failure
    426  * @user_data: Function specific data
    427  * Returns: TRUE on success, FALSE on failure
    428  *
    429  * Setter for "ConfigMethods" property. Sets the methods string, apply such
    430  * change and returns true on success. Returns false otherwise.
    431  */
    432 dbus_bool_t wpas_dbus_setter_config_methods(
    433 	const struct wpa_dbus_property_desc *property_desc,
    434 	DBusMessageIter *iter, DBusError *error, void *user_data)
    435 {
    436 	struct wpa_supplicant *wpa_s = user_data;
    437 	char *methods, *new_methods;
    438 
    439 	if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING,
    440 					      &methods))
    441 		return FALSE;
    442 
    443 	new_methods = os_strdup(methods);
    444 	if (!new_methods)
    445 		return FALSE;
    446 
    447 	os_free(wpa_s->conf->config_methods);
    448 	wpa_s->conf->config_methods = new_methods;
    449 
    450 	wpa_s->conf->changed_parameters |= CFG_CHANGED_CONFIG_METHODS;
    451 	wpa_supplicant_update_config(wpa_s);
    452 
    453 	return TRUE;
    454 }
    455 
    456 
    457 /**
    458  * wpas_dbus_getter_wps_device_name - Get current WPS device name
    459  * @iter: Pointer to incoming dbus message iter
    460  * @error: Location to store error on failure
    461  * @user_data: Function specific data
    462  * Returns: TRUE on success, FALSE on failure
    463  *
    464  * Getter for "DeviceName" property.
    465  */
    466 dbus_bool_t wpas_dbus_getter_wps_device_name(
    467 	const struct wpa_dbus_property_desc *property_desc,
    468 	DBusMessageIter *iter, DBusError *error, void *user_data)
    469 {
    470 	struct wpa_supplicant *wpa_s = user_data;
    471 
    472 	return wpas_dbus_string_property_getter(iter, wpa_s->conf->device_name,
    473 						error);
    474 }
    475 
    476 
    477 /**
    478  * wpas_dbus_setter_wps_device_name - Set current WPS device name
    479  * @iter: Pointer to incoming dbus message iter
    480  * @error: Location to store error on failure
    481  * @user_data: Function specific data
    482  * Returns: TRUE on success, FALSE on failure
    483  *
    484  * Setter for "DeviceName" property.
    485  */
    486 dbus_bool_t wpas_dbus_setter_wps_device_name(
    487 	const struct wpa_dbus_property_desc *property_desc,
    488 	DBusMessageIter *iter, DBusError *error, void *user_data)
    489 {
    490 	struct wpa_supplicant *wpa_s = user_data;
    491 	char *methods, *devname;
    492 
    493 	if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING,
    494 					      &methods))
    495 		return FALSE;
    496 
    497 	if (os_strlen(methods) > WPS_DEV_NAME_MAX_LEN)
    498 		return FALSE;
    499 
    500 	devname = os_strdup(methods);
    501 	if (!devname)
    502 		return FALSE;
    503 
    504 	os_free(wpa_s->conf->device_name);
    505 	wpa_s->conf->device_name = devname;
    506 	wpa_s->conf->changed_parameters |= CFG_CHANGED_DEVICE_NAME;
    507 	wpa_supplicant_update_config(wpa_s);
    508 
    509 	return TRUE;
    510 }
    511 
    512 
    513 /**
    514  * wpas_dbus_getter_wps_manufacturer - Get current manufacturer name
    515  * @iter: Pointer to incoming dbus message iter
    516  * @error: Location to store error on failure
    517  * @user_data: Function specific data
    518  * Returns: TRUE on success, FALSE on failure
    519  *
    520  * Getter for "Manufacturer" property.
    521  */
    522 dbus_bool_t wpas_dbus_getter_wps_manufacturer(
    523 	const struct wpa_dbus_property_desc *property_desc,
    524 	DBusMessageIter *iter, DBusError *error, void *user_data)
    525 {
    526 	struct wpa_supplicant *wpa_s = user_data;
    527 
    528 	return wpas_dbus_string_property_getter(iter, wpa_s->conf->manufacturer,
    529 						error);
    530 }
    531 
    532 
    533 /**
    534  * wpas_dbus_setter_wps_manufacturer - Set current manufacturer name
    535  * @iter: Pointer to incoming dbus message iter
    536  * @error: Location to store error on failure
    537  * @user_data: Function specific data
    538  * Returns: TRUE on success, FALSE on failure
    539  *
    540  * Setter for "Manufacturer" property.
    541  */
    542 dbus_bool_t wpas_dbus_setter_wps_manufacturer(
    543 	const struct wpa_dbus_property_desc *property_desc,
    544 	DBusMessageIter *iter, DBusError *error, void *user_data)
    545 {
    546 	struct wpa_supplicant *wpa_s = user_data;
    547 	char *methods, *manufacturer;
    548 
    549 	if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING,
    550 					      &methods))
    551 		return FALSE;
    552 
    553 	if (os_strlen(methods) > WPS_MANUFACTURER_MAX_LEN)
    554 		return FALSE;
    555 
    556 	manufacturer = os_strdup(methods);
    557 	if (!manufacturer)
    558 		return FALSE;
    559 
    560 	os_free(wpa_s->conf->manufacturer);
    561 	wpa_s->conf->manufacturer = manufacturer;
    562 	wpa_s->conf->changed_parameters |= CFG_CHANGED_WPS_STRING;
    563 	wpa_supplicant_update_config(wpa_s);
    564 
    565 	return TRUE;
    566 }
    567 
    568 
    569 /**
    570  * wpas_dbus_getter_wps_device_model_name - Get current device model name
    571  * @iter: Pointer to incoming dbus message iter
    572  * @error: Location to store error on failure
    573  * @user_data: Function specific data
    574  * Returns: TRUE on success, FALSE on failure
    575  *
    576  * Getter for "ModelName" property.
    577  */
    578 dbus_bool_t wpas_dbus_getter_wps_device_model_name(
    579 	const struct wpa_dbus_property_desc *property_desc,
    580 	DBusMessageIter *iter, DBusError *error, void *user_data)
    581 {
    582 	struct wpa_supplicant *wpa_s = user_data;
    583 
    584 	return wpas_dbus_string_property_getter(iter, wpa_s->conf->model_name,
    585 						error);
    586 }
    587 
    588 
    589 /**
    590  * wpas_dbus_setter_wps_device_model_name - Set current device model name
    591  * @iter: Pointer to incoming dbus message iter
    592  * @error: Location to store error on failure
    593  * @user_data: Function specific data
    594  * Returns: TRUE on success, FALSE on failure
    595  *
    596  * Setter for "ModelName" property.
    597  */
    598 dbus_bool_t wpas_dbus_setter_wps_device_model_name(
    599 	const struct wpa_dbus_property_desc *property_desc,
    600 	DBusMessageIter *iter, DBusError *error, void *user_data)
    601 {
    602 	struct wpa_supplicant *wpa_s = user_data;
    603 	char *methods, *model_name;
    604 
    605 	if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING,
    606 					      &methods))
    607 		return FALSE;
    608 
    609 	if (os_strlen(methods) > WPS_MODEL_NAME_MAX_LEN)
    610 		return FALSE;
    611 
    612 	model_name = os_strdup(methods);
    613 	if (!model_name)
    614 		return FALSE;
    615 	os_free(wpa_s->conf->model_name);
    616 	wpa_s->conf->model_name = model_name;
    617 	wpa_s->conf->changed_parameters |= CFG_CHANGED_WPS_STRING;
    618 	wpa_supplicant_update_config(wpa_s);
    619 
    620 	return TRUE;
    621 }
    622 
    623 
    624 /**
    625  * wpas_dbus_getter_wps_device_model_number - Get current device model number
    626  * @iter: Pointer to incoming dbus message iter
    627  * @error: Location to store error on failure
    628  * @user_data: Function specific data
    629  * Returns: TRUE on success, FALSE on failure
    630  *
    631  * Getter for "ModelNumber" property.
    632  */
    633 dbus_bool_t wpas_dbus_getter_wps_device_model_number(
    634 	const struct wpa_dbus_property_desc *property_desc,
    635 	DBusMessageIter *iter, DBusError *error, void *user_data)
    636 {
    637 	struct wpa_supplicant *wpa_s = user_data;
    638 
    639 	return wpas_dbus_string_property_getter(iter, wpa_s->conf->model_number,
    640 						error);
    641 }
    642 
    643 
    644 /**
    645  * wpas_dbus_setter_wps_device_model_number - Set current device model number
    646  * @iter: Pointer to incoming dbus message iter
    647  * @error: Location to store error on failure
    648  * @user_data: Function specific data
    649  * Returns: TRUE on success, FALSE on failure
    650  *
    651  * Setter for "ModelNumber" property.
    652  */
    653 dbus_bool_t wpas_dbus_setter_wps_device_model_number(
    654 	const struct wpa_dbus_property_desc *property_desc,
    655 	DBusMessageIter *iter, DBusError *error, void *user_data)
    656 {
    657 	struct wpa_supplicant *wpa_s = user_data;
    658 	char *methods, *model_number;
    659 
    660 	if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING,
    661 					      &methods))
    662 		return FALSE;
    663 
    664 	if (os_strlen(methods) > WPS_MODEL_NUMBER_MAX_LEN)
    665 		return FALSE;
    666 
    667 	model_number = os_strdup(methods);
    668 	if (!model_number)
    669 		return FALSE;
    670 
    671 	os_free(wpa_s->conf->model_number);
    672 	wpa_s->conf->model_number = model_number;
    673 	wpa_s->conf->changed_parameters |= CFG_CHANGED_WPS_STRING;
    674 	wpa_supplicant_update_config(wpa_s);
    675 
    676 	return TRUE;
    677 }
    678 
    679 
    680 /**
    681  * wpas_dbus_getter_wps_device_serial_number - Get current device serial number
    682  * @iter: Pointer to incoming dbus message iter
    683  * @error: Location to store error on failure
    684  * @user_data: Function specific data
    685  * Returns: TRUE on success, FALSE on failure
    686  *
    687  * Getter for "SerialNumber" property.
    688  */
    689 dbus_bool_t wpas_dbus_getter_wps_device_serial_number(
    690 	const struct wpa_dbus_property_desc *property_desc,
    691 	DBusMessageIter *iter, DBusError *error, void *user_data)
    692 {
    693 	struct wpa_supplicant *wpa_s = user_data;
    694 
    695 	return wpas_dbus_string_property_getter(iter,
    696 						wpa_s->conf->serial_number,
    697 						error);
    698 }
    699 
    700 
    701 /**
    702  * wpas_dbus_setter_wps_device_serial_number - Set current device serial number
    703  * @iter: Pointer to incoming dbus message iter
    704  * @error: Location to store error on failure
    705  * @user_data: Function specific data
    706  * Returns: TRUE on success, FALSE on failure
    707  *
    708  * Setter for "SerialNumber" property.
    709  */
    710 dbus_bool_t wpas_dbus_setter_wps_device_serial_number(
    711 	const struct wpa_dbus_property_desc *property_desc,
    712 	DBusMessageIter *iter, DBusError *error, void *user_data)
    713 {
    714 	struct wpa_supplicant *wpa_s = user_data;
    715 	char *methods, *serial_number;
    716 
    717 	if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING,
    718 					      &methods))
    719 		return FALSE;
    720 
    721 	if (os_strlen(methods) > WPS_SERIAL_NUMBER_MAX_LEN)
    722 		return FALSE;
    723 
    724 	serial_number = os_strdup(methods);
    725 	if (!serial_number)
    726 		return FALSE;
    727 	os_free(wpa_s->conf->serial_number);
    728 	wpa_s->conf->serial_number = serial_number;
    729 	wpa_s->conf->changed_parameters |= CFG_CHANGED_WPS_STRING;
    730 	wpa_supplicant_update_config(wpa_s);
    731 
    732 	return TRUE;
    733 }
    734 
    735 
    736 /**
    737  * wpas_dbus_getter_wps_device_device_type - Get current device type
    738  * @iter: Pointer to incoming dbus message iter
    739  * @error: Location to store error on failure
    740  * @user_data: Function specific data
    741  * Returns: TRUE on success, FALSE on failure
    742  *
    743  * Getter for "DeviceType" property.
    744  */
    745 dbus_bool_t wpas_dbus_getter_wps_device_device_type(
    746 	const struct wpa_dbus_property_desc *property_desc,
    747 	DBusMessageIter *iter, DBusError *error, void *user_data)
    748 {
    749 	struct wpa_supplicant *wpa_s = user_data;
    750 
    751 	if (!wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
    752 						    (char *)
    753 						    wpa_s->conf->device_type,
    754 						    WPS_DEV_TYPE_LEN, error)) {
    755 		dbus_set_error(error, DBUS_ERROR_FAILED,
    756 			       "%s: error constructing reply", __func__);
    757 		return FALSE;
    758 	}
    759 
    760 	return TRUE;
    761 }
    762 
    763 
    764 /**
    765  * wpas_dbus_setter_wps_device_device_type - Set current device type
    766  * @iter: Pointer to incoming dbus message iter
    767  * @error: Location to store error on failure
    768  * @user_data: Function specific data
    769  * Returns: TRUE on success, FALSE on failure
    770  *
    771  * Setter for "DeviceType" property.
    772  */
    773 dbus_bool_t wpas_dbus_setter_wps_device_device_type(
    774 	const struct wpa_dbus_property_desc *property_desc,
    775 	DBusMessageIter *iter, DBusError *error, void *user_data)
    776 {
    777 	struct wpa_supplicant *wpa_s = user_data;
    778 	u8 *dev_type;
    779 	int dev_len;
    780 	DBusMessageIter variant, array_iter;
    781 
    782 	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_VARIANT)
    783 		return FALSE;
    784 
    785 	dbus_message_iter_recurse(iter, &variant);
    786 	if (dbus_message_iter_get_arg_type(&variant) != DBUS_TYPE_ARRAY)
    787 		return FALSE;
    788 
    789 	dbus_message_iter_recurse(&variant, &array_iter);
    790 	dbus_message_iter_get_fixed_array(&array_iter, &dev_type, &dev_len);
    791 
    792 	if (dev_len != WPS_DEV_TYPE_LEN)
    793 		return FALSE;
    794 
    795 	os_memcpy(wpa_s->conf->device_type, dev_type, WPS_DEV_TYPE_LEN);
    796 	wpa_s->conf->changed_parameters |= CFG_CHANGED_DEVICE_TYPE;
    797 	wpa_supplicant_update_config(wpa_s);
    798 
    799 	return TRUE;
    800 }
    801