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 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, ¶ms->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, ¶ms->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, ¶ms->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(¶ms, 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 ¶ms, &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 */ 335 DBusMessage * 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 */ 356 dbus_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 */ 378 dbus_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 */ 414 dbus_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 */ 436 dbus_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 */ 470 dbus_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 */ 490 dbus_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 */ 526 dbus_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 */ 546 dbus_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 */ 582 dbus_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 */ 602 dbus_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 */ 637 dbus_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 */ 657 dbus_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 */ 693 dbus_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 */ 714 dbus_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 */ 749 dbus_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 */ 777 dbus_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