1 /*
2 * WPA Supplicant / dbus-based control interface
3 * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
4 * Copyright (c) 2009-2010, Witold Sowa <witold.sowa@gmail.com>
5 * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
6 *
7 * This software may be distributed under the terms of the BSD license.
8 * See README for more details.
9 */
10
11 #include "includes.h"
12
13 #include "common.h"
14 #include "common/ieee802_11_defs.h"
15 #include "wps/wps.h"
16 #include "ap/sta_info.h"
17 #include "../config.h"
18 #include "../wpa_supplicant_i.h"
19 #include "../bss.h"
20 #include "../wpas_glue.h"
21 #include "dbus_new_helpers.h"
22 #include "dbus_dict_helpers.h"
23 #include "dbus_new.h"
24 #include "dbus_new_handlers.h"
25 #include "dbus_common_i.h"
26 #include "dbus_new_handlers_p2p.h"
27 #include "p2p/p2p.h"
28 #include "../p2p_supplicant.h"
29
30 #ifdef CONFIG_AP /* until needed by something else */
31
32 /*
33 * NameOwnerChanged handling
34 *
35 * Some services we provide allow an application to register for
36 * a signal that it needs. While it can also unregister, we must
37 * be prepared for the case where the application simply crashes
38 * and thus doesn't clean up properly. The way to handle this in
39 * DBus is to register for the NameOwnerChanged signal which will
40 * signal an owner change to NULL if the peer closes the socket
41 * for whatever reason.
42 *
43 * Handle this signal via a filter function whenever necessary.
44 * The code below also handles refcounting in case in the future
45 * there will be multiple instances of this subscription scheme.
46 */
47 static const char wpas_dbus_noc_filter_str[] =
48 "interface=org.freedesktop.DBus,member=NameOwnerChanged";
49
50
noc_filter(DBusConnection * conn,DBusMessage * message,void * data)51 static DBusHandlerResult noc_filter(DBusConnection *conn,
52 DBusMessage *message, void *data)
53 {
54 struct wpas_dbus_priv *priv = data;
55
56 if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_SIGNAL)
57 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
58
59 if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS,
60 "NameOwnerChanged")) {
61 const char *name;
62 const char *prev_owner;
63 const char *new_owner;
64 DBusError derr;
65 struct wpa_supplicant *wpa_s;
66
67 dbus_error_init(&derr);
68
69 if (!dbus_message_get_args(message, &derr,
70 DBUS_TYPE_STRING, &name,
71 DBUS_TYPE_STRING, &prev_owner,
72 DBUS_TYPE_STRING, &new_owner,
73 DBUS_TYPE_INVALID)) {
74 /* Ignore this error */
75 dbus_error_free(&derr);
76 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
77 }
78
79 for (wpa_s = priv->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
80 if (wpa_s->preq_notify_peer != NULL &&
81 os_strcmp(name, wpa_s->preq_notify_peer) == 0 &&
82 (new_owner == NULL || os_strlen(new_owner) == 0)) {
83 /* probe request owner disconnected */
84 os_free(wpa_s->preq_notify_peer);
85 wpa_s->preq_notify_peer = NULL;
86 wpas_dbus_unsubscribe_noc(priv);
87 }
88 }
89 }
90
91 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
92 }
93
94
wpas_dbus_subscribe_noc(struct wpas_dbus_priv * priv)95 void wpas_dbus_subscribe_noc(struct wpas_dbus_priv *priv)
96 {
97 priv->dbus_noc_refcnt++;
98 if (priv->dbus_noc_refcnt > 1)
99 return;
100
101 if (!dbus_connection_add_filter(priv->con, noc_filter, priv, NULL)) {
102 wpa_printf(MSG_ERROR, "dbus: failed to add filter");
103 return;
104 }
105
106 dbus_bus_add_match(priv->con, wpas_dbus_noc_filter_str, NULL);
107 }
108
109
wpas_dbus_unsubscribe_noc(struct wpas_dbus_priv * priv)110 void wpas_dbus_unsubscribe_noc(struct wpas_dbus_priv *priv)
111 {
112 priv->dbus_noc_refcnt--;
113 if (priv->dbus_noc_refcnt > 0)
114 return;
115
116 dbus_bus_remove_match(priv->con, wpas_dbus_noc_filter_str, NULL);
117 dbus_connection_remove_filter(priv->con, noc_filter, priv);
118 }
119
120 #endif /* CONFIG_AP */
121
122
123 /**
124 * wpas_dbus_signal_interface - Send a interface related event signal
125 * @wpa_s: %wpa_supplicant network interface data
126 * @sig_name: signal name - InterfaceAdded or InterfaceRemoved
127 * @properties: Whether to add second argument with object properties
128 *
129 * Notify listeners about event related with interface
130 */
wpas_dbus_signal_interface(struct wpa_supplicant * wpa_s,const char * sig_name,dbus_bool_t properties)131 static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s,
132 const char *sig_name,
133 dbus_bool_t properties)
134 {
135 struct wpas_dbus_priv *iface;
136 DBusMessage *msg;
137 DBusMessageIter iter;
138
139 iface = wpa_s->global->dbus;
140
141 /* Do nothing if the control interface is not turned on */
142 if (iface == NULL || !wpa_s->dbus_new_path)
143 return;
144
145 msg = dbus_message_new_signal(WPAS_DBUS_NEW_PATH,
146 WPAS_DBUS_NEW_INTERFACE, sig_name);
147 if (msg == NULL)
148 return;
149
150 dbus_message_iter_init_append(msg, &iter);
151 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
152 &wpa_s->dbus_new_path) ||
153 (properties &&
154 !wpa_dbus_get_object_properties(
155 iface, wpa_s->dbus_new_path,
156 WPAS_DBUS_NEW_IFACE_INTERFACE, &iter)))
157 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
158 else
159 dbus_connection_send(iface->con, msg, NULL);
160 dbus_message_unref(msg);
161 }
162
163
164 /**
165 * wpas_dbus_signal_interface_added - Send a interface created signal
166 * @wpa_s: %wpa_supplicant network interface data
167 *
168 * Notify listeners about creating new interface
169 */
wpas_dbus_signal_interface_added(struct wpa_supplicant * wpa_s)170 static void wpas_dbus_signal_interface_added(struct wpa_supplicant *wpa_s)
171 {
172 wpas_dbus_signal_interface(wpa_s, "InterfaceAdded", TRUE);
173 }
174
175
176 /**
177 * wpas_dbus_signal_interface_removed - Send a interface removed signal
178 * @wpa_s: %wpa_supplicant network interface data
179 *
180 * Notify listeners about removing interface
181 */
wpas_dbus_signal_interface_removed(struct wpa_supplicant * wpa_s)182 static void wpas_dbus_signal_interface_removed(struct wpa_supplicant *wpa_s)
183 {
184 wpas_dbus_signal_interface(wpa_s, "InterfaceRemoved", FALSE);
185
186 }
187
188
189 /**
190 * wpas_dbus_signal_scan_done - send scan done signal
191 * @wpa_s: %wpa_supplicant network interface data
192 * @success: indicates if scanning succeed or failed
193 *
194 * Notify listeners about finishing a scan
195 */
wpas_dbus_signal_scan_done(struct wpa_supplicant * wpa_s,int success)196 void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s, int success)
197 {
198 struct wpas_dbus_priv *iface;
199 DBusMessage *msg;
200 dbus_bool_t succ;
201
202 iface = wpa_s->global->dbus;
203
204 /* Do nothing if the control interface is not turned on */
205 if (iface == NULL || !wpa_s->dbus_new_path)
206 return;
207
208 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
209 WPAS_DBUS_NEW_IFACE_INTERFACE,
210 "ScanDone");
211 if (msg == NULL)
212 return;
213
214 succ = success ? TRUE : FALSE;
215 if (dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &succ,
216 DBUS_TYPE_INVALID))
217 dbus_connection_send(iface->con, msg, NULL);
218 else
219 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
220 dbus_message_unref(msg);
221 }
222
223
224 /**
225 * wpas_dbus_signal_bss - Send a BSS related event signal
226 * @wpa_s: %wpa_supplicant network interface data
227 * @bss_obj_path: BSS object path
228 * @sig_name: signal name - BSSAdded or BSSRemoved
229 * @properties: Whether to add second argument with object properties
230 *
231 * Notify listeners about event related with BSS
232 */
wpas_dbus_signal_bss(struct wpa_supplicant * wpa_s,const char * bss_obj_path,const char * sig_name,dbus_bool_t properties)233 static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s,
234 const char *bss_obj_path,
235 const char *sig_name, dbus_bool_t properties)
236 {
237 struct wpas_dbus_priv *iface;
238 DBusMessage *msg;
239 DBusMessageIter iter;
240
241 iface = wpa_s->global->dbus;
242
243 /* Do nothing if the control interface is not turned on */
244 if (iface == NULL || !wpa_s->dbus_new_path)
245 return;
246
247 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
248 WPAS_DBUS_NEW_IFACE_INTERFACE,
249 sig_name);
250 if (msg == NULL)
251 return;
252
253 dbus_message_iter_init_append(msg, &iter);
254 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
255 &bss_obj_path) ||
256 (properties &&
257 !wpa_dbus_get_object_properties(iface, bss_obj_path,
258 WPAS_DBUS_NEW_IFACE_BSS,
259 &iter)))
260 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
261 else
262 dbus_connection_send(iface->con, msg, NULL);
263 dbus_message_unref(msg);
264 }
265
266
267 /**
268 * wpas_dbus_signal_bss_added - Send a BSS added signal
269 * @wpa_s: %wpa_supplicant network interface data
270 * @bss_obj_path: new BSS object path
271 *
272 * Notify listeners about adding new BSS
273 */
wpas_dbus_signal_bss_added(struct wpa_supplicant * wpa_s,const char * bss_obj_path)274 static void wpas_dbus_signal_bss_added(struct wpa_supplicant *wpa_s,
275 const char *bss_obj_path)
276 {
277 wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSAdded", TRUE);
278 }
279
280
281 /**
282 * wpas_dbus_signal_bss_removed - Send a BSS removed signal
283 * @wpa_s: %wpa_supplicant network interface data
284 * @bss_obj_path: BSS object path
285 *
286 * Notify listeners about removing BSS
287 */
wpas_dbus_signal_bss_removed(struct wpa_supplicant * wpa_s,const char * bss_obj_path)288 static void wpas_dbus_signal_bss_removed(struct wpa_supplicant *wpa_s,
289 const char *bss_obj_path)
290 {
291 wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSRemoved", FALSE);
292 }
293
294
295 /**
296 * wpas_dbus_signal_blob - Send a blob related event signal
297 * @wpa_s: %wpa_supplicant network interface data
298 * @name: blob name
299 * @sig_name: signal name - BlobAdded or BlobRemoved
300 *
301 * Notify listeners about event related with blob
302 */
wpas_dbus_signal_blob(struct wpa_supplicant * wpa_s,const char * name,const char * sig_name)303 static void wpas_dbus_signal_blob(struct wpa_supplicant *wpa_s,
304 const char *name, const char *sig_name)
305 {
306 struct wpas_dbus_priv *iface;
307 DBusMessage *msg;
308
309 iface = wpa_s->global->dbus;
310
311 /* Do nothing if the control interface is not turned on */
312 if (iface == NULL || !wpa_s->dbus_new_path)
313 return;
314
315 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
316 WPAS_DBUS_NEW_IFACE_INTERFACE,
317 sig_name);
318 if (msg == NULL)
319 return;
320
321 if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &name,
322 DBUS_TYPE_INVALID))
323 dbus_connection_send(iface->con, msg, NULL);
324 else
325 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
326 dbus_message_unref(msg);
327 }
328
329
330 /**
331 * wpas_dbus_signal_blob_added - Send a blob added signal
332 * @wpa_s: %wpa_supplicant network interface data
333 * @name: blob name
334 *
335 * Notify listeners about adding a new blob
336 */
wpas_dbus_signal_blob_added(struct wpa_supplicant * wpa_s,const char * name)337 void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s,
338 const char *name)
339 {
340 wpas_dbus_signal_blob(wpa_s, name, "BlobAdded");
341 }
342
343
344 /**
345 * wpas_dbus_signal_blob_removed - Send a blob removed signal
346 * @wpa_s: %wpa_supplicant network interface data
347 * @name: blob name
348 *
349 * Notify listeners about removing blob
350 */
wpas_dbus_signal_blob_removed(struct wpa_supplicant * wpa_s,const char * name)351 void wpas_dbus_signal_blob_removed(struct wpa_supplicant *wpa_s,
352 const char *name)
353 {
354 wpas_dbus_signal_blob(wpa_s, name, "BlobRemoved");
355 }
356
357
358 /**
359 * wpas_dbus_signal_network - Send a network related event signal
360 * @wpa_s: %wpa_supplicant network interface data
361 * @id: new network id
362 * @sig_name: signal name - NetworkAdded, NetworkRemoved or NetworkSelected
363 * @properties: determines if add second argument with object properties
364 *
365 * Notify listeners about event related with configured network
366 */
wpas_dbus_signal_network(struct wpa_supplicant * wpa_s,int id,const char * sig_name,dbus_bool_t properties)367 static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s,
368 int id, const char *sig_name,
369 dbus_bool_t properties)
370 {
371 struct wpas_dbus_priv *iface;
372 DBusMessage *msg;
373 DBusMessageIter iter;
374 char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
375
376 iface = wpa_s->global->dbus;
377
378 /* Do nothing if the control interface is not turned on */
379 if (iface == NULL || !wpa_s->dbus_new_path)
380 return;
381
382 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
383 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
384 wpa_s->dbus_new_path, id);
385
386 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
387 WPAS_DBUS_NEW_IFACE_INTERFACE,
388 sig_name);
389 if (msg == NULL)
390 return;
391
392 dbus_message_iter_init_append(msg, &iter);
393 path = net_obj_path;
394 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
395 &path) ||
396 (properties &&
397 !wpa_dbus_get_object_properties(
398 iface, net_obj_path, WPAS_DBUS_NEW_IFACE_NETWORK,
399 &iter)))
400 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
401 else
402 dbus_connection_send(iface->con, msg, NULL);
403 dbus_message_unref(msg);
404 }
405
406
407 /**
408 * wpas_dbus_signal_network_added - Send a network added signal
409 * @wpa_s: %wpa_supplicant network interface data
410 * @id: new network id
411 *
412 * Notify listeners about adding new network
413 */
wpas_dbus_signal_network_added(struct wpa_supplicant * wpa_s,int id)414 static void wpas_dbus_signal_network_added(struct wpa_supplicant *wpa_s,
415 int id)
416 {
417 wpas_dbus_signal_network(wpa_s, id, "NetworkAdded", TRUE);
418 }
419
420
421 /**
422 * wpas_dbus_signal_network_removed - Send a network removed signal
423 * @wpa_s: %wpa_supplicant network interface data
424 * @id: network id
425 *
426 * Notify listeners about removing a network
427 */
wpas_dbus_signal_network_removed(struct wpa_supplicant * wpa_s,int id)428 static void wpas_dbus_signal_network_removed(struct wpa_supplicant *wpa_s,
429 int id)
430 {
431 wpas_dbus_signal_network(wpa_s, id, "NetworkRemoved", FALSE);
432 }
433
434
435 /**
436 * wpas_dbus_signal_network_selected - Send a network selected signal
437 * @wpa_s: %wpa_supplicant network interface data
438 * @id: network id
439 *
440 * Notify listeners about selecting a network
441 */
wpas_dbus_signal_network_selected(struct wpa_supplicant * wpa_s,int id)442 void wpas_dbus_signal_network_selected(struct wpa_supplicant *wpa_s, int id)
443 {
444 wpas_dbus_signal_network(wpa_s, id, "NetworkSelected", FALSE);
445 }
446
447
448 /**
449 * wpas_dbus_signal_network_request - Indicate that additional information
450 * (EAP password, etc.) is required to complete the association to this SSID
451 * @wpa_s: %wpa_supplicant network interface data
452 * @rtype: The specific additional information required
453 * @default_text: Optional description of required information
454 *
455 * Request additional information or passwords to complete an association
456 * request.
457 */
wpas_dbus_signal_network_request(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid,enum wpa_ctrl_req_type rtype,const char * default_txt)458 void wpas_dbus_signal_network_request(struct wpa_supplicant *wpa_s,
459 struct wpa_ssid *ssid,
460 enum wpa_ctrl_req_type rtype,
461 const char *default_txt)
462 {
463 struct wpas_dbus_priv *iface;
464 DBusMessage *msg;
465 DBusMessageIter iter;
466 char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
467 const char *field, *txt = NULL, *net_ptr;
468
469 iface = wpa_s->global->dbus;
470
471 /* Do nothing if the control interface is not turned on */
472 if (iface == NULL || !wpa_s->dbus_new_path)
473 return;
474
475 field = wpa_supplicant_ctrl_req_to_string(rtype, default_txt, &txt);
476 if (field == NULL)
477 return;
478
479 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
480 WPAS_DBUS_NEW_IFACE_INTERFACE,
481 "NetworkRequest");
482 if (msg == NULL)
483 return;
484
485 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
486 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
487 wpa_s->dbus_new_path, ssid->id);
488 net_ptr = &net_obj_path[0];
489
490 dbus_message_iter_init_append(msg, &iter);
491 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
492 &net_ptr) ||
493 !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &field) ||
494 !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &txt))
495 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
496 else
497 dbus_connection_send(iface->con, msg, NULL);
498 dbus_message_unref(msg);
499 }
500
501
502 /**
503 * wpas_dbus_signal_network_enabled_changed - Signals Enabled property changes
504 * @wpa_s: %wpa_supplicant network interface data
505 * @ssid: configured network which Enabled property has changed
506 *
507 * Sends PropertyChanged signals containing new value of Enabled property
508 * for specified network
509 */
wpas_dbus_signal_network_enabled_changed(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid)510 void wpas_dbus_signal_network_enabled_changed(struct wpa_supplicant *wpa_s,
511 struct wpa_ssid *ssid)
512 {
513
514 char path[WPAS_DBUS_OBJECT_PATH_MAX];
515
516 if (!wpa_s->dbus_new_path)
517 return;
518 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
519 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
520 wpa_s->dbus_new_path, ssid->id);
521
522 wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
523 WPAS_DBUS_NEW_IFACE_NETWORK, "Enabled");
524 }
525
526
527 #ifdef CONFIG_WPS
528
529 /**
530 * wpas_dbus_signal_wps_event_pbc_overlap - Signals PBC overlap WPS event
531 * @wpa_s: %wpa_supplicant network interface data
532 *
533 * Sends Event dbus signal with name "pbc-overlap" and empty dict as arguments
534 */
wpas_dbus_signal_wps_event_pbc_overlap(struct wpa_supplicant * wpa_s)535 void wpas_dbus_signal_wps_event_pbc_overlap(struct wpa_supplicant *wpa_s)
536 {
537
538 DBusMessage *msg;
539 DBusMessageIter iter, dict_iter;
540 struct wpas_dbus_priv *iface;
541 char *key = "pbc-overlap";
542
543 iface = wpa_s->global->dbus;
544
545 /* Do nothing if the control interface is not turned on */
546 if (iface == NULL || !wpa_s->dbus_new_path)
547 return;
548
549 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
550 WPAS_DBUS_NEW_IFACE_WPS, "Event");
551 if (msg == NULL)
552 return;
553
554 dbus_message_iter_init_append(msg, &iter);
555
556 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
557 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
558 !wpa_dbus_dict_close_write(&iter, &dict_iter))
559 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
560 else
561 dbus_connection_send(iface->con, msg, NULL);
562
563 dbus_message_unref(msg);
564 }
565
566
567 /**
568 * wpas_dbus_signal_wps_event_success - Signals Success WPS event
569 * @wpa_s: %wpa_supplicant network interface data
570 *
571 * Sends Event dbus signal with name "success" and empty dict as arguments
572 */
wpas_dbus_signal_wps_event_success(struct wpa_supplicant * wpa_s)573 void wpas_dbus_signal_wps_event_success(struct wpa_supplicant *wpa_s)
574 {
575
576 DBusMessage *msg;
577 DBusMessageIter iter, dict_iter;
578 struct wpas_dbus_priv *iface;
579 char *key = "success";
580
581 iface = wpa_s->global->dbus;
582
583 /* Do nothing if the control interface is not turned on */
584 if (iface == NULL || !wpa_s->dbus_new_path)
585 return;
586
587 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
588 WPAS_DBUS_NEW_IFACE_WPS, "Event");
589 if (msg == NULL)
590 return;
591
592 dbus_message_iter_init_append(msg, &iter);
593
594 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
595 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
596 !wpa_dbus_dict_close_write(&iter, &dict_iter))
597 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
598 else
599 dbus_connection_send(iface->con, msg, NULL);
600
601 dbus_message_unref(msg);
602 }
603
604
605 /**
606 * wpas_dbus_signal_wps_event_fail - Signals Fail WPS event
607 * @wpa_s: %wpa_supplicant network interface data
608 * @fail: WPS failure information
609 *
610 * Sends Event dbus signal with name "fail" and dictionary containing
611 * "msg field with fail message number (int32) as arguments
612 */
wpas_dbus_signal_wps_event_fail(struct wpa_supplicant * wpa_s,struct wps_event_fail * fail)613 void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant *wpa_s,
614 struct wps_event_fail *fail)
615 {
616
617 DBusMessage *msg;
618 DBusMessageIter iter, dict_iter;
619 struct wpas_dbus_priv *iface;
620 char *key = "fail";
621
622 iface = wpa_s->global->dbus;
623
624 /* Do nothing if the control interface is not turned on */
625 if (iface == NULL || !wpa_s->dbus_new_path)
626 return;
627
628 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
629 WPAS_DBUS_NEW_IFACE_WPS, "Event");
630 if (msg == NULL)
631 return;
632
633 dbus_message_iter_init_append(msg, &iter);
634
635 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
636 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
637 !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
638 !wpa_dbus_dict_append_int32(&dict_iter, "config_error",
639 fail->config_error) ||
640 !wpa_dbus_dict_append_int32(&dict_iter, "error_indication",
641 fail->error_indication) ||
642 !wpa_dbus_dict_close_write(&iter, &dict_iter))
643 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
644 else
645 dbus_connection_send(iface->con, msg, NULL);
646
647 dbus_message_unref(msg);
648 }
649
650
651 /**
652 * wpas_dbus_signal_wps_event_m2d - Signals M2D WPS event
653 * @wpa_s: %wpa_supplicant network interface data
654 * @m2d: M2D event data information
655 *
656 * Sends Event dbus signal with name "m2d" and dictionary containing
657 * fields of wps_event_m2d structure.
658 */
wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant * wpa_s,struct wps_event_m2d * m2d)659 void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant *wpa_s,
660 struct wps_event_m2d *m2d)
661 {
662
663 DBusMessage *msg;
664 DBusMessageIter iter, dict_iter;
665 struct wpas_dbus_priv *iface;
666 char *key = "m2d";
667
668 iface = wpa_s->global->dbus;
669
670 /* Do nothing if the control interface is not turned on */
671 if (iface == NULL || !wpa_s->dbus_new_path)
672 return;
673
674 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
675 WPAS_DBUS_NEW_IFACE_WPS, "Event");
676 if (msg == NULL)
677 return;
678
679 dbus_message_iter_init_append(msg, &iter);
680
681 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
682 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
683 !wpa_dbus_dict_append_uint16(&dict_iter, "config_methods",
684 m2d->config_methods) ||
685 !wpa_dbus_dict_append_byte_array(&dict_iter, "manufacturer",
686 (const char *) m2d->manufacturer,
687 m2d->manufacturer_len) ||
688 !wpa_dbus_dict_append_byte_array(&dict_iter, "model_name",
689 (const char *) m2d->model_name,
690 m2d->model_name_len) ||
691 !wpa_dbus_dict_append_byte_array(&dict_iter, "model_number",
692 (const char *) m2d->model_number,
693 m2d->model_number_len) ||
694 !wpa_dbus_dict_append_byte_array(&dict_iter, "serial_number",
695 (const char *)
696 m2d->serial_number,
697 m2d->serial_number_len) ||
698 !wpa_dbus_dict_append_byte_array(&dict_iter, "dev_name",
699 (const char *) m2d->dev_name,
700 m2d->dev_name_len) ||
701 !wpa_dbus_dict_append_byte_array(&dict_iter, "primary_dev_type",
702 (const char *)
703 m2d->primary_dev_type, 8) ||
704 !wpa_dbus_dict_append_uint16(&dict_iter, "config_error",
705 m2d->config_error) ||
706 !wpa_dbus_dict_append_uint16(&dict_iter, "dev_password_id",
707 m2d->dev_password_id) ||
708 !wpa_dbus_dict_close_write(&iter, &dict_iter))
709 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
710 else
711 dbus_connection_send(iface->con, msg, NULL);
712
713 dbus_message_unref(msg);
714 }
715
716
717 /**
718 * wpas_dbus_signal_wps_cred - Signals new credentials
719 * @wpa_s: %wpa_supplicant network interface data
720 * @cred: WPS Credential information
721 *
722 * Sends signal with credentials in directory argument
723 */
wpas_dbus_signal_wps_cred(struct wpa_supplicant * wpa_s,const struct wps_credential * cred)724 void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s,
725 const struct wps_credential *cred)
726 {
727 DBusMessage *msg;
728 DBusMessageIter iter, dict_iter;
729 struct wpas_dbus_priv *iface;
730 char *auth_type[5]; /* we have five possible authentication types */
731 int at_num = 0;
732 char *encr_type[3]; /* we have three possible encryption types */
733 int et_num = 0;
734
735 iface = wpa_s->global->dbus;
736
737 /* Do nothing if the control interface is not turned on */
738 if (iface == NULL || !wpa_s->dbus_new_path)
739 return;
740
741 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
742 WPAS_DBUS_NEW_IFACE_WPS,
743 "Credentials");
744 if (msg == NULL)
745 return;
746
747 dbus_message_iter_init_append(msg, &iter);
748 if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
749 goto nomem;
750
751 if (cred->auth_type & WPS_AUTH_OPEN)
752 auth_type[at_num++] = "open";
753 #ifndef CONFIG_NO_TKIP
754 if (cred->auth_type & WPS_AUTH_WPAPSK)
755 auth_type[at_num++] = "wpa-psk";
756 if (cred->auth_type & WPS_AUTH_WPA)
757 auth_type[at_num++] = "wpa-eap";
758 #endif /* CONFIG_NO_TKIP */
759 if (cred->auth_type & WPS_AUTH_WPA2)
760 auth_type[at_num++] = "wpa2-eap";
761 if (cred->auth_type & WPS_AUTH_WPA2PSK)
762 auth_type[at_num++] = "wpa2-psk";
763
764 if (cred->encr_type & WPS_ENCR_NONE)
765 encr_type[et_num++] = "none";
766 #ifndef CONFIG_NO_TKIP
767 if (cred->encr_type & WPS_ENCR_TKIP)
768 encr_type[et_num++] = "tkip";
769 #endif /* CONFIG_NO_TKIP */
770 if (cred->encr_type & WPS_ENCR_AES)
771 encr_type[et_num++] = "aes";
772
773 if ((wpa_s->current_ssid &&
774 !wpa_dbus_dict_append_byte_array(
775 &dict_iter, "BSSID",
776 (const char *) wpa_s->current_ssid->bssid, ETH_ALEN)) ||
777 !wpa_dbus_dict_append_byte_array(&dict_iter, "SSID",
778 (const char *) cred->ssid,
779 cred->ssid_len) ||
780 !wpa_dbus_dict_append_string_array(&dict_iter, "AuthType",
781 (const char **) auth_type,
782 at_num) ||
783 !wpa_dbus_dict_append_string_array(&dict_iter, "EncrType",
784 (const char **) encr_type,
785 et_num) ||
786 !wpa_dbus_dict_append_byte_array(&dict_iter, "Key",
787 (const char *) cred->key,
788 cred->key_len) ||
789 !wpa_dbus_dict_append_uint32(&dict_iter, "KeyIndex",
790 cred->key_idx) ||
791 !wpa_dbus_dict_close_write(&iter, &dict_iter))
792 goto nomem;
793
794 dbus_connection_send(iface->con, msg, NULL);
795
796 nomem:
797 dbus_message_unref(msg);
798 }
799
800 #endif /* CONFIG_WPS */
801
802
803 #ifdef CONFIG_MESH
804
wpas_dbus_signal_mesh_group_started(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid)805 void wpas_dbus_signal_mesh_group_started(struct wpa_supplicant *wpa_s,
806 struct wpa_ssid *ssid)
807 {
808 struct wpas_dbus_priv *iface;
809 DBusMessage *msg;
810 DBusMessageIter iter, dict_iter;
811
812 iface = wpa_s->global->dbus;
813
814 /* Do nothing if the control interface is not turned on */
815 if (!iface || !wpa_s->dbus_new_path)
816 return;
817
818 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
819 WPAS_DBUS_NEW_IFACE_MESH,
820 "MeshGroupStarted");
821 if (!msg)
822 return;
823
824 dbus_message_iter_init_append(msg, &iter);
825 if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
826 !wpa_dbus_dict_append_byte_array(&dict_iter, "SSID",
827 (const char *) ssid->ssid,
828 ssid->ssid_len) ||
829 !wpa_dbus_dict_close_write(&iter, &dict_iter))
830 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
831 else
832 dbus_connection_send(iface->con, msg, NULL);
833 dbus_message_unref(msg);
834 }
835
836
wpas_dbus_signal_mesh_group_removed(struct wpa_supplicant * wpa_s,const u8 * meshid,u8 meshid_len,int reason)837 void wpas_dbus_signal_mesh_group_removed(struct wpa_supplicant *wpa_s,
838 const u8 *meshid, u8 meshid_len,
839 int reason)
840 {
841 struct wpas_dbus_priv *iface;
842 DBusMessage *msg;
843 DBusMessageIter iter, dict_iter;
844
845 iface = wpa_s->global->dbus;
846
847 /* Do nothing if the control interface is not turned on */
848 if (!iface || !wpa_s->dbus_new_path)
849 return;
850
851 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
852 WPAS_DBUS_NEW_IFACE_MESH,
853 "MeshGroupRemoved");
854 if (!msg)
855 return;
856
857 dbus_message_iter_init_append(msg, &iter);
858 if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
859 !wpa_dbus_dict_append_byte_array(&dict_iter, "SSID",
860 (const char *) meshid,
861 meshid_len) ||
862 !wpa_dbus_dict_append_int32(&dict_iter, "DisconnectReason",
863 reason) ||
864 !wpa_dbus_dict_close_write(&iter, &dict_iter))
865 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
866 else
867 dbus_connection_send(iface->con, msg, NULL);
868 dbus_message_unref(msg);
869 }
870
871
wpas_dbus_signal_mesh_peer_connected(struct wpa_supplicant * wpa_s,const u8 * peer_addr)872 void wpas_dbus_signal_mesh_peer_connected(struct wpa_supplicant *wpa_s,
873 const u8 *peer_addr)
874 {
875 struct wpas_dbus_priv *iface;
876 DBusMessage *msg;
877 DBusMessageIter iter, dict_iter;
878
879 iface = wpa_s->global->dbus;
880
881 /* Do nothing if the control interface is not turned on */
882 if (!iface || !wpa_s->dbus_new_path)
883 return;
884
885 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
886 WPAS_DBUS_NEW_IFACE_MESH,
887 "MeshPeerConnected");
888 if (!msg)
889 return;
890
891 dbus_message_iter_init_append(msg, &iter);
892 if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
893 !wpa_dbus_dict_append_byte_array(&dict_iter, "PeerAddress",
894 (const char *) peer_addr,
895 ETH_ALEN) ||
896 !wpa_dbus_dict_close_write(&iter, &dict_iter))
897 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
898 else
899 dbus_connection_send(iface->con, msg, NULL);
900 dbus_message_unref(msg);
901 }
902
903
wpas_dbus_signal_mesh_peer_disconnected(struct wpa_supplicant * wpa_s,const u8 * peer_addr,int reason)904 void wpas_dbus_signal_mesh_peer_disconnected(struct wpa_supplicant *wpa_s,
905 const u8 *peer_addr, int reason)
906 {
907 struct wpas_dbus_priv *iface;
908 DBusMessage *msg;
909 DBusMessageIter iter, dict_iter;
910
911 iface = wpa_s->global->dbus;
912
913 /* Do nothing if the control interface is not turned on */
914 if (!iface || !wpa_s->dbus_new_path)
915 return;
916
917 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
918 WPAS_DBUS_NEW_IFACE_MESH,
919 "MeshPeerDisconnected");
920 if (!msg)
921 return;
922
923 dbus_message_iter_init_append(msg, &iter);
924 if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
925 !wpa_dbus_dict_append_byte_array(&dict_iter, "PeerAddress",
926 (const char *) peer_addr,
927 ETH_ALEN) ||
928 !wpa_dbus_dict_append_int32(&dict_iter, "DisconnectReason",
929 reason) ||
930 !wpa_dbus_dict_close_write(&iter, &dict_iter))
931 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
932 else
933 dbus_connection_send(iface->con, msg, NULL);
934 dbus_message_unref(msg);
935 }
936
937 #endif /* CONFIG_MESH */
938
939
940 #ifdef CONFIG_INTERWORKING
941
wpas_dbus_signal_interworking_ap_added(struct wpa_supplicant * wpa_s,struct wpa_bss * bss,struct wpa_cred * cred,const char * type,int excluded,int bh,int bss_load,int conn_capab)942 void wpas_dbus_signal_interworking_ap_added(struct wpa_supplicant *wpa_s,
943 struct wpa_bss *bss,
944 struct wpa_cred *cred,
945 const char *type,
946 int excluded,
947 int bh,
948 int bss_load,
949 int conn_capab)
950 {
951 struct wpas_dbus_priv *iface;
952 DBusMessage *msg;
953 DBusMessageIter iter, dict_iter;
954 char bss_path[WPAS_DBUS_OBJECT_PATH_MAX], *bss_obj_path;
955 char cred_path[WPAS_DBUS_OBJECT_PATH_MAX], *cred_obj_path;
956
957 iface = wpa_s->global->dbus;
958
959 /* Do nothing if the control interface is not turned on */
960 if (!iface || !wpa_s->dbus_new_path)
961 return;
962
963 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
964 WPAS_DBUS_NEW_IFACE_INTERFACE,
965 "InterworkingAPAdded");
966 if (!msg)
967 return;
968
969 os_snprintf(bss_path, WPAS_DBUS_OBJECT_PATH_MAX,
970 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
971 wpa_s->dbus_new_path, bss->id);
972 bss_obj_path = bss_path;
973
974 os_snprintf(cred_path, WPAS_DBUS_OBJECT_PATH_MAX,
975 "%s/" WPAS_DBUS_NEW_CREDENTIALS_PART "/%u",
976 wpa_s->dbus_new_path, cred->id);
977 cred_obj_path = cred_path;
978
979 dbus_message_iter_init_append(msg, &iter);
980 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
981 &bss_obj_path) ||
982 !dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
983 &cred_obj_path) ||
984 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
985 !wpa_dbus_dict_append_string(&dict_iter, "type", type) ||
986 !wpa_dbus_dict_append_int32(&dict_iter, "excluded", excluded) ||
987 !wpa_dbus_dict_append_int32(&dict_iter, "priority",
988 cred->priority) ||
989 !wpa_dbus_dict_append_int32(&dict_iter, "sp_priority",
990 cred->sp_priority) ||
991 !wpa_dbus_dict_append_int32(&dict_iter, "below_min_backhaul", bh) ||
992 !wpa_dbus_dict_append_int32(&dict_iter, "over_max_bss_load",
993 bss_load) ||
994 !wpa_dbus_dict_append_int32(&dict_iter, "conn_capab_missing",
995 conn_capab) ||
996 !wpa_dbus_dict_close_write(&iter, &dict_iter))
997 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
998 else
999 dbus_connection_send(iface->con, msg, NULL);
1000 dbus_message_unref(msg);
1001 }
1002
1003
wpas_dbus_signal_interworking_select_done(struct wpa_supplicant * wpa_s)1004 void wpas_dbus_signal_interworking_select_done(struct wpa_supplicant *wpa_s)
1005 {
1006 struct wpas_dbus_priv *iface;
1007 DBusMessage *msg;
1008
1009 iface = wpa_s->global->dbus;
1010
1011 /* Do nothing if the control interface is not turned on */
1012 if (!iface || !wpa_s->dbus_new_path)
1013 return;
1014
1015 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1016 WPAS_DBUS_NEW_IFACE_INTERFACE,
1017 "InterworkingSelectDone");
1018 if (!msg)
1019 return;
1020
1021 dbus_connection_send(iface->con, msg, NULL);
1022
1023 dbus_message_unref(msg);
1024 }
1025
1026
wpas_dbus_signal_anqp_query_done(struct wpa_supplicant * wpa_s,const u8 * dst,const char * result)1027 void wpas_dbus_signal_anqp_query_done(struct wpa_supplicant *wpa_s,
1028 const u8 *dst, const char *result)
1029 {
1030 struct wpas_dbus_priv *iface;
1031 DBusMessage *msg;
1032 DBusMessageIter iter;
1033 char addr[WPAS_DBUS_OBJECT_PATH_MAX], *bssid;
1034
1035 os_snprintf(addr, WPAS_DBUS_OBJECT_PATH_MAX, MACSTR, MAC2STR(dst));
1036 bssid = addr;
1037
1038 iface = wpa_s->global->dbus;
1039
1040 /* Do nothing if the control interface is not turned on */
1041 if (!iface || !wpa_s->dbus_new_path)
1042 return;
1043
1044 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1045 WPAS_DBUS_NEW_IFACE_INTERFACE,
1046 "ANQPQueryDone");
1047 if (!msg)
1048 return;
1049
1050 dbus_message_iter_init_append(msg, &iter);
1051
1052 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &bssid) ||
1053 !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &result))
1054 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1055 else
1056 dbus_connection_send(iface->con, msg, NULL);
1057 dbus_message_unref(msg);
1058 }
1059
1060 #endif /* CONFIG_INTERWORKING */
1061
1062
wpas_dbus_signal_certification(struct wpa_supplicant * wpa_s,int depth,const char * subject,const char * altsubject[],int num_altsubject,const char * cert_hash,const struct wpabuf * cert)1063 void wpas_dbus_signal_certification(struct wpa_supplicant *wpa_s,
1064 int depth, const char *subject,
1065 const char *altsubject[],
1066 int num_altsubject,
1067 const char *cert_hash,
1068 const struct wpabuf *cert)
1069 {
1070 struct wpas_dbus_priv *iface;
1071 DBusMessage *msg;
1072 DBusMessageIter iter, dict_iter;
1073
1074 iface = wpa_s->global->dbus;
1075
1076 /* Do nothing if the control interface is not turned on */
1077 if (iface == NULL || !wpa_s->dbus_new_path)
1078 return;
1079
1080 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1081 WPAS_DBUS_NEW_IFACE_INTERFACE,
1082 "Certification");
1083 if (msg == NULL)
1084 return;
1085
1086 dbus_message_iter_init_append(msg, &iter);
1087 if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
1088 !wpa_dbus_dict_append_uint32(&dict_iter, "depth", depth) ||
1089 !wpa_dbus_dict_append_string(&dict_iter, "subject", subject) ||
1090 (altsubject && num_altsubject &&
1091 !wpa_dbus_dict_append_string_array(&dict_iter, "altsubject",
1092 altsubject, num_altsubject)) ||
1093 (cert_hash &&
1094 !wpa_dbus_dict_append_string(&dict_iter, "cert_hash",
1095 cert_hash)) ||
1096 (cert &&
1097 !wpa_dbus_dict_append_byte_array(&dict_iter, "cert",
1098 wpabuf_head(cert),
1099 wpabuf_len(cert))) ||
1100 !wpa_dbus_dict_close_write(&iter, &dict_iter))
1101 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1102 else
1103 dbus_connection_send(iface->con, msg, NULL);
1104 dbus_message_unref(msg);
1105 }
1106
1107
wpas_dbus_signal_eap_status(struct wpa_supplicant * wpa_s,const char * status,const char * parameter)1108 void wpas_dbus_signal_eap_status(struct wpa_supplicant *wpa_s,
1109 const char *status, const char *parameter)
1110 {
1111 struct wpas_dbus_priv *iface;
1112 DBusMessage *msg;
1113 DBusMessageIter iter;
1114
1115 iface = wpa_s->global->dbus;
1116
1117 /* Do nothing if the control interface is not turned on */
1118 if (iface == NULL || !wpa_s->dbus_new_path)
1119 return;
1120
1121 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1122 WPAS_DBUS_NEW_IFACE_INTERFACE,
1123 "EAP");
1124 if (msg == NULL)
1125 return;
1126
1127 dbus_message_iter_init_append(msg, &iter);
1128
1129 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &status) ||
1130 !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
1131 ¶meter))
1132 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1133 else
1134 dbus_connection_send(iface->con, msg, NULL);
1135 dbus_message_unref(msg);
1136 }
1137
1138
wpas_dbus_signal_psk_mismatch(struct wpa_supplicant * wpa_s)1139 void wpas_dbus_signal_psk_mismatch(struct wpa_supplicant *wpa_s)
1140 {
1141 struct wpas_dbus_priv *iface;
1142 DBusMessage *msg;
1143
1144 iface = wpa_s->global->dbus;
1145
1146 /* Do nothing if the control interface is not turned on */
1147 if (!iface || !wpa_s->dbus_new_path)
1148 return;
1149
1150 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1151 WPAS_DBUS_NEW_IFACE_INTERFACE,
1152 "PskMismatch");
1153 if (!msg)
1154 return;
1155
1156 dbus_connection_send(iface->con, msg, NULL);
1157
1158 dbus_message_unref(msg);
1159 }
1160
1161
wpas_dbus_signal_sae_password_mismatch(struct wpa_supplicant * wpa_s)1162 void wpas_dbus_signal_sae_password_mismatch(struct wpa_supplicant *wpa_s)
1163 {
1164 struct wpas_dbus_priv *iface;
1165 DBusMessage *msg;
1166
1167 iface = wpa_s->global->dbus;
1168
1169 /* Do nothing if the control interface is not turned on */
1170 if (!iface || !wpa_s->dbus_new_path)
1171 return;
1172
1173 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1174 WPAS_DBUS_NEW_IFACE_INTERFACE,
1175 "SaePasswordMismatch");
1176 if (!msg)
1177 return;
1178
1179 dbus_connection_send(iface->con, msg, NULL);
1180
1181 dbus_message_unref(msg);
1182 }
1183
1184
1185 /**
1186 * wpas_dbus_signal_sta - Send a station related event signal
1187 * @wpa_s: %wpa_supplicant network interface data
1188 * @sta: station mac address
1189 * @sig_name: signal name - StaAuthorized or StaDeauthorized
1190 *
1191 * Notify listeners about event related with station
1192 */
wpas_dbus_signal_sta(struct wpa_supplicant * wpa_s,const u8 * sta,const char * sig_name)1193 static void wpas_dbus_signal_sta(struct wpa_supplicant *wpa_s,
1194 const u8 *sta, const char *sig_name)
1195 {
1196 struct wpas_dbus_priv *iface;
1197 DBusMessage *msg;
1198 char sta_mac[WPAS_DBUS_OBJECT_PATH_MAX];
1199 char *dev_mac;
1200
1201 os_snprintf(sta_mac, WPAS_DBUS_OBJECT_PATH_MAX, MACSTR, MAC2STR(sta));
1202 dev_mac = sta_mac;
1203
1204 iface = wpa_s->global->dbus;
1205
1206 /* Do nothing if the control interface is not turned on */
1207 if (iface == NULL || !wpa_s->dbus_new_path)
1208 return;
1209
1210 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1211 WPAS_DBUS_NEW_IFACE_INTERFACE, sig_name);
1212 if (msg == NULL)
1213 return;
1214
1215 if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &dev_mac,
1216 DBUS_TYPE_INVALID))
1217 dbus_connection_send(iface->con, msg, NULL);
1218 else
1219 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1220 dbus_message_unref(msg);
1221
1222 wpa_printf(MSG_DEBUG, "dbus: Station MAC address '%s' '%s'",
1223 sta_mac, sig_name);
1224 }
1225
1226
1227 /**
1228 * wpas_dbus_signal_sta_authorized - Send a STA authorized signal
1229 * @wpa_s: %wpa_supplicant network interface data
1230 * @sta: station mac address
1231 *
1232 * Notify listeners a new station has been authorized
1233 */
wpas_dbus_signal_sta_authorized(struct wpa_supplicant * wpa_s,const u8 * sta)1234 void wpas_dbus_signal_sta_authorized(struct wpa_supplicant *wpa_s,
1235 const u8 *sta)
1236 {
1237 wpas_dbus_signal_sta(wpa_s, sta, "StaAuthorized");
1238 }
1239
1240
1241 /**
1242 * wpas_dbus_signal_sta_deauthorized - Send a STA deauthorized signal
1243 * @wpa_s: %wpa_supplicant network interface data
1244 * @sta: station mac address
1245 *
1246 * Notify listeners a station has been deauthorized
1247 */
wpas_dbus_signal_sta_deauthorized(struct wpa_supplicant * wpa_s,const u8 * sta)1248 void wpas_dbus_signal_sta_deauthorized(struct wpa_supplicant *wpa_s,
1249 const u8 *sta)
1250 {
1251 wpas_dbus_signal_sta(wpa_s, sta, "StaDeauthorized");
1252 }
1253
1254
1255 /**
1256 * wpas_dbus_signal_station - Send an event signal related to a station object
1257 * @wpa_s: %wpa_supplicant network interface data
1258 * @station_obj_path: Station object path
1259 * @sig_name: signal name - StationAdded or StationRemoved
1260 * @properties: Whether to add second argument with object properties
1261 *
1262 * Notify listeners about event related with station.
1263 */
wpas_dbus_signal_station(struct wpa_supplicant * wpa_s,const char * station_obj_path,const char * sig_name,dbus_bool_t properties)1264 static void wpas_dbus_signal_station(struct wpa_supplicant *wpa_s,
1265 const char *station_obj_path,
1266 const char *sig_name,
1267 dbus_bool_t properties)
1268 {
1269 struct wpas_dbus_priv *iface;
1270 DBusMessage *msg;
1271 DBusMessageIter iter;
1272
1273 iface = wpa_s->global->dbus;
1274
1275 /* Do nothing if the control interface is not turned on */
1276 if (!iface || !wpa_s->dbus_new_path)
1277 return;
1278
1279 wpa_printf(MSG_DEBUG, "dbus: STA signal %s", sig_name);
1280 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1281 WPAS_DBUS_NEW_IFACE_INTERFACE, sig_name);
1282 if (!msg)
1283 return;
1284
1285 dbus_message_iter_init_append(msg, &iter);
1286 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1287 &station_obj_path) ||
1288 (properties &&
1289 !wpa_dbus_get_object_properties(iface, station_obj_path,
1290 WPAS_DBUS_NEW_IFACE_STA,
1291 &iter)))
1292 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1293 else
1294 dbus_connection_send(iface->con, msg, NULL);
1295 dbus_message_unref(msg);
1296 }
1297
1298
1299 /**
1300 * wpas_dbus_signal_station_added - Send a Station added signal
1301 * @wpa_s: %wpa_supplicant network interface data
1302 * @station_obj_path: new Station object path
1303 *
1304 * Notify listeners about adding new Station
1305 */
wpas_dbus_signal_station_added(struct wpa_supplicant * wpa_s,const char * station_obj_path)1306 static void wpas_dbus_signal_station_added(struct wpa_supplicant *wpa_s,
1307 const char *station_obj_path)
1308 {
1309 wpas_dbus_signal_station(wpa_s, station_obj_path, "StationAdded", TRUE);
1310 }
1311
1312
1313 /**
1314 * wpas_dbus_signal_station_removed - Send a Station removed signal
1315 * @wpa_s: %wpa_supplicant network interface data
1316 * @station_obj_path: Station object path
1317 *
1318 * Notify listeners about removing Station
1319 */
wpas_dbus_signal_station_removed(struct wpa_supplicant * wpa_s,const char * station_obj_path)1320 static void wpas_dbus_signal_station_removed(struct wpa_supplicant *wpa_s,
1321 const char *station_obj_path)
1322 {
1323 wpas_dbus_signal_station(wpa_s, station_obj_path, "StationRemoved",
1324 FALSE);
1325 }
1326
1327
1328 #ifdef CONFIG_P2P
1329
1330 /**
1331 * wpas_dbus_signal_p2p_group_removed - Signals P2P group was removed
1332 * @wpa_s: %wpa_supplicant network interface data
1333 * @role: role of this device (client or GO)
1334 * Sends signal with i/f name and role as string arguments
1335 */
wpas_dbus_signal_p2p_group_removed(struct wpa_supplicant * wpa_s,const char * role)1336 void wpas_dbus_signal_p2p_group_removed(struct wpa_supplicant *wpa_s,
1337 const char *role)
1338 {
1339 DBusMessage *msg;
1340 DBusMessageIter iter, dict_iter;
1341 struct wpas_dbus_priv *iface = wpa_s->global->dbus;
1342 struct wpa_supplicant *parent;
1343
1344 /* Do nothing if the control interface is not turned on */
1345 if (iface == NULL)
1346 return;
1347
1348 parent = wpa_s->parent;
1349 if (parent->p2p_mgmt)
1350 parent = parent->parent;
1351
1352 if (!wpa_s->dbus_groupobj_path || !wpa_s->dbus_new_path ||
1353 !parent->dbus_new_path)
1354 return;
1355
1356 msg = dbus_message_new_signal(parent->dbus_new_path,
1357 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1358 "GroupFinished");
1359 if (msg == NULL)
1360 return;
1361
1362 dbus_message_iter_init_append(msg, &iter);
1363 if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
1364 !wpa_dbus_dict_append_object_path(&dict_iter,
1365 "interface_object",
1366 wpa_s->dbus_new_path) ||
1367 !wpa_dbus_dict_append_string(&dict_iter, "role", role) ||
1368 !wpa_dbus_dict_append_object_path(&dict_iter, "group_object",
1369 wpa_s->dbus_groupobj_path) ||
1370 !wpa_dbus_dict_close_write(&iter, &dict_iter))
1371 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1372 else
1373 dbus_connection_send(iface->con, msg, NULL);
1374 dbus_message_unref(msg);
1375 }
1376
1377
1378 /**
1379 * wpas_dbus_signal_p2p_provision_discovery - Signals various PD events
1380 *
1381 * @dev_addr - who sent the request or responded to our request.
1382 * @request - Will be 1 if request, 0 for response.
1383 * @status - valid only in case of response
1384 * @config_methods - wps config methods
1385 * @generated_pin - pin to be displayed in case of WPS_CONFIG_DISPLAY method
1386 *
1387 * Sends following provision discovery related events:
1388 * ProvisionDiscoveryRequestDisplayPin
1389 * ProvisionDiscoveryResponseDisplayPin
1390 * ProvisionDiscoveryRequestEnterPin
1391 * ProvisionDiscoveryResponseEnterPin
1392 * ProvisionDiscoveryPBCRequest
1393 * ProvisionDiscoveryPBCResponse
1394 *
1395 * TODO::
1396 * ProvisionDiscoveryFailure (timeout case)
1397 */
wpas_dbus_signal_p2p_provision_discovery(struct wpa_supplicant * wpa_s,const u8 * dev_addr,int request,enum p2p_prov_disc_status status,u16 config_methods,unsigned int generated_pin)1398 void wpas_dbus_signal_p2p_provision_discovery(struct wpa_supplicant *wpa_s,
1399 const u8 *dev_addr, int request,
1400 enum p2p_prov_disc_status status,
1401 u16 config_methods,
1402 unsigned int generated_pin)
1403 {
1404 DBusMessage *msg;
1405 DBusMessageIter iter;
1406 struct wpas_dbus_priv *iface;
1407 char *_signal;
1408 int add_pin = 0;
1409 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1410 int error_ret = 1;
1411 char pin[9], *p_pin = NULL;
1412
1413 iface = wpa_s->global->dbus;
1414
1415 /* Do nothing if the control interface is not turned on */
1416 if (iface == NULL)
1417 return;
1418
1419 if (wpa_s->p2p_mgmt)
1420 wpa_s = wpa_s->parent;
1421 if (!wpa_s->dbus_new_path)
1422 return;
1423
1424 if (request || !status) {
1425 if (config_methods & WPS_CONFIG_DISPLAY)
1426 _signal = request ?
1427 "ProvisionDiscoveryRequestDisplayPin" :
1428 "ProvisionDiscoveryResponseEnterPin";
1429 else if (config_methods & WPS_CONFIG_KEYPAD)
1430 _signal = request ?
1431 "ProvisionDiscoveryRequestEnterPin" :
1432 "ProvisionDiscoveryResponseDisplayPin";
1433 else if (config_methods & WPS_CONFIG_PUSHBUTTON)
1434 _signal = request ? "ProvisionDiscoveryPBCRequest" :
1435 "ProvisionDiscoveryPBCResponse";
1436 else
1437 return; /* Unknown or un-supported method */
1438 } else {
1439 /* Explicit check for failure response */
1440 _signal = "ProvisionDiscoveryFailure";
1441 }
1442
1443 add_pin = ((request && (config_methods & WPS_CONFIG_DISPLAY)) ||
1444 (!request && !status &&
1445 (config_methods & WPS_CONFIG_KEYPAD)));
1446
1447 if (add_pin) {
1448 os_snprintf(pin, sizeof(pin), "%08d", generated_pin);
1449 p_pin = pin;
1450 }
1451
1452 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1453 WPAS_DBUS_NEW_IFACE_P2PDEVICE, _signal);
1454 if (msg == NULL)
1455 return;
1456
1457 /* Check if this is a known peer */
1458 if (!p2p_peer_known(wpa_s->global->p2p, dev_addr))
1459 goto error;
1460
1461 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1462 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1463 COMPACT_MACSTR,
1464 wpa_s->dbus_new_path, MAC2STR(dev_addr));
1465
1466 path = peer_obj_path;
1467
1468 dbus_message_iter_init_append(msg, &iter);
1469
1470 if (!dbus_message_iter_append_basic(&iter,
1471 DBUS_TYPE_OBJECT_PATH,
1472 &path))
1473 goto error;
1474
1475 if (!request && status)
1476 /* Attach status to ProvisionDiscoveryFailure */
1477 error_ret = !dbus_message_iter_append_basic(&iter,
1478 DBUS_TYPE_INT32,
1479 &status);
1480 else
1481 error_ret = (add_pin &&
1482 !dbus_message_iter_append_basic(&iter,
1483 DBUS_TYPE_STRING,
1484 &p_pin));
1485
1486 error:
1487 if (!error_ret)
1488 dbus_connection_send(iface->con, msg, NULL);
1489 else
1490 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1491
1492 dbus_message_unref(msg);
1493 }
1494
1495
1496 /**
1497 * wpas_dbus_signal_p2p_go_neg_req - Signal P2P GO Negotiation Request RX
1498 * @wpa_s: %wpa_supplicant network interface data
1499 * @src: Source address of the message triggering this notification
1500 * @dev_passwd_id: WPS Device Password Id
1501 * @go_intent: Peer's GO Intent value
1502 *
1503 * Sends signal to notify that a peer P2P Device is requesting group owner
1504 * negotiation with us.
1505 */
wpas_dbus_signal_p2p_go_neg_req(struct wpa_supplicant * wpa_s,const u8 * src,u16 dev_passwd_id,u8 go_intent)1506 void wpas_dbus_signal_p2p_go_neg_req(struct wpa_supplicant *wpa_s,
1507 const u8 *src, u16 dev_passwd_id,
1508 u8 go_intent)
1509 {
1510 DBusMessage *msg;
1511 DBusMessageIter iter;
1512 struct wpas_dbus_priv *iface;
1513 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1514
1515 iface = wpa_s->global->dbus;
1516
1517 /* Do nothing if the control interface is not turned on */
1518 if (iface == NULL)
1519 return;
1520
1521 if (wpa_s->p2p_mgmt)
1522 wpa_s = wpa_s->parent;
1523 if (!wpa_s->dbus_new_path)
1524 return;
1525
1526 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1527 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
1528 wpa_s->dbus_new_path, MAC2STR(src));
1529 path = peer_obj_path;
1530
1531 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1532 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1533 "GONegotiationRequest");
1534 if (msg == NULL)
1535 return;
1536
1537 dbus_message_iter_init_append(msg, &iter);
1538
1539 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1540 &path) ||
1541 !dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT16,
1542 &dev_passwd_id) ||
1543 !dbus_message_iter_append_basic(&iter, DBUS_TYPE_BYTE,
1544 &go_intent))
1545 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1546 else
1547 dbus_connection_send(iface->con, msg, NULL);
1548
1549 dbus_message_unref(msg);
1550 }
1551
1552
wpas_dbus_get_group_obj_path(struct wpa_supplicant * wpa_s,const struct wpa_ssid * ssid,char * group_obj_path)1553 static int wpas_dbus_get_group_obj_path(struct wpa_supplicant *wpa_s,
1554 const struct wpa_ssid *ssid,
1555 char *group_obj_path)
1556 {
1557 char group_name[3];
1558
1559 if (!wpa_s->dbus_new_path ||
1560 os_memcmp(ssid->ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN))
1561 return -1;
1562
1563 os_memcpy(group_name, ssid->ssid + P2P_WILDCARD_SSID_LEN, 2);
1564 group_name[2] = '\0';
1565
1566 os_snprintf(group_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1567 "%s/" WPAS_DBUS_NEW_P2P_GROUPS_PART "/%s",
1568 wpa_s->dbus_new_path, group_name);
1569
1570 return 0;
1571 }
1572
1573
1574 struct group_changed_data {
1575 struct wpa_supplicant *wpa_s;
1576 struct p2p_peer_info *info;
1577 };
1578
1579
match_group_where_peer_is_client(struct p2p_group * group,void * user_data)1580 static int match_group_where_peer_is_client(struct p2p_group *group,
1581 void *user_data)
1582 {
1583 struct group_changed_data *data = user_data;
1584 const struct p2p_group_config *cfg;
1585 struct wpa_supplicant *wpa_s_go;
1586
1587 if (!p2p_group_is_client_connected(group, data->info->p2p_device_addr))
1588 return 1;
1589
1590 cfg = p2p_group_get_config(group);
1591
1592 wpa_s_go = wpas_get_p2p_go_iface(data->wpa_s, cfg->ssid,
1593 cfg->ssid_len);
1594 if (wpa_s_go != NULL && wpa_s_go == data->wpa_s) {
1595 wpas_dbus_signal_peer_groups_changed(
1596 data->wpa_s->p2pdev, data->info->p2p_device_addr);
1597 return 0;
1598 }
1599
1600 return 1;
1601 }
1602
1603
signal_peer_groups_changed(struct p2p_peer_info * info,void * user_data)1604 static void signal_peer_groups_changed(struct p2p_peer_info *info,
1605 void *user_data)
1606 {
1607 struct group_changed_data *data = user_data;
1608 struct wpa_supplicant *wpa_s_go;
1609
1610 wpa_s_go = wpas_get_p2p_client_iface(data->wpa_s,
1611 info->p2p_device_addr);
1612 if (wpa_s_go != NULL && wpa_s_go == data->wpa_s) {
1613 wpas_dbus_signal_peer_groups_changed(data->wpa_s->p2pdev,
1614 info->p2p_device_addr);
1615 return;
1616 }
1617
1618 data->info = info;
1619 p2p_loop_on_all_groups(data->wpa_s->global->p2p,
1620 match_group_where_peer_is_client, data);
1621 data->info = NULL;
1622 }
1623
1624
peer_groups_changed(struct wpa_supplicant * wpa_s)1625 static void peer_groups_changed(struct wpa_supplicant *wpa_s)
1626 {
1627 struct group_changed_data data;
1628
1629 os_memset(&data, 0, sizeof(data));
1630 data.wpa_s = wpa_s;
1631
1632 p2p_loop_on_known_peers(wpa_s->global->p2p,
1633 signal_peer_groups_changed, &data);
1634 }
1635
1636
1637 /**
1638 * wpas_dbus_signal_p2p_group_started - Signals P2P group has
1639 * started. Emitted when a group is successfully started
1640 * irrespective of the role (client/GO) of the current device
1641 *
1642 * @wpa_s: %wpa_supplicant network interface data
1643 * @client: this device is P2P client
1644 * @persistent: 0 - non persistent group, 1 - persistent group
1645 * @ip: When group role is client, it contains local IP address, netmask, and
1646 * GO's IP address, if assigned; otherwise, NULL
1647 */
wpas_dbus_signal_p2p_group_started(struct wpa_supplicant * wpa_s,int client,int persistent,const u8 * ip)1648 void wpas_dbus_signal_p2p_group_started(struct wpa_supplicant *wpa_s,
1649 int client, int persistent,
1650 const u8 *ip)
1651 {
1652 DBusMessage *msg;
1653 DBusMessageIter iter, dict_iter;
1654 struct wpas_dbus_priv *iface;
1655 struct wpa_supplicant *parent;
1656
1657 parent = wpa_s->parent;
1658 if (parent->p2p_mgmt)
1659 parent = parent->parent;
1660
1661 iface = parent->global->dbus;
1662
1663 /* Do nothing if the control interface is not turned on */
1664 if (iface == NULL || !parent->dbus_new_path || !wpa_s->dbus_new_path)
1665 return;
1666
1667 if (wpa_s->dbus_groupobj_path == NULL)
1668 return;
1669
1670 /* New interface has been created for this group */
1671 msg = dbus_message_new_signal(parent->dbus_new_path,
1672 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1673 "GroupStarted");
1674 if (msg == NULL)
1675 return;
1676
1677 dbus_message_iter_init_append(msg, &iter);
1678 /*
1679 * In case the device supports creating a separate interface the
1680 * DBus client will need to know the object path for the interface
1681 * object this group was created on, so include it here.
1682 */
1683 if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
1684 !wpa_dbus_dict_append_object_path(&dict_iter,
1685 "interface_object",
1686 wpa_s->dbus_new_path) ||
1687 !wpa_dbus_dict_append_string(&dict_iter, "role",
1688 client ? "client" : "GO") ||
1689 !wpa_dbus_dict_append_bool(&dict_iter, "persistent",
1690 !!persistent) ||
1691 !wpa_dbus_dict_append_object_path(&dict_iter, "group_object",
1692 wpa_s->dbus_groupobj_path) ||
1693 (ip &&
1694 (!wpa_dbus_dict_append_byte_array(&dict_iter, "IpAddr",
1695 (char *) ip, 4) ||
1696 !wpa_dbus_dict_append_byte_array(&dict_iter, "IpAddrMask",
1697 (char *) ip + 4, 4) ||
1698 !wpa_dbus_dict_append_byte_array(&dict_iter, "IpAddrGo",
1699 (char *) ip + 8, 4))) ||
1700 !wpa_dbus_dict_close_write(&iter, &dict_iter)) {
1701 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1702 } else {
1703 dbus_connection_send(iface->con, msg, NULL);
1704 if (client)
1705 peer_groups_changed(wpa_s);
1706 }
1707 dbus_message_unref(msg);
1708 }
1709
1710
1711 /**
1712 * wpas_dbus_signal_p2p_go_neg_resp - Emit GONegotiation Success/Failure signal
1713 * @wpa_s: %wpa_supplicant network interface data
1714 * @res: Result of the GO Neg Request
1715 */
wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant * wpa_s,struct p2p_go_neg_results * res)1716 void wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s,
1717 struct p2p_go_neg_results *res)
1718 {
1719 DBusMessage *msg;
1720 DBusMessageIter iter, dict_iter;
1721 DBusMessageIter iter_dict_entry, iter_dict_val, iter_dict_array;
1722 struct wpas_dbus_priv *iface;
1723 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1724 dbus_int32_t freqs[P2P_MAX_CHANNELS];
1725 dbus_int32_t *f_array = freqs;
1726
1727
1728 iface = wpa_s->global->dbus;
1729
1730 if (wpa_s->p2p_mgmt)
1731 wpa_s = wpa_s->parent;
1732
1733 os_memset(freqs, 0, sizeof(freqs));
1734 /* Do nothing if the control interface is not turned on */
1735 if (iface == NULL || !wpa_s->dbus_new_path)
1736 return;
1737
1738 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1739 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
1740 wpa_s->dbus_new_path, MAC2STR(res->peer_device_addr));
1741 path = peer_obj_path;
1742
1743 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1744 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1745 res->status ? "GONegotiationFailure" :
1746 "GONegotiationSuccess");
1747 if (msg == NULL)
1748 return;
1749
1750 dbus_message_iter_init_append(msg, &iter);
1751 if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
1752 !wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
1753 path) ||
1754 !wpa_dbus_dict_append_int32(&dict_iter, "status", res->status))
1755 goto err;
1756
1757 if (!res->status) {
1758 int i = 0;
1759 int freq_list_num = 0;
1760
1761 if ((res->role_go &&
1762 !wpa_dbus_dict_append_string(&dict_iter, "passphrase",
1763 res->passphrase)) ||
1764 !wpa_dbus_dict_append_string(&dict_iter, "role_go",
1765 res->role_go ? "GO" :
1766 "client") ||
1767 !wpa_dbus_dict_append_int32(&dict_iter, "frequency",
1768 res->freq) ||
1769 !wpa_dbus_dict_append_byte_array(&dict_iter, "ssid",
1770 (const char *) res->ssid,
1771 res->ssid_len) ||
1772 !wpa_dbus_dict_append_byte_array(&dict_iter,
1773 "peer_device_addr",
1774 (const char *)
1775 res->peer_device_addr,
1776 ETH_ALEN) ||
1777 !wpa_dbus_dict_append_byte_array(&dict_iter,
1778 "peer_interface_addr",
1779 (const char *)
1780 res->peer_interface_addr,
1781 ETH_ALEN) ||
1782 !wpa_dbus_dict_append_string(&dict_iter, "wps_method",
1783 p2p_wps_method_text(
1784 res->wps_method)))
1785 goto err;
1786
1787 for (i = 0; i < P2P_MAX_CHANNELS; i++) {
1788 if (res->freq_list[i]) {
1789 freqs[i] = res->freq_list[i];
1790 freq_list_num++;
1791 }
1792 }
1793
1794 if (!wpa_dbus_dict_begin_array(&dict_iter,
1795 "frequency_list",
1796 DBUS_TYPE_INT32_AS_STRING,
1797 &iter_dict_entry,
1798 &iter_dict_val,
1799 &iter_dict_array) ||
1800 !dbus_message_iter_append_fixed_array(&iter_dict_array,
1801 DBUS_TYPE_INT32,
1802 &f_array,
1803 freq_list_num) ||
1804 !wpa_dbus_dict_end_array(&dict_iter,
1805 &iter_dict_entry,
1806 &iter_dict_val,
1807 &iter_dict_array) ||
1808 !wpa_dbus_dict_append_int32(&dict_iter, "persistent_group",
1809 res->persistent_group) ||
1810 !wpa_dbus_dict_append_uint32(&dict_iter,
1811 "peer_config_timeout",
1812 res->peer_config_timeout))
1813 goto err;
1814 }
1815
1816 if (!wpa_dbus_dict_close_write(&iter, &dict_iter))
1817 goto err;
1818
1819 dbus_connection_send(iface->con, msg, NULL);
1820 err:
1821 dbus_message_unref(msg);
1822 }
1823
1824
1825 /**
1826 * wpas_dbus_signal_p2p_invitation_result - Emit InvitationResult signal
1827 * @wpa_s: %wpa_supplicant network interface data
1828 * @status: Status of invitation process
1829 * @bssid: Basic Service Set Identifier
1830 */
wpas_dbus_signal_p2p_invitation_result(struct wpa_supplicant * wpa_s,int status,const u8 * bssid)1831 void wpas_dbus_signal_p2p_invitation_result(struct wpa_supplicant *wpa_s,
1832 int status, const u8 *bssid)
1833 {
1834 DBusMessage *msg;
1835 DBusMessageIter iter, dict_iter;
1836 struct wpas_dbus_priv *iface;
1837
1838 wpa_printf(MSG_DEBUG, "%s", __func__);
1839
1840 iface = wpa_s->global->dbus;
1841 /* Do nothing if the control interface is not turned on */
1842 if (iface == NULL)
1843 return;
1844
1845 if (wpa_s->p2p_mgmt)
1846 wpa_s = wpa_s->parent;
1847 if (!wpa_s->dbus_new_path)
1848 return;
1849
1850 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1851 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1852 "InvitationResult");
1853
1854 if (msg == NULL)
1855 return;
1856
1857 dbus_message_iter_init_append(msg, &iter);
1858 if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
1859 !wpa_dbus_dict_append_int32(&dict_iter, "status", status) ||
1860 (bssid &&
1861 !wpa_dbus_dict_append_byte_array(&dict_iter, "BSSID",
1862 (const char *) bssid,
1863 ETH_ALEN)) ||
1864 !wpa_dbus_dict_close_write(&iter, &dict_iter))
1865 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1866 else
1867 dbus_connection_send(iface->con, msg, NULL);
1868 dbus_message_unref(msg);
1869 }
1870
1871
1872 /**
1873 *
1874 * Method to emit a signal for a peer joining the group.
1875 * The signal will carry path to the group member object
1876 * constructed using p2p i/f addr used for connecting.
1877 *
1878 * @wpa_s: %wpa_supplicant network interface data
1879 * @peer_addr: P2P Device Address of the peer joining the group
1880 */
wpas_dbus_signal_p2p_peer_joined(struct wpa_supplicant * wpa_s,const u8 * peer_addr)1881 void wpas_dbus_signal_p2p_peer_joined(struct wpa_supplicant *wpa_s,
1882 const u8 *peer_addr)
1883 {
1884 struct wpas_dbus_priv *iface;
1885 DBusMessage *msg;
1886 DBusMessageIter iter;
1887 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1888 struct wpa_supplicant *parent;
1889
1890 iface = wpa_s->global->dbus;
1891
1892 /* Do nothing if the control interface is not turned on */
1893 if (iface == NULL)
1894 return;
1895
1896 if (!wpa_s->dbus_groupobj_path)
1897 return;
1898
1899 parent = wpa_s->parent;
1900 if (parent->p2p_mgmt)
1901 parent = parent->parent;
1902 if (!parent->dbus_new_path)
1903 return;
1904
1905 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1906 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1907 COMPACT_MACSTR,
1908 parent->dbus_new_path, MAC2STR(peer_addr));
1909
1910 msg = dbus_message_new_signal(wpa_s->dbus_groupobj_path,
1911 WPAS_DBUS_NEW_IFACE_P2P_GROUP,
1912 "PeerJoined");
1913 if (msg == NULL)
1914 return;
1915
1916 dbus_message_iter_init_append(msg, &iter);
1917 path = peer_obj_path;
1918 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1919 &path)) {
1920 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1921 } else {
1922 dbus_connection_send(iface->con, msg, NULL);
1923 wpas_dbus_signal_peer_groups_changed(parent, peer_addr);
1924 }
1925 dbus_message_unref(msg);
1926 }
1927
1928
1929 /**
1930 *
1931 * Method to emit a signal for a peer disconnecting the group.
1932 * The signal will carry path to the group member object
1933 * constructed using the P2P Device Address of the peer.
1934 *
1935 * @wpa_s: %wpa_supplicant network interface data
1936 * @peer_addr: P2P Device Address of the peer joining the group
1937 */
wpas_dbus_signal_p2p_peer_disconnected(struct wpa_supplicant * wpa_s,const u8 * peer_addr)1938 void wpas_dbus_signal_p2p_peer_disconnected(struct wpa_supplicant *wpa_s,
1939 const u8 *peer_addr)
1940 {
1941 struct wpas_dbus_priv *iface;
1942 DBusMessage *msg;
1943 DBusMessageIter iter;
1944 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1945 struct wpa_supplicant *parent;
1946
1947 iface = wpa_s->global->dbus;
1948
1949 /* Do nothing if the control interface is not turned on */
1950 if (iface == NULL)
1951 return;
1952
1953 if (!wpa_s->dbus_groupobj_path)
1954 return;
1955
1956 parent = wpa_s->parent;
1957 if (parent->p2p_mgmt)
1958 parent = parent->parent;
1959 if (!parent->dbus_new_path)
1960 return;
1961
1962 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1963 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1964 COMPACT_MACSTR,
1965 parent->dbus_new_path, MAC2STR(peer_addr));
1966
1967 msg = dbus_message_new_signal(wpa_s->dbus_groupobj_path,
1968 WPAS_DBUS_NEW_IFACE_P2P_GROUP,
1969 "PeerDisconnected");
1970 if (msg == NULL)
1971 return;
1972
1973 dbus_message_iter_init_append(msg, &iter);
1974 path = peer_obj_path;
1975 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1976 &path)) {
1977 wpa_printf(MSG_ERROR,
1978 "dbus: Failed to construct PeerDisconnected signal");
1979 } else {
1980 dbus_connection_send(iface->con, msg, NULL);
1981 wpas_dbus_signal_peer_groups_changed(parent, peer_addr);
1982 }
1983 dbus_message_unref(msg);
1984 }
1985
1986
1987 /**
1988 *
1989 * Method to emit a signal for a service discovery request.
1990 * The signal will carry station address, frequency, dialog token,
1991 * update indicator and it tlvs
1992 *
1993 * @wpa_s: %wpa_supplicant network interface data
1994 * @sa: station addr (p2p i/f) of the peer
1995 * @dialog_token: service discovery request dialog token
1996 * @update_indic: service discovery request update indicator
1997 * @tlvs: service discovery request generated byte array of tlvs
1998 * @tlvs_len: service discovery request tlvs length
1999 */
wpas_dbus_signal_p2p_sd_request(struct wpa_supplicant * wpa_s,int freq,const u8 * sa,u8 dialog_token,u16 update_indic,const u8 * tlvs,size_t tlvs_len)2000 void wpas_dbus_signal_p2p_sd_request(struct wpa_supplicant *wpa_s,
2001 int freq, const u8 *sa, u8 dialog_token,
2002 u16 update_indic, const u8 *tlvs,
2003 size_t tlvs_len)
2004 {
2005 DBusMessage *msg;
2006 DBusMessageIter iter, dict_iter;
2007 struct wpas_dbus_priv *iface;
2008 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
2009
2010 iface = wpa_s->global->dbus;
2011
2012 /* Do nothing if the control interface is not turned on */
2013 if (iface == NULL)
2014 return;
2015
2016 if (wpa_s->p2p_mgmt)
2017 wpa_s = wpa_s->parent;
2018 if (!wpa_s->dbus_new_path)
2019 return;
2020
2021 /* Check if this is a known peer */
2022 if (!p2p_peer_known(wpa_s->global->p2p, sa))
2023 return;
2024
2025 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
2026 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2027 "ServiceDiscoveryRequest");
2028 if (msg == NULL)
2029 return;
2030
2031 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2032 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
2033 COMPACT_MACSTR, wpa_s->dbus_new_path, MAC2STR(sa));
2034
2035 path = peer_obj_path;
2036
2037 dbus_message_iter_init_append(msg, &iter);
2038 if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
2039 !wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
2040 path) ||
2041 !wpa_dbus_dict_append_int32(&dict_iter, "frequency", freq) ||
2042 !wpa_dbus_dict_append_int32(&dict_iter, "dialog_token",
2043 dialog_token) ||
2044 !wpa_dbus_dict_append_uint16(&dict_iter, "update_indicator",
2045 update_indic) ||
2046 !wpa_dbus_dict_append_byte_array(&dict_iter, "tlvs",
2047 (const char *) tlvs,
2048 tlvs_len) ||
2049 !wpa_dbus_dict_close_write(&iter, &dict_iter))
2050 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
2051 else
2052 dbus_connection_send(iface->con, msg, NULL);
2053 dbus_message_unref(msg);
2054 }
2055
2056
2057 /**
2058 *
2059 * Method to emit a signal for a service discovery response.
2060 * The signal will carry station address, update indicator and it
2061 * tlvs
2062 *
2063 * @wpa_s: %wpa_supplicant network interface data
2064 * @sa: station addr (p2p i/f) of the peer
2065 * @update_indic: service discovery request update indicator
2066 * @tlvs: service discovery request generated byte array of tlvs
2067 * @tlvs_len: service discovery request tlvs length
2068 */
wpas_dbus_signal_p2p_sd_response(struct wpa_supplicant * wpa_s,const u8 * sa,u16 update_indic,const u8 * tlvs,size_t tlvs_len)2069 void wpas_dbus_signal_p2p_sd_response(struct wpa_supplicant *wpa_s,
2070 const u8 *sa, u16 update_indic,
2071 const u8 *tlvs, size_t tlvs_len)
2072 {
2073 DBusMessage *msg;
2074 DBusMessageIter iter, dict_iter;
2075 struct wpas_dbus_priv *iface;
2076 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
2077
2078 iface = wpa_s->global->dbus;
2079
2080 /* Do nothing if the control interface is not turned on */
2081 if (iface == NULL)
2082 return;
2083
2084 if (wpa_s->p2p_mgmt)
2085 wpa_s = wpa_s->parent;
2086 if (!wpa_s->dbus_new_path)
2087 return;
2088
2089 /* Check if this is a known peer */
2090 if (!p2p_peer_known(wpa_s->global->p2p, sa))
2091 return;
2092
2093 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
2094 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2095 "ServiceDiscoveryResponse");
2096 if (msg == NULL)
2097 return;
2098
2099 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2100 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
2101 COMPACT_MACSTR, wpa_s->dbus_new_path, MAC2STR(sa));
2102
2103 path = peer_obj_path;
2104
2105 dbus_message_iter_init_append(msg, &iter);
2106 if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
2107 !wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
2108 path) ||
2109 !wpa_dbus_dict_append_uint16(&dict_iter, "update_indicator",
2110 update_indic) ||
2111 !wpa_dbus_dict_append_byte_array(&dict_iter, "tlvs",
2112 (const char *) tlvs,
2113 tlvs_len) ||
2114 !wpa_dbus_dict_close_write(&iter, &dict_iter))
2115 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
2116 else
2117 dbus_connection_send(iface->con, msg, NULL);
2118 dbus_message_unref(msg);
2119 }
2120
2121
2122 /**
2123 * wpas_dbus_signal_persistent_group - Send a persistent group related
2124 * event signal
2125 * @wpa_s: %wpa_supplicant network interface data
2126 * @id: new persistent group id
2127 * @sig_name: signal name - PersistentGroupAdded, PersistentGroupRemoved
2128 * @properties: determines if add second argument with object properties
2129 *
2130 * Notify listeners about an event related to persistent groups.
2131 */
wpas_dbus_signal_persistent_group(struct wpa_supplicant * wpa_s,int id,const char * sig_name,dbus_bool_t properties)2132 static void wpas_dbus_signal_persistent_group(struct wpa_supplicant *wpa_s,
2133 int id, const char *sig_name,
2134 dbus_bool_t properties)
2135 {
2136 struct wpas_dbus_priv *iface;
2137 DBusMessage *msg;
2138 DBusMessageIter iter;
2139 char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
2140
2141 iface = wpa_s->global->dbus;
2142
2143 /* Do nothing if the control interface is not turned on */
2144 if (iface == NULL)
2145 return;
2146
2147 if (wpa_s->p2p_mgmt)
2148 wpa_s = wpa_s->parent;
2149 if (!wpa_s->dbus_new_path)
2150 return;
2151
2152 os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2153 "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
2154 wpa_s->dbus_new_path, id);
2155
2156 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
2157 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2158 sig_name);
2159 if (msg == NULL)
2160 return;
2161
2162 dbus_message_iter_init_append(msg, &iter);
2163 path = pgrp_obj_path;
2164 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
2165 &path) ||
2166 (properties &&
2167 !wpa_dbus_get_object_properties(
2168 iface, pgrp_obj_path,
2169 WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, &iter)))
2170 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
2171 else
2172 dbus_connection_send(iface->con, msg, NULL);
2173
2174 dbus_message_unref(msg);
2175 }
2176
2177
2178 /**
2179 * wpas_dbus_signal_persistent_group_added - Send a persistent_group
2180 * added signal
2181 * @wpa_s: %wpa_supplicant network interface data
2182 * @id: new persistent group id
2183 *
2184 * Notify listeners about addition of a new persistent group.
2185 */
wpas_dbus_signal_persistent_group_added(struct wpa_supplicant * wpa_s,int id)2186 static void wpas_dbus_signal_persistent_group_added(
2187 struct wpa_supplicant *wpa_s, int id)
2188 {
2189 wpas_dbus_signal_persistent_group(wpa_s, id, "PersistentGroupAdded",
2190 TRUE);
2191 }
2192
2193
2194 /**
2195 * wpas_dbus_signal_persistent_group_removed - Send a persistent_group
2196 * removed signal
2197 * @wpa_s: %wpa_supplicant network interface data
2198 * @id: persistent group id
2199 *
2200 * Notify listeners about removal of a persistent group.
2201 */
wpas_dbus_signal_persistent_group_removed(struct wpa_supplicant * wpa_s,int id)2202 static void wpas_dbus_signal_persistent_group_removed(
2203 struct wpa_supplicant *wpa_s, int id)
2204 {
2205 wpas_dbus_signal_persistent_group(wpa_s, id, "PersistentGroupRemoved",
2206 FALSE);
2207 }
2208
2209
2210 /**
2211 * wpas_dbus_signal_p2p_wps_failed - Signals WpsFailed event
2212 * @wpa_s: %wpa_supplicant network interface data
2213 * @fail: WPS failure information
2214 *
2215 * Sends Event dbus signal with name "fail" and dictionary containing
2216 * "msg" field with fail message number (int32) as arguments
2217 */
wpas_dbus_signal_p2p_wps_failed(struct wpa_supplicant * wpa_s,struct wps_event_fail * fail)2218 void wpas_dbus_signal_p2p_wps_failed(struct wpa_supplicant *wpa_s,
2219 struct wps_event_fail *fail)
2220 {
2221
2222 DBusMessage *msg;
2223 DBusMessageIter iter, dict_iter;
2224 struct wpas_dbus_priv *iface;
2225 char *key = "fail";
2226
2227 iface = wpa_s->global->dbus;
2228
2229 /* Do nothing if the control interface is not turned on */
2230 if (iface == NULL)
2231 return;
2232
2233 if (wpa_s->p2p_mgmt)
2234 wpa_s = wpa_s->parent;
2235
2236 if (!wpa_s->dbus_new_path)
2237 return;
2238 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
2239 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2240 "WpsFailed");
2241 if (msg == NULL)
2242 return;
2243
2244 dbus_message_iter_init_append(msg, &iter);
2245
2246 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
2247 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
2248 !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
2249 !wpa_dbus_dict_append_int16(&dict_iter, "config_error",
2250 fail->config_error) ||
2251 !wpa_dbus_dict_close_write(&iter, &dict_iter))
2252 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
2253 else
2254 dbus_connection_send(iface->con, msg, NULL);
2255
2256 dbus_message_unref(msg);
2257 }
2258
2259
2260 /**
2261 * wpas_dbus_signal_p2p_group_formation_failure - Signals GroupFormationFailure event
2262 * @wpa_s: %wpa_supplicant network interface data
2263 * @reason: indicates the reason code for group formation failure
2264 *
2265 * Sends Event dbus signal and string reason code when available.
2266 */
wpas_dbus_signal_p2p_group_formation_failure(struct wpa_supplicant * wpa_s,const char * reason)2267 void wpas_dbus_signal_p2p_group_formation_failure(struct wpa_supplicant *wpa_s,
2268 const char *reason)
2269 {
2270 DBusMessage *msg;
2271 struct wpas_dbus_priv *iface;
2272
2273 iface = wpa_s->global->dbus;
2274
2275 /* Do nothing if the control interface is not turned on */
2276 if (iface == NULL)
2277 return;
2278
2279 if (wpa_s->p2p_mgmt)
2280 wpa_s = wpa_s->parent;
2281
2282 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
2283 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2284 "GroupFormationFailure");
2285 if (msg == NULL)
2286 return;
2287
2288 if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &reason,
2289 DBUS_TYPE_INVALID))
2290 dbus_connection_send(iface->con, msg, NULL);
2291 else
2292 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
2293
2294 dbus_message_unref(msg);
2295 }
2296
2297
2298 /**
2299 * wpas_dbus_signal_p2p_invitation_received - Emit InvitationReceived signal
2300 * @wpa_s: %wpa_supplicant network interface data
2301 * @sa: Source address of the Invitation Request
2302 * @dev_add: GO Device Address
2303 * @bssid: P2P Group BSSID or %NULL if not received
2304 * @id: Persistent group id or %0 if not persistent group
2305 * @op_freq: Operating frequency for the group
2306 */
2307
wpas_dbus_signal_p2p_invitation_received(struct wpa_supplicant * wpa_s,const u8 * sa,const u8 * dev_addr,const u8 * bssid,int id,int op_freq)2308 void wpas_dbus_signal_p2p_invitation_received(struct wpa_supplicant *wpa_s,
2309 const u8 *sa, const u8 *dev_addr,
2310 const u8 *bssid, int id,
2311 int op_freq)
2312 {
2313 DBusMessage *msg;
2314 DBusMessageIter iter, dict_iter;
2315 struct wpas_dbus_priv *iface;
2316
2317 iface = wpa_s->global->dbus;
2318
2319 /* Do nothing if the control interface is not turned on */
2320 if (iface == NULL)
2321 return;
2322
2323 if (wpa_s->p2p_mgmt)
2324 wpa_s = wpa_s->parent;
2325
2326 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
2327 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2328 "InvitationReceived");
2329 if (msg == NULL)
2330 return;
2331
2332 dbus_message_iter_init_append(msg, &iter);
2333 if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
2334 (sa &&
2335 !wpa_dbus_dict_append_byte_array(&dict_iter, "sa",
2336 (const char *) sa, ETH_ALEN)) ||
2337 (dev_addr &&
2338 !wpa_dbus_dict_append_byte_array(&dict_iter, "go_dev_addr",
2339 (const char *) dev_addr,
2340 ETH_ALEN)) ||
2341 (bssid &&
2342 !wpa_dbus_dict_append_byte_array(&dict_iter, "bssid",
2343 (const char *) bssid,
2344 ETH_ALEN)) ||
2345 (id &&
2346 !wpa_dbus_dict_append_int32(&dict_iter, "persistent_id", id)) ||
2347 !wpa_dbus_dict_append_int32(&dict_iter, "op_freq", op_freq) ||
2348 !wpa_dbus_dict_close_write(&iter, &dict_iter)) {
2349 dbus_message_unref(msg);
2350 return;
2351 }
2352
2353 dbus_connection_send(iface->con, msg, NULL);
2354 dbus_message_unref(msg);
2355 }
2356
2357
2358 /**
2359 * wpas_dbus_signal_p2p_bootstrap_req - Signals BootstrappingRequest event
2360 * @wpa_s: %wpa_supplicant network interface data
2361 * @src: Source address of the message triggering this notification
2362 * @bootstrap_method: Peer's bootstrap method
2363 *
2364 * Sends a signal to notify that a peer P2P Device is requesting bootstrapping
2365 * negotiation with us.
2366 */
wpas_dbus_signal_p2p_bootstrap_req(struct wpa_supplicant * wpa_s,const u8 * src,u16 bootstrap_method)2367 void wpas_dbus_signal_p2p_bootstrap_req(struct wpa_supplicant *wpa_s,
2368 const u8 *src, u16 bootstrap_method)
2369 {
2370 DBusMessage *msg;
2371 DBusMessageIter iter;
2372 struct wpas_dbus_priv *iface;
2373 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
2374
2375 iface = wpa_s->global->dbus;
2376
2377 /* Do nothing if the control interface is not turned on */
2378 if (!iface)
2379 return;
2380
2381 if (wpa_s->p2p_mgmt)
2382 wpa_s = wpa_s->parent;
2383 if (!wpa_s->dbus_new_path)
2384 return;
2385
2386 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2387 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
2388 wpa_s->dbus_new_path, MAC2STR(src));
2389 path = peer_obj_path;
2390
2391 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
2392 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2393 "BootstrappingRequest");
2394 if (!msg)
2395 return;
2396
2397 dbus_message_iter_init_append(msg, &iter);
2398
2399 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
2400 &path) ||
2401 !dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT16,
2402 &bootstrap_method))
2403 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
2404 else
2405 dbus_connection_send(iface->con, msg, NULL);
2406
2407 dbus_message_unref(msg);
2408 }
2409
2410
2411 /**
2412 * wpas_dbus_signal_p2p_bootstrap_rsp - Signals BootstrappingResponse event
2413 * @wpa_s: %wpa_supplicant network interface data
2414 * @src: Source address of the peer with which bootstrapping is done
2415 * @status: Status of Bootstrapping handshake
2416 * @bootstrap_method: Local device requested bootstrap method
2417 *
2418 * Sends a signal to notify that a peer P2P Device is requesting bootstrapping
2419 * negotiation with us.
2420 */
wpas_dbus_signal_p2p_bootstrap_rsp(struct wpa_supplicant * wpa_s,const u8 * src,int status,u16 bootstrap_method)2421 void wpas_dbus_signal_p2p_bootstrap_rsp(struct wpa_supplicant *wpa_s,
2422 const u8 *src, int status,
2423 u16 bootstrap_method)
2424 {
2425 DBusMessage *msg;
2426 DBusMessageIter iter;
2427 struct wpas_dbus_priv *iface;
2428 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
2429
2430 iface = wpa_s->global->dbus;
2431
2432 /* Do nothing if the control interface is not turned on */
2433 if (!iface)
2434 return;
2435
2436 if (wpa_s->p2p_mgmt)
2437 wpa_s = wpa_s->parent;
2438 if (!wpa_s->dbus_new_path)
2439 return;
2440
2441 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2442 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
2443 wpa_s->dbus_new_path, MAC2STR(src));
2444 path = peer_obj_path;
2445
2446 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
2447 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2448 "BootstrappingCompleted");
2449 if (!msg)
2450 return;
2451
2452 dbus_message_iter_init_append(msg, &iter);
2453
2454 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
2455 &path) ||
2456 !dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32,
2457 &status) ||
2458 !dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT16,
2459 &bootstrap_method))
2460 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
2461 else
2462 dbus_connection_send(iface->con, msg, NULL);
2463
2464 dbus_message_unref(msg);
2465 }
2466
2467
2468 #endif /* CONFIG_P2P */
2469
2470
2471 /**
2472 * wpas_dbus_signal_prop_changed - Signals change of property
2473 * @wpa_s: %wpa_supplicant network interface data
2474 * @property: indicates which property has changed
2475 *
2476 * Sends PropertyChanged signals with path, interface and arguments
2477 * depending on which property has changed.
2478 */
wpas_dbus_signal_prop_changed(struct wpa_supplicant * wpa_s,enum wpas_dbus_prop property)2479 void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
2480 enum wpas_dbus_prop property)
2481 {
2482 char *prop;
2483 dbus_bool_t flush;
2484
2485 if (wpa_s->dbus_new_path == NULL)
2486 return; /* Skip signal since D-Bus setup is not yet ready */
2487
2488 flush = FALSE;
2489 switch (property) {
2490 case WPAS_DBUS_PROP_AP_SCAN:
2491 prop = "ApScan";
2492 break;
2493 case WPAS_DBUS_PROP_SCANNING:
2494 prop = "Scanning";
2495 break;
2496 case WPAS_DBUS_PROP_STATE:
2497 prop = "State";
2498 break;
2499 case WPAS_DBUS_PROP_CURRENT_BSS:
2500 prop = "CurrentBSS";
2501 break;
2502 case WPAS_DBUS_PROP_CURRENT_NETWORK:
2503 prop = "CurrentNetwork";
2504 break;
2505 case WPAS_DBUS_PROP_BSSS:
2506 prop = "BSSs";
2507 break;
2508 case WPAS_DBUS_PROP_STATIONS:
2509 prop = "Stations";
2510 break;
2511 case WPAS_DBUS_PROP_CURRENT_AUTH_MODE:
2512 prop = "CurrentAuthMode";
2513 break;
2514 case WPAS_DBUS_PROP_DISCONNECT_REASON:
2515 prop = "DisconnectReason";
2516 flush = TRUE;
2517 break;
2518 case WPAS_DBUS_PROP_AUTH_STATUS_CODE:
2519 prop = "AuthStatusCode";
2520 flush = TRUE;
2521 break;
2522 case WPAS_DBUS_PROP_ASSOC_STATUS_CODE:
2523 prop = "AssocStatusCode";
2524 flush = TRUE;
2525 break;
2526 case WPAS_DBUS_PROP_ROAM_TIME:
2527 prop = "RoamTime";
2528 break;
2529 case WPAS_DBUS_PROP_ROAM_COMPLETE:
2530 prop = "RoamComplete";
2531 break;
2532 case WPAS_DBUS_PROP_SCAN_IN_PROGRESS_6GHZ:
2533 prop = "ScanInProgress6GHz";
2534 flush = TRUE;
2535 break;
2536 case WPAS_DBUS_PROP_SESSION_LENGTH:
2537 prop = "SessionLength";
2538 break;
2539 case WPAS_DBUS_PROP_BSS_TM_STATUS:
2540 prop = "BSSTMStatus";
2541 break;
2542 case WPAS_DBUS_PROP_MAC_ADDRESS:
2543 prop = "MACAddress";
2544 break;
2545 case WPAS_DBUS_PROP_SIGNAL_CHANGE:
2546 prop = "SignalChange";
2547 break;
2548 default:
2549 wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
2550 __func__, property);
2551 return;
2552 }
2553
2554 wpa_dbus_mark_property_changed(wpa_s->global->dbus,
2555 wpa_s->dbus_new_path,
2556 WPAS_DBUS_NEW_IFACE_INTERFACE, prop);
2557 if (flush) {
2558 wpa_dbus_flush_object_changed_properties(
2559 wpa_s->global->dbus->con, wpa_s->dbus_new_path);
2560 }
2561 }
2562
2563
2564 /**
2565 * wpas_dbus_bss_signal_prop_changed - Signals change of BSS property
2566 * @wpa_s: %wpa_supplicant network interface data
2567 * @property: indicates which property has changed
2568 * @id: unique BSS identifier
2569 *
2570 * Sends PropertyChanged signals with path, interface, and arguments depending
2571 * on which property has changed.
2572 */
wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant * wpa_s,enum wpas_dbus_bss_prop property,unsigned int id)2573 void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant *wpa_s,
2574 enum wpas_dbus_bss_prop property,
2575 unsigned int id)
2576 {
2577 char path[WPAS_DBUS_OBJECT_PATH_MAX];
2578 char *prop;
2579
2580 if (!wpa_s->dbus_new_path)
2581 return;
2582
2583 switch (property) {
2584 case WPAS_DBUS_BSS_PROP_SIGNAL:
2585 prop = "Signal";
2586 break;
2587 case WPAS_DBUS_BSS_PROP_FREQ:
2588 prop = "Frequency";
2589 break;
2590 case WPAS_DBUS_BSS_PROP_MODE:
2591 prop = "Mode";
2592 break;
2593 case WPAS_DBUS_BSS_PROP_PRIVACY:
2594 prop = "Privacy";
2595 break;
2596 case WPAS_DBUS_BSS_PROP_RATES:
2597 prop = "Rates";
2598 break;
2599 case WPAS_DBUS_BSS_PROP_WPA:
2600 prop = "WPA";
2601 break;
2602 case WPAS_DBUS_BSS_PROP_RSN:
2603 prop = "RSN";
2604 break;
2605 case WPAS_DBUS_BSS_PROP_WPS:
2606 prop = "WPS";
2607 break;
2608 case WPAS_DBUS_BSS_PROP_IES:
2609 prop = "IEs";
2610 break;
2611 case WPAS_DBUS_BSS_PROP_AGE:
2612 prop = "Age";
2613 break;
2614 case WPAS_DBUS_BSS_PROP_ANQP:
2615 prop = "ANQP";
2616 break;
2617 default:
2618 wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
2619 __func__, property);
2620 return;
2621 }
2622
2623 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
2624 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
2625 wpa_s->dbus_new_path, id);
2626
2627 wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
2628 WPAS_DBUS_NEW_IFACE_BSS, prop);
2629 }
2630
2631
2632 /**
2633 * wpas_dbus_signal_debug_level_changed - Signals change of debug param
2634 * @global: wpa_global structure
2635 *
2636 * Sends PropertyChanged signals informing that debug level has changed.
2637 */
wpas_dbus_signal_debug_level_changed(struct wpa_global * global)2638 void wpas_dbus_signal_debug_level_changed(struct wpa_global *global)
2639 {
2640 wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
2641 WPAS_DBUS_NEW_INTERFACE,
2642 "DebugLevel");
2643 }
2644
2645
2646 /**
2647 * wpas_dbus_signal_debug_timestamp_changed - Signals change of debug param
2648 * @global: wpa_global structure
2649 *
2650 * Sends PropertyChanged signals informing that debug timestamp has changed.
2651 */
wpas_dbus_signal_debug_timestamp_changed(struct wpa_global * global)2652 void wpas_dbus_signal_debug_timestamp_changed(struct wpa_global *global)
2653 {
2654 wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
2655 WPAS_DBUS_NEW_INTERFACE,
2656 "DebugTimestamp");
2657 }
2658
2659
2660 /**
2661 * wpas_dbus_signal_debug_show_keys_changed - Signals change of debug param
2662 * @global: wpa_global structure
2663 *
2664 * Sends PropertyChanged signals informing that debug show_keys has changed.
2665 */
wpas_dbus_signal_debug_show_keys_changed(struct wpa_global * global)2666 void wpas_dbus_signal_debug_show_keys_changed(struct wpa_global *global)
2667 {
2668 wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
2669 WPAS_DBUS_NEW_INTERFACE,
2670 "DebugShowKeys");
2671 }
2672
2673
wpas_dbus_register(struct wpa_dbus_object_desc * obj_desc,void * priv,WPADBusArgumentFreeFunction priv_free,const struct wpa_dbus_method_desc * methods,const struct wpa_dbus_property_desc * properties,const struct wpa_dbus_signal_desc * signals)2674 static void wpas_dbus_register(struct wpa_dbus_object_desc *obj_desc,
2675 void *priv,
2676 WPADBusArgumentFreeFunction priv_free,
2677 const struct wpa_dbus_method_desc *methods,
2678 const struct wpa_dbus_property_desc *properties,
2679 const struct wpa_dbus_signal_desc *signals)
2680 {
2681 int n;
2682
2683 obj_desc->user_data = priv;
2684 obj_desc->user_data_free_func = priv_free;
2685 obj_desc->methods = methods;
2686 obj_desc->properties = properties;
2687 obj_desc->signals = signals;
2688
2689 for (n = 0; properties && properties->dbus_property; properties++)
2690 n++;
2691
2692 obj_desc->prop_changed_flags = os_zalloc(n);
2693 if (!obj_desc->prop_changed_flags)
2694 wpa_printf(MSG_DEBUG, "dbus: %s: can't register handlers",
2695 __func__);
2696 }
2697
2698
2699 static const struct wpa_dbus_method_desc wpas_dbus_global_methods[] = {
2700 { "CreateInterface", WPAS_DBUS_NEW_INTERFACE,
2701 (WPADBusMethodHandler) wpas_dbus_handler_create_interface,
2702 {
2703 { "args", "a{sv}", ARG_IN },
2704 { "path", "o", ARG_OUT },
2705 END_ARGS
2706 }
2707 },
2708 { "RemoveInterface", WPAS_DBUS_NEW_INTERFACE,
2709 (WPADBusMethodHandler) wpas_dbus_handler_remove_interface,
2710 {
2711 { "path", "o", ARG_IN },
2712 END_ARGS
2713 }
2714 },
2715 { "GetInterface", WPAS_DBUS_NEW_INTERFACE,
2716 (WPADBusMethodHandler) wpas_dbus_handler_get_interface,
2717 {
2718 { "ifname", "s", ARG_IN },
2719 { "path", "o", ARG_OUT },
2720 END_ARGS
2721 }
2722 },
2723 { "ExpectDisconnect", WPAS_DBUS_NEW_INTERFACE,
2724 (WPADBusMethodHandler) wpas_dbus_handler_expect_disconnect,
2725 {
2726 END_ARGS
2727 }
2728 },
2729 { NULL, NULL, NULL, { END_ARGS } }
2730 };
2731
2732 static const struct wpa_dbus_property_desc wpas_dbus_global_properties[] = {
2733 { "DebugLevel", WPAS_DBUS_NEW_INTERFACE, "s",
2734 wpas_dbus_getter_debug_level,
2735 wpas_dbus_setter_debug_level,
2736 NULL
2737 },
2738 { "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE, "b",
2739 wpas_dbus_getter_debug_timestamp,
2740 wpas_dbus_setter_debug_timestamp,
2741 NULL
2742 },
2743 { "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE, "b",
2744 wpas_dbus_getter_debug_show_keys,
2745 wpas_dbus_setter_debug_show_keys,
2746 NULL
2747 },
2748 { "Interfaces", WPAS_DBUS_NEW_INTERFACE, "ao",
2749 wpas_dbus_getter_interfaces,
2750 NULL,
2751 NULL
2752 },
2753 { "EapMethods", WPAS_DBUS_NEW_INTERFACE, "as",
2754 wpas_dbus_getter_eap_methods,
2755 NULL,
2756 NULL
2757 },
2758 { "Capabilities", WPAS_DBUS_NEW_INTERFACE, "as",
2759 wpas_dbus_getter_global_capabilities,
2760 NULL,
2761 NULL
2762 },
2763 #ifdef CONFIG_WIFI_DISPLAY
2764 { "WFDIEs", WPAS_DBUS_NEW_INTERFACE, "ay",
2765 wpas_dbus_getter_global_wfd_ies,
2766 wpas_dbus_setter_global_wfd_ies,
2767 NULL
2768 },
2769 #endif /* CONFIG_WIFI_DISPLAY */
2770 { NULL, NULL, NULL, NULL, NULL, NULL }
2771 };
2772
2773 static const struct wpa_dbus_signal_desc wpas_dbus_global_signals[] = {
2774 { "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE,
2775 {
2776 { "path", "o", ARG_OUT },
2777 { "properties", "a{sv}", ARG_OUT },
2778 END_ARGS
2779 }
2780 },
2781 { "InterfaceRemoved", WPAS_DBUS_NEW_INTERFACE,
2782 {
2783 { "path", "o", ARG_OUT },
2784 END_ARGS
2785 }
2786 },
2787 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2788 { "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE,
2789 {
2790 { "properties", "a{sv}", ARG_OUT },
2791 END_ARGS
2792 }
2793 },
2794 { NULL, NULL, { END_ARGS } }
2795 };
2796
2797
uscore_to_dbus(const char * uscore)2798 static char * uscore_to_dbus(const char *uscore)
2799 {
2800 const char *p = uscore;
2801 char *str, *s;
2802 dbus_bool_t last_was_uscore = TRUE;
2803
2804 s = str = os_zalloc(os_strlen(uscore) + 1);
2805 if (!str)
2806 return NULL;
2807 while (p && *p) {
2808 if (*p == '_') {
2809 last_was_uscore = TRUE;
2810 } else {
2811 *s++ = last_was_uscore ? toupper(*p) : *p;
2812 last_was_uscore = FALSE;
2813 }
2814 p++;
2815 }
2816
2817 return str;
2818 }
2819
2820
2821 static int wpa_dbus_ctrl_iface_props_init(struct wpas_dbus_priv *priv);
2822
2823
wpa_dbus_ctrl_iface_props_deinit(struct wpas_dbus_priv * priv)2824 static void wpa_dbus_ctrl_iface_props_deinit(struct wpas_dbus_priv *priv)
2825 {
2826 int idx = priv->globals_start;
2827
2828 /* Free all allocated property values */
2829 while (priv->all_interface_properties[idx].dbus_property)
2830 os_free((char *)
2831 priv->all_interface_properties[idx++].dbus_property);
2832 os_free((char *) priv->all_interface_properties);
2833 }
2834
2835
2836 /**
2837 * wpas_dbus_ctrl_iface_init - Initialize dbus control interface
2838 * @global: Pointer to global data from wpa_supplicant_init()
2839 * Returns: 0 on success or -1 on failure
2840 *
2841 * Initialize the dbus control interface for wpa_supplicant and start
2842 * receiving commands from external programs over the bus.
2843 */
wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv * priv)2844 int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv *priv)
2845 {
2846 struct wpa_dbus_object_desc *obj_desc;
2847 int ret;
2848
2849 ret = wpa_dbus_ctrl_iface_props_init(priv);
2850 if (ret < 0) {
2851 wpa_printf(MSG_ERROR,
2852 "dbus: Not enough memory to init interface properties");
2853 return -1;
2854 }
2855
2856 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
2857 if (!obj_desc) {
2858 wpa_printf(MSG_ERROR,
2859 "Not enough memory to create object description");
2860 goto error;
2861 }
2862
2863 wpas_dbus_register(obj_desc, priv->global, NULL,
2864 wpas_dbus_global_methods,
2865 wpas_dbus_global_properties,
2866 wpas_dbus_global_signals);
2867
2868 wpa_printf(MSG_DEBUG, "dbus: Register D-Bus object '%s'",
2869 WPAS_DBUS_NEW_PATH);
2870 ret = wpa_dbus_ctrl_iface_init(priv, WPAS_DBUS_NEW_PATH,
2871 WPAS_DBUS_NEW_SERVICE,
2872 obj_desc);
2873 if (ret < 0) {
2874 free_dbus_object_desc(obj_desc);
2875 goto error;
2876 }
2877
2878 priv->dbus_new_initialized = 1;
2879 return 0;
2880
2881 error:
2882 wpa_dbus_ctrl_iface_props_deinit(priv);
2883 return -1;
2884 }
2885
2886
2887 /**
2888 * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for
2889 * wpa_supplicant
2890 * @priv: Pointer to dbus private data from wpas_dbus_init()
2891 *
2892 * Deinitialize the dbus control interface that was initialized with
2893 * wpas_dbus_ctrl_iface_init().
2894 */
wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv * priv)2895 void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv *priv)
2896 {
2897 if (!priv->dbus_new_initialized)
2898 return;
2899 wpa_printf(MSG_DEBUG, "dbus: Unregister D-Bus object '%s'",
2900 WPAS_DBUS_NEW_PATH);
2901 dbus_connection_unregister_object_path(priv->con, WPAS_DBUS_NEW_PATH);
2902 wpa_dbus_ctrl_iface_props_deinit(priv);
2903 }
2904
2905
wpa_dbus_free(void * ptr)2906 static void wpa_dbus_free(void *ptr)
2907 {
2908 os_free(ptr);
2909 }
2910
2911
2912 static const struct wpa_dbus_property_desc wpas_dbus_network_properties[] = {
2913 { "Properties", WPAS_DBUS_NEW_IFACE_NETWORK, "a{sv}",
2914 wpas_dbus_getter_network_properties,
2915 wpas_dbus_setter_network_properties,
2916 NULL
2917 },
2918 { "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK, "b",
2919 wpas_dbus_getter_enabled,
2920 wpas_dbus_setter_enabled,
2921 NULL
2922 },
2923 { NULL, NULL, NULL, NULL, NULL, NULL }
2924 };
2925
2926
2927 static const struct wpa_dbus_signal_desc wpas_dbus_network_signals[] = {
2928 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
2929 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK,
2930 {
2931 { "properties", "a{sv}", ARG_OUT },
2932 END_ARGS
2933 }
2934 },
2935 { NULL, NULL, { END_ARGS } }
2936 };
2937
2938
2939 /**
2940 * wpas_dbus_register_network - Register a configured network with dbus
2941 * @wpa_s: wpa_supplicant interface structure
2942 * @ssid: network configuration data
2943 * Returns: 0 on success, -1 on failure
2944 *
2945 * Registers network representing object with dbus
2946 */
wpas_dbus_register_network(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid)2947 int wpas_dbus_register_network(struct wpa_supplicant *wpa_s,
2948 struct wpa_ssid *ssid)
2949 {
2950 struct wpas_dbus_priv *ctrl_iface;
2951 struct wpa_dbus_object_desc *obj_desc;
2952 struct network_handler_args *arg;
2953 char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2954
2955 #ifdef CONFIG_P2P
2956 /*
2957 * If it is a persistent group register it as such.
2958 * This is to handle cases where an interface is being initialized
2959 * with a list of networks read from config.
2960 */
2961 if (network_is_persistent_group(ssid))
2962 return wpas_dbus_register_persistent_group(wpa_s, ssid);
2963 #endif /* CONFIG_P2P */
2964
2965 /* Do nothing if the control interface is not turned on */
2966 if (wpa_s == NULL || wpa_s->global == NULL || !wpa_s->dbus_new_path)
2967 return 0;
2968 ctrl_iface = wpa_s->global->dbus;
2969 if (ctrl_iface == NULL)
2970 return 0;
2971
2972 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2973 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
2974 wpa_s->dbus_new_path, ssid->id);
2975
2976 wpa_printf(MSG_DEBUG, "dbus: Register network object '%s'",
2977 net_obj_path);
2978 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
2979 if (!obj_desc) {
2980 wpa_printf(MSG_ERROR,
2981 "Not enough memory to create object description");
2982 goto err;
2983 }
2984
2985 /* allocate memory for handlers arguments */
2986 arg = os_zalloc(sizeof(struct network_handler_args));
2987 if (!arg) {
2988 wpa_printf(MSG_ERROR,
2989 "Not enough memory to create arguments for method");
2990 goto err;
2991 }
2992
2993 arg->wpa_s = wpa_s;
2994 arg->ssid = ssid;
2995
2996 wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
2997 wpas_dbus_network_properties,
2998 wpas_dbus_network_signals);
2999
3000 if (wpa_dbus_register_object_per_iface(ctrl_iface, net_obj_path,
3001 wpa_s->ifname, obj_desc))
3002 goto err;
3003
3004 wpas_dbus_signal_network_added(wpa_s, ssid->id);
3005
3006 return 0;
3007
3008 err:
3009 free_dbus_object_desc(obj_desc);
3010 return -1;
3011 }
3012
3013
3014 /**
3015 * wpas_dbus_unregister_network - Unregister a configured network from dbus
3016 * @wpa_s: wpa_supplicant interface structure
3017 * @nid: network id
3018 * Returns: 0 on success, -1 on failure
3019 *
3020 * Unregisters network representing object from dbus
3021 */
wpas_dbus_unregister_network(struct wpa_supplicant * wpa_s,int nid)3022 int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid)
3023 {
3024 struct wpas_dbus_priv *ctrl_iface;
3025 char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3026 int ret;
3027 #ifdef CONFIG_P2P
3028 struct wpa_ssid *ssid;
3029
3030 ssid = wpa_config_get_network(wpa_s->conf, nid);
3031
3032 /* If it is a persistent group unregister it as such */
3033 if (ssid && network_is_persistent_group(ssid))
3034 return wpas_dbus_unregister_persistent_group(wpa_s, nid);
3035 #endif /* CONFIG_P2P */
3036
3037 /* Do nothing if the control interface is not turned on */
3038 if (wpa_s->global == NULL || wpa_s->dbus_new_path == NULL)
3039 return 0;
3040 ctrl_iface = wpa_s->global->dbus;
3041 if (ctrl_iface == NULL)
3042 return 0;
3043
3044 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3045 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
3046 wpa_s->dbus_new_path, nid);
3047
3048 wpa_printf(MSG_DEBUG, "dbus: Unregister network object '%s'",
3049 net_obj_path);
3050 ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, net_obj_path);
3051
3052 if (!ret)
3053 wpas_dbus_signal_network_removed(wpa_s, nid);
3054
3055 return ret;
3056 }
3057
3058
3059 static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = {
3060 { "SSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
3061 wpas_dbus_getter_bss_ssid,
3062 NULL,
3063 NULL
3064 },
3065 { "BSSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
3066 wpas_dbus_getter_bss_bssid,
3067 NULL,
3068 NULL
3069 },
3070 { "Privacy", WPAS_DBUS_NEW_IFACE_BSS, "b",
3071 wpas_dbus_getter_bss_privacy,
3072 NULL,
3073 NULL
3074 },
3075 { "Mode", WPAS_DBUS_NEW_IFACE_BSS, "s",
3076 wpas_dbus_getter_bss_mode,
3077 NULL,
3078 NULL
3079 },
3080 { "Signal", WPAS_DBUS_NEW_IFACE_BSS, "n",
3081 wpas_dbus_getter_bss_signal,
3082 NULL,
3083 NULL
3084 },
3085 { "Frequency", WPAS_DBUS_NEW_IFACE_BSS, "q",
3086 wpas_dbus_getter_bss_frequency,
3087 NULL,
3088 NULL
3089 },
3090 { "Rates", WPAS_DBUS_NEW_IFACE_BSS, "au",
3091 wpas_dbus_getter_bss_rates,
3092 NULL,
3093 NULL
3094 },
3095 { "WPA", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
3096 wpas_dbus_getter_bss_wpa,
3097 NULL,
3098 NULL
3099 },
3100 { "RSN", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
3101 wpas_dbus_getter_bss_rsn,
3102 NULL,
3103 NULL
3104 },
3105 { "WPS", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
3106 wpas_dbus_getter_bss_wps,
3107 NULL,
3108 NULL
3109 },
3110 { "IEs", WPAS_DBUS_NEW_IFACE_BSS, "ay",
3111 wpas_dbus_getter_bss_ies,
3112 NULL,
3113 NULL
3114 },
3115 { "Age", WPAS_DBUS_NEW_IFACE_BSS, "u",
3116 wpas_dbus_getter_bss_age,
3117 NULL,
3118 NULL
3119 },
3120 {"ANQP", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
3121 wpas_dbus_getter_bss_anqp,
3122 NULL,
3123 NULL,
3124 },
3125 { NULL, NULL, NULL, NULL, NULL, NULL }
3126 };
3127
3128
3129 static const struct wpa_dbus_signal_desc wpas_dbus_bss_signals[] = {
3130 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
3131 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSS,
3132 {
3133 { "properties", "a{sv}", ARG_OUT },
3134 END_ARGS
3135 }
3136 },
3137 { NULL, NULL, { END_ARGS } }
3138 };
3139
3140
3141 /**
3142 * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus
3143 * @wpa_s: wpa_supplicant interface structure
3144 * @bssid: scanned network bssid
3145 * @id: unique BSS identifier
3146 * Returns: 0 on success, -1 on failure
3147 *
3148 * Unregisters BSS representing object from dbus
3149 */
wpas_dbus_unregister_bss(struct wpa_supplicant * wpa_s,u8 bssid[ETH_ALEN],unsigned int id)3150 int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s,
3151 u8 bssid[ETH_ALEN], unsigned int id)
3152 {
3153 struct wpas_dbus_priv *ctrl_iface;
3154 char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3155
3156 /* Do nothing if the control interface is not turned on */
3157 if (wpa_s == NULL || wpa_s->global == NULL || !wpa_s->dbus_new_path)
3158 return 0;
3159 ctrl_iface = wpa_s->global->dbus;
3160 if (ctrl_iface == NULL)
3161 return 0;
3162
3163 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3164 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
3165 wpa_s->dbus_new_path, id);
3166
3167 wpa_printf(MSG_DEBUG, "dbus: Unregister BSS object '%s'",
3168 bss_obj_path);
3169 if (wpa_dbus_unregister_object_per_iface(ctrl_iface, bss_obj_path)) {
3170 wpa_printf(MSG_ERROR, "dbus: Cannot unregister BSS object %s",
3171 bss_obj_path);
3172 return -1;
3173 }
3174
3175 wpas_dbus_signal_bss_removed(wpa_s, bss_obj_path);
3176 wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSSS);
3177
3178 return 0;
3179 }
3180
3181
3182 /**
3183 * wpas_dbus_register_bss - Register a scanned BSS with dbus
3184 * @wpa_s: wpa_supplicant interface structure
3185 * @bssid: scanned network bssid
3186 * @id: unique BSS identifier
3187 * Returns: 0 on success, -1 on failure
3188 *
3189 * Registers BSS representing object with dbus
3190 */
wpas_dbus_register_bss(struct wpa_supplicant * wpa_s,u8 bssid[ETH_ALEN],unsigned int id)3191 int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s,
3192 u8 bssid[ETH_ALEN], unsigned int id)
3193 {
3194 struct wpas_dbus_priv *ctrl_iface;
3195 struct wpa_dbus_object_desc *obj_desc;
3196 char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3197 struct bss_handler_args *arg;
3198
3199 /* Do nothing if the control interface is not turned on */
3200 if (wpa_s == NULL || wpa_s->global == NULL || !wpa_s->dbus_new_path)
3201 return 0;
3202 ctrl_iface = wpa_s->global->dbus;
3203 if (ctrl_iface == NULL)
3204 return 0;
3205
3206 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3207 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
3208 wpa_s->dbus_new_path, id);
3209
3210 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
3211 if (!obj_desc) {
3212 wpa_printf(MSG_ERROR,
3213 "Not enough memory to create object description");
3214 goto err;
3215 }
3216
3217 arg = os_zalloc(sizeof(struct bss_handler_args));
3218 if (!arg) {
3219 wpa_printf(MSG_ERROR,
3220 "Not enough memory to create arguments for handler");
3221 goto err;
3222 }
3223 arg->wpa_s = wpa_s;
3224 arg->id = id;
3225
3226 wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
3227 wpas_dbus_bss_properties,
3228 wpas_dbus_bss_signals);
3229
3230 wpa_printf(MSG_DEBUG, "dbus: Register BSS object '%s'",
3231 bss_obj_path);
3232 if (wpa_dbus_register_object_per_iface(ctrl_iface, bss_obj_path,
3233 wpa_s->ifname, obj_desc)) {
3234 wpa_printf(MSG_ERROR,
3235 "Cannot register BSSID dbus object %s.",
3236 bss_obj_path);
3237 goto err;
3238 }
3239
3240 wpas_dbus_signal_bss_added(wpa_s, bss_obj_path);
3241 wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSSS);
3242
3243 return 0;
3244
3245 err:
3246 free_dbus_object_desc(obj_desc);
3247 return -1;
3248 }
3249
3250
3251 static const struct wpa_dbus_property_desc wpas_dbus_sta_properties[] = {
3252 { "Address", WPAS_DBUS_NEW_IFACE_STA, "ay",
3253 wpas_dbus_getter_sta_address,
3254 NULL, NULL
3255 },
3256 { "AID", WPAS_DBUS_NEW_IFACE_STA, "q",
3257 wpas_dbus_getter_sta_aid,
3258 NULL, NULL
3259 },
3260 { "Capabilities", WPAS_DBUS_NEW_IFACE_STA, "q",
3261 wpas_dbus_getter_sta_caps,
3262 NULL, NULL
3263 },
3264 { "RxPackets", WPAS_DBUS_NEW_IFACE_STA, "t",
3265 wpas_dbus_getter_sta_rx_packets,
3266 NULL, NULL
3267 },
3268 { "TxPackets", WPAS_DBUS_NEW_IFACE_STA, "t",
3269 wpas_dbus_getter_sta_tx_packets,
3270 NULL, NULL
3271 },
3272 { "RxBytes", WPAS_DBUS_NEW_IFACE_STA, "t",
3273 wpas_dbus_getter_sta_rx_bytes,
3274 NULL, NULL
3275 },
3276 { "TxBytes", WPAS_DBUS_NEW_IFACE_STA, "t",
3277 wpas_dbus_getter_sta_tx_bytes,
3278 NULL, NULL
3279 },
3280 { NULL, NULL, NULL, NULL, NULL, NULL }
3281 };
3282
3283
3284 static const struct wpa_dbus_signal_desc wpas_dbus_sta_signals[] = {
3285 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
3286 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_STA,
3287 {
3288 { "properties", "a{sv}", ARG_OUT },
3289 END_ARGS
3290 }
3291 },
3292 { NULL, NULL, { END_ARGS } }
3293 };
3294
3295
3296 /**
3297 * wpas_dbus_unregister_sta - Unregister a connected station from dbus
3298 * @wpa_s: wpa_supplicant interface structure
3299 * @sta: station MAC address
3300 * Returns: 0 on success, -1 on failure
3301 *
3302 * Unregisters STA representing object from dbus.
3303 */
wpas_dbus_unregister_sta(struct wpa_supplicant * wpa_s,const u8 * sta)3304 int wpas_dbus_unregister_sta(struct wpa_supplicant *wpa_s, const u8 *sta)
3305 {
3306 struct wpas_dbus_priv *ctrl_iface;
3307 char station_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3308
3309 /* Do nothing if the control interface is not turned on */
3310 if (!wpa_s || !wpa_s->global)
3311 return 0;
3312 ctrl_iface = wpa_s->global->dbus;
3313 if (!ctrl_iface)
3314 return 0;
3315
3316 os_snprintf(station_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3317 "%s/" WPAS_DBUS_NEW_STAS_PART "/" COMPACT_MACSTR,
3318 wpa_s->dbus_new_path, MAC2STR(sta));
3319
3320 wpa_printf(MSG_DEBUG, "dbus: Unregister STA object '%s'",
3321 station_obj_path);
3322 if (wpa_dbus_unregister_object_per_iface(ctrl_iface,
3323 station_obj_path)) {
3324 wpa_printf(MSG_ERROR, "dbus: Cannot unregister STA object %s",
3325 station_obj_path);
3326 return -1;
3327 }
3328
3329 wpas_dbus_signal_station_removed(wpa_s, station_obj_path);
3330 wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_STATIONS);
3331
3332 return 0;
3333 }
3334
3335
3336 /**
3337 * wpas_dbus_register_sta - Register a connected station with dbus
3338 * @wpa_s: wpa_supplicant interface structure
3339 * @sta: station MAC address
3340 * Returns: 0 on success, -1 on failure
3341 *
3342 * Registers STA representing object with dbus.
3343 */
wpas_dbus_register_sta(struct wpa_supplicant * wpa_s,const u8 * sta)3344 int wpas_dbus_register_sta(struct wpa_supplicant *wpa_s, const u8 *sta)
3345 {
3346 struct wpas_dbus_priv *ctrl_iface;
3347 struct wpa_dbus_object_desc *obj_desc;
3348 char station_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3349 struct sta_handler_args *arg;
3350
3351 /* Do nothing if the control interface is not turned on */
3352 if (!wpa_s || !wpa_s->global)
3353 return 0;
3354 ctrl_iface = wpa_s->global->dbus;
3355 if (!ctrl_iface)
3356 return 0;
3357
3358 os_snprintf(station_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3359 "%s/" WPAS_DBUS_NEW_STAS_PART "/" COMPACT_MACSTR,
3360 wpa_s->dbus_new_path, MAC2STR(sta));
3361
3362 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
3363 if (!obj_desc) {
3364 wpa_printf(MSG_ERROR,
3365 "Not enough memory to create object description");
3366 goto err;
3367 }
3368
3369 arg = os_zalloc(sizeof(struct sta_handler_args));
3370 if (!arg) {
3371 wpa_printf(MSG_ERROR,
3372 "Not enough memory to create arguments for handler");
3373 goto err;
3374 }
3375 arg->wpa_s = wpa_s;
3376 arg->sta = sta;
3377
3378 wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
3379 wpas_dbus_sta_properties, wpas_dbus_sta_signals);
3380
3381 wpa_printf(MSG_DEBUG, "dbus: Register STA object '%s'",
3382 station_obj_path);
3383 if (wpa_dbus_register_object_per_iface(ctrl_iface, station_obj_path,
3384 wpa_s->ifname, obj_desc)) {
3385 wpa_printf(MSG_ERROR,
3386 "Cannot register STA dbus object %s",
3387 station_obj_path);
3388 goto err;
3389 }
3390
3391 wpas_dbus_signal_station_added(wpa_s, station_obj_path);
3392 wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_STATIONS);
3393
3394 return 0;
3395
3396 err:
3397 free_dbus_object_desc(obj_desc);
3398 return -1;
3399 }
3400
3401
3402 static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
3403 { "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE,
3404 (WPADBusMethodHandler) wpas_dbus_handler_scan,
3405 {
3406 { "args", "a{sv}", ARG_IN },
3407 END_ARGS
3408 }
3409 },
3410 { "SignalPoll", WPAS_DBUS_NEW_IFACE_INTERFACE,
3411 (WPADBusMethodHandler) wpas_dbus_handler_signal_poll,
3412 {
3413 { "args", "a{sv}", ARG_OUT },
3414 END_ARGS
3415 }
3416 },
3417 { "Disconnect", WPAS_DBUS_NEW_IFACE_INTERFACE,
3418 (WPADBusMethodHandler) wpas_dbus_handler_disconnect,
3419 {
3420 END_ARGS
3421 }
3422 },
3423 { "AddNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
3424 (WPADBusMethodHandler) wpas_dbus_handler_add_network,
3425 {
3426 { "args", "a{sv}", ARG_IN },
3427 { "path", "o", ARG_OUT },
3428 END_ARGS
3429 }
3430 },
3431 { "Reassociate", WPAS_DBUS_NEW_IFACE_INTERFACE,
3432 (WPADBusMethodHandler) wpas_dbus_handler_reassociate,
3433 {
3434 END_ARGS
3435 }
3436 },
3437 { "Reattach", WPAS_DBUS_NEW_IFACE_INTERFACE,
3438 (WPADBusMethodHandler) wpas_dbus_handler_reattach,
3439 {
3440 END_ARGS
3441 }
3442 },
3443 { "Reconnect", WPAS_DBUS_NEW_IFACE_INTERFACE,
3444 (WPADBusMethodHandler) wpas_dbus_handler_reconnect,
3445 {
3446 END_ARGS
3447 }
3448 },
3449 { "RemoveNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
3450 (WPADBusMethodHandler) wpas_dbus_handler_remove_network,
3451 {
3452 { "path", "o", ARG_IN },
3453 END_ARGS
3454 }
3455 },
3456 { "RemoveAllNetworks", WPAS_DBUS_NEW_IFACE_INTERFACE,
3457 (WPADBusMethodHandler) wpas_dbus_handler_remove_all_networks,
3458 {
3459 END_ARGS
3460 }
3461 },
3462 { "SelectNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
3463 (WPADBusMethodHandler) wpas_dbus_handler_select_network,
3464 {
3465 { "path", "o", ARG_IN },
3466 END_ARGS
3467 }
3468 },
3469 { "NetworkReply", WPAS_DBUS_NEW_IFACE_INTERFACE,
3470 (WPADBusMethodHandler) wpas_dbus_handler_network_reply,
3471 {
3472 { "path", "o", ARG_IN },
3473 { "field", "s", ARG_IN },
3474 { "value", "s", ARG_IN },
3475 END_ARGS
3476 }
3477 },
3478 { "Roam", WPAS_DBUS_NEW_IFACE_INTERFACE,
3479 (WPADBusMethodHandler) wpas_dbus_handler_roam,
3480 {
3481 { "addr", "s", ARG_IN },
3482 END_ARGS
3483 }
3484 },
3485
3486 #ifndef CONFIG_NO_CONFIG_BLOBS
3487 { "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
3488 (WPADBusMethodHandler) wpas_dbus_handler_add_blob,
3489 {
3490 { "name", "s", ARG_IN },
3491 { "data", "ay", ARG_IN },
3492 END_ARGS
3493 }
3494 },
3495 { "GetBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
3496 (WPADBusMethodHandler) wpas_dbus_handler_get_blob,
3497 {
3498 { "name", "s", ARG_IN },
3499 { "data", "ay", ARG_OUT },
3500 END_ARGS
3501 }
3502 },
3503 { "RemoveBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
3504 (WPADBusMethodHandler) wpas_dbus_handler_remove_blob,
3505 {
3506 { "name", "s", ARG_IN },
3507 END_ARGS
3508 }
3509 },
3510 #endif /* CONFIG_NO_CONFIG_BLOBS */
3511 { "SetPKCS11EngineAndModulePath", WPAS_DBUS_NEW_IFACE_INTERFACE,
3512 (WPADBusMethodHandler)
3513 wpas_dbus_handler_set_pkcs11_engine_and_module_path,
3514 {
3515 { "pkcs11_engine_path", "s", ARG_IN },
3516 { "pkcs11_module_path", "s", ARG_IN },
3517 END_ARGS
3518 }
3519 },
3520 #ifdef CONFIG_WPS
3521 { "Start", WPAS_DBUS_NEW_IFACE_WPS,
3522 (WPADBusMethodHandler) wpas_dbus_handler_wps_start,
3523 {
3524 { "args", "a{sv}", ARG_IN },
3525 { "output", "a{sv}", ARG_OUT },
3526 END_ARGS
3527 }
3528 },
3529 { "Cancel", WPAS_DBUS_NEW_IFACE_WPS,
3530 (WPADBusMethodHandler) wpas_dbus_handler_wps_cancel,
3531 {
3532 END_ARGS
3533 }
3534 },
3535 #endif /* CONFIG_WPS */
3536 #ifdef CONFIG_P2P
3537 { "Find", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3538 (WPADBusMethodHandler) wpas_dbus_handler_p2p_find,
3539 {
3540 { "args", "a{sv}", ARG_IN },
3541 END_ARGS
3542 }
3543 },
3544 { "StopFind", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3545 (WPADBusMethodHandler) wpas_dbus_handler_p2p_stop_find,
3546 {
3547 END_ARGS
3548 }
3549 },
3550 { "Listen", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3551 (WPADBusMethodHandler) wpas_dbus_handler_p2p_listen,
3552 {
3553 { "timeout", "i", ARG_IN },
3554 END_ARGS
3555 }
3556 },
3557 { "ExtendedListen", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3558 (WPADBusMethodHandler) wpas_dbus_handler_p2p_extendedlisten,
3559 {
3560 { "args", "a{sv}", ARG_IN },
3561 END_ARGS
3562 }
3563 },
3564 { "PresenceRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3565 (WPADBusMethodHandler) wpas_dbus_handler_p2p_presence_request,
3566 {
3567 { "args", "a{sv}", ARG_IN },
3568 END_ARGS
3569 }
3570 },
3571 { "ProvisionDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3572 (WPADBusMethodHandler) wpas_dbus_handler_p2p_prov_disc_req,
3573 {
3574 { "peer", "o", ARG_IN },
3575 { "config_method", "s", ARG_IN },
3576 END_ARGS
3577 }
3578 },
3579 { "Connect", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3580 (WPADBusMethodHandler) wpas_dbus_handler_p2p_connect,
3581 {
3582 { "args", "a{sv}", ARG_IN },
3583 { "generated_pin", "s", ARG_OUT },
3584 END_ARGS
3585 }
3586 },
3587 { "GroupAdd", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3588 (WPADBusMethodHandler) wpas_dbus_handler_p2p_group_add,
3589 {
3590 { "args", "a{sv}", ARG_IN },
3591 END_ARGS
3592 }
3593 },
3594 { "Cancel", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3595 (WPADBusMethodHandler) wpas_dbus_handler_p2p_cancel,
3596 {
3597 END_ARGS
3598 }
3599 },
3600 { "Invite", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3601 (WPADBusMethodHandler) wpas_dbus_handler_p2p_invite,
3602 {
3603 { "args", "a{sv}", ARG_IN },
3604 END_ARGS
3605 }
3606 },
3607 { "Disconnect", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3608 (WPADBusMethodHandler) wpas_dbus_handler_p2p_disconnect,
3609 {
3610 END_ARGS
3611 }
3612 },
3613 { "RejectPeer", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3614 (WPADBusMethodHandler) wpas_dbus_handler_p2p_rejectpeer,
3615 {
3616 { "peer", "o", ARG_IN },
3617 END_ARGS
3618 }
3619 },
3620 { "RemoveClient", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3621 (WPADBusMethodHandler) wpas_dbus_handler_p2p_remove_client,
3622 {
3623 { "args", "a{sv}", ARG_IN },
3624 END_ARGS
3625 }
3626 },
3627 { "Flush", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3628 (WPADBusMethodHandler) wpas_dbus_handler_p2p_flush,
3629 {
3630 END_ARGS
3631 }
3632 },
3633 { "AddService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3634 (WPADBusMethodHandler) wpas_dbus_handler_p2p_add_service,
3635 {
3636 { "args", "a{sv}", ARG_IN },
3637 END_ARGS
3638 }
3639 },
3640 { "DeleteService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3641 (WPADBusMethodHandler) wpas_dbus_handler_p2p_delete_service,
3642 {
3643 { "args", "a{sv}", ARG_IN },
3644 END_ARGS
3645 }
3646 },
3647 { "FlushService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3648 (WPADBusMethodHandler) wpas_dbus_handler_p2p_flush_service,
3649 {
3650 END_ARGS
3651 }
3652 },
3653 { "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3654 (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_sd_req,
3655 {
3656 { "args", "a{sv}", ARG_IN },
3657 { "ref", "t", ARG_OUT },
3658 END_ARGS
3659 }
3660 },
3661 { "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3662 (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_sd_res,
3663 {
3664 { "args", "a{sv}", ARG_IN },
3665 END_ARGS
3666 }
3667 },
3668 { "ServiceDiscoveryCancelRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3669 (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_sd_cancel_req,
3670 {
3671 { "args", "t", ARG_IN },
3672 END_ARGS
3673 }
3674 },
3675 { "ServiceUpdate", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3676 (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_update,
3677 {
3678 END_ARGS
3679 }
3680 },
3681 { "ServiceDiscoveryExternal", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3682 (WPADBusMethodHandler) wpas_dbus_handler_p2p_serv_disc_external,
3683 {
3684 { "arg", "i", ARG_IN },
3685 END_ARGS
3686 }
3687 },
3688 { "AddPersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3689 (WPADBusMethodHandler) wpas_dbus_handler_add_persistent_group,
3690 {
3691 { "args", "a{sv}", ARG_IN },
3692 { "path", "o", ARG_OUT },
3693 END_ARGS
3694 }
3695 },
3696 { "RemovePersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3697 (WPADBusMethodHandler) wpas_dbus_handler_remove_persistent_group,
3698 {
3699 { "path", "o", ARG_IN },
3700 END_ARGS
3701 }
3702 },
3703 { "RemoveAllPersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3704 (WPADBusMethodHandler)
3705 wpas_dbus_handler_remove_all_persistent_groups,
3706 {
3707 END_ARGS
3708 }
3709 },
3710 #endif /* CONFIG_P2P */
3711 { "FlushBSS", WPAS_DBUS_NEW_IFACE_INTERFACE,
3712 (WPADBusMethodHandler) wpas_dbus_handler_flush_bss,
3713 {
3714 { "age", "u", ARG_IN },
3715 END_ARGS
3716 }
3717 },
3718 #ifdef CONFIG_AP
3719 { "SubscribeProbeReq", WPAS_DBUS_NEW_IFACE_INTERFACE,
3720 (WPADBusMethodHandler) wpas_dbus_handler_subscribe_preq,
3721 {
3722 END_ARGS
3723 }
3724 },
3725 { "UnsubscribeProbeReq", WPAS_DBUS_NEW_IFACE_INTERFACE,
3726 (WPADBusMethodHandler) wpas_dbus_handler_unsubscribe_preq,
3727 {
3728 END_ARGS
3729 }
3730 },
3731 #endif /* CONFIG_AP */
3732 { "EAPLogoff", WPAS_DBUS_NEW_IFACE_INTERFACE,
3733 (WPADBusMethodHandler) wpas_dbus_handler_eap_logoff,
3734 {
3735 END_ARGS
3736 }
3737 },
3738 { "EAPLogon", WPAS_DBUS_NEW_IFACE_INTERFACE,
3739 (WPADBusMethodHandler) wpas_dbus_handler_eap_logon,
3740 {
3741 END_ARGS
3742 }
3743 },
3744 #ifdef CONFIG_AUTOSCAN
3745 { "AutoScan", WPAS_DBUS_NEW_IFACE_INTERFACE,
3746 (WPADBusMethodHandler) wpas_dbus_handler_autoscan,
3747 {
3748 { "arg", "s", ARG_IN },
3749 END_ARGS
3750 }
3751 },
3752 #endif /* CONFIG_AUTOSCAN */
3753 #ifdef CONFIG_TDLS
3754 { "TDLSDiscover", WPAS_DBUS_NEW_IFACE_INTERFACE,
3755 (WPADBusMethodHandler) wpas_dbus_handler_tdls_discover,
3756 {
3757 { "peer_address", "s", ARG_IN },
3758 END_ARGS
3759 }
3760 },
3761 { "TDLSSetup", WPAS_DBUS_NEW_IFACE_INTERFACE,
3762 (WPADBusMethodHandler) wpas_dbus_handler_tdls_setup,
3763 {
3764 { "peer_address", "s", ARG_IN },
3765 END_ARGS
3766 }
3767 },
3768 { "TDLSStatus", WPAS_DBUS_NEW_IFACE_INTERFACE,
3769 (WPADBusMethodHandler) wpas_dbus_handler_tdls_status,
3770 {
3771 { "peer_address", "s", ARG_IN },
3772 { "status", "s", ARG_OUT },
3773 END_ARGS
3774 }
3775 },
3776 { "TDLSTeardown", WPAS_DBUS_NEW_IFACE_INTERFACE,
3777 (WPADBusMethodHandler) wpas_dbus_handler_tdls_teardown,
3778 {
3779 { "peer_address", "s", ARG_IN },
3780 END_ARGS
3781 }
3782 },
3783 { "TDLSChannelSwitch", WPAS_DBUS_NEW_IFACE_INTERFACE,
3784 (WPADBusMethodHandler) wpas_dbus_handler_tdls_channel_switch,
3785 {
3786 { "args", "a{sv}", ARG_IN },
3787 END_ARGS
3788 }
3789 },
3790 { "TDLSCancelChannelSwitch", WPAS_DBUS_NEW_IFACE_INTERFACE,
3791 (WPADBusMethodHandler) wpas_dbus_handler_tdls_cancel_channel_switch,
3792 {
3793 { "peer_address", "s", ARG_IN },
3794 END_ARGS
3795 }
3796 },
3797 #endif /* CONFIG_TDLS */
3798 { "VendorElemAdd", WPAS_DBUS_NEW_IFACE_INTERFACE,
3799 (WPADBusMethodHandler) wpas_dbus_handler_vendor_elem_add,
3800 {
3801 { "frame_id", "i", ARG_IN },
3802 { "ielems", "ay", ARG_IN },
3803 END_ARGS
3804 }
3805 },
3806 { "VendorElemGet", WPAS_DBUS_NEW_IFACE_INTERFACE,
3807 (WPADBusMethodHandler) wpas_dbus_handler_vendor_elem_get,
3808 {
3809 { "frame_id", "i", ARG_IN },
3810 { "ielems", "ay", ARG_OUT },
3811 END_ARGS
3812 }
3813 },
3814 { "VendorElemRem", WPAS_DBUS_NEW_IFACE_INTERFACE,
3815 (WPADBusMethodHandler) wpas_dbus_handler_vendor_elem_remove,
3816 {
3817 { "frame_id", "i", ARG_IN },
3818 { "ielems", "ay", ARG_IN },
3819 END_ARGS
3820 }
3821 },
3822 #ifndef CONFIG_NO_CONFIG_WRITE
3823 { "SaveConfig", WPAS_DBUS_NEW_IFACE_INTERFACE,
3824 (WPADBusMethodHandler) wpas_dbus_handler_save_config,
3825 {
3826 END_ARGS
3827 }
3828 },
3829 #endif /* CONFIG_NO_CONFIG_WRITE */
3830 { "AbortScan", WPAS_DBUS_NEW_IFACE_INTERFACE,
3831 (WPADBusMethodHandler) wpas_dbus_handler_abort_scan,
3832 {
3833 END_ARGS
3834 }
3835 },
3836 #ifdef CONFIG_INTERWORKING
3837 { "AddCred", WPAS_DBUS_NEW_IFACE_INTERFACE,
3838 (WPADBusMethodHandler) wpas_dbus_handler_add_cred,
3839 {
3840 { "args", "a{sv}", ARG_IN },
3841 { "path", "o", ARG_OUT },
3842 END_ARGS
3843 }
3844 },
3845 { "RemoveCred", WPAS_DBUS_NEW_IFACE_INTERFACE,
3846 (WPADBusMethodHandler) wpas_dbus_handler_remove_cred,
3847 {
3848 { "path", "o", ARG_IN },
3849 END_ARGS
3850 }
3851 },
3852 { "RemoveAllCreds", WPAS_DBUS_NEW_IFACE_INTERFACE,
3853 (WPADBusMethodHandler) wpas_dbus_handler_remove_all_creds,
3854 {
3855 END_ARGS
3856 }
3857 },
3858 { "InterworkingSelect", WPAS_DBUS_NEW_IFACE_INTERFACE,
3859 (WPADBusMethodHandler) wpas_dbus_handler_interworking_select,
3860 {
3861 END_ARGS
3862 }
3863 },
3864 {"ANQPGet", WPAS_DBUS_NEW_IFACE_INTERFACE,
3865 (WPADBusMethodHandler) wpas_dbus_handler_anqp_get,
3866 {
3867 { "args", "a{sv}", ARG_IN },
3868 END_ARGS
3869 },
3870 },
3871 #endif /* CONFIG_INTERWORKING */
3872 #ifdef CONFIG_NAN_USD
3873 { "NANPublish", WPAS_DBUS_NEW_IFACE_INTERFACE,
3874 (WPADBusMethodHandler) wpas_dbus_handler_nan_publish,
3875 {
3876 { "args", "a{sv}", ARG_IN },
3877 { "publish_id", "u", ARG_OUT },
3878 END_ARGS
3879 }
3880 },
3881 { "NANCancelPublish", WPAS_DBUS_NEW_IFACE_INTERFACE,
3882 (WPADBusMethodHandler) wpas_dbus_handler_nan_cancel_publish,
3883 {
3884 { "publish_id", "u", ARG_IN },
3885 END_ARGS
3886 }
3887 },
3888 { "NANUpdatePublish", WPAS_DBUS_NEW_IFACE_INTERFACE,
3889 (WPADBusMethodHandler) wpas_dbus_handler_nan_update_publish,
3890 {
3891 { "args", "a{sv}", ARG_IN },
3892 END_ARGS
3893 }
3894 },
3895 { "NANPublishStopListen", WPAS_DBUS_NEW_IFACE_INTERFACE,
3896 (WPADBusMethodHandler) wpas_dbus_handler_nan_publish_stop_listen,
3897 {
3898 { "publish_id", "u", ARG_IN },
3899 END_ARGS
3900 }
3901 },
3902 { "NANSubscribe", WPAS_DBUS_NEW_IFACE_INTERFACE,
3903 (WPADBusMethodHandler) wpas_dbus_handler_nan_subscribe,
3904 {
3905 { "args", "a{sv}", ARG_IN },
3906 { "subscribe_id", "u", ARG_OUT },
3907 END_ARGS
3908 }
3909 },
3910 { "NANCancelSubscribe", WPAS_DBUS_NEW_IFACE_INTERFACE,
3911 (WPADBusMethodHandler) wpas_dbus_handler_nan_cancel_subscribe,
3912 {
3913 { "subscribe_id", "u", ARG_IN },
3914 END_ARGS
3915 }
3916 },
3917 { "NANSubscribeStopListen", WPAS_DBUS_NEW_IFACE_INTERFACE,
3918 (WPADBusMethodHandler) wpas_dbus_handler_nan_subscribe_stop_listen,
3919 {
3920 { "subscribe_id", "u", ARG_IN },
3921 END_ARGS
3922 }
3923 },
3924 { "NANTransmit", WPAS_DBUS_NEW_IFACE_INTERFACE,
3925 (WPADBusMethodHandler) wpas_dbus_handler_nan_transmit,
3926 {
3927 { "args", "a{sv}", ARG_IN },
3928 END_ARGS
3929 }
3930 },
3931 #endif /* CONFIG_NAN_USD */
3932 { NULL, NULL, NULL, { END_ARGS } }
3933 };
3934
3935 static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = {
3936 { "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}",
3937 wpas_dbus_getter_capabilities,
3938 NULL,
3939 NULL
3940 },
3941 { "State", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3942 wpas_dbus_getter_state,
3943 NULL,
3944 NULL
3945 },
3946 { "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
3947 wpas_dbus_getter_scanning,
3948 NULL,
3949 NULL
3950 },
3951 { "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
3952 wpas_dbus_getter_ap_scan,
3953 wpas_dbus_setter_ap_scan,
3954 NULL
3955 },
3956 { "BSSExpireAge", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
3957 wpas_dbus_getter_bss_expire_age,
3958 wpas_dbus_setter_bss_expire_age,
3959 NULL
3960 },
3961 { "BSSExpireCount", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
3962 wpas_dbus_getter_bss_expire_count,
3963 wpas_dbus_setter_bss_expire_count,
3964 NULL
3965 },
3966 { "Country", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3967 wpas_dbus_getter_country,
3968 wpas_dbus_setter_country,
3969 NULL
3970 },
3971 { "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3972 wpas_dbus_getter_ifname,
3973 NULL,
3974 NULL
3975 },
3976 { "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3977 wpas_dbus_getter_driver,
3978 NULL,
3979 NULL
3980 },
3981 { "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3982 wpas_dbus_getter_bridge_ifname,
3983 wpas_dbus_setter_bridge_ifname,
3984 NULL
3985 },
3986 { "ConfigFile", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
3987 wpas_dbus_getter_config_file,
3988 NULL,
3989 NULL
3990 },
3991 { "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
3992 wpas_dbus_getter_current_bss,
3993 NULL,
3994 NULL
3995 },
3996 { "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
3997 wpas_dbus_getter_current_network,
3998 NULL,
3999 NULL
4000 },
4001 { "CurrentAuthMode", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
4002 wpas_dbus_getter_current_auth_mode,
4003 NULL,
4004 NULL
4005 },
4006 { "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{say}",
4007 wpas_dbus_getter_blobs,
4008 NULL,
4009 NULL
4010 },
4011 { "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
4012 wpas_dbus_getter_bsss,
4013 NULL,
4014 NULL
4015 },
4016 { "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
4017 wpas_dbus_getter_networks,
4018 NULL,
4019 NULL
4020 },
4021 { "FastReauth", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
4022 wpas_dbus_getter_fast_reauth,
4023 wpas_dbus_setter_fast_reauth,
4024 NULL
4025 },
4026 { "ScanInterval", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
4027 wpas_dbus_getter_scan_interval,
4028 wpas_dbus_setter_scan_interval,
4029 NULL
4030 },
4031 { "PKCS11EnginePath", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
4032 wpas_dbus_getter_pkcs11_engine_path,
4033 NULL,
4034 NULL
4035 },
4036 { "PKCS11ModulePath", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
4037 wpas_dbus_getter_pkcs11_module_path,
4038 NULL,
4039 NULL
4040 },
4041 #ifdef CONFIG_WPS
4042 { "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b",
4043 wpas_dbus_getter_process_credentials,
4044 wpas_dbus_setter_process_credentials,
4045 NULL
4046 },
4047 { "ConfigMethods", WPAS_DBUS_NEW_IFACE_WPS, "s",
4048 wpas_dbus_getter_config_methods,
4049 wpas_dbus_setter_config_methods,
4050 NULL
4051 },
4052 {
4053 "DeviceName", WPAS_DBUS_NEW_IFACE_WPS, "s",
4054 wpas_dbus_getter_wps_device_name,
4055 wpas_dbus_setter_wps_device_name,
4056 NULL
4057 },
4058 {
4059 "Manufacturer", WPAS_DBUS_NEW_IFACE_WPS, "s",
4060 wpas_dbus_getter_wps_manufacturer,
4061 wpas_dbus_setter_wps_manufacturer,
4062 NULL
4063 },
4064 {
4065 "ModelName", WPAS_DBUS_NEW_IFACE_WPS, "s",
4066 wpas_dbus_getter_wps_device_model_name,
4067 wpas_dbus_setter_wps_device_model_name,
4068 NULL
4069 },
4070 {
4071 "ModelNumber", WPAS_DBUS_NEW_IFACE_WPS, "s",
4072 wpas_dbus_getter_wps_device_model_number,
4073 wpas_dbus_setter_wps_device_model_number,
4074 NULL
4075 },
4076 {
4077 "SerialNumber", WPAS_DBUS_NEW_IFACE_WPS, "s",
4078 wpas_dbus_getter_wps_device_serial_number,
4079 wpas_dbus_setter_wps_device_serial_number,
4080 NULL
4081 },
4082 {
4083 "DeviceType", WPAS_DBUS_NEW_IFACE_WPS, "ay",
4084 wpas_dbus_getter_wps_device_device_type,
4085 wpas_dbus_setter_wps_device_device_type,
4086 NULL
4087 },
4088 #endif /* CONFIG_WPS */
4089 #ifdef CONFIG_P2P
4090 { "P2PDeviceConfig", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "a{sv}",
4091 wpas_dbus_getter_p2p_device_config,
4092 wpas_dbus_setter_p2p_device_config,
4093 NULL
4094 },
4095 { "DeviceAddress", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ay",
4096 wpas_dbus_getter_p2p_device_address,
4097 NULL,
4098 NULL
4099 },
4100 { "Peers", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
4101 wpas_dbus_getter_p2p_peers,
4102 NULL,
4103 NULL
4104 },
4105 { "Role", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "s",
4106 wpas_dbus_getter_p2p_role,
4107 NULL,
4108 NULL
4109 },
4110 { "Group", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
4111 wpas_dbus_getter_p2p_group,
4112 NULL,
4113 NULL
4114 },
4115 { "PeerGO", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
4116 wpas_dbus_getter_p2p_peergo,
4117 NULL,
4118 NULL
4119 },
4120 { "PersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
4121 wpas_dbus_getter_persistent_groups,
4122 NULL,
4123 NULL
4124 },
4125 #endif /* CONFIG_P2P */
4126 { "DisconnectReason", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
4127 wpas_dbus_getter_disconnect_reason,
4128 NULL,
4129 NULL
4130 },
4131 { "AuthStatusCode", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
4132 wpas_dbus_getter_auth_status_code,
4133 NULL,
4134 NULL
4135 },
4136 { "AssocStatusCode", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
4137 wpas_dbus_getter_assoc_status_code,
4138 NULL,
4139 NULL
4140 },
4141 {
4142 "RoamTime", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
4143 wpas_dbus_getter_roam_time,
4144 NULL,
4145 NULL
4146 },
4147 {
4148 "RoamComplete", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
4149 wpas_dbus_getter_roam_complete,
4150 NULL,
4151 NULL
4152 },
4153 {
4154 "ScanInProgress6GHz", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
4155 wpas_dbus_getter_scan_in_progress_6ghz,
4156 NULL,
4157 NULL
4158 },
4159 {
4160 "SessionLength", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
4161 wpas_dbus_getter_session_length,
4162 NULL,
4163 NULL
4164 },
4165 {
4166 "BSSTMStatus", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
4167 wpas_dbus_getter_bss_tm_status,
4168 NULL,
4169 NULL
4170 },
4171 #ifdef CONFIG_MESH
4172 { "MeshPeers", WPAS_DBUS_NEW_IFACE_MESH, "aay",
4173 wpas_dbus_getter_mesh_peers,
4174 NULL,
4175 NULL
4176 },
4177 { "MeshGroup", WPAS_DBUS_NEW_IFACE_MESH, "ay",
4178 wpas_dbus_getter_mesh_group,
4179 NULL,
4180 NULL
4181 },
4182 #endif /* CONFIG_MESH */
4183 { "Stations", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
4184 wpas_dbus_getter_stas,
4185 NULL,
4186 NULL
4187 },
4188 { "MACAddressRandomizationMask", WPAS_DBUS_NEW_IFACE_INTERFACE,
4189 "a{say}",
4190 wpas_dbus_getter_mac_address_randomization_mask,
4191 wpas_dbus_setter_mac_address_randomization_mask,
4192 NULL
4193 },
4194 { "MACAddress", WPAS_DBUS_NEW_IFACE_INTERFACE, "ay",
4195 wpas_dbus_getter_mac_address,
4196 NULL,
4197 NULL,
4198 },
4199 { "SignalChange", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}",
4200 wpas_dbus_getter_signal_change,
4201 NULL,
4202 NULL
4203 },
4204 { NULL, NULL, NULL, NULL, NULL, NULL }
4205 };
4206
4207 static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = {
4208 { "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE,
4209 {
4210 { "success", "b", ARG_OUT },
4211 END_ARGS
4212 }
4213 },
4214 { "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
4215 {
4216 { "path", "o", ARG_OUT },
4217 { "properties", "a{sv}", ARG_OUT },
4218 END_ARGS
4219 }
4220 },
4221 { "BSSRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
4222 {
4223 { "path", "o", ARG_OUT },
4224 END_ARGS
4225 }
4226 },
4227 { "BlobAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
4228 {
4229 { "name", "s", ARG_OUT },
4230 END_ARGS
4231 }
4232 },
4233 { "BlobRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
4234 {
4235 { "name", "s", ARG_OUT },
4236 END_ARGS
4237 }
4238 },
4239 { "NetworkAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
4240 {
4241 { "path", "o", ARG_OUT },
4242 { "properties", "a{sv}", ARG_OUT },
4243 END_ARGS
4244 }
4245 },
4246 { "NetworkRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
4247 {
4248 { "path", "o", ARG_OUT },
4249 END_ARGS
4250 }
4251 },
4252 { "NetworkSelected", WPAS_DBUS_NEW_IFACE_INTERFACE,
4253 {
4254 { "path", "o", ARG_OUT },
4255 END_ARGS
4256 }
4257 },
4258 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
4259 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE,
4260 {
4261 { "properties", "a{sv}", ARG_OUT },
4262 END_ARGS
4263 }
4264 },
4265 #ifdef CONFIG_WPS
4266 { "Event", WPAS_DBUS_NEW_IFACE_WPS,
4267 {
4268 { "name", "s", ARG_OUT },
4269 { "args", "a{sv}", ARG_OUT },
4270 END_ARGS
4271 }
4272 },
4273 { "Credentials", WPAS_DBUS_NEW_IFACE_WPS,
4274 {
4275 { "credentials", "a{sv}", ARG_OUT },
4276 END_ARGS
4277 }
4278 },
4279 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
4280 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS,
4281 {
4282 { "properties", "a{sv}", ARG_OUT },
4283 END_ARGS
4284 }
4285 },
4286 #endif /* CONFIG_WPS */
4287 #ifdef CONFIG_P2P
4288 { "DeviceFound", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4289 {
4290 { "path", "o", ARG_OUT },
4291 END_ARGS
4292 }
4293 },
4294 { "DeviceFoundProperties", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4295 {
4296 { "path", "o", ARG_OUT },
4297 { "properties", "a{sv}", ARG_OUT },
4298 END_ARGS
4299 }
4300 },
4301 { "DeviceLost", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4302 {
4303 { "path", "o", ARG_OUT },
4304 END_ARGS
4305 }
4306 },
4307 { "FindStopped", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4308 {
4309 END_ARGS
4310 }
4311 },
4312 { "ProvisionDiscoveryRequestDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4313 {
4314 { "peer_object", "o", ARG_OUT },
4315 { "pin", "s", ARG_OUT },
4316 END_ARGS
4317 }
4318 },
4319 { "ProvisionDiscoveryResponseDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4320 {
4321 { "peer_object", "o", ARG_OUT },
4322 { "pin", "s", ARG_OUT },
4323 END_ARGS
4324 }
4325 },
4326 { "ProvisionDiscoveryRequestEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4327 {
4328 { "peer_object", "o", ARG_OUT },
4329 END_ARGS
4330 }
4331 },
4332 { "ProvisionDiscoveryResponseEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4333 {
4334 { "peer_object", "o", ARG_OUT },
4335 END_ARGS
4336 }
4337 },
4338 { "ProvisionDiscoveryPBCRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4339 {
4340 { "peer_object", "o", ARG_OUT },
4341 END_ARGS
4342 }
4343 },
4344 { "ProvisionDiscoveryPBCResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4345 {
4346 { "peer_object", "o", ARG_OUT },
4347 END_ARGS
4348 }
4349 },
4350 { "ProvisionDiscoveryFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4351 {
4352 { "peer_object", "o", ARG_OUT },
4353 { "status", "i", ARG_OUT },
4354 END_ARGS
4355 }
4356 },
4357 { "GroupStarted", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4358 {
4359 { "properties", "a{sv}", ARG_OUT },
4360 END_ARGS
4361 }
4362 },
4363 { "GroupFormationFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4364 {
4365 { "reason", "s", ARG_OUT },
4366 END_ARGS
4367 }
4368 },
4369 { "GONegotiationSuccess", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4370 {
4371 { "properties", "a{sv}", ARG_OUT },
4372 END_ARGS
4373 }
4374 },
4375 { "GONegotiationFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4376 {
4377 { "properties", "a{sv}", ARG_OUT },
4378 END_ARGS
4379 }
4380 },
4381 { "GONegotiationRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4382 {
4383 { "path", "o", ARG_OUT },
4384 { "dev_passwd_id", "q", ARG_OUT },
4385 { "device_go_intent", "y", ARG_OUT },
4386 END_ARGS
4387 }
4388 },
4389 { "InvitationResult", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4390 {
4391 { "invite_result", "a{sv}", ARG_OUT },
4392 END_ARGS
4393 }
4394 },
4395 { "GroupFinished", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4396 {
4397 { "properties", "a{sv}", ARG_OUT },
4398 END_ARGS
4399 }
4400 },
4401 { "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4402 {
4403 { "sd_request", "a{sv}", ARG_OUT },
4404 END_ARGS
4405 }
4406 },
4407 { "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4408 {
4409 { "sd_response", "a{sv}", ARG_OUT },
4410 END_ARGS
4411 }
4412 },
4413 { "PersistentGroupAdded", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4414 {
4415 { "path", "o", ARG_OUT },
4416 { "properties", "a{sv}", ARG_OUT },
4417 END_ARGS
4418 }
4419 },
4420 { "PersistentGroupRemoved", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4421 {
4422 { "path", "o", ARG_OUT },
4423 END_ARGS
4424 }
4425 },
4426 { "WpsFailed", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4427 {
4428 { "name", "s", ARG_OUT },
4429 { "args", "a{sv}", ARG_OUT },
4430 END_ARGS
4431 }
4432 },
4433 { "InvitationReceived", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4434 {
4435 { "properties", "a{sv}", ARG_OUT },
4436 END_ARGS
4437 }
4438 },
4439 { "BootstrappingRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4440 {
4441 { "path", "o", ARG_OUT },
4442 { "bootstrap_method", "q", ARG_OUT },
4443 END_ARGS
4444 }
4445 },
4446 { "BootstrappingCompleted", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4447 {
4448 { "path", "o", ARG_OUT },
4449 { "status", "i", ARG_OUT },
4450 END_ARGS
4451 }
4452 },
4453 #endif /* CONFIG_P2P */
4454 #ifdef CONFIG_AP
4455 { "ProbeRequest", WPAS_DBUS_NEW_IFACE_INTERFACE,
4456 {
4457 { "args", "a{sv}", ARG_OUT },
4458 END_ARGS
4459 }
4460 },
4461 #endif /* CONFIG_AP */
4462 { "Certification", WPAS_DBUS_NEW_IFACE_INTERFACE,
4463 {
4464 { "certification", "a{sv}", ARG_OUT },
4465 END_ARGS
4466 }
4467 },
4468 { "EAP", WPAS_DBUS_NEW_IFACE_INTERFACE,
4469 {
4470 { "status", "s", ARG_OUT },
4471 { "parameter", "s", ARG_OUT },
4472 END_ARGS
4473 }
4474 },
4475 { "StaAuthorized", WPAS_DBUS_NEW_IFACE_INTERFACE,
4476 {
4477 { "name", "s", ARG_OUT },
4478 END_ARGS
4479 }
4480 },
4481 { "StaDeauthorized", WPAS_DBUS_NEW_IFACE_INTERFACE,
4482 {
4483 { "name", "s", ARG_OUT },
4484 END_ARGS
4485 }
4486 },
4487 { "StationAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
4488 {
4489 { "path", "o", ARG_OUT },
4490 { "properties", "a{sv}", ARG_OUT },
4491 END_ARGS
4492 }
4493 },
4494 { "StationRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
4495 {
4496 { "path", "o", ARG_OUT },
4497 END_ARGS
4498 }
4499 },
4500 { "NetworkRequest", WPAS_DBUS_NEW_IFACE_INTERFACE,
4501 {
4502 { "path", "o", ARG_OUT },
4503 { "field", "s", ARG_OUT },
4504 { "text", "s", ARG_OUT },
4505 END_ARGS
4506 }
4507 },
4508 #ifdef CONFIG_MESH
4509 { "MeshGroupStarted", WPAS_DBUS_NEW_IFACE_MESH,
4510 {
4511 { "args", "a{sv}", ARG_OUT },
4512 END_ARGS
4513 }
4514 },
4515 { "MeshGroupRemoved", WPAS_DBUS_NEW_IFACE_MESH,
4516 {
4517 { "args", "a{sv}", ARG_OUT },
4518 END_ARGS
4519 }
4520 },
4521 { "MeshPeerConnected", WPAS_DBUS_NEW_IFACE_MESH,
4522 {
4523 { "args", "a{sv}", ARG_OUT },
4524 END_ARGS
4525 }
4526 },
4527 { "MeshPeerDisconnected", WPAS_DBUS_NEW_IFACE_MESH,
4528 {
4529 { "args", "a{sv}", ARG_OUT },
4530 END_ARGS
4531 }
4532 },
4533 #endif /* CONFIG_MESH */
4534 #ifdef CONFIG_INTERWORKING
4535 { "InterworkingAPAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
4536 {
4537 { "bss", "o", ARG_OUT },
4538 { "cred", "o", ARG_OUT },
4539 { "properties", "a{sv}", ARG_OUT },
4540 END_ARGS
4541 }
4542 },
4543 { "InterworkingSelectDone", WPAS_DBUS_NEW_IFACE_INTERFACE,
4544 {
4545 END_ARGS
4546 }
4547 },
4548 {"ANQPQueryDone", WPAS_DBUS_NEW_IFACE_INTERFACE,
4549 {
4550 { "addr", "s", ARG_OUT },
4551 { "result", "s", ARG_OUT },
4552 END_ARGS
4553 }
4554 },
4555 #endif /* CONFIG_INTERWORKING */
4556 #ifdef CONFIG_HS20
4557 { "HS20TermsAndConditions", WPAS_DBUS_NEW_IFACE_INTERFACE,
4558 {
4559 { "url", "s", ARG_OUT },
4560 END_ARGS
4561 }
4562 },
4563 #endif /* CONFIG_HS20 */
4564 #ifdef CONFIG_NAN_USD
4565 { "NANDiscoveryResult", WPAS_DBUS_NEW_IFACE_INTERFACE,
4566 {
4567 { "args", "a{sv}", ARG_OUT },
4568 END_ARGS
4569 }
4570 },
4571 { "NANReplied", WPAS_DBUS_NEW_IFACE_INTERFACE,
4572 {
4573 { "args", "a{sv}", ARG_OUT },
4574 END_ARGS
4575 }
4576 },
4577 { "NANReceive", WPAS_DBUS_NEW_IFACE_INTERFACE,
4578 {
4579 { "args", "a{sv}", ARG_OUT },
4580 END_ARGS
4581 }
4582 },
4583 { "NANPublishTerminated", WPAS_DBUS_NEW_IFACE_INTERFACE,
4584 {
4585 { "publish_id", "u", ARG_OUT },
4586 { "reason", "s", ARG_OUT },
4587 END_ARGS
4588 }
4589 },
4590 { "NANSubscribeTerminated", WPAS_DBUS_NEW_IFACE_INTERFACE,
4591 {
4592 { "subscribe_id", "u", ARG_OUT },
4593 { "reason", "s", ARG_OUT },
4594 END_ARGS
4595 }
4596 },
4597 #endif /* CONFIG_NAN_USD */
4598 { NULL, NULL, { END_ARGS } }
4599 };
4600
4601
wpa_dbus_ctrl_iface_props_init(struct wpas_dbus_priv * priv)4602 static int wpa_dbus_ctrl_iface_props_init(struct wpas_dbus_priv *priv)
4603 {
4604 size_t all_size;
4605 unsigned int i, j, count, num_const, num_globals;
4606 const char *global_name;
4607 static const char * const ignored_globals[] = {
4608 "bss_expiration_age", "bss_expiration_scan_count",
4609 "ap_scan", "country", "fast_reauth",
4610 "pkcs11_engine_path", "pkcs11_module_path"
4611 };
4612
4613 /* wpas_dbus_interface_properties terminates with a NULL element */
4614 num_const = ARRAY_SIZE(wpas_dbus_interface_properties) - 1;
4615
4616 num_globals = wpa_config_get_num_global_field_names();
4617 priv->globals_start = num_const;
4618
4619 /* allocate enough for all properties + terminating NULL element */
4620 all_size = (num_globals + num_const + 1) *
4621 sizeof(wpas_dbus_interface_properties[0]);
4622 priv->all_interface_properties = os_zalloc(all_size);
4623 if (!priv->all_interface_properties) {
4624 wpa_printf(MSG_ERROR,
4625 "dbus: Not enough memory for interface properties");
4626 return -1;
4627 }
4628
4629 /* Copy constant interface properties to the start of the array */
4630 os_memcpy(priv->all_interface_properties,
4631 wpas_dbus_interface_properties,
4632 sizeof(wpas_dbus_interface_properties));
4633
4634 /* Dynamically construct interface global properties */
4635 for (i = 0, count = num_const; i < num_globals; i++) {
4636 struct wpa_dbus_property_desc *desc;
4637 int no_var = 0;
4638
4639 /* ignore globals that are actually just methods */
4640 global_name = wpa_config_get_global_field_name(i, &no_var);
4641 if (no_var)
4642 continue;
4643 /* Ignore fields already explicitly exposed */
4644 for (j = 0; j < ARRAY_SIZE(ignored_globals); j++) {
4645 if (os_strcmp(global_name, ignored_globals[j]) == 0)
4646 break;
4647 }
4648 if (j < ARRAY_SIZE(ignored_globals))
4649 continue;
4650
4651 desc = &priv->all_interface_properties[count++];
4652 desc->dbus_property = uscore_to_dbus(global_name);
4653 if (!desc->dbus_property) {
4654 wpa_printf(MSG_ERROR,
4655 "dbus: Not enough memory for D-Bus property name");
4656 goto error;
4657 }
4658 desc->dbus_interface = WPAS_DBUS_NEW_IFACE_INTERFACE;
4659 desc->type = "s";
4660 desc->getter = wpas_dbus_getter_iface_global;
4661 desc->setter = wpas_dbus_setter_iface_global;
4662 desc->data = global_name;
4663 }
4664
4665 return 0;
4666
4667 error:
4668 wpa_dbus_ctrl_iface_props_deinit(priv);
4669 return -1;
4670 }
4671
4672
4673 /**
4674 * wpas_dbus_register_interface - Register an interface with D-Bus
4675 * @wpa_s: wpa_supplicant interface structure
4676 * Returns: 0 on success, -1 on failure
4677 */
wpas_dbus_register_interface(struct wpa_supplicant * wpa_s)4678 int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s)
4679 {
4680 struct wpa_dbus_object_desc *obj_desc = NULL;
4681 struct wpas_dbus_priv *ctrl_iface = wpa_s->global->dbus;
4682 int next;
4683
4684 /* Do nothing if the control interface is not turned on */
4685 if (ctrl_iface == NULL)
4686 return 0;
4687
4688 /* Create and set the interface's object path */
4689 wpa_s->dbus_new_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
4690 if (wpa_s->dbus_new_path == NULL)
4691 return -1;
4692 next = ctrl_iface->next_objid++;
4693 os_snprintf(wpa_s->dbus_new_path, WPAS_DBUS_OBJECT_PATH_MAX,
4694 WPAS_DBUS_NEW_PATH_INTERFACES "/%u",
4695 next);
4696
4697 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
4698 if (!obj_desc) {
4699 wpa_printf(MSG_ERROR,
4700 "Not enough memory to create object description");
4701 goto err;
4702 }
4703
4704 wpas_dbus_register(obj_desc, wpa_s, NULL, wpas_dbus_interface_methods,
4705 ctrl_iface->all_interface_properties,
4706 wpas_dbus_interface_signals);
4707
4708 wpa_printf(MSG_DEBUG, "dbus: Register interface object '%s'",
4709 wpa_s->dbus_new_path);
4710 if (wpa_dbus_register_object_per_iface(ctrl_iface,
4711 wpa_s->dbus_new_path,
4712 wpa_s->ifname, obj_desc))
4713 goto err;
4714
4715 wpas_dbus_signal_interface_added(wpa_s);
4716
4717 return 0;
4718
4719 err:
4720 os_free(wpa_s->dbus_new_path);
4721 wpa_s->dbus_new_path = NULL;
4722 free_dbus_object_desc(obj_desc);
4723 return -1;
4724 }
4725
4726
4727 /**
4728 * wpas_dbus_unregister_interface - Unregister the interface from D-Bus
4729 * @wpa_s: wpa_supplicant interface structure
4730 * Returns: 0 on success, -1 on failure
4731 */
wpas_dbus_unregister_interface(struct wpa_supplicant * wpa_s)4732 int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s)
4733 {
4734 struct wpas_dbus_priv *ctrl_iface;
4735
4736 /* Do nothing if the control interface is not turned on */
4737 if (wpa_s == NULL || wpa_s->global == NULL)
4738 return 0;
4739 ctrl_iface = wpa_s->global->dbus;
4740 if (ctrl_iface == NULL || wpa_s->dbus_new_path == NULL)
4741 return 0;
4742
4743 wpa_printf(MSG_DEBUG, "dbus: Unregister interface object '%s'",
4744 wpa_s->dbus_new_path);
4745
4746 #ifdef CONFIG_AP
4747 if (wpa_s->preq_notify_peer) {
4748 wpas_dbus_unsubscribe_noc(ctrl_iface);
4749 os_free(wpa_s->preq_notify_peer);
4750 wpa_s->preq_notify_peer = NULL;
4751 }
4752 #endif /* CONFIG_AP */
4753
4754 if (wpa_dbus_unregister_object_per_iface(ctrl_iface,
4755 wpa_s->dbus_new_path))
4756 return -1;
4757
4758 wpas_dbus_signal_interface_removed(wpa_s);
4759
4760 os_free(wpa_s->dbus_new_path);
4761 wpa_s->dbus_new_path = NULL;
4762
4763 return 0;
4764 }
4765
4766 #ifdef CONFIG_P2P
4767
4768 static const struct wpa_dbus_property_desc wpas_dbus_p2p_peer_properties[] = {
4769 { "DeviceName", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
4770 wpas_dbus_getter_p2p_peer_device_name,
4771 NULL,
4772 NULL
4773 },
4774 { "Manufacturer", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
4775 wpas_dbus_getter_p2p_peer_manufacturer,
4776 NULL,
4777 NULL
4778 },
4779 { "ModelName", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
4780 wpas_dbus_getter_p2p_peer_modelname,
4781 NULL,
4782 NULL
4783 },
4784 { "ModelNumber", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
4785 wpas_dbus_getter_p2p_peer_modelnumber,
4786 NULL,
4787 NULL
4788 },
4789 { "SerialNumber", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
4790 wpas_dbus_getter_p2p_peer_serialnumber,
4791 NULL,
4792 NULL
4793 },
4794 { "PrimaryDeviceType", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
4795 wpas_dbus_getter_p2p_peer_primary_device_type,
4796 NULL,
4797 NULL
4798 },
4799 { "config_method", WPAS_DBUS_NEW_IFACE_P2P_PEER, "q",
4800 wpas_dbus_getter_p2p_peer_config_method,
4801 NULL,
4802 NULL
4803 },
4804 { "level", WPAS_DBUS_NEW_IFACE_P2P_PEER, "i",
4805 wpas_dbus_getter_p2p_peer_level,
4806 NULL,
4807 NULL
4808 },
4809 { "devicecapability", WPAS_DBUS_NEW_IFACE_P2P_PEER, "y",
4810 wpas_dbus_getter_p2p_peer_device_capability,
4811 NULL,
4812 NULL
4813 },
4814 { "groupcapability", WPAS_DBUS_NEW_IFACE_P2P_PEER, "y",
4815 wpas_dbus_getter_p2p_peer_group_capability,
4816 NULL,
4817 NULL
4818 },
4819 { "SecondaryDeviceTypes", WPAS_DBUS_NEW_IFACE_P2P_PEER, "aay",
4820 wpas_dbus_getter_p2p_peer_secondary_device_types,
4821 NULL,
4822 NULL
4823 },
4824 { "VendorExtension", WPAS_DBUS_NEW_IFACE_P2P_PEER, "aay",
4825 wpas_dbus_getter_p2p_peer_vendor_extension,
4826 NULL,
4827 NULL
4828 },
4829 { "IEs", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
4830 wpas_dbus_getter_p2p_peer_ies,
4831 NULL,
4832 NULL
4833 },
4834 { "DeviceAddress", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
4835 wpas_dbus_getter_p2p_peer_device_address,
4836 NULL,
4837 NULL
4838 },
4839 { "Groups", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ao",
4840 wpas_dbus_getter_p2p_peer_groups,
4841 NULL,
4842 NULL
4843 },
4844 { "VSIE", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
4845 wpas_dbus_getter_p2p_peer_vsie,
4846 NULL,
4847 NULL
4848 },
4849 { NULL, NULL, NULL, NULL, NULL, NULL }
4850 };
4851
4852 static const struct wpa_dbus_signal_desc wpas_dbus_p2p_peer_signals[] = {
4853 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
4854 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_P2P_PEER,
4855 {
4856 { "properties", "a{sv}", ARG_OUT },
4857 END_ARGS
4858 }
4859 },
4860 { NULL, NULL, { END_ARGS } }
4861 };
4862
4863 /**
4864 * wpas_dbus_signal_peer - Send a peer related event signal
4865 * @wpa_s: %wpa_supplicant network interface data
4866 * @dev: peer device object
4867 * @interface: name of the interface emitting this signal.
4868 * In case of peer objects, it would be emitted by either
4869 * the "interface object" or by "peer objects"
4870 * @sig_name: signal name - DeviceFound
4871 * @properties: Whether to add a second argument with object properties
4872 *
4873 * Notify listeners about event related with p2p peer device
4874 */
wpas_dbus_signal_peer(struct wpa_supplicant * wpa_s,const u8 * dev_addr,const char * interface,const char * sig_name,dbus_bool_t properties)4875 static void wpas_dbus_signal_peer(struct wpa_supplicant *wpa_s,
4876 const u8 *dev_addr, const char *interface,
4877 const char *sig_name, dbus_bool_t properties)
4878 {
4879 struct wpas_dbus_priv *iface;
4880 DBusMessage *msg;
4881 DBusMessageIter iter;
4882 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
4883
4884 if (wpa_s->p2p_mgmt)
4885 wpa_s = wpa_s->parent;
4886
4887 iface = wpa_s->global->dbus;
4888
4889 /* Do nothing if the control interface is not turned on */
4890 if (iface == NULL || !wpa_s->dbus_new_path)
4891 return;
4892
4893 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
4894 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
4895 wpa_s->dbus_new_path, MAC2STR(dev_addr));
4896
4897 msg = dbus_message_new_signal(wpa_s->dbus_new_path, interface,
4898 sig_name);
4899 if (msg == NULL)
4900 return;
4901
4902 dbus_message_iter_init_append(msg, &iter);
4903 path = peer_obj_path;
4904 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
4905 &path) ||
4906 (properties && !wpa_dbus_get_object_properties(
4907 iface, peer_obj_path, WPAS_DBUS_NEW_IFACE_P2P_PEER,
4908 &iter)))
4909 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
4910 else
4911 dbus_connection_send(iface->con, msg, NULL);
4912
4913 dbus_message_unref(msg);
4914 }
4915
4916
4917 /**
4918 * wpas_dbus_signal_peer_found - Send a peer found signal
4919 * @wpa_s: %wpa_supplicant network interface data
4920 * @dev_addr: Peer P2P Device Address
4921 *
4922 * Notify listeners about find a p2p peer device found
4923 */
wpas_dbus_signal_peer_device_found(struct wpa_supplicant * wpa_s,const u8 * dev_addr)4924 void wpas_dbus_signal_peer_device_found(struct wpa_supplicant *wpa_s,
4925 const u8 *dev_addr)
4926 {
4927 wpas_dbus_signal_peer(wpa_s, dev_addr,
4928 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4929 "DeviceFound", FALSE);
4930
4931 wpas_dbus_signal_peer(wpa_s, dev_addr,
4932 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4933 "DeviceFoundProperties", TRUE);
4934 }
4935
4936 /**
4937 * wpas_dbus_signal_peer_lost - Send a peer lost signal
4938 * @wpa_s: %wpa_supplicant network interface data
4939 * @dev_addr: Peer P2P Device Address
4940 *
4941 * Notify listeners about lost a p2p peer device
4942 */
wpas_dbus_signal_peer_device_lost(struct wpa_supplicant * wpa_s,const u8 * dev_addr)4943 void wpas_dbus_signal_peer_device_lost(struct wpa_supplicant *wpa_s,
4944 const u8 *dev_addr)
4945 {
4946 wpas_dbus_signal_peer(wpa_s, dev_addr,
4947 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
4948 "DeviceLost", FALSE);
4949 }
4950
4951 /**
4952 * wpas_dbus_register_peer - Register a discovered peer object with dbus
4953 * @wpa_s: wpa_supplicant interface structure
4954 * @dev_addr: P2P Device Address of the peer
4955 * Returns: 0 on success, -1 on failure
4956 *
4957 * Registers network representing object with dbus
4958 */
wpas_dbus_register_peer(struct wpa_supplicant * wpa_s,const u8 * dev_addr)4959 int wpas_dbus_register_peer(struct wpa_supplicant *wpa_s, const u8 *dev_addr)
4960 {
4961 struct wpas_dbus_priv *ctrl_iface;
4962 struct wpa_dbus_object_desc *obj_desc;
4963 struct peer_handler_args *arg;
4964 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
4965
4966 /* Do nothing if the control interface is not turned on */
4967 if (wpa_s == NULL || wpa_s->global == NULL)
4968 return 0;
4969
4970 ctrl_iface = wpa_s->global->dbus;
4971 if (ctrl_iface == NULL)
4972 return 0;
4973
4974 wpa_s = wpa_s->parent->parent;
4975 if (!wpa_s->dbus_new_path)
4976 return 0;
4977
4978 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
4979 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
4980 wpa_s->dbus_new_path, MAC2STR(dev_addr));
4981
4982 wpa_printf(MSG_INFO, "dbus: Register peer object '%s'",
4983 peer_obj_path);
4984 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
4985 if (!obj_desc) {
4986 wpa_printf(MSG_ERROR,
4987 "Not enough memory to create object description");
4988 goto err;
4989 }
4990
4991 /* allocate memory for handlers arguments */
4992 arg = os_zalloc(sizeof(struct peer_handler_args));
4993 if (!arg) {
4994 wpa_printf(MSG_ERROR,
4995 "Not enough memory to create arguments for method");
4996 goto err;
4997 }
4998
4999 arg->wpa_s = wpa_s;
5000 os_memcpy(arg->p2p_device_addr, dev_addr, ETH_ALEN);
5001
5002 wpas_dbus_register(obj_desc, arg, wpa_dbus_free,
5003 NULL,
5004 wpas_dbus_p2p_peer_properties,
5005 wpas_dbus_p2p_peer_signals);
5006
5007 if (wpa_dbus_register_object_per_iface(ctrl_iface, peer_obj_path,
5008 wpa_s->ifname, obj_desc))
5009 goto err;
5010
5011 return 0;
5012
5013 err:
5014 free_dbus_object_desc(obj_desc);
5015 return -1;
5016 }
5017
5018 /**
5019 * wpas_dbus_unregister_peer - Unregister a peer object with dbus
5020 * @wpa_s: wpa_supplicant interface structure
5021 * @dev_addr: p2p device addr
5022 * Returns: 0 on success, -1 on failure
5023 *
5024 * Registers network representing object with dbus
5025 */
wpas_dbus_unregister_peer(struct wpa_supplicant * wpa_s,const u8 * dev_addr)5026 int wpas_dbus_unregister_peer(struct wpa_supplicant *wpa_s,
5027 const u8 *dev_addr)
5028 {
5029 struct wpas_dbus_priv *ctrl_iface;
5030 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
5031 int ret;
5032
5033 /* Do nothing if the control interface is not turned on */
5034 if (wpa_s == NULL || wpa_s->global == NULL)
5035 return 0;
5036
5037 wpa_s = wpa_s->parent->parent;
5038 if (!wpa_s->dbus_new_path)
5039 return 0;
5040
5041 ctrl_iface = wpa_s->global->dbus;
5042 if (ctrl_iface == NULL)
5043 return 0;
5044
5045 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
5046 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
5047 wpa_s->dbus_new_path, MAC2STR(dev_addr));
5048
5049 wpa_printf(MSG_INFO, "dbus: Unregister peer object '%s'",
5050 peer_obj_path);
5051 ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, peer_obj_path);
5052
5053 return ret;
5054 }
5055
5056
5057 /**
5058 * wpas_dbus_signal_p2p_find_stopped - Send P2P Find stopped signal
5059 * @wpa_s: %wpa_supplicant network interface data
5060 *
5061 * Notify listeners about P2P Find stopped
5062 */
wpas_dbus_signal_p2p_find_stopped(struct wpa_supplicant * wpa_s)5063 void wpas_dbus_signal_p2p_find_stopped(struct wpa_supplicant *wpa_s)
5064 {
5065 struct wpas_dbus_priv *iface;
5066 DBusMessage *msg;
5067
5068 iface = wpa_s->global->dbus;
5069
5070 /* Do nothing if the control interface is not turned on */
5071 if (iface == NULL)
5072 return;
5073
5074 if (wpa_s->p2p_mgmt)
5075 wpa_s = wpa_s->parent;
5076
5077 if (!wpa_s->dbus_new_path)
5078 return;
5079
5080 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
5081 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
5082 "FindStopped");
5083 if (msg == NULL)
5084 return;
5085
5086 dbus_connection_send(iface->con, msg, NULL);
5087
5088 dbus_message_unref(msg);
5089 }
5090
5091
5092 /**
5093 * wpas_dbus_signal_peer_groups_changed - Send peer group change property signal
5094 * @wpa_s: %wpa_supplicant network interface data
5095 * @dev_addr: P2P Device Address
5096 *
5097 * Notify listeners about peer Groups property changes.
5098 */
wpas_dbus_signal_peer_groups_changed(struct wpa_supplicant * wpa_s,const u8 * dev_addr)5099 void wpas_dbus_signal_peer_groups_changed(struct wpa_supplicant *wpa_s,
5100 const u8 *dev_addr)
5101 {
5102 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
5103
5104 if (wpa_s->p2p_mgmt)
5105 wpa_s = wpa_s->parent;
5106
5107 if (!wpa_s->dbus_new_path)
5108 return;
5109 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
5110 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
5111 wpa_s->dbus_new_path, MAC2STR(dev_addr));
5112
5113 wpa_dbus_mark_property_changed(wpa_s->global->dbus, peer_obj_path,
5114 WPAS_DBUS_NEW_IFACE_P2P_PEER, "Groups");
5115 }
5116
5117
5118 static const struct wpa_dbus_property_desc wpas_dbus_p2p_group_properties[] = {
5119 { "Members", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ao",
5120 wpas_dbus_getter_p2p_group_members,
5121 NULL,
5122 NULL
5123 },
5124 { "Group", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "o",
5125 wpas_dbus_getter_p2p_group,
5126 NULL,
5127 NULL
5128 },
5129 { "Role", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "s",
5130 wpas_dbus_getter_p2p_role,
5131 NULL,
5132 NULL
5133 },
5134 { "SSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
5135 wpas_dbus_getter_p2p_group_ssid,
5136 NULL,
5137 NULL
5138 },
5139 { "BSSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
5140 wpas_dbus_getter_p2p_group_bssid,
5141 NULL,
5142 NULL
5143 },
5144 { "Frequency", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "q",
5145 wpas_dbus_getter_p2p_group_frequency,
5146 NULL,
5147 NULL
5148 },
5149 { "Passphrase", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "s",
5150 wpas_dbus_getter_p2p_group_passphrase,
5151 NULL,
5152 NULL
5153 },
5154 { "PSK", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
5155 wpas_dbus_getter_p2p_group_psk,
5156 NULL,
5157 NULL
5158 },
5159 { "WPSVendorExtensions", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "aay",
5160 wpas_dbus_getter_p2p_group_vendor_ext,
5161 wpas_dbus_setter_p2p_group_vendor_ext,
5162 NULL
5163 },
5164 { "GODeviceAddress", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "o",
5165 wpas_dbus_getter_p2p_group_go_device_address,
5166 NULL,
5167 NULL
5168 },
5169 { NULL, NULL, NULL, NULL, NULL, NULL }
5170 };
5171
5172 static const struct wpa_dbus_signal_desc wpas_dbus_p2p_group_signals[] = {
5173 { "PeerJoined", WPAS_DBUS_NEW_IFACE_P2P_GROUP,
5174 {
5175 { "peer", "o", ARG_OUT },
5176 END_ARGS
5177 }
5178 },
5179 { "PeerDisconnected", WPAS_DBUS_NEW_IFACE_P2P_GROUP,
5180 {
5181 { "peer", "o", ARG_OUT },
5182 END_ARGS
5183 }
5184 },
5185 { NULL, NULL, { END_ARGS } }
5186 };
5187
5188 /**
5189 * wpas_dbus_register_p2p_group - Register a p2p group object with dbus
5190 * @wpa_s: wpa_supplicant interface structure
5191 * @ssid: SSID struct
5192 * Returns: 0 on success, -1 on failure
5193 *
5194 * Registers p2p group representing object with dbus
5195 */
wpas_dbus_register_p2p_group(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid)5196 void wpas_dbus_register_p2p_group(struct wpa_supplicant *wpa_s,
5197 struct wpa_ssid *ssid)
5198 {
5199 struct wpas_dbus_priv *ctrl_iface;
5200 struct wpa_dbus_object_desc *obj_desc;
5201 char group_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
5202
5203 /* Do nothing if the control interface is not turned on */
5204 if (wpa_s == NULL || wpa_s->global == NULL)
5205 return;
5206
5207 ctrl_iface = wpa_s->global->dbus;
5208 if (ctrl_iface == NULL)
5209 return;
5210
5211 if (wpa_s->dbus_groupobj_path) {
5212 wpa_printf(MSG_INFO, "%s: Group object '%s' already exists",
5213 __func__, wpa_s->dbus_groupobj_path);
5214 return;
5215 }
5216
5217 if (wpas_dbus_get_group_obj_path(wpa_s, ssid, group_obj_path) < 0)
5218 return;
5219
5220 wpa_s->dbus_groupobj_path = os_strdup(group_obj_path);
5221 if (wpa_s->dbus_groupobj_path == NULL)
5222 return;
5223
5224 wpa_printf(MSG_INFO, "dbus: Register group object '%s'",
5225 group_obj_path);
5226 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
5227 if (!obj_desc) {
5228 wpa_printf(MSG_ERROR,
5229 "Not enough memory to create object description");
5230 goto err;
5231 }
5232
5233 wpas_dbus_register(obj_desc, wpa_s, NULL, NULL,
5234 wpas_dbus_p2p_group_properties,
5235 wpas_dbus_p2p_group_signals);
5236
5237 if (wpa_dbus_register_object_per_iface(ctrl_iface, group_obj_path,
5238 wpa_s->ifname, obj_desc))
5239 goto err;
5240
5241 return;
5242
5243 err:
5244 if (wpa_s->dbus_groupobj_path) {
5245 os_free(wpa_s->dbus_groupobj_path);
5246 wpa_s->dbus_groupobj_path = NULL;
5247 }
5248
5249 free_dbus_object_desc(obj_desc);
5250 }
5251
5252 /**
5253 * wpas_dbus_unregister_p2p_group - Unregister a p2p group object from dbus
5254 * @wpa_s: wpa_supplicant interface structure
5255 * @ssid: network name of the p2p group started
5256 */
wpas_dbus_unregister_p2p_group(struct wpa_supplicant * wpa_s,const struct wpa_ssid * ssid)5257 void wpas_dbus_unregister_p2p_group(struct wpa_supplicant *wpa_s,
5258 const struct wpa_ssid *ssid)
5259 {
5260 struct wpas_dbus_priv *ctrl_iface;
5261
5262 /* Do nothing if the control interface is not turned on */
5263 if (wpa_s == NULL || wpa_s->global == NULL)
5264 return;
5265
5266 if (wpa_s->p2p_mgmt)
5267 wpa_s = wpa_s->parent;
5268
5269 ctrl_iface = wpa_s->global->dbus;
5270 if (ctrl_iface == NULL)
5271 return;
5272
5273 if (!wpa_s->dbus_groupobj_path) {
5274 wpa_printf(MSG_DEBUG,
5275 "%s: Group object has already unregistered",
5276 __func__);
5277 return;
5278 }
5279
5280 peer_groups_changed(wpa_s);
5281
5282 wpa_printf(MSG_DEBUG, "dbus: Unregister group object '%s'",
5283 wpa_s->dbus_groupobj_path);
5284
5285 wpa_dbus_unregister_object_per_iface(ctrl_iface,
5286 wpa_s->dbus_groupobj_path);
5287
5288 os_free(wpa_s->dbus_groupobj_path);
5289 wpa_s->dbus_groupobj_path = NULL;
5290 }
5291
5292 static const struct wpa_dbus_property_desc
5293 wpas_dbus_persistent_group_properties[] = {
5294 { "Properties", WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, "a{sv}",
5295 wpas_dbus_getter_persistent_group_properties,
5296 wpas_dbus_setter_persistent_group_properties,
5297 NULL
5298 },
5299 { NULL, NULL, NULL, NULL, NULL, NULL }
5300 };
5301
5302 /* No signals intended for persistent group objects */
5303
5304 /**
5305 * wpas_dbus_register_persistent_group - Register a configured(saved)
5306 * persistent group with dbus
5307 * @wpa_s: wpa_supplicant interface structure
5308 * @ssid: persistent group (still represented as a network within wpa)
5309 * configuration data
5310 * Returns: 0 on success, -1 on failure
5311 *
5312 * Registers a persistent group representing object with dbus.
5313 */
wpas_dbus_register_persistent_group(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid)5314 int wpas_dbus_register_persistent_group(struct wpa_supplicant *wpa_s,
5315 struct wpa_ssid *ssid)
5316 {
5317 struct wpas_dbus_priv *ctrl_iface;
5318 struct wpa_dbus_object_desc *obj_desc;
5319 struct network_handler_args *arg;
5320 char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
5321
5322 /* Do nothing if the control interface is not turned on */
5323 if (wpa_s == NULL || wpa_s->global == NULL)
5324 return 0;
5325 wpa_s = wpa_s->parent->parent;
5326 if (!wpa_s->dbus_new_path)
5327 return 0;
5328
5329 /* Make sure ssid is a persistent group */
5330 if (ssid->disabled != 2 && !ssid->p2p_persistent_group)
5331 return -1; /* should we return w/o complaining? */
5332
5333 if (wpa_s->p2p_mgmt)
5334 wpa_s = wpa_s->parent;
5335
5336 ctrl_iface = wpa_s->global->dbus;
5337 if (ctrl_iface == NULL)
5338 return 0;
5339
5340 /*
5341 * Intentionally not coming up with different numbering scheme
5342 * for persistent groups.
5343 */
5344 os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
5345 "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
5346 wpa_s->dbus_new_path, ssid->id);
5347
5348 wpa_printf(MSG_DEBUG, "dbus: Register persistent group object '%s'",
5349 pgrp_obj_path);
5350 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
5351 if (!obj_desc) {
5352 wpa_printf(MSG_ERROR,
5353 "dbus: Not enough memory to create object description");
5354 goto err;
5355 }
5356
5357 /*
5358 * Reusing the same context structure as that for networks
5359 * since these are represented using same data structure.
5360 */
5361 /* allocate memory for handlers arguments */
5362 arg = os_zalloc(sizeof(struct network_handler_args));
5363 if (!arg) {
5364 wpa_printf(MSG_ERROR,
5365 "dbus: Not enough memory to create arguments for method");
5366 goto err;
5367 }
5368
5369 arg->wpa_s = wpa_s;
5370 arg->ssid = ssid;
5371
5372 wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
5373 wpas_dbus_persistent_group_properties,
5374 NULL);
5375
5376 if (wpa_dbus_register_object_per_iface(ctrl_iface, pgrp_obj_path,
5377 wpa_s->ifname, obj_desc))
5378 goto err;
5379
5380 wpas_dbus_signal_persistent_group_added(wpa_s, ssid->id);
5381
5382 return 0;
5383
5384 err:
5385 free_dbus_object_desc(obj_desc);
5386 return -1;
5387 }
5388
5389
5390 /**
5391 * wpas_dbus_unregister_persistent_group - Unregister a persistent_group
5392 * from dbus
5393 * @wpa_s: wpa_supplicant interface structure
5394 * @nid: network id
5395 * Returns: 0 on success, -1 on failure
5396 *
5397 * Unregisters persistent group representing object from dbus
5398 *
5399 * NOTE: There is a slight issue with the semantics here. While the
5400 * implementation simply means the persistent group is unloaded from memory,
5401 * it should not get interpreted as the group is actually being erased/removed
5402 * from persistent storage as well.
5403 */
wpas_dbus_unregister_persistent_group(struct wpa_supplicant * wpa_s,int nid)5404 int wpas_dbus_unregister_persistent_group(struct wpa_supplicant *wpa_s,
5405 int nid)
5406 {
5407 struct wpas_dbus_priv *ctrl_iface;
5408 char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
5409 int ret;
5410
5411 /* Do nothing if the control interface is not turned on */
5412 if (wpa_s == NULL || wpa_s->global == NULL)
5413 return 0;
5414
5415 wpa_s = wpa_s->parent->parent;
5416
5417 ctrl_iface = wpa_s->global->dbus;
5418 if (ctrl_iface == NULL || !wpa_s->dbus_new_path)
5419 return 0;
5420
5421 os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
5422 "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
5423 wpa_s->dbus_new_path, nid);
5424
5425 wpa_printf(MSG_DEBUG, "dbus: Unregister persistent group object '%s'",
5426 pgrp_obj_path);
5427 ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, pgrp_obj_path);
5428
5429 if (!ret)
5430 wpas_dbus_signal_persistent_group_removed(wpa_s, nid);
5431
5432 return ret;
5433 }
5434
5435 #endif /* CONFIG_P2P */
5436
5437
5438 #ifdef CONFIG_HS20
5439 /**
5440 * wpas_dbus_signal_hs20_t_c_acceptance - Signals a terms and conditions was
5441 * received.
5442 *
5443 * @wpa_s: %wpa_supplicant network interface data
5444 * @url: URL of the terms and conditions acceptance page.
5445 */
wpas_dbus_signal_hs20_t_c_acceptance(struct wpa_supplicant * wpa_s,const char * url)5446 void wpas_dbus_signal_hs20_t_c_acceptance(struct wpa_supplicant *wpa_s,
5447 const char *url)
5448 {
5449 struct wpas_dbus_priv *iface;
5450 DBusMessage *msg;
5451
5452 iface = wpa_s->global->dbus;
5453
5454 /* Do nothing if the control interface is not turned on */
5455 if (!iface || !wpa_s->dbus_new_path)
5456 return;
5457
5458 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
5459 WPAS_DBUS_NEW_IFACE_INTERFACE,
5460 "HS20TermsAndConditions");
5461 if (!msg)
5462 return;
5463
5464 if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &url,
5465 DBUS_TYPE_INVALID))
5466 dbus_connection_send(iface->con, msg, NULL);
5467 else
5468 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
5469 dbus_message_unref(msg);
5470 }
5471 #endif /* CONFIG_HS20 */
5472
5473
5474 #ifdef CONFIG_NAN_USD
5475
5476 /**
5477 * wpas_dbus_signal_nan_discovery_result - Send NANDiscoveryResult signal
5478 * @wpa_s: %wpa_supplicant network interface data
5479 * @srv_proto_type: Service Protocol Type
5480 * @subscribe_id: Subscribe ID of the session
5481 * @peer_publish_id: Publish ID of the sender
5482 * @peer_addr: MAC address of the peer device
5483 * @ssi: Service specific information payload
5484 * @ssi_len: Length of the SSI field
5485 *
5486 * This is used to indicate the NAN DE DiscoveryResult event.
5487 */
wpas_dbus_signal_nan_discovery_result(struct wpa_supplicant * wpa_s,enum nan_service_protocol_type srv_proto_type,int subscribe_id,int peer_publish_id,const u8 * peer_addr,bool fsd,bool fsd_gas,const u8 * ssi,size_t ssi_len)5488 void wpas_dbus_signal_nan_discovery_result(struct wpa_supplicant *wpa_s,
5489 enum nan_service_protocol_type
5490 srv_proto_type,
5491 int subscribe_id,
5492 int peer_publish_id,
5493 const u8 *peer_addr,
5494 bool fsd, bool fsd_gas,
5495 const u8 *ssi, size_t ssi_len)
5496 {
5497 struct wpas_dbus_priv *iface;
5498 DBusMessage *msg;
5499 DBusMessageIter iter, dict_iter;
5500 char addr_str[20];
5501
5502 iface = wpa_s->global->dbus;
5503 /* Do nothing if the interface is not turned on */
5504 if (!iface || !wpa_s->dbus_new_path)
5505 return;
5506 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
5507 WPAS_DBUS_NEW_IFACE_INTERFACE,
5508 "NANDiscoveryResult");
5509 if (!msg)
5510 return;
5511
5512 snprintf(addr_str, sizeof(addr_str), MACSTR, MAC2STR(peer_addr));
5513
5514 dbus_message_iter_init_append(msg, &iter);
5515
5516 if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
5517 !wpa_dbus_dict_append_uint32(&dict_iter, "subscribe_id",
5518 subscribe_id) ||
5519 !wpa_dbus_dict_append_uint32(&dict_iter, "publish_id",
5520 peer_publish_id) ||
5521 !wpa_dbus_dict_append_string(&dict_iter, "peer_addr", addr_str) ||
5522 !wpa_dbus_dict_append_bool(&dict_iter, "fsd", fsd) ||
5523 !wpa_dbus_dict_append_bool(&dict_iter, "fsd_gas", fsd_gas) ||
5524 !wpa_dbus_dict_append_uint32(&dict_iter, "srv_proto_type",
5525 srv_proto_type) ||
5526 (ssi &&
5527 !wpa_dbus_dict_append_byte_array(&dict_iter,
5528 "ssi",
5529 (const char *) ssi,
5530 ssi_len)) ||
5531 !wpa_dbus_dict_close_write(&iter, &dict_iter))
5532 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
5533 else
5534 dbus_connection_send(iface->con, msg, NULL);
5535 dbus_message_unref(msg);
5536 }
5537
5538
5539 /**
5540 * wpas_dbus_signal_nan_replied - Send NANReplied signal
5541 * @wpa_s: %wpa_supplicant network interface data
5542 * @srv_proto_type: Service Protocol Type
5543 * @publish_id: Publish id of the session
5544 * @peer_subscribe_id: Subscribe id of the sender
5545 * @peer_addr: MAC address of the peer device
5546 * @ssi: Service specific information payload
5547 * @ssi_len: Length of the SSI field
5548 *
5549 * This is used to indicate the NAN DE Replied event.
5550 */
wpas_dbus_signal_nan_replied(struct wpa_supplicant * wpa_s,enum nan_service_protocol_type srv_proto_type,int publish_id,int peer_subscribe_id,const u8 * peer_addr,const u8 * ssi,size_t ssi_len)5551 void wpas_dbus_signal_nan_replied(struct wpa_supplicant *wpa_s,
5552 enum nan_service_protocol_type srv_proto_type,
5553 int publish_id,
5554 int peer_subscribe_id,
5555 const u8 *peer_addr,
5556 const u8 *ssi, size_t ssi_len)
5557 {
5558 struct wpas_dbus_priv *iface;
5559 DBusMessage *msg;
5560 DBusMessageIter iter, dict_iter;
5561 char addr_str[20];
5562
5563 iface = wpa_s->global->dbus;
5564 /* Do nothing if the interface is not turned on */
5565 if (!iface || !wpa_s->dbus_new_path)
5566 return;
5567
5568 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
5569 WPAS_DBUS_NEW_IFACE_INTERFACE,
5570 "NANReplied");
5571 if (!msg)
5572 return;
5573
5574 snprintf(addr_str, sizeof(addr_str), MACSTR, MAC2STR(peer_addr));
5575
5576 dbus_message_iter_init_append(msg, &iter);
5577
5578 if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
5579 !wpa_dbus_dict_append_uint32(&dict_iter, "publish_id",
5580 publish_id) ||
5581 !wpa_dbus_dict_append_uint32(&dict_iter, "subscribe_id",
5582 peer_subscribe_id) ||
5583 !wpa_dbus_dict_append_string(&dict_iter, "peer_addr", addr_str) ||
5584 !wpa_dbus_dict_append_uint32(&dict_iter, "srv_proto_type",
5585 srv_proto_type) ||
5586 (ssi &&
5587 !wpa_dbus_dict_append_byte_array(&dict_iter, "ssi",
5588 (const char *) ssi,
5589 ssi_len)) ||
5590 !wpa_dbus_dict_close_write(&iter, &dict_iter))
5591 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
5592 else
5593 dbus_connection_send(iface->con, msg, NULL);
5594 dbus_message_unref(msg);
5595 }
5596
5597
5598 /**
5599 * wpas_dbus_signal_nan_receive - Send NANReceive signal
5600 * @wpa_s: %wpa_supplicant network interface data
5601 * @id: The original publish_id or subscribe_id
5602 * @peer_id: Peer instance identifier
5603 * @peer_addr: Address of the sender
5604 * @ssi: Service specific information payload
5605 * @ssi_len: Length of the SSI
5606 *
5607 * This is used to indicate the NAN DE Receive event to notify reception of a
5608 * follow-up frame.
5609 */
wpas_dbus_signal_nan_receive(struct wpa_supplicant * wpa_s,int id,int peer_id,const u8 * peer_addr,const u8 * ssi,size_t ssi_len)5610 void wpas_dbus_signal_nan_receive(struct wpa_supplicant *wpa_s,
5611 int id, int peer_id, const u8 *peer_addr,
5612 const u8 *ssi, size_t ssi_len)
5613 {
5614 struct wpas_dbus_priv *iface;
5615 DBusMessage *msg;
5616 DBusMessageIter iter, dict_iter;
5617 char addr_str[20];
5618
5619 iface = wpa_s->global->dbus;
5620 /* Do nothing if the interface is not turned on */
5621 if (!iface || !wpa_s->dbus_new_path)
5622 return;
5623
5624 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
5625 WPAS_DBUS_NEW_IFACE_INTERFACE,
5626 "NANReceive");
5627 if (!msg)
5628 return;
5629
5630 snprintf(addr_str, sizeof(addr_str), MACSTR, MAC2STR(peer_addr));
5631
5632 dbus_message_iter_init_append(msg, &iter);
5633
5634 if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
5635 !wpa_dbus_dict_append_uint32(&dict_iter, "id", id) ||
5636 !wpa_dbus_dict_append_uint32(&dict_iter, "peer_id", peer_id) ||
5637 !wpa_dbus_dict_append_string(&dict_iter, "peer_addr", addr_str) ||
5638 (ssi &&
5639 !wpa_dbus_dict_append_byte_array(&dict_iter, "ssi",
5640 (const char *) ssi,
5641 ssi_len)) ||
5642 !wpa_dbus_dict_close_write(&iter, &dict_iter))
5643 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
5644 else
5645 dbus_connection_send(iface->con, msg, NULL);
5646 dbus_message_unref(msg);
5647 }
5648
5649
5650 /**
5651 * wpas_dbus_signal_nan_publish_terminated - Send NANPublishTerminated signal
5652 * @wpa_s: %wpa_supplicant network interface data
5653 * @publish_id: The publish_id of the session
5654 * @reason: The reason of the termination
5655 *
5656 * This is used to indicate the NAN DE PublishTerminated event to notify when
5657 * the session has expired.
5658 */
wpas_dbus_signal_nan_publish_terminated(struct wpa_supplicant * wpa_s,int publish_id,const char * reason)5659 void wpas_dbus_signal_nan_publish_terminated(struct wpa_supplicant *wpa_s,
5660 int publish_id,
5661 const char *reason)
5662 {
5663 struct wpas_dbus_priv *iface;
5664 DBusMessage *msg;
5665 dbus_uint32_t pub_id = publish_id;
5666
5667 iface = wpa_s->global->dbus;
5668 /* Do nothing if the interface is not turned on */
5669 if (!iface || !wpa_s->dbus_new_path)
5670 return;
5671
5672 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
5673 WPAS_DBUS_NEW_IFACE_INTERFACE,
5674 "NANPublishTerminated");
5675 if (!msg)
5676 return;
5677
5678 if (!dbus_message_append_args(msg, DBUS_TYPE_UINT32, &pub_id,
5679 DBUS_TYPE_INVALID) ||
5680 !dbus_message_append_args(msg, DBUS_TYPE_STRING, &reason,
5681 DBUS_TYPE_INVALID))
5682 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
5683 else
5684 dbus_connection_send(iface->con, msg, NULL);
5685 dbus_message_unref(msg);
5686 }
5687
5688
5689 /**
5690 * wpas_dbus_signal_nan_subscribe_terminated - Send NANSubscribeTerminated signal
5691 * @wpa_s: %wpa_supplicant network interface data
5692 * @subscribe_id: The subscribe_id of the session
5693 * @reason: The reason of the termination
5694 *
5695 * This is used to indicate the NAN DE SubscribeTerminated event to notify when
5696 * the session has expired.
5697 */
wpas_dbus_signal_nan_subscribe_terminated(struct wpa_supplicant * wpa_s,int subscribe_id,const char * reason)5698 void wpas_dbus_signal_nan_subscribe_terminated(struct wpa_supplicant *wpa_s,
5699 int subscribe_id,
5700 const char *reason)
5701 {
5702 struct wpas_dbus_priv *iface;
5703 DBusMessage *msg;
5704 dbus_uint32_t sub_id = subscribe_id;
5705
5706 iface = wpa_s->global->dbus;
5707 /* Do nothing if the interface is not turned on */
5708 if (!iface || !wpa_s->dbus_new_path)
5709 return;
5710
5711 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
5712 WPAS_DBUS_NEW_IFACE_INTERFACE,
5713 "NANSubscribeTerminated");
5714 if (!msg)
5715 return;
5716
5717 if (!dbus_message_append_args(msg, DBUS_TYPE_UINT32, &sub_id,
5718 DBUS_TYPE_INVALID) ||
5719 !dbus_message_append_args(msg, DBUS_TYPE_STRING, &reason,
5720 DBUS_TYPE_INVALID))
5721 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
5722 else
5723 dbus_connection_send(iface->con, msg, NULL);
5724 dbus_message_unref(msg);
5725 }
5726
5727 #endif /* CONFIG_NAN_USD */
5728