dbus_old.c revision 8d520ff1dc2da35cdca849e982051b86468016d8
1/* 2 * WPA Supplicant / dbus-based control interface 3 * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * Alternatively, this software may be distributed under the terms of BSD 10 * license. 11 * 12 * See README and COPYING for more details. 13 */ 14 15#include "includes.h" 16#include <dbus/dbus.h> 17 18#include "common.h" 19#include "eloop.h" 20#include "wps/wps.h" 21#include "../config.h" 22#include "../wpa_supplicant_i.h" 23#include "../bss.h" 24#include "dbus_old.h" 25#include "dbus_old_handlers.h" 26#include "dbus_common.h" 27#include "dbus_common_i.h" 28 29 30/** 31 * wpas_dbus_decompose_object_path - Decompose an interface object path into parts 32 * @path: The dbus object path 33 * @network: (out) the configured network this object path refers to, if any 34 * @bssid: (out) the scanned bssid this object path refers to, if any 35 * Returns: The object path of the network interface this path refers to 36 * 37 * For a given object path, decomposes the object path into object id, network, 38 * and BSSID parts, if those parts exist. 39 */ 40char * wpas_dbus_decompose_object_path(const char *path, char **network, 41 char **bssid) 42{ 43 const unsigned int dev_path_prefix_len = 44 strlen(WPAS_DBUS_PATH_INTERFACES "/"); 45 char *obj_path_only; 46 char *next_sep; 47 48 /* Be a bit paranoid about path */ 49 if (!path || strncmp(path, WPAS_DBUS_PATH_INTERFACES "/", 50 dev_path_prefix_len)) 51 return NULL; 52 53 /* Ensure there's something at the end of the path */ 54 if ((path + dev_path_prefix_len)[0] == '\0') 55 return NULL; 56 57 obj_path_only = os_strdup(path); 58 if (obj_path_only == NULL) 59 return NULL; 60 61 next_sep = strchr(obj_path_only + dev_path_prefix_len, '/'); 62 if (next_sep != NULL) { 63 const char *net_part = strstr(next_sep, 64 WPAS_DBUS_NETWORKS_PART "/"); 65 const char *bssid_part = strstr(next_sep, 66 WPAS_DBUS_BSSIDS_PART "/"); 67 68 if (network && net_part) { 69 /* Deal with a request for a configured network */ 70 const char *net_name = net_part + 71 strlen(WPAS_DBUS_NETWORKS_PART "/"); 72 *network = NULL; 73 if (strlen(net_name)) 74 *network = os_strdup(net_name); 75 } else if (bssid && bssid_part) { 76 /* Deal with a request for a scanned BSSID */ 77 const char *bssid_name = bssid_part + 78 strlen(WPAS_DBUS_BSSIDS_PART "/"); 79 if (strlen(bssid_name)) 80 *bssid = os_strdup(bssid_name); 81 else 82 *bssid = NULL; 83 } 84 85 /* Cut off interface object path before "/" */ 86 *next_sep = '\0'; 87 } 88 89 return obj_path_only; 90} 91 92 93/** 94 * wpas_dbus_new_invalid_iface_error - Return a new invalid interface error message 95 * @message: Pointer to incoming dbus message this error refers to 96 * Returns: A dbus error message 97 * 98 * Convenience function to create and return an invalid interface error 99 */ 100DBusMessage * wpas_dbus_new_invalid_iface_error(DBusMessage *message) 101{ 102 return dbus_message_new_error(message, WPAS_ERROR_INVALID_IFACE, 103 "wpa_supplicant knows nothing about " 104 "this interface."); 105} 106 107 108/** 109 * wpas_dbus_new_invalid_network_error - Return a new invalid network error message 110 * @message: Pointer to incoming dbus message this error refers to 111 * Returns: a dbus error message 112 * 113 * Convenience function to create and return an invalid network error 114 */ 115DBusMessage * wpas_dbus_new_invalid_network_error(DBusMessage *message) 116{ 117 return dbus_message_new_error(message, WPAS_ERROR_INVALID_NETWORK, 118 "The requested network does not exist."); 119} 120 121 122/** 123 * wpas_dbus_new_invalid_bssid_error - Return a new invalid bssid error message 124 * @message: Pointer to incoming dbus message this error refers to 125 * Returns: a dbus error message 126 * 127 * Convenience function to create and return an invalid bssid error 128 */ 129static DBusMessage * wpas_dbus_new_invalid_bssid_error(DBusMessage *message) 130{ 131 return dbus_message_new_error(message, WPAS_ERROR_INVALID_BSSID, 132 "The BSSID requested was invalid."); 133} 134 135 136/** 137 * wpas_dispatch_network_method - dispatch messages for configured networks 138 * @message: the incoming dbus message 139 * @wpa_s: a network interface's data 140 * @network_id: id of the configured network we're interested in 141 * Returns: a reply dbus message, or a dbus error message 142 * 143 * This function dispatches all incoming dbus messages for configured networks. 144 */ 145static DBusMessage * wpas_dispatch_network_method(DBusMessage *message, 146 struct wpa_supplicant *wpa_s, 147 int network_id) 148{ 149 DBusMessage *reply = NULL; 150 const char *method = dbus_message_get_member(message); 151 struct wpa_ssid *ssid; 152 153 ssid = wpa_config_get_network(wpa_s->conf, network_id); 154 if (ssid == NULL) 155 return wpas_dbus_new_invalid_network_error(message); 156 157 if (!strcmp(method, "set")) 158 reply = wpas_dbus_iface_set_network(message, wpa_s, ssid); 159 else if (!strcmp(method, "enable")) 160 reply = wpas_dbus_iface_enable_network(message, wpa_s, ssid); 161 else if (!strcmp(method, "disable")) 162 reply = wpas_dbus_iface_disable_network(message, wpa_s, ssid); 163 164 return reply; 165} 166 167 168/** 169 * wpas_dispatch_bssid_method - dispatch messages for scanned networks 170 * @message: the incoming dbus message 171 * @wpa_s: a network interface's data 172 * @bssid: bssid of the scanned network we're interested in 173 * Returns: a reply dbus message, or a dbus error message 174 * 175 * This function dispatches all incoming dbus messages for scanned networks. 176 */ 177static DBusMessage * wpas_dispatch_bssid_method(DBusMessage *message, 178 struct wpa_supplicant *wpa_s, 179 const char *bssid_txt) 180{ 181 u8 bssid[ETH_ALEN]; 182 struct wpa_bss *bss; 183 184 if (hexstr2bin(bssid_txt, bssid, ETH_ALEN) < 0) 185 return wpas_dbus_new_invalid_bssid_error(message); 186 187 bss = wpa_bss_get_bssid(wpa_s, bssid); 188 if (bss == NULL) 189 return wpas_dbus_new_invalid_bssid_error(message); 190 191 /* Dispatch the method call against the scanned bssid */ 192 if (os_strcmp(dbus_message_get_member(message), "properties") == 0) 193 return wpas_dbus_bssid_properties(message, wpa_s, bss); 194 195 return NULL; 196} 197 198 199/** 200 * wpas_iface_message_handler - Dispatch messages for interfaces or networks 201 * @connection: Connection to the system message bus 202 * @message: An incoming dbus message 203 * @user_data: A pointer to a dbus control interface data structure 204 * Returns: Whether or not the message was handled 205 * 206 * This function dispatches all incoming dbus messages for network interfaces, 207 * or objects owned by them, such as scanned BSSIDs and configured networks. 208 */ 209static DBusHandlerResult wpas_iface_message_handler(DBusConnection *connection, 210 DBusMessage *message, 211 void *user_data) 212{ 213 struct wpa_supplicant *wpa_s = user_data; 214 const char *method = dbus_message_get_member(message); 215 const char *path = dbus_message_get_path(message); 216 const char *msg_interface = dbus_message_get_interface(message); 217 char *iface_obj_path = NULL; 218 char *network = NULL; 219 char *bssid = NULL; 220 DBusMessage *reply = NULL; 221 222 /* Caller must specify a message interface */ 223 if (!msg_interface) 224 goto out; 225 226 iface_obj_path = wpas_dbus_decompose_object_path(path, &network, 227 &bssid); 228 if (iface_obj_path == NULL) { 229 reply = wpas_dbus_new_invalid_iface_error(message); 230 goto out; 231 } 232 233 /* Make sure the message's object path actually refers to the 234 * wpa_supplicant structure it's supposed to (which is wpa_s) 235 */ 236 if (wpa_supplicant_get_iface_by_dbus_path(wpa_s->global, 237 iface_obj_path) != wpa_s) { 238 reply = wpas_dbus_new_invalid_iface_error(message); 239 goto out; 240 } 241 242 if (network && !strcmp(msg_interface, WPAS_DBUS_IFACE_NETWORK)) { 243 /* A method for one of this interface's configured networks */ 244 int nid = strtoul(network, NULL, 10); 245 if (errno != EINVAL) 246 reply = wpas_dispatch_network_method(message, wpa_s, 247 nid); 248 else 249 reply = wpas_dbus_new_invalid_network_error(message); 250 } else if (bssid && !strcmp(msg_interface, WPAS_DBUS_IFACE_BSSID)) { 251 /* A method for one of this interface's scanned BSSIDs */ 252 reply = wpas_dispatch_bssid_method(message, wpa_s, bssid); 253 } else if (!strcmp(msg_interface, WPAS_DBUS_IFACE_INTERFACE)) { 254 /* A method for an interface only. */ 255 if (!strcmp(method, "scan")) 256 reply = wpas_dbus_iface_scan(message, wpa_s); 257 else if (!strcmp(method, "scanResults")) 258 reply = wpas_dbus_iface_scan_results(message, wpa_s); 259 else if (!strcmp(method, "addNetwork")) 260 reply = wpas_dbus_iface_add_network(message, wpa_s); 261 else if (!strcmp(method, "removeNetwork")) 262 reply = wpas_dbus_iface_remove_network(message, wpa_s); 263 else if (!strcmp(method, "selectNetwork")) 264 reply = wpas_dbus_iface_select_network(message, wpa_s); 265 else if (!strcmp(method, "capabilities")) 266 reply = wpas_dbus_iface_capabilities(message, wpa_s); 267 else if (!strcmp(method, "disconnect")) 268 reply = wpas_dbus_iface_disconnect(message, wpa_s); 269 else if (!strcmp(method, "setAPScan")) 270 reply = wpas_dbus_iface_set_ap_scan(message, wpa_s); 271 else if (!strcmp(method, "setSmartcardModules")) 272 reply = wpas_dbus_iface_set_smartcard_modules(message, 273 wpa_s); 274 else if (!strcmp(method, "state")) 275 reply = wpas_dbus_iface_get_state(message, wpa_s); 276 else if (!strcmp(method, "scanning")) 277 reply = wpas_dbus_iface_get_scanning(message, wpa_s); 278 else if (!strcmp(method, "setBlobs")) 279 reply = wpas_dbus_iface_set_blobs(message, wpa_s); 280 else if (!strcmp(method, "removeBlobs")) 281 reply = wpas_dbus_iface_remove_blobs(message, wpa_s); 282#ifdef CONFIG_WPS 283 else if (!os_strcmp(method, "wpsPbc")) 284 reply = wpas_dbus_iface_wps_pbc(message, wpa_s); 285 else if (!os_strcmp(method, "wpsPin")) 286 reply = wpas_dbus_iface_wps_pin(message, wpa_s); 287 else if (!os_strcmp(method, "wpsReg")) 288 reply = wpas_dbus_iface_wps_reg(message, wpa_s); 289#endif /* CONFIG_WPS */ 290 else if (!os_strcmp(method, "flush")) 291 reply = wpas_dbus_iface_flush(message, wpa_s); 292 } 293 294 /* If the message was handled, send back the reply */ 295 if (reply) { 296 if (!dbus_message_get_no_reply(message)) 297 dbus_connection_send(connection, reply, NULL); 298 dbus_message_unref(reply); 299 } 300 301out: 302 os_free(iface_obj_path); 303 os_free(network); 304 os_free(bssid); 305 return reply ? DBUS_HANDLER_RESULT_HANDLED : 306 DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 307} 308 309 310/** 311 * wpas_message_handler - dispatch incoming dbus messages 312 * @connection: connection to the system message bus 313 * @message: an incoming dbus message 314 * @user_data: a pointer to a dbus control interface data structure 315 * Returns: whether or not the message was handled 316 * 317 * This function dispatches all incoming dbus messages to the correct 318 * handlers, depending on what the message's target object path is, 319 * and what the method call is. 320 */ 321static DBusHandlerResult wpas_message_handler(DBusConnection *connection, 322 DBusMessage *message, void *user_data) 323{ 324 struct wpas_dbus_priv *ctrl_iface = user_data; 325 const char *method; 326 const char *path; 327 const char *msg_interface; 328 DBusMessage *reply = NULL; 329 330 method = dbus_message_get_member(message); 331 path = dbus_message_get_path(message); 332 msg_interface = dbus_message_get_interface(message); 333 if (!method || !path || !ctrl_iface || !msg_interface) 334 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 335 336 /* Validate the method interface */ 337 if (strcmp(msg_interface, WPAS_DBUS_INTERFACE) != 0) 338 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 339 340 if (!strcmp(path, WPAS_DBUS_PATH)) { 341 /* dispatch methods against our global dbus interface here */ 342 if (!strcmp(method, "addInterface")) { 343 reply = wpas_dbus_global_add_interface( 344 message, ctrl_iface->global); 345 } else if (!strcmp(method, "removeInterface")) { 346 reply = wpas_dbus_global_remove_interface( 347 message, ctrl_iface->global); 348 } else if (!strcmp(method, "getInterface")) { 349 reply = wpas_dbus_global_get_interface( 350 message, ctrl_iface->global); 351 } else if (!strcmp(method, "setDebugParams")) { 352 reply = wpas_dbus_global_set_debugparams( 353 message, ctrl_iface->global); 354 } 355 } 356 357 /* If the message was handled, send back the reply */ 358 if (reply) { 359 if (!dbus_message_get_no_reply(message)) 360 dbus_connection_send(connection, reply, NULL); 361 dbus_message_unref(reply); 362 } 363 364 return reply ? DBUS_HANDLER_RESULT_HANDLED : 365 DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 366} 367 368 369/** 370 * wpa_supplicant_dbus_notify_scan_results - Send a scan results signal 371 * @wpa_s: %wpa_supplicant network interface data 372 * Returns: 0 on success, -1 on failure 373 * 374 * Notify listeners that this interface has updated scan results. 375 */ 376void wpa_supplicant_dbus_notify_scan_results(struct wpa_supplicant *wpa_s) 377{ 378 struct wpas_dbus_priv *iface = wpa_s->global->dbus; 379 DBusMessage *_signal; 380 381 /* Do nothing if the control interface is not turned on */ 382 if (iface == NULL) 383 return; 384 385 _signal = dbus_message_new_signal(wpa_s->dbus_path, 386 WPAS_DBUS_IFACE_INTERFACE, 387 "ScanResultsAvailable"); 388 if (_signal == NULL) { 389 wpa_printf(MSG_ERROR, "dbus: Not enough memory to send scan " 390 "results signal"); 391 return; 392 } 393 dbus_connection_send(iface->con, _signal, NULL); 394 dbus_message_unref(_signal); 395} 396 397 398/** 399 * wpa_supplicant_dbus_notify_state_change - Send a state change signal 400 * @wpa_s: %wpa_supplicant network interface data 401 * @new_state: new state wpa_supplicant is entering 402 * @old_state: old state wpa_supplicant is leaving 403 * Returns: 0 on success, -1 on failure 404 * 405 * Notify listeners that wpa_supplicant has changed state 406 */ 407void wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant *wpa_s, 408 enum wpa_states new_state, 409 enum wpa_states old_state) 410{ 411 struct wpas_dbus_priv *iface; 412 DBusMessage *_signal = NULL; 413 const char *new_state_str, *old_state_str; 414 415 if (wpa_s->dbus_path == NULL) 416 return; /* Skip signal since D-Bus setup is not yet ready */ 417 418 /* Do nothing if the control interface is not turned on */ 419 if (wpa_s->global == NULL) 420 return; 421 iface = wpa_s->global->dbus; 422 if (iface == NULL) 423 return; 424 425 /* Only send signal if state really changed */ 426 if (new_state == old_state) 427 return; 428 429 _signal = dbus_message_new_signal(wpa_s->dbus_path, 430 WPAS_DBUS_IFACE_INTERFACE, 431 "StateChange"); 432 if (_signal == NULL) { 433 wpa_printf(MSG_ERROR, 434 "dbus: wpa_supplicant_dbus_notify_state_change: " 435 "could not create dbus signal; likely out of " 436 "memory"); 437 return; 438 } 439 440 new_state_str = wpa_supplicant_state_txt(new_state); 441 old_state_str = wpa_supplicant_state_txt(old_state); 442 if (new_state_str == NULL || old_state_str == NULL) { 443 wpa_printf(MSG_ERROR, 444 "dbus: wpa_supplicant_dbus_notify_state_change: " 445 "Could not convert state strings"); 446 goto out; 447 } 448 449 if (!dbus_message_append_args(_signal, 450 DBUS_TYPE_STRING, &new_state_str, 451 DBUS_TYPE_STRING, &old_state_str, 452 DBUS_TYPE_INVALID)) { 453 wpa_printf(MSG_ERROR, 454 "dbus: wpa_supplicant_dbus_notify_state_change: " 455 "Not enough memory to construct state change " 456 "signal"); 457 goto out; 458 } 459 460 dbus_connection_send(iface->con, _signal, NULL); 461 462out: 463 dbus_message_unref(_signal); 464} 465 466 467/** 468 * wpa_supplicant_dbus_notify_scanning - send scanning status 469 * @wpa_s: %wpa_supplicant network interface data 470 * Returns: 0 on success, -1 on failure 471 * 472 * Notify listeners of interface scanning state changes 473 */ 474void wpa_supplicant_dbus_notify_scanning(struct wpa_supplicant *wpa_s) 475{ 476 struct wpas_dbus_priv *iface = wpa_s->global->dbus; 477 DBusMessage *_signal; 478 dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE; 479 480 /* Do nothing if the control interface is not turned on */ 481 if (iface == NULL) 482 return; 483 484 _signal = dbus_message_new_signal(wpa_s->dbus_path, 485 WPAS_DBUS_IFACE_INTERFACE, 486 "Scanning"); 487 if (_signal == NULL) { 488 wpa_printf(MSG_ERROR, "dbus: Not enough memory to send scan " 489 "results signal"); 490 return; 491 } 492 493 if (dbus_message_append_args(_signal, 494 DBUS_TYPE_BOOLEAN, &scanning, 495 DBUS_TYPE_INVALID)) { 496 dbus_connection_send(iface->con, _signal, NULL); 497 } else { 498 wpa_printf(MSG_ERROR, "dbus: Not enough memory to construct " 499 "signal"); 500 } 501 dbus_message_unref(_signal); 502} 503 504 505#ifdef CONFIG_WPS 506void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s, 507 const struct wps_credential *cred) 508{ 509 struct wpas_dbus_priv *iface; 510 DBusMessage *_signal = NULL; 511 512 /* Do nothing if the control interface is not turned on */ 513 if (wpa_s->global == NULL) 514 return; 515 iface = wpa_s->global->dbus; 516 if (iface == NULL) 517 return; 518 519 _signal = dbus_message_new_signal(wpa_s->dbus_path, 520 WPAS_DBUS_IFACE_INTERFACE, 521 "WpsCred"); 522 if (_signal == NULL) { 523 wpa_printf(MSG_ERROR, 524 "dbus: wpa_supplicant_dbus_notify_wps_cred: " 525 "Could not create dbus signal; likely out of " 526 "memory"); 527 return; 528 } 529 530 if (!dbus_message_append_args(_signal, 531 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, 532 &cred->cred_attr, cred->cred_attr_len, 533 DBUS_TYPE_INVALID)) { 534 wpa_printf(MSG_ERROR, 535 "dbus: wpa_supplicant_dbus_notify_wps_cred: " 536 "Not enough memory to construct signal"); 537 goto out; 538 } 539 540 dbus_connection_send(iface->con, _signal, NULL); 541 542out: 543 dbus_message_unref(_signal); 544} 545#else /* CONFIG_WPS */ 546void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s, 547 const struct wps_credential *cred) 548{ 549} 550#endif /* CONFIG_WPS */ 551 552 553/** 554 * wpa_supplicant_dbus_ctrl_iface_init - Initialize dbus control interface 555 * @global: Pointer to global data from wpa_supplicant_init() 556 * Returns: 0 on success, -1 on failure 557 * 558 * Initialize the dbus control interface and start receiving commands from 559 * external programs over the bus. 560 */ 561int wpa_supplicant_dbus_ctrl_iface_init(struct wpas_dbus_priv *iface) 562{ 563 DBusError error; 564 int ret = -1; 565 DBusObjectPathVTable wpas_vtable = { 566 NULL, &wpas_message_handler, NULL, NULL, NULL, NULL 567 }; 568 569 /* Register the message handler for the global dbus interface */ 570 if (!dbus_connection_register_object_path(iface->con, 571 WPAS_DBUS_PATH, &wpas_vtable, 572 iface)) { 573 wpa_printf(MSG_ERROR, "dbus: Could not set up message " 574 "handler"); 575 return -1; 576 } 577 578 /* Register our service with the message bus */ 579 dbus_error_init(&error); 580 switch (dbus_bus_request_name(iface->con, WPAS_DBUS_SERVICE, 581 0, &error)) { 582 case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER: 583 ret = 0; 584 break; 585 case DBUS_REQUEST_NAME_REPLY_EXISTS: 586 case DBUS_REQUEST_NAME_REPLY_IN_QUEUE: 587 case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER: 588 wpa_printf(MSG_ERROR, "dbus: Could not request service name: " 589 "already registered"); 590 break; 591 default: 592 wpa_printf(MSG_ERROR, "dbus: Could not request service name: " 593 "%s %s", error.name, error.message); 594 break; 595 } 596 dbus_error_free(&error); 597 598 if (ret != 0) 599 return -1; 600 601 wpa_printf(MSG_DEBUG, "Providing DBus service '" WPAS_DBUS_SERVICE 602 "'."); 603 604 return 0; 605} 606 607 608/** 609 * wpas_dbus_register_new_iface - Register a new interface with dbus 610 * @wpa_s: %wpa_supplicant interface description structure to register 611 * Returns: 0 on success, -1 on error 612 * 613 * Registers a new interface with dbus and assigns it a dbus object path. 614 */ 615int wpas_dbus_register_iface(struct wpa_supplicant *wpa_s) 616{ 617 struct wpas_dbus_priv *ctrl_iface = wpa_s->global->dbus; 618 DBusConnection * con; 619 u32 next; 620 DBusObjectPathVTable vtable = { 621 NULL, &wpas_iface_message_handler, NULL, NULL, NULL, NULL 622 }; 623 624 /* Do nothing if the control interface is not turned on */ 625 if (ctrl_iface == NULL) 626 return 0; 627 628 con = ctrl_iface->con; 629 next = ctrl_iface->next_objid++; 630 631 /* Create and set the interface's object path */ 632 wpa_s->dbus_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX); 633 if (wpa_s->dbus_path == NULL) 634 return -1; 635 os_snprintf(wpa_s->dbus_path, WPAS_DBUS_OBJECT_PATH_MAX, 636 WPAS_DBUS_PATH_INTERFACES "/%u", 637 next); 638 639 /* Register the message handler for the interface functions */ 640 if (!dbus_connection_register_fallback(con, wpa_s->dbus_path, &vtable, 641 wpa_s)) { 642 wpa_printf(MSG_ERROR, "dbus: Could not set up message " 643 "handler for interface %s", wpa_s->ifname); 644 return -1; 645 } 646 647 return 0; 648} 649 650 651/** 652 * wpas_dbus_unregister_iface - Unregister an interface from dbus 653 * @wpa_s: wpa_supplicant interface structure 654 * Returns: 0 on success, -1 on failure 655 * 656 * Unregisters the interface with dbus 657 */ 658int wpas_dbus_unregister_iface(struct wpa_supplicant *wpa_s) 659{ 660 struct wpas_dbus_priv *ctrl_iface; 661 DBusConnection *con; 662 663 /* Do nothing if the control interface is not turned on */ 664 if (wpa_s == NULL || wpa_s->global == NULL) 665 return 0; 666 ctrl_iface = wpa_s->global->dbus; 667 if (ctrl_iface == NULL) 668 return 0; 669 670 con = ctrl_iface->con; 671 if (!dbus_connection_unregister_object_path(con, wpa_s->dbus_path)) 672 return -1; 673 674 os_free(wpa_s->dbus_path); 675 wpa_s->dbus_path = NULL; 676 677 return 0; 678} 679 680 681/** 682 * wpa_supplicant_get_iface_by_dbus_path - Get a new network interface 683 * @global: Pointer to global data from wpa_supplicant_init() 684 * @path: Pointer to a dbus object path representing an interface 685 * Returns: Pointer to the interface or %NULL if not found 686 */ 687struct wpa_supplicant * wpa_supplicant_get_iface_by_dbus_path( 688 struct wpa_global *global, const char *path) 689{ 690 struct wpa_supplicant *wpa_s; 691 692 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { 693 if (strcmp(wpa_s->dbus_path, path) == 0) 694 return wpa_s; 695 } 696 return NULL; 697} 698