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 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