1/*
2 * WPA Supplicant / dbus-based control interface (WPS)
3 * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
4 * Copyright (c) 2009, Witold Sowa <witold.sowa@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
24struct 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
33static 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
64static 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
95static 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
126static 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
147static 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
181static 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 */
221DBusMessage * 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			ret = os_snprintf(npin, sizeof(npin), "%08d", ret);
291			if (os_snprintf_error(sizeof(npin), ret))
292				return wpas_dbus_error_unknown_error(
293					message, "invalid PIN");
294		}
295	} else {
296		ret = wpas_wps_start_pbc(wpa_s, params.bssid, 0, 0);
297	}
298
299	if (ret < 0) {
300		wpa_printf(MSG_DEBUG,
301			   "dbus: WPS.Start wpas_wps_failed in role %s and key %s",
302			   (params.role == 1 ? "enrollee" : "registrar"),
303			   (params.type == 0 ? "" :
304			    (params.type == 1 ? "pin" : "pbc")));
305		return wpas_dbus_error_unknown_error(message,
306						     "WPS start failed");
307	}
308
309	reply = dbus_message_new_method_return(message);
310	if (!reply)
311		return wpas_dbus_error_no_memory(message);
312
313	dbus_message_iter_init_append(reply, &iter);
314	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
315	    (os_strlen(npin) > 0 &&
316	     !wpa_dbus_dict_append_string(&dict_iter, "Pin", npin)) ||
317	    !wpa_dbus_dict_close_write(&iter, &dict_iter)) {
318		dbus_message_unref(reply);
319		return wpas_dbus_error_no_memory(message);
320	}
321
322	return reply;
323}
324
325
326/**
327 * wpas_dbus_handler_wps_cancel - Cancel ongoing WPS configuration
328 * @message: Pointer to incoming dbus message
329 * @wpa_s: %wpa_supplicant data structure
330 * Returns: NULL on success or DBus error on failure
331 *
332 * Handler for "Cancel" method call. Returns NULL if WPS cancel successful
333 * or DBus error on WPS cancel failure
334 */
335DBusMessage * wpas_dbus_handler_wps_cancel(DBusMessage *message,
336					   struct wpa_supplicant *wpa_s)
337{
338	if (wpas_wps_cancel(wpa_s))
339		return wpas_dbus_error_unknown_error(message,
340						     "WPS cancel failed");
341
342	return NULL;
343}
344
345
346/**
347 * wpas_dbus_getter_process_credentials - Check if credentials are processed
348 * @message: Pointer to incoming dbus message
349 * @wpa_s: %wpa_supplicant data structure
350 * Returns: TRUE on success, FALSE on failure
351 *
352 * Getter for "ProcessCredentials" property. Returns returned boolean will be
353 * true if wps_cred_processing configuration field is not equal to 1 or false
354 * if otherwise.
355 */
356dbus_bool_t wpas_dbus_getter_process_credentials(
357	const struct wpa_dbus_property_desc *property_desc,
358	DBusMessageIter *iter, DBusError *error, void *user_data)
359{
360	struct wpa_supplicant *wpa_s = user_data;
361	dbus_bool_t process = wpa_s->conf->wps_cred_processing != 1;
362
363	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
364						&process, error);
365}
366
367
368/**
369 * wpas_dbus_setter_process_credentials - Set credentials_processed conf param
370 * @iter: Pointer to incoming dbus message iter
371 * @error: Location to store error on failure
372 * @user_data: Function specific data
373 * Returns: TRUE on success, FALSE on failure
374 *
375 * Setter for "ProcessCredentials" property. Sets credentials_processed on 2
376 * if boolean argument is true or on 1 if otherwise.
377 */
378dbus_bool_t wpas_dbus_setter_process_credentials(
379	const struct wpa_dbus_property_desc *property_desc,
380	DBusMessageIter *iter, DBusError *error, void *user_data)
381{
382	struct wpa_supplicant *wpa_s = user_data;
383	dbus_bool_t process_credentials, old_pc;
384
385	if (!wpa_s->dbus_new_path)
386		return FALSE;
387	if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_BOOLEAN,
388					      &process_credentials))
389		return FALSE;
390
391	old_pc = wpa_s->conf->wps_cred_processing != 1;
392	wpa_s->conf->wps_cred_processing = (process_credentials ? 2 : 1);
393
394	if ((wpa_s->conf->wps_cred_processing != 1) != old_pc)
395		wpa_dbus_mark_property_changed(wpa_s->global->dbus,
396					       wpa_s->dbus_new_path,
397					       WPAS_DBUS_NEW_IFACE_WPS,
398					       "ProcessCredentials");
399
400	return TRUE;
401}
402
403
404/**
405 * wpas_dbus_getter_config_methods - Get current WPS configuration methods
406 * @iter: Pointer to incoming dbus message iter
407 * @error: Location to store error on failure
408 * @user_data: Function specific data
409 * Returns: TRUE on success, FALSE on failure
410 *
411 * Getter for "ConfigMethods" property. Returned boolean will be true if
412 * providing the relevant string worked, or false otherwise.
413 */
414dbus_bool_t wpas_dbus_getter_config_methods(
415	const struct wpa_dbus_property_desc *property_desc,
416	DBusMessageIter *iter, DBusError *error, void *user_data)
417{
418	struct wpa_supplicant *wpa_s = user_data;
419
420	return wpas_dbus_string_property_getter(iter,
421						wpa_s->conf->config_methods,
422						error);
423}
424
425
426/**
427 * wpas_dbus_setter_config_methods - Set WPS configuration methods
428 * @iter: Pointer to incoming dbus message iter
429 * @error: Location to store error on failure
430 * @user_data: Function specific data
431 * Returns: TRUE on success, FALSE on failure
432 *
433 * Setter for "ConfigMethods" property. Sets the methods string, apply such
434 * change and returns true on success. Returns false otherwise.
435 */
436dbus_bool_t wpas_dbus_setter_config_methods(
437	const struct wpa_dbus_property_desc *property_desc,
438	DBusMessageIter *iter, DBusError *error, void *user_data)
439{
440	struct wpa_supplicant *wpa_s = user_data;
441	char *methods, *new_methods;
442
443	if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING,
444					      &methods))
445		return FALSE;
446
447	new_methods = os_strdup(methods);
448	if (!new_methods)
449		return FALSE;
450
451	os_free(wpa_s->conf->config_methods);
452	wpa_s->conf->config_methods = new_methods;
453
454	wpa_s->conf->changed_parameters |= CFG_CHANGED_CONFIG_METHODS;
455	wpa_supplicant_update_config(wpa_s);
456
457	return TRUE;
458}
459
460
461/**
462 * wpas_dbus_getter_wps_device_name - Get current WPS device name
463 * @iter: Pointer to incoming dbus message iter
464 * @error: Location to store error on failure
465 * @user_data: Function specific data
466 * Returns: TRUE on success, FALSE on failure
467 *
468 * Getter for "DeviceName" property.
469 */
470dbus_bool_t wpas_dbus_getter_wps_device_name(
471	const struct wpa_dbus_property_desc *property_desc,
472	DBusMessageIter *iter, DBusError *error, void *user_data)
473{
474	struct wpa_supplicant *wpa_s = user_data;
475
476	return wpas_dbus_string_property_getter(iter, wpa_s->conf->device_name,
477						error);
478}
479
480
481/**
482 * wpas_dbus_setter_wps_device_name - Set current WPS device name
483 * @iter: Pointer to incoming dbus message iter
484 * @error: Location to store error on failure
485 * @user_data: Function specific data
486 * Returns: TRUE on success, FALSE on failure
487 *
488 * Setter for "DeviceName" property.
489 */
490dbus_bool_t wpas_dbus_setter_wps_device_name(
491	const struct wpa_dbus_property_desc *property_desc,
492	DBusMessageIter *iter, DBusError *error, void *user_data)
493{
494	struct wpa_supplicant *wpa_s = user_data;
495	char *methods, *devname;
496
497	if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING,
498					      &methods))
499		return FALSE;
500
501	if (os_strlen(methods) > WPS_DEV_NAME_MAX_LEN)
502		return FALSE;
503
504	devname = os_strdup(methods);
505	if (!devname)
506		return FALSE;
507
508	os_free(wpa_s->conf->device_name);
509	wpa_s->conf->device_name = devname;
510	wpa_s->conf->changed_parameters |= CFG_CHANGED_DEVICE_NAME;
511	wpa_supplicant_update_config(wpa_s);
512
513	return TRUE;
514}
515
516
517/**
518 * wpas_dbus_getter_wps_manufacturer - Get current manufacturer name
519 * @iter: Pointer to incoming dbus message iter
520 * @error: Location to store error on failure
521 * @user_data: Function specific data
522 * Returns: TRUE on success, FALSE on failure
523 *
524 * Getter for "Manufacturer" property.
525 */
526dbus_bool_t wpas_dbus_getter_wps_manufacturer(
527	const struct wpa_dbus_property_desc *property_desc,
528	DBusMessageIter *iter, DBusError *error, void *user_data)
529{
530	struct wpa_supplicant *wpa_s = user_data;
531
532	return wpas_dbus_string_property_getter(iter, wpa_s->conf->manufacturer,
533						error);
534}
535
536
537/**
538 * wpas_dbus_setter_wps_manufacturer - Set current manufacturer name
539 * @iter: Pointer to incoming dbus message iter
540 * @error: Location to store error on failure
541 * @user_data: Function specific data
542 * Returns: TRUE on success, FALSE on failure
543 *
544 * Setter for "Manufacturer" property.
545 */
546dbus_bool_t wpas_dbus_setter_wps_manufacturer(
547	const struct wpa_dbus_property_desc *property_desc,
548	DBusMessageIter *iter, DBusError *error, void *user_data)
549{
550	struct wpa_supplicant *wpa_s = user_data;
551	char *methods, *manufacturer;
552
553	if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING,
554					      &methods))
555		return FALSE;
556
557	if (os_strlen(methods) > WPS_MANUFACTURER_MAX_LEN)
558		return FALSE;
559
560	manufacturer = os_strdup(methods);
561	if (!manufacturer)
562		return FALSE;
563
564	os_free(wpa_s->conf->manufacturer);
565	wpa_s->conf->manufacturer = manufacturer;
566	wpa_s->conf->changed_parameters |= CFG_CHANGED_WPS_STRING;
567	wpa_supplicant_update_config(wpa_s);
568
569	return TRUE;
570}
571
572
573/**
574 * wpas_dbus_getter_wps_device_model_name - Get current device model name
575 * @iter: Pointer to incoming dbus message iter
576 * @error: Location to store error on failure
577 * @user_data: Function specific data
578 * Returns: TRUE on success, FALSE on failure
579 *
580 * Getter for "ModelName" property.
581 */
582dbus_bool_t wpas_dbus_getter_wps_device_model_name(
583	const struct wpa_dbus_property_desc *property_desc,
584	DBusMessageIter *iter, DBusError *error, void *user_data)
585{
586	struct wpa_supplicant *wpa_s = user_data;
587
588	return wpas_dbus_string_property_getter(iter, wpa_s->conf->model_name,
589						error);
590}
591
592
593/**
594 * wpas_dbus_setter_wps_device_model_name - Set current device model name
595 * @iter: Pointer to incoming dbus message iter
596 * @error: Location to store error on failure
597 * @user_data: Function specific data
598 * Returns: TRUE on success, FALSE on failure
599 *
600 * Setter for "ModelName" property.
601 */
602dbus_bool_t wpas_dbus_setter_wps_device_model_name(
603	const struct wpa_dbus_property_desc *property_desc,
604	DBusMessageIter *iter, DBusError *error, void *user_data)
605{
606	struct wpa_supplicant *wpa_s = user_data;
607	char *methods, *model_name;
608
609	if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING,
610					      &methods))
611		return FALSE;
612
613	if (os_strlen(methods) > WPS_MODEL_NAME_MAX_LEN)
614		return FALSE;
615
616	model_name = os_strdup(methods);
617	if (!model_name)
618		return FALSE;
619	os_free(wpa_s->conf->model_name);
620	wpa_s->conf->model_name = model_name;
621	wpa_s->conf->changed_parameters |= CFG_CHANGED_WPS_STRING;
622	wpa_supplicant_update_config(wpa_s);
623
624	return TRUE;
625}
626
627
628/**
629 * wpas_dbus_getter_wps_device_model_number - Get current device model number
630 * @iter: Pointer to incoming dbus message iter
631 * @error: Location to store error on failure
632 * @user_data: Function specific data
633 * Returns: TRUE on success, FALSE on failure
634 *
635 * Getter for "ModelNumber" property.
636 */
637dbus_bool_t wpas_dbus_getter_wps_device_model_number(
638	const struct wpa_dbus_property_desc *property_desc,
639	DBusMessageIter *iter, DBusError *error, void *user_data)
640{
641	struct wpa_supplicant *wpa_s = user_data;
642
643	return wpas_dbus_string_property_getter(iter, wpa_s->conf->model_number,
644						error);
645}
646
647
648/**
649 * wpas_dbus_setter_wps_device_model_number - Set current device model number
650 * @iter: Pointer to incoming dbus message iter
651 * @error: Location to store error on failure
652 * @user_data: Function specific data
653 * Returns: TRUE on success, FALSE on failure
654 *
655 * Setter for "ModelNumber" property.
656 */
657dbus_bool_t wpas_dbus_setter_wps_device_model_number(
658	const struct wpa_dbus_property_desc *property_desc,
659	DBusMessageIter *iter, DBusError *error, void *user_data)
660{
661	struct wpa_supplicant *wpa_s = user_data;
662	char *methods, *model_number;
663
664	if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING,
665					      &methods))
666		return FALSE;
667
668	if (os_strlen(methods) > WPS_MODEL_NUMBER_MAX_LEN)
669		return FALSE;
670
671	model_number = os_strdup(methods);
672	if (!model_number)
673		return FALSE;
674
675	os_free(wpa_s->conf->model_number);
676	wpa_s->conf->model_number = model_number;
677	wpa_s->conf->changed_parameters |= CFG_CHANGED_WPS_STRING;
678	wpa_supplicant_update_config(wpa_s);
679
680	return TRUE;
681}
682
683
684/**
685 * wpas_dbus_getter_wps_device_serial_number - Get current device serial number
686 * @iter: Pointer to incoming dbus message iter
687 * @error: Location to store error on failure
688 * @user_data: Function specific data
689 * Returns: TRUE on success, FALSE on failure
690 *
691 * Getter for "SerialNumber" property.
692 */
693dbus_bool_t wpas_dbus_getter_wps_device_serial_number(
694	const struct wpa_dbus_property_desc *property_desc,
695	DBusMessageIter *iter, DBusError *error, void *user_data)
696{
697	struct wpa_supplicant *wpa_s = user_data;
698
699	return wpas_dbus_string_property_getter(iter,
700						wpa_s->conf->serial_number,
701						error);
702}
703
704
705/**
706 * wpas_dbus_setter_wps_device_serial_number - Set current device serial number
707 * @iter: Pointer to incoming dbus message iter
708 * @error: Location to store error on failure
709 * @user_data: Function specific data
710 * Returns: TRUE on success, FALSE on failure
711 *
712 * Setter for "SerialNumber" property.
713 */
714dbus_bool_t wpas_dbus_setter_wps_device_serial_number(
715	const struct wpa_dbus_property_desc *property_desc,
716	DBusMessageIter *iter, DBusError *error, void *user_data)
717{
718	struct wpa_supplicant *wpa_s = user_data;
719	char *methods, *serial_number;
720
721	if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING,
722					      &methods))
723		return FALSE;
724
725	if (os_strlen(methods) > WPS_SERIAL_NUMBER_MAX_LEN)
726		return FALSE;
727
728	serial_number = os_strdup(methods);
729	if (!serial_number)
730		return FALSE;
731	os_free(wpa_s->conf->serial_number);
732	wpa_s->conf->serial_number = serial_number;
733	wpa_s->conf->changed_parameters |= CFG_CHANGED_WPS_STRING;
734	wpa_supplicant_update_config(wpa_s);
735
736	return TRUE;
737}
738
739
740/**
741 * wpas_dbus_getter_wps_device_device_type - Get current device type
742 * @iter: Pointer to incoming dbus message iter
743 * @error: Location to store error on failure
744 * @user_data: Function specific data
745 * Returns: TRUE on success, FALSE on failure
746 *
747 * Getter for "DeviceType" property.
748 */
749dbus_bool_t wpas_dbus_getter_wps_device_device_type(
750	const struct wpa_dbus_property_desc *property_desc,
751	DBusMessageIter *iter, DBusError *error, void *user_data)
752{
753	struct wpa_supplicant *wpa_s = user_data;
754
755	if (!wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
756						    (char *)
757						    wpa_s->conf->device_type,
758						    WPS_DEV_TYPE_LEN, error)) {
759		dbus_set_error(error, DBUS_ERROR_FAILED,
760			       "%s: error constructing reply", __func__);
761		return FALSE;
762	}
763
764	return TRUE;
765}
766
767
768/**
769 * wpas_dbus_setter_wps_device_device_type - Set current device type
770 * @iter: Pointer to incoming dbus message iter
771 * @error: Location to store error on failure
772 * @user_data: Function specific data
773 * Returns: TRUE on success, FALSE on failure
774 *
775 * Setter for "DeviceType" property.
776 */
777dbus_bool_t wpas_dbus_setter_wps_device_device_type(
778	const struct wpa_dbus_property_desc *property_desc,
779	DBusMessageIter *iter, DBusError *error, void *user_data)
780{
781	struct wpa_supplicant *wpa_s = user_data;
782	u8 *dev_type;
783	int dev_len;
784	DBusMessageIter variant, array_iter;
785
786	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_VARIANT)
787		return FALSE;
788
789	dbus_message_iter_recurse(iter, &variant);
790	if (dbus_message_iter_get_arg_type(&variant) != DBUS_TYPE_ARRAY)
791		return FALSE;
792
793	dbus_message_iter_recurse(&variant, &array_iter);
794	dbus_message_iter_get_fixed_array(&array_iter, &dev_type, &dev_len);
795
796	if (dev_len != WPS_DEV_TYPE_LEN)
797		return FALSE;
798
799	os_memcpy(wpa_s->conf->device_type, dev_type, WPS_DEV_TYPE_LEN);
800	wpa_s->conf->changed_parameters |= CFG_CHANGED_DEVICE_TYPE;
801	wpa_supplicant_update_config(wpa_s);
802
803	return TRUE;
804}
805