2 * WPA Supplicant / dbus-based control interface
3 * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
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.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
19 #include "drivers/driver.h"
21 #include "../config.h"
22 #include "../wpa_supplicant_i.h"
24 #include "dbus_old_handlers.h"
25 #include "dbus_common.h"
26 #include "dbus_common_i.h"
30 * wpas_dbus_decompose_object_path - Decompose an interface object path into parts
31 * @path: The dbus object path
32 * @network: (out) the configured network this object path refers to, if any
33 * @bssid: (out) the scanned bssid this object path refers to, if any
34 * Returns: The object path of the network interface this path refers to
36 * For a given object path, decomposes the object path into object id, network,
37 * and BSSID parts, if those parts exist.
39 char * wpas_dbus_decompose_object_path(const char *path
, char **network
,
42 const unsigned int dev_path_prefix_len
=
43 strlen(WPAS_DBUS_PATH_INTERFACES
"/");
47 /* Be a bit paranoid about path */
48 if (!path
|| strncmp(path
, WPAS_DBUS_PATH_INTERFACES
"/",
52 /* Ensure there's something at the end of the path */
53 if ((path
+ dev_path_prefix_len
)[0] == '\0')
56 obj_path_only
= os_strdup(path
);
57 if (obj_path_only
== NULL
)
60 next_sep
= strchr(obj_path_only
+ dev_path_prefix_len
, '/');
61 if (next_sep
!= NULL
) {
62 const char *net_part
= strstr(next_sep
,
63 WPAS_DBUS_NETWORKS_PART
"/");
64 const char *bssid_part
= strstr(next_sep
,
65 WPAS_DBUS_BSSIDS_PART
"/");
67 if (network
&& net_part
) {
68 /* Deal with a request for a configured network */
69 const char *net_name
= net_part
+
70 strlen(WPAS_DBUS_NETWORKS_PART
"/");
73 *network
= os_strdup(net_name
);
74 } else if (bssid
&& bssid_part
) {
75 /* Deal with a request for a scanned BSSID */
76 const char *bssid_name
= bssid_part
+
77 strlen(WPAS_DBUS_BSSIDS_PART
"/");
78 if (strlen(bssid_name
))
79 *bssid
= os_strdup(bssid_name
);
84 /* Cut off interface object path before "/" */
93 * wpas_dbus_new_invalid_iface_error - Return a new invalid interface error message
94 * @message: Pointer to incoming dbus message this error refers to
95 * Returns: A dbus error message
97 * Convenience function to create and return an invalid interface error
99 DBusMessage
* wpas_dbus_new_invalid_iface_error(DBusMessage
*message
)
101 return dbus_message_new_error(message
, WPAS_ERROR_INVALID_IFACE
,
102 "wpa_supplicant knows nothing about "
108 * wpas_dbus_new_invalid_network_error - Return a new invalid network error message
109 * @message: Pointer to incoming dbus message this error refers to
110 * Returns: a dbus error message
112 * Convenience function to create and return an invalid network error
114 DBusMessage
* wpas_dbus_new_invalid_network_error(DBusMessage
*message
)
116 return dbus_message_new_error(message
, WPAS_ERROR_INVALID_NETWORK
,
117 "The requested network does not exist.");
122 * wpas_dbus_new_invalid_bssid_error - Return a new invalid bssid error message
123 * @message: Pointer to incoming dbus message this error refers to
124 * Returns: a dbus error message
126 * Convenience function to create and return an invalid bssid error
128 static DBusMessage
* wpas_dbus_new_invalid_bssid_error(DBusMessage
*message
)
130 return dbus_message_new_error(message
, WPAS_ERROR_INVALID_BSSID
,
131 "The BSSID requested was invalid.");
136 * wpas_dispatch_network_method - dispatch messages for configured networks
137 * @message: the incoming dbus message
138 * @wpa_s: a network interface's data
139 * @network_id: id of the configured network we're interested in
140 * Returns: a reply dbus message, or a dbus error message
142 * This function dispatches all incoming dbus messages for configured networks.
144 static DBusMessage
* wpas_dispatch_network_method(DBusMessage
*message
,
145 struct wpa_supplicant
*wpa_s
,
148 DBusMessage
*reply
= NULL
;
149 const char *method
= dbus_message_get_member(message
);
150 struct wpa_ssid
*ssid
;
152 ssid
= wpa_config_get_network(wpa_s
->conf
, network_id
);
154 return wpas_dbus_new_invalid_network_error(message
);
156 if (!strcmp(method
, "set"))
157 reply
= wpas_dbus_iface_set_network(message
, wpa_s
, ssid
);
158 else if (!strcmp(method
, "enable"))
159 reply
= wpas_dbus_iface_enable_network(message
, wpa_s
, ssid
);
160 else if (!strcmp(method
, "disable"))
161 reply
= wpas_dbus_iface_disable_network(message
, wpa_s
, ssid
);
168 * wpas_dispatch_bssid_method - dispatch messages for scanned networks
169 * @message: the incoming dbus message
170 * @wpa_s: a network interface's data
171 * @bssid: bssid of the scanned network we're interested in
172 * Returns: a reply dbus message, or a dbus error message
174 * This function dispatches all incoming dbus messages for scanned networks.
176 static DBusMessage
* wpas_dispatch_bssid_method(DBusMessage
*message
,
177 struct wpa_supplicant
*wpa_s
,
180 DBusMessage
*reply
= NULL
;
181 const char *method
= dbus_message_get_member(message
);
182 struct wpa_scan_res
*res
= NULL
;
185 /* Ensure we actually have scan data */
186 if (wpa_s
->scan_res
== NULL
&&
187 wpa_supplicant_get_scan_results(wpa_s
) < 0) {
188 reply
= wpas_dbus_new_invalid_bssid_error(message
);
192 /* Find the bssid's scan data */
193 for (i
= 0; i
< wpa_s
->scan_res
->num
; i
++) {
194 struct wpa_scan_res
*search_res
= wpa_s
->scan_res
->res
[i
];
197 memset(mac_str
, 0, sizeof(mac_str
));
198 snprintf(mac_str
, sizeof(mac_str
) - 1, WPAS_DBUS_BSSID_FORMAT
,
199 MAC2STR(search_res
->bssid
));
200 if (!strcmp(bssid
, mac_str
)) {
207 reply
= wpas_dbus_new_invalid_bssid_error(message
);
211 /* Dispatch the method call against the scanned bssid */
212 if (!strcmp(method
, "properties"))
213 reply
= wpas_dbus_bssid_properties(message
, wpa_s
, res
);
221 * wpas_iface_message_handler - Dispatch messages for interfaces or networks
222 * @connection: Connection to the system message bus
223 * @message: An incoming dbus message
224 * @user_data: A pointer to a dbus control interface data structure
225 * Returns: Whether or not the message was handled
227 * This function dispatches all incoming dbus messages for network interfaces,
228 * or objects owned by them, such as scanned BSSIDs and configured networks.
230 static DBusHandlerResult
wpas_iface_message_handler(DBusConnection
*connection
,
231 DBusMessage
*message
,
234 struct wpa_supplicant
*wpa_s
= user_data
;
235 const char *method
= dbus_message_get_member(message
);
236 const char *path
= dbus_message_get_path(message
);
237 const char *msg_interface
= dbus_message_get_interface(message
);
238 char *iface_obj_path
= NULL
;
239 char *network
= NULL
;
241 DBusMessage
*reply
= NULL
;
243 /* Caller must specify a message interface */
247 iface_obj_path
= wpas_dbus_decompose_object_path(path
, &network
,
249 if (iface_obj_path
== NULL
) {
250 reply
= wpas_dbus_new_invalid_iface_error(message
);
254 /* Make sure the message's object path actually refers to the
255 * wpa_supplicant structure it's supposed to (which is wpa_s)
257 if (wpa_supplicant_get_iface_by_dbus_path(wpa_s
->global
,
258 iface_obj_path
) != wpa_s
) {
259 reply
= wpas_dbus_new_invalid_iface_error(message
);
263 if (network
&& !strcmp(msg_interface
, WPAS_DBUS_IFACE_NETWORK
)) {
264 /* A method for one of this interface's configured networks */
265 int nid
= strtoul(network
, NULL
, 10);
267 reply
= wpas_dispatch_network_method(message
, wpa_s
,
270 reply
= wpas_dbus_new_invalid_network_error(message
);
271 } else if (bssid
&& !strcmp(msg_interface
, WPAS_DBUS_IFACE_BSSID
)) {
272 /* A method for one of this interface's scanned BSSIDs */
273 reply
= wpas_dispatch_bssid_method(message
, wpa_s
, bssid
);
274 } else if (!strcmp(msg_interface
, WPAS_DBUS_IFACE_INTERFACE
)) {
275 /* A method for an interface only. */
276 if (!strcmp(method
, "scan"))
277 reply
= wpas_dbus_iface_scan(message
, wpa_s
);
278 else if (!strcmp(method
, "scanResults"))
279 reply
= wpas_dbus_iface_scan_results(message
, wpa_s
);
280 else if (!strcmp(method
, "addNetwork"))
281 reply
= wpas_dbus_iface_add_network(message
, wpa_s
);
282 else if (!strcmp(method
, "removeNetwork"))
283 reply
= wpas_dbus_iface_remove_network(message
, wpa_s
);
284 else if (!strcmp(method
, "selectNetwork"))
285 reply
= wpas_dbus_iface_select_network(message
, wpa_s
);
286 else if (!strcmp(method
, "capabilities"))
287 reply
= wpas_dbus_iface_capabilities(message
, wpa_s
);
288 else if (!strcmp(method
, "disconnect"))
289 reply
= wpas_dbus_iface_disconnect(message
, wpa_s
);
290 else if (!strcmp(method
, "setAPScan"))
291 reply
= wpas_dbus_iface_set_ap_scan(message
, wpa_s
);
292 else if (!strcmp(method
, "setSmartcardModules"))
293 reply
= wpas_dbus_iface_set_smartcard_modules(message
,
295 else if (!strcmp(method
, "state"))
296 reply
= wpas_dbus_iface_get_state(message
, wpa_s
);
297 else if (!strcmp(method
, "scanning"))
298 reply
= wpas_dbus_iface_get_scanning(message
, wpa_s
);
299 else if (!strcmp(method
, "setBlobs"))
300 reply
= wpas_dbus_iface_set_blobs(message
, wpa_s
);
301 else if (!strcmp(method
, "removeBlobs"))
302 reply
= wpas_dbus_iface_remove_blobs(message
, wpa_s
);
304 else if (!os_strcmp(method
, "wpsPbc"))
305 reply
= wpas_dbus_iface_wps_pbc(message
, wpa_s
);
306 else if (!os_strcmp(method
, "wpsPin"))
307 reply
= wpas_dbus_iface_wps_pin(message
, wpa_s
);
308 else if (!os_strcmp(method
, "wpsReg"))
309 reply
= wpas_dbus_iface_wps_reg(message
, wpa_s
);
310 #endif /* CONFIG_WPS */
313 /* If the message was handled, send back the reply */
315 if (!dbus_message_get_no_reply(message
))
316 dbus_connection_send(connection
, reply
, NULL
);
317 dbus_message_unref(reply
);
321 os_free(iface_obj_path
);
324 return reply
? DBUS_HANDLER_RESULT_HANDLED
:
325 DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
330 * wpas_message_handler - dispatch incoming dbus messages
331 * @connection: connection to the system message bus
332 * @message: an incoming dbus message
333 * @user_data: a pointer to a dbus control interface data structure
334 * Returns: whether or not the message was handled
336 * This function dispatches all incoming dbus messages to the correct
337 * handlers, depending on what the message's target object path is,
338 * and what the method call is.
340 static DBusHandlerResult
wpas_message_handler(DBusConnection
*connection
,
341 DBusMessage
*message
, void *user_data
)
343 struct wpas_dbus_priv
*ctrl_iface
= user_data
;
346 const char *msg_interface
;
347 DBusMessage
*reply
= NULL
;
349 method
= dbus_message_get_member(message
);
350 path
= dbus_message_get_path(message
);
351 msg_interface
= dbus_message_get_interface(message
);
352 if (!method
|| !path
|| !ctrl_iface
|| !msg_interface
)
353 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
355 /* Validate the method interface */
356 if (strcmp(msg_interface
, WPAS_DBUS_INTERFACE
) != 0)
357 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
359 if (!strcmp(path
, WPAS_DBUS_PATH
)) {
360 /* dispatch methods against our global dbus interface here */
361 if (!strcmp(method
, "addInterface")) {
362 reply
= wpas_dbus_global_add_interface(
363 message
, ctrl_iface
->global
);
364 } else if (!strcmp(method
, "removeInterface")) {
365 reply
= wpas_dbus_global_remove_interface(
366 message
, ctrl_iface
->global
);
367 } else if (!strcmp(method
, "getInterface")) {
368 reply
= wpas_dbus_global_get_interface(
369 message
, ctrl_iface
->global
);
370 } else if (!strcmp(method
, "setDebugParams")) {
371 reply
= wpas_dbus_global_set_debugparams(
372 message
, ctrl_iface
->global
);
376 /* If the message was handled, send back the reply */
378 if (!dbus_message_get_no_reply(message
))
379 dbus_connection_send(connection
, reply
, NULL
);
380 dbus_message_unref(reply
);
383 return reply
? DBUS_HANDLER_RESULT_HANDLED
:
384 DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
389 * wpa_supplicant_dbus_notify_scan_results - Send a scan results signal
390 * @wpa_s: %wpa_supplicant network interface data
391 * Returns: 0 on success, -1 on failure
393 * Notify listeners that this interface has updated scan results.
395 void wpa_supplicant_dbus_notify_scan_results(struct wpa_supplicant
*wpa_s
)
397 struct wpas_dbus_priv
*iface
= wpa_s
->global
->dbus
;
398 DBusMessage
*_signal
;
401 /* Do nothing if the control interface is not turned on */
405 path
= wpa_supplicant_get_dbus_path(wpa_s
);
407 perror("wpa_supplicant_dbus_notify_scan_results[dbus]: "
408 "interface didn't have a dbus path");
409 wpa_printf(MSG_ERROR
,
410 "wpa_supplicant_dbus_notify_scan_results[dbus]: "
411 "interface didn't have a dbus path; can't send "
412 "scan result signal.");
415 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_IFACE_INTERFACE
,
416 "ScanResultsAvailable");
417 if (_signal
== NULL
) {
418 perror("wpa_supplicant_dbus_notify_scan_results[dbus]: "
419 "couldn't create dbus signal; likely out of memory");
420 wpa_printf(MSG_ERROR
, "dbus control interface: not enough "
421 "memory to send scan results signal.");
424 dbus_connection_send(iface
->con
, _signal
, NULL
);
425 dbus_message_unref(_signal
);
430 * wpa_supplicant_dbus_notify_state_change - Send a state change signal
431 * @wpa_s: %wpa_supplicant network interface data
432 * @new_state: new state wpa_supplicant is entering
433 * @old_state: old state wpa_supplicant is leaving
434 * Returns: 0 on success, -1 on failure
436 * Notify listeners that wpa_supplicant has changed state
438 void wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant
*wpa_s
,
439 enum wpa_states new_state
,
440 enum wpa_states old_state
)
442 struct wpas_dbus_priv
*iface
;
443 DBusMessage
*_signal
= NULL
;
445 const char *new_state_str
, *old_state_str
;
447 /* Do nothing if the control interface is not turned on */
448 if (wpa_s
->global
== NULL
)
450 iface
= wpa_s
->global
->dbus
;
454 /* Only send signal if state really changed */
455 if (new_state
== old_state
)
458 path
= wpa_supplicant_get_dbus_path(wpa_s
);
460 perror("wpa_supplicant_dbus_notify_state_change[dbus]: "
461 "interface didn't have a dbus path");
462 wpa_printf(MSG_ERROR
,
463 "wpa_supplicant_dbus_notify_state_change[dbus]: "
464 "interface didn't have a dbus path; can't send "
468 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_IFACE_INTERFACE
,
470 if (_signal
== NULL
) {
471 perror("wpa_supplicant_dbus_notify_state_change[dbus]: "
472 "couldn't create dbus signal; likely out of memory");
473 wpa_printf(MSG_ERROR
,
474 "wpa_supplicant_dbus_notify_state_change[dbus]: "
475 "couldn't create dbus signal; likely out of "
480 new_state_str
= wpa_supplicant_state_txt(new_state
);
481 old_state_str
= wpa_supplicant_state_txt(old_state
);
482 if (new_state_str
== NULL
|| old_state_str
== NULL
) {
483 perror("wpa_supplicant_dbus_notify_state_change[dbus]: "
484 "couldn't convert state strings");
485 wpa_printf(MSG_ERROR
,
486 "wpa_supplicant_dbus_notify_state_change[dbus]: "
487 "couldn't convert state strings.");
491 if (!dbus_message_append_args(_signal
,
492 DBUS_TYPE_STRING
, &new_state_str
,
493 DBUS_TYPE_STRING
, &old_state_str
,
494 DBUS_TYPE_INVALID
)) {
495 perror("wpa_supplicant_dbus_notify_state_change[dbus]: "
496 "not enough memory to construct state change signal.");
497 wpa_printf(MSG_ERROR
,
498 "wpa_supplicant_dbus_notify_state_change[dbus]: "
499 "not enough memory to construct state change "
504 dbus_connection_send(iface
->con
, _signal
, NULL
);
507 dbus_message_unref(_signal
);
512 * wpa_supplicant_dbus_notify_scanning - send scanning status
513 * @wpa_s: %wpa_supplicant network interface data
514 * Returns: 0 on success, -1 on failure
516 * Notify listeners of interface scanning state changes
518 void wpa_supplicant_dbus_notify_scanning(struct wpa_supplicant
*wpa_s
)
520 struct wpas_dbus_priv
*iface
= wpa_s
->global
->dbus
;
521 DBusMessage
*_signal
;
523 dbus_bool_t scanning
= wpa_s
->scanning
? TRUE
: FALSE
;
525 /* Do nothing if the control interface is not turned on */
529 path
= wpa_supplicant_get_dbus_path(wpa_s
);
531 perror("wpa_supplicant_dbus_notify_scanning[dbus]: interface "
532 "didn't have a dbus path");
533 wpa_printf(MSG_ERROR
,
534 "%s[dbus]: interface didn't have a dbus path; "
535 "can't send scanning signal.", __FUNCTION__
);
538 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_IFACE_INTERFACE
,
540 if (_signal
== NULL
) {
541 perror("wpa_supplicant_dbus_notify_scanning[dbus]: couldn't "
542 "create dbus signal; likely out of memory");
543 wpa_printf(MSG_ERROR
, "%s[dbus]: dbus control interface: not "
544 "enough memory to send scan results signal.",
549 if (dbus_message_append_args(_signal
,
550 DBUS_TYPE_BOOLEAN
, &scanning
,
551 DBUS_TYPE_INVALID
)) {
552 dbus_connection_send(iface
->con
, _signal
, NULL
);
554 perror("wpa_supplicant_dbus_notify_scanning[dbus]: not enough "
555 "memory to construct signal.");
556 wpa_printf(MSG_ERROR
, "%s[dbus]: not enough memory to "
557 "construct signal.", __FUNCTION__
);
559 dbus_message_unref(_signal
);
564 void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant
*wpa_s
,
565 const struct wps_credential
*cred
)
567 struct wpas_dbus_priv
*iface
;
568 DBusMessage
*_signal
= NULL
;
571 /* Do nothing if the control interface is not turned on */
572 if (wpa_s
->global
== NULL
)
574 iface
= wpa_s
->global
->dbus
;
578 path
= wpa_supplicant_get_dbus_path(wpa_s
);
580 perror("wpa_supplicant_dbus_notify_wps_cred[dbus]: "
581 "interface didn't have a dbus path");
582 wpa_printf(MSG_ERROR
,
583 "wpa_supplicant_dbus_notify_wps_cred[dbus]: "
584 "interface didn't have a dbus path; can't send "
588 _signal
= dbus_message_new_signal(path
, WPAS_DBUS_IFACE_INTERFACE
,
590 if (_signal
== NULL
) {
591 perror("wpa_supplicant_dbus_notify_wps_cred[dbus]: "
592 "couldn't create dbus signal; likely out of memory");
593 wpa_printf(MSG_ERROR
,
594 "wpa_supplicant_dbus_notify_wps_cred[dbus]: "
595 "couldn't create dbus signal; likely out of "
600 if (!dbus_message_append_args(_signal
,
601 DBUS_TYPE_ARRAY
, DBUS_TYPE_BYTE
,
602 &cred
->cred_attr
, cred
->cred_attr_len
,
603 DBUS_TYPE_INVALID
)) {
604 perror("wpa_supplicant_dbus_notify_wps_cred[dbus]: "
605 "not enough memory to construct signal.");
606 wpa_printf(MSG_ERROR
,
607 "wpa_supplicant_dbus_notify_wps_cred[dbus]: "
608 "not enough memory to construct signal.");
612 dbus_connection_send(iface
->con
, _signal
, NULL
);
615 dbus_message_unref(_signal
);
617 #else /* CONFIG_WPS */
618 void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant
*wpa_s
,
619 const struct wps_credential
*cred
)
622 #endif /* CONFIG_WPS */
626 * wpa_supplicant_dbus_ctrl_iface_init - Initialize dbus control interface
627 * @global: Pointer to global data from wpa_supplicant_init()
628 * Returns: 0 on success, -1 on failure
630 * Initialize the dbus control interface and start receiving commands from
631 * external programs over the bus.
633 int wpa_supplicant_dbus_ctrl_iface_init(struct wpas_dbus_priv
*iface
)
637 DBusObjectPathVTable wpas_vtable
= {
638 NULL
, &wpas_message_handler
, NULL
, NULL
, NULL
, NULL
641 /* Register the message handler for the global dbus interface */
642 if (!dbus_connection_register_object_path(iface
->con
,
643 WPAS_DBUS_PATH
, &wpas_vtable
,
645 perror("dbus_connection_register_object_path[dbus]");
646 wpa_printf(MSG_ERROR
, "Could not set up DBus message "
651 /* Register our service with the message bus */
652 dbus_error_init(&error
);
653 switch (dbus_bus_request_name(iface
->con
, WPAS_DBUS_SERVICE
,
655 case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER
:
658 case DBUS_REQUEST_NAME_REPLY_EXISTS
:
659 case DBUS_REQUEST_NAME_REPLY_IN_QUEUE
:
660 case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER
:
661 perror("dbus_bus_request_name[dbus]");
662 wpa_printf(MSG_ERROR
, "Could not request DBus service name: "
663 "already registered.");
666 perror("dbus_bus_request_name[dbus]");
667 wpa_printf(MSG_ERROR
, "Could not request DBus service name: "
668 "%s %s.", error
.name
, error
.message
);
671 dbus_error_free(&error
);
676 wpa_printf(MSG_DEBUG
, "Providing DBus service '" WPAS_DBUS_SERVICE
684 * wpas_dbus_register_new_iface - Register a new interface with dbus
685 * @wpa_s: %wpa_supplicant interface description structure to register
686 * Returns: 0 on success, -1 on error
688 * Registers a new interface with dbus and assigns it a dbus object path.
690 int wpas_dbus_register_iface(struct wpa_supplicant
*wpa_s
)
692 struct wpas_dbus_priv
*ctrl_iface
= wpa_s
->global
->dbus
;
693 DBusConnection
* con
;
695 DBusObjectPathVTable vtable
= {
696 NULL
, &wpas_iface_message_handler
, NULL
, NULL
, NULL
, NULL
701 /* Do nothing if the control interface is not turned on */
702 if (ctrl_iface
== NULL
)
705 con
= ctrl_iface
->con
;
706 next
= ctrl_iface
->next_objid
++;
708 /* Create and set the interface's object path */
709 path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
712 snprintf(path
, WPAS_DBUS_OBJECT_PATH_MAX
,
713 WPAS_DBUS_PATH_INTERFACES
"/%u",
715 if (wpa_supplicant_set_dbus_path(wpa_s
, path
)) {
716 wpa_printf(MSG_DEBUG
,
717 "Failed to set dbus path for interface %s",
722 /* Register the message handler for the interface functions */
723 if (!dbus_connection_register_fallback(con
, path
, &vtable
, wpa_s
)) {
724 perror("wpas_dbus_register_iface [dbus]");
725 wpa_printf(MSG_ERROR
, "Could not set up DBus message "
726 "handler for interface %s.", wpa_s
->ifname
);
738 * wpas_dbus_unregister_iface - Unregister an interface from dbus
739 * @wpa_s: wpa_supplicant interface structure
740 * Returns: 0 on success, -1 on failure
742 * Unregisters the interface with dbus
744 int wpas_dbus_unregister_iface(struct wpa_supplicant
*wpa_s
)
746 struct wpas_dbus_priv
*ctrl_iface
;
750 /* Do nothing if the control interface is not turned on */
751 if (wpa_s
== NULL
|| wpa_s
->global
== NULL
)
753 ctrl_iface
= wpa_s
->global
->dbus
;
754 if (ctrl_iface
== NULL
)
757 con
= ctrl_iface
->con
;
758 path
= wpa_supplicant_get_dbus_path(wpa_s
);
760 if (!dbus_connection_unregister_object_path(con
, path
))
763 os_free(wpa_s
->dbus_path
);
764 wpa_s
->dbus_path
= NULL
;
771 * wpa_supplicant_get_iface_by_dbus_path - Get a new network interface
772 * @global: Pointer to global data from wpa_supplicant_init()
773 * @path: Pointer to a dbus object path representing an interface
774 * Returns: Pointer to the interface or %NULL if not found
776 struct wpa_supplicant
* wpa_supplicant_get_iface_by_dbus_path(
777 struct wpa_global
*global
, const char *path
)
779 struct wpa_supplicant
*wpa_s
;
781 for (wpa_s
= global
->ifaces
; wpa_s
; wpa_s
= wpa_s
->next
) {
782 if (strcmp(wpa_s
->dbus_path
, path
) == 0)
790 * wpa_supplicant_set_dbus_path - Assign a dbus path to an interface
791 * @wpa_s: wpa_supplicant interface structure
792 * @path: dbus path to set on the interface
793 * Returns: 0 on succes, -1 on error
795 int wpa_supplicant_set_dbus_path(struct wpa_supplicant
*wpa_s
,
798 u32 len
= strlen (path
);
799 if (len
>= WPAS_DBUS_OBJECT_PATH_MAX
)
801 if (wpa_s
->dbus_path
)
803 wpa_s
->dbus_path
= os_strdup(path
);
809 * wpa_supplicant_get_dbus_path - Get an interface's dbus path
810 * @wpa_s: %wpa_supplicant interface structure
811 * Returns: Interface's dbus object path, or %NULL on error
813 const char * wpa_supplicant_get_dbus_path(struct wpa_supplicant
*wpa_s
)
815 return wpa_s
->dbus_path
;