]> git.ipfire.org Git - thirdparty/hostap.git/blame - wpa_supplicant/dbus/dbus_new.c
Create DBus getter/setter for ScanInterval
[thirdparty/hostap.git] / wpa_supplicant / dbus / dbus_new.c
CommitLineData
8fc2fb56
WS
1/*
2 * WPA Supplicant / dbus-based control interface
3 * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
8e5568f8 4 * Copyright (c) 2009-2010, Witold Sowa <witold.sowa@gmail.com>
ccd286d0 5 * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
8fc2fb56
WS
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * Alternatively, this software may be distributed under the terms of BSD
12 * license.
13 *
14 * See README and COPYING for more details.
15 */
16
17#include "includes.h"
18
19#include "common.h"
9abafccc 20#include "common/ieee802_11_defs.h"
8fc2fb56 21#include "wps/wps.h"
a206a29a
JM
22#include "../config.h"
23#include "../wpa_supplicant_i.h"
ccd286d0 24#include "../bss.h"
a9022616 25#include "../wpas_glue.h"
a206a29a 26#include "dbus_new_helpers.h"
8fc2fb56 27#include "dbus_dict_helpers.h"
a206a29a
JM
28#include "dbus_new.h"
29#include "dbus_new_handlers.h"
8ddef94b 30#include "dbus_common_i.h"
9abafccc
JB
31#include "dbus_new_handlers_p2p.h"
32#include "p2p/p2p.h"
8fc2fb56 33
8fc2fb56
WS
34
35/**
36 * wpas_dbus_signal_interface - Send a interface related event signal
37 * @wpa_s: %wpa_supplicant network interface data
38 * @sig_name: signal name - InterfaceAdded or InterfaceRemoved
88ba1f72 39 * @properties: Whether to add second argument with object properties
8fc2fb56
WS
40 *
41 * Notify listeners about event related with interface
42 */
43static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s,
e376f119 44 const char *sig_name, int properties)
8fc2fb56 45{
8ddef94b 46 struct wpas_dbus_priv *iface;
88ba1f72 47 DBusMessage *msg;
6aeeb6fa 48 DBusMessageIter iter;
8fc2fb56 49
8ddef94b 50 iface = wpa_s->global->dbus;
8fc2fb56
WS
51
52 /* Do nothing if the control interface is not turned on */
53 if (iface == NULL)
54 return;
55
88ba1f72
JM
56 msg = dbus_message_new_signal(WPAS_DBUS_NEW_PATH,
57 WPAS_DBUS_NEW_INTERFACE, sig_name);
58 if (msg == NULL)
8fc2fb56 59 return;
e376f119 60
88ba1f72 61 dbus_message_iter_init_append(msg, &iter);
c49cf2d6 62 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
88ba1f72 63 &wpa_s->dbus_new_path))
e376f119
WS
64 goto err;
65
66 if (properties) {
6aeeb6fa
DW
67 if (!wpa_dbus_get_object_properties(
68 iface, wpa_s->dbus_new_path,
69 WPAS_DBUS_NEW_IFACE_INTERFACE, &iter))
e376f119 70 goto err;
8fc2fb56 71 }
e376f119 72
88ba1f72
JM
73 dbus_connection_send(iface->con, msg, NULL);
74 dbus_message_unref(msg);
e376f119
WS
75 return;
76
77err:
88ba1f72
JM
78 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
79 dbus_message_unref(msg);
8fc2fb56
WS
80}
81
82
83/**
b7e8feec 84 * wpas_dbus_signal_interface_added - Send a interface created signal
8fc2fb56
WS
85 * @wpa_s: %wpa_supplicant network interface data
86 *
87 * Notify listeners about creating new interface
88 */
b7e8feec 89static void wpas_dbus_signal_interface_added(struct wpa_supplicant *wpa_s)
8fc2fb56 90{
b7e8feec 91 wpas_dbus_signal_interface(wpa_s, "InterfaceAdded", TRUE);
8fc2fb56
WS
92}
93
94
95/**
96 * wpas_dbus_signal_interface_removed - Send a interface removed signal
97 * @wpa_s: %wpa_supplicant network interface data
98 *
99 * Notify listeners about removing interface
100 */
101static void wpas_dbus_signal_interface_removed(struct wpa_supplicant *wpa_s)
102{
e376f119 103 wpas_dbus_signal_interface(wpa_s, "InterfaceRemoved", FALSE);
8fc2fb56
WS
104
105}
106
107
108/**
109 * wpas_dbus_signal_scan_done - send scan done signal
110 * @wpa_s: %wpa_supplicant network interface data
111 * @success: indicates if scanning succeed or failed
112 *
113 * Notify listeners about finishing a scan
114 */
52bdd880 115void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s, int success)
8fc2fb56 116{
8ddef94b 117 struct wpas_dbus_priv *iface;
88ba1f72 118 DBusMessage *msg;
8fc2fb56
WS
119 dbus_bool_t succ;
120
8ddef94b 121 iface = wpa_s->global->dbus;
8fc2fb56
WS
122
123 /* Do nothing if the control interface is not turned on */
124 if (iface == NULL)
125 return;
126
88ba1f72
JM
127 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
128 WPAS_DBUS_NEW_IFACE_INTERFACE,
129 "ScanDone");
130 if (msg == NULL)
8fc2fb56 131 return;
8fc2fb56
WS
132
133 succ = success ? TRUE : FALSE;
88ba1f72
JM
134 if (dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &succ,
135 DBUS_TYPE_INVALID))
136 dbus_connection_send(iface->con, msg, NULL);
137 else
138 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
139 dbus_message_unref(msg);
8fc2fb56
WS
140}
141
142
143/**
144 * wpas_dbus_signal_blob - Send a BSS related event signal
145 * @wpa_s: %wpa_supplicant network interface data
146 * @bss_obj_path: BSS object path
147 * @sig_name: signal name - BSSAdded or BSSRemoved
88ba1f72 148 * @properties: Whether to add second argument with object properties
8fc2fb56
WS
149 *
150 * Notify listeners about event related with BSS
151 */
152static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s,
153 const char *bss_obj_path,
e376f119 154 const char *sig_name, int properties)
8fc2fb56 155{
8ddef94b 156 struct wpas_dbus_priv *iface;
88ba1f72 157 DBusMessage *msg;
6aeeb6fa 158 DBusMessageIter iter;
8fc2fb56 159
8ddef94b 160 iface = wpa_s->global->dbus;
8fc2fb56
WS
161
162 /* Do nothing if the control interface is not turned on */
163 if (iface == NULL)
164 return;
165
88ba1f72
JM
166 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
167 WPAS_DBUS_NEW_IFACE_INTERFACE,
168 sig_name);
169 if (msg == NULL)
8fc2fb56 170 return;
e376f119 171
88ba1f72 172 dbus_message_iter_init_append(msg, &iter);
e376f119
WS
173 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
174 &bss_obj_path))
175 goto err;
176
177 if (properties) {
6aeeb6fa
DW
178 if (!wpa_dbus_get_object_properties(iface, bss_obj_path,
179 WPAS_DBUS_NEW_IFACE_BSS,
180 &iter))
e376f119 181 goto err;
8fc2fb56 182 }
e376f119 183
88ba1f72
JM
184 dbus_connection_send(iface->con, msg, NULL);
185 dbus_message_unref(msg);
e376f119
WS
186 return;
187
188err:
88ba1f72
JM
189 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
190 dbus_message_unref(msg);
8fc2fb56
WS
191}
192
193
194/**
195 * wpas_dbus_signal_bss_added - Send a BSS added signal
196 * @wpa_s: %wpa_supplicant network interface data
197 * @bss_obj_path: new BSS object path
198 *
199 * Notify listeners about adding new BSS
200 */
201static void wpas_dbus_signal_bss_added(struct wpa_supplicant *wpa_s,
202 const char *bss_obj_path)
203{
e376f119 204 wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSAdded", TRUE);
8fc2fb56
WS
205}
206
207
208/**
209 * wpas_dbus_signal_bss_removed - Send a BSS removed signal
210 * @wpa_s: %wpa_supplicant network interface data
211 * @bss_obj_path: BSS object path
212 *
213 * Notify listeners about removing BSS
214 */
215static void wpas_dbus_signal_bss_removed(struct wpa_supplicant *wpa_s,
216 const char *bss_obj_path)
217{
e376f119 218 wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSRemoved", FALSE);
8fc2fb56
WS
219}
220
221
222/**
223 * wpas_dbus_signal_blob - Send a blob related event signal
224 * @wpa_s: %wpa_supplicant network interface data
225 * @name: blob name
226 * @sig_name: signal name - BlobAdded or BlobRemoved
227 *
228 * Notify listeners about event related with blob
229 */
230static void wpas_dbus_signal_blob(struct wpa_supplicant *wpa_s,
231 const char *name, const char *sig_name)
232{
8ddef94b 233 struct wpas_dbus_priv *iface;
88ba1f72 234 DBusMessage *msg;
8fc2fb56 235
8ddef94b 236 iface = wpa_s->global->dbus;
8fc2fb56
WS
237
238 /* Do nothing if the control interface is not turned on */
239 if (iface == NULL)
240 return;
241
88ba1f72
JM
242 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
243 WPAS_DBUS_NEW_IFACE_INTERFACE,
244 sig_name);
245 if (msg == NULL)
8fc2fb56 246 return;
8fc2fb56 247
88ba1f72
JM
248 if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &name,
249 DBUS_TYPE_INVALID))
250 dbus_connection_send(iface->con, msg, NULL);
251 else
252 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
253 dbus_message_unref(msg);
8fc2fb56
WS
254}
255
256
257/**
258 * wpas_dbus_signal_blob_added - Send a blob added signal
259 * @wpa_s: %wpa_supplicant network interface data
260 * @name: blob name
261 *
262 * Notify listeners about adding a new blob
263 */
52bdd880
JM
264void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s,
265 const char *name)
8fc2fb56
WS
266{
267 wpas_dbus_signal_blob(wpa_s, name, "BlobAdded");
268}
269
270
271/**
272 * wpas_dbus_signal_blob_removed - Send a blob removed signal
273 * @wpa_s: %wpa_supplicant network interface data
274 * @name: blob name
275 *
276 * Notify listeners about removing blob
277 */
52bdd880
JM
278void wpas_dbus_signal_blob_removed(struct wpa_supplicant *wpa_s,
279 const char *name)
8fc2fb56
WS
280{
281 wpas_dbus_signal_blob(wpa_s, name, "BlobRemoved");
282}
283
284
285/**
286 * wpas_dbus_signal_network - Send a network related event signal
287 * @wpa_s: %wpa_supplicant network interface data
288 * @id: new network id
289 * @sig_name: signal name - NetworkAdded, NetworkRemoved or NetworkSelected
e376f119 290 * @properties: determines if add second argument with object properties
8fc2fb56
WS
291 *
292 * Notify listeners about event related with configured network
293 */
294static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s,
e376f119
WS
295 int id, const char *sig_name,
296 int properties)
8fc2fb56 297{
8ddef94b 298 struct wpas_dbus_priv *iface;
88ba1f72 299 DBusMessage *msg;
6aeeb6fa 300 DBusMessageIter iter;
88ba1f72 301 char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
8fc2fb56 302
8ddef94b 303 iface = wpa_s->global->dbus;
8fc2fb56
WS
304
305 /* Do nothing if the control interface is not turned on */
306 if (iface == NULL)
307 return;
308
8fc2fb56 309 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
c49cf2d6
JM
310 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
311 wpa_s->dbus_new_path, id);
8fc2fb56 312
88ba1f72
JM
313 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
314 WPAS_DBUS_NEW_IFACE_INTERFACE,
315 sig_name);
316 if (msg == NULL)
8fc2fb56 317 return;
e376f119 318
88ba1f72
JM
319 dbus_message_iter_init_append(msg, &iter);
320 path = net_obj_path;
e376f119 321 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
88ba1f72 322 &path))
e376f119
WS
323 goto err;
324
325 if (properties) {
6aeeb6fa
DW
326 if (!wpa_dbus_get_object_properties(
327 iface, net_obj_path, WPAS_DBUS_NEW_IFACE_NETWORK,
328 &iter))
e376f119 329 goto err;
8fc2fb56
WS
330 }
331
88ba1f72 332 dbus_connection_send(iface->con, msg, NULL);
e376f119 333
88ba1f72 334 dbus_message_unref(msg);
e376f119
WS
335 return;
336
337err:
88ba1f72
JM
338 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
339 dbus_message_unref(msg);
8fc2fb56
WS
340}
341
342
343/**
344 * wpas_dbus_signal_network_added - Send a network added signal
345 * @wpa_s: %wpa_supplicant network interface data
346 * @id: new network id
347 *
348 * Notify listeners about adding new network
349 */
350static void wpas_dbus_signal_network_added(struct wpa_supplicant *wpa_s,
351 int id)
352{
e376f119 353 wpas_dbus_signal_network(wpa_s, id, "NetworkAdded", TRUE);
8fc2fb56
WS
354}
355
356
357/**
17efbfac 358 * wpas_dbus_signal_network_removed - Send a network removed signal
8fc2fb56
WS
359 * @wpa_s: %wpa_supplicant network interface data
360 * @id: network id
361 *
362 * Notify listeners about removing a network
363 */
364static void wpas_dbus_signal_network_removed(struct wpa_supplicant *wpa_s,
365 int id)
366{
e376f119 367 wpas_dbus_signal_network(wpa_s, id, "NetworkRemoved", FALSE);
8fc2fb56
WS
368}
369
370
371/**
372 * wpas_dbus_signal_network_selected - Send a network selected signal
373 * @wpa_s: %wpa_supplicant network interface data
374 * @id: network id
375 *
376 * Notify listeners about selecting a network
377 */
52bdd880 378void wpas_dbus_signal_network_selected(struct wpa_supplicant *wpa_s, int id)
8fc2fb56 379{
e376f119 380 wpas_dbus_signal_network(wpa_s, id, "NetworkSelected", FALSE);
8fc2fb56
WS
381}
382
383
a9022616
DW
384/**
385 * wpas_dbus_signal_network_request - Indicate that additional information
386 * (EAP password, etc.) is required to complete the association to this SSID
387 * @wpa_s: %wpa_supplicant network interface data
388 * @rtype: The specific additional information required
389 * @default_text: Optional description of required information
390 *
391 * Request additional information or passwords to complete an association
392 * request.
393 */
394void wpas_dbus_signal_network_request(struct wpa_supplicant *wpa_s,
395 struct wpa_ssid *ssid,
396 enum wpa_ctrl_req_type rtype,
397 const char *default_txt)
398{
399 struct wpas_dbus_priv *iface;
400 DBusMessage *msg;
401 DBusMessageIter iter;
402 char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
403 const char *field, *txt = NULL, *net_ptr;
404
405 iface = wpa_s->global->dbus;
406
407 /* Do nothing if the control interface is not turned on */
408 if (iface == NULL)
409 return;
410
411 field = wpa_supplicant_ctrl_req_to_string(rtype, default_txt, &txt);
412 if (field == NULL)
413 return;
414
415 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
416 WPAS_DBUS_NEW_IFACE_INTERFACE,
417 "NetworkRequest");
418 if (msg == NULL)
419 return;
420
421 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
422 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
423 wpa_s->dbus_new_path, ssid->id);
424 net_ptr = &net_obj_path[0];
425
426 dbus_message_iter_init_append(msg, &iter);
427 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
428 &net_ptr))
429 goto err;
430 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &field))
431 goto err;
432 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &txt))
433 goto err;
434
435 dbus_connection_send(iface->con, msg, NULL);
436 dbus_message_unref(msg);
437 return;
438
439err:
440 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
441 dbus_message_unref(msg);
442}
443
444
8fc2fb56 445/**
17efbfac 446 * wpas_dbus_signal_network_enabled_changed - Signals Enabled property changes
8fc2fb56
WS
447 * @wpa_s: %wpa_supplicant network interface data
448 * @ssid: configured network which Enabled property has changed
449 *
450 * Sends PropertyChanged signals containing new value of Enabled property
451 * for specified network
452 */
52bdd880
JM
453void wpas_dbus_signal_network_enabled_changed(struct wpa_supplicant *wpa_s,
454 struct wpa_ssid *ssid)
8fc2fb56
WS
455{
456
8fc2fb56
WS
457 char path[WPAS_DBUS_OBJECT_PATH_MAX];
458 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
459 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
c49cf2d6 460 wpa_s->dbus_new_path, ssid->id);
8fc2fb56 461
abd7a4e3
WS
462 wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
463 WPAS_DBUS_NEW_IFACE_NETWORK, "Enabled");
8fc2fb56
WS
464}
465
466
467#ifdef CONFIG_WPS
468
469/**
470 * wpas_dbus_signal_wps_event_success - Signals Success WPS event
471 * @wpa_s: %wpa_supplicant network interface data
472 *
473 * Sends Event dbus signal with name "success" and empty dict as arguments
474 */
52bdd880 475void wpas_dbus_signal_wps_event_success(struct wpa_supplicant *wpa_s)
8fc2fb56
WS
476{
477
88ba1f72 478 DBusMessage *msg;
8fc2fb56 479 DBusMessageIter iter, dict_iter;
8ddef94b 480 struct wpas_dbus_priv *iface;
8fc2fb56 481 char *key = "success";
8fc2fb56 482
8ddef94b 483 iface = wpa_s->global->dbus;
8fc2fb56
WS
484
485 /* Do nothing if the control interface is not turned on */
486 if (iface == NULL)
487 return;
488
88ba1f72
JM
489 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
490 WPAS_DBUS_NEW_IFACE_WPS, "Event");
491 if (msg == NULL)
8fc2fb56 492 return;
8fc2fb56 493
88ba1f72 494 dbus_message_iter_init_append(msg, &iter);
8fc2fb56
WS
495
496 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
497 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
88ba1f72
JM
498 !wpa_dbus_dict_close_write(&iter, &dict_iter))
499 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
500 else
501 dbus_connection_send(iface->con, msg, NULL);
8fc2fb56 502
88ba1f72 503 dbus_message_unref(msg);
8fc2fb56
WS
504}
505
506
507/**
508 * wpas_dbus_signal_wps_event_fail - Signals Fail WPS event
509 * @wpa_s: %wpa_supplicant network interface data
510 *
511 * Sends Event dbus signal with name "fail" and dictionary containing
512 * "msg field with fail message number (int32) as arguments
513 */
52bdd880
JM
514void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant *wpa_s,
515 struct wps_event_fail *fail)
8fc2fb56
WS
516{
517
88ba1f72 518 DBusMessage *msg;
8fc2fb56 519 DBusMessageIter iter, dict_iter;
8ddef94b 520 struct wpas_dbus_priv *iface;
3864e6ea 521 char *key = "fail";
8fc2fb56 522
8ddef94b 523 iface = wpa_s->global->dbus;
8fc2fb56
WS
524
525 /* Do nothing if the control interface is not turned on */
526 if (iface == NULL)
527 return;
528
88ba1f72
JM
529 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
530 WPAS_DBUS_NEW_IFACE_WPS, "Event");
531 if (msg == NULL)
8fc2fb56 532 return;
8fc2fb56 533
88ba1f72 534 dbus_message_iter_init_append(msg, &iter);
8fc2fb56
WS
535
536 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
537 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
538 !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
88ba1f72
JM
539 !wpa_dbus_dict_close_write(&iter, &dict_iter))
540 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
541 else
542 dbus_connection_send(iface->con, msg, NULL);
8fc2fb56 543
88ba1f72 544 dbus_message_unref(msg);
8fc2fb56
WS
545}
546
547
548/**
549 * wpas_dbus_signal_wps_event_m2d - Signals M2D WPS event
550 * @wpa_s: %wpa_supplicant network interface data
551 *
552 * Sends Event dbus signal with name "m2d" and dictionary containing
553 * fields of wps_event_m2d structure.
554 */
52bdd880
JM
555void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant *wpa_s,
556 struct wps_event_m2d *m2d)
8fc2fb56
WS
557{
558
88ba1f72 559 DBusMessage *msg;
8fc2fb56 560 DBusMessageIter iter, dict_iter;
8ddef94b 561 struct wpas_dbus_priv *iface;
3864e6ea 562 char *key = "m2d";
8fc2fb56 563
8ddef94b 564 iface = wpa_s->global->dbus;
8fc2fb56
WS
565
566 /* Do nothing if the control interface is not turned on */
567 if (iface == NULL)
568 return;
569
88ba1f72
JM
570 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
571 WPAS_DBUS_NEW_IFACE_WPS, "Event");
572 if (msg == NULL)
8fc2fb56 573 return;
8fc2fb56 574
88ba1f72 575 dbus_message_iter_init_append(msg, &iter);
8fc2fb56 576
88ba1f72
JM
577 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
578 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
579 !wpa_dbus_dict_append_uint16(&dict_iter, "config_methods",
580 m2d->config_methods) ||
581 !wpa_dbus_dict_append_byte_array(&dict_iter, "manufacturer",
582 (const char *) m2d->manufacturer,
583 m2d->manufacturer_len) ||
584 !wpa_dbus_dict_append_byte_array(&dict_iter, "model_name",
585 (const char *) m2d->model_name,
586 m2d->model_name_len) ||
587 !wpa_dbus_dict_append_byte_array(&dict_iter, "model_number",
588 (const char *) m2d->model_number,
589 m2d->model_number_len) ||
590 !wpa_dbus_dict_append_byte_array(&dict_iter, "serial_number",
591 (const char *)
592 m2d->serial_number,
593 m2d->serial_number_len) ||
594 !wpa_dbus_dict_append_byte_array(&dict_iter, "dev_name",
595 (const char *) m2d->dev_name,
596 m2d->dev_name_len) ||
597 !wpa_dbus_dict_append_byte_array(&dict_iter, "primary_dev_type",
598 (const char *)
599 m2d->primary_dev_type, 8) ||
600 !wpa_dbus_dict_append_uint16(&dict_iter, "config_error",
601 m2d->config_error) ||
602 !wpa_dbus_dict_append_uint16(&dict_iter, "dev_password_id",
603 m2d->dev_password_id) ||
604 !wpa_dbus_dict_close_write(&iter, &dict_iter))
605 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
606 else
607 dbus_connection_send(iface->con, msg, NULL);
608
609 dbus_message_unref(msg);
8fc2fb56
WS
610}
611
612
613/**
614 * wpas_dbus_signal_wps_cred - Signals new credentials
615 * @wpa_s: %wpa_supplicant network interface data
616 *
617 * Sends signal with credentials in directory argument
618 */
52bdd880
JM
619void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s,
620 const struct wps_credential *cred)
8fc2fb56 621{
88ba1f72 622 DBusMessage *msg;
8fc2fb56 623 DBusMessageIter iter, dict_iter;
8ddef94b 624 struct wpas_dbus_priv *iface;
8fc2fb56
WS
625 char *auth_type[6]; /* we have six possible authorization types */
626 int at_num = 0;
627 char *encr_type[4]; /* we have four possible encryption types */
628 int et_num = 0;
629
8ddef94b 630 iface = wpa_s->global->dbus;
8fc2fb56
WS
631
632 /* Do nothing if the control interface is not turned on */
633 if (iface == NULL)
634 return;
635
88ba1f72
JM
636 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
637 WPAS_DBUS_NEW_IFACE_WPS,
638 "Credentials");
639 if (msg == NULL)
8fc2fb56 640 return;
8fc2fb56 641
88ba1f72 642 dbus_message_iter_init_append(msg, &iter);
c2b8c674 643 if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
8fc2fb56 644 goto nomem;
8fc2fb56
WS
645
646 if (cred->auth_type & WPS_AUTH_OPEN)
647 auth_type[at_num++] = "open";
648 if (cred->auth_type & WPS_AUTH_WPAPSK)
649 auth_type[at_num++] = "wpa-psk";
650 if (cred->auth_type & WPS_AUTH_SHARED)
651 auth_type[at_num++] = "shared";
652 if (cred->auth_type & WPS_AUTH_WPA)
653 auth_type[at_num++] = "wpa-eap";
654 if (cred->auth_type & WPS_AUTH_WPA2)
655 auth_type[at_num++] = "wpa2-eap";
656 if (cred->auth_type & WPS_AUTH_WPA2PSK)
657 auth_type[at_num++] =
658 "wpa2-psk";
659
660 if (cred->encr_type & WPS_ENCR_NONE)
661 encr_type[et_num++] = "none";
662 if (cred->encr_type & WPS_ENCR_WEP)
663 encr_type[et_num++] = "wep";
664 if (cred->encr_type & WPS_ENCR_TKIP)
665 encr_type[et_num++] = "tkip";
666 if (cred->encr_type & WPS_ENCR_AES)
667 encr_type[et_num++] = "aes";
668
669 if (wpa_s->current_ssid) {
670 if (!wpa_dbus_dict_append_byte_array(
671 &dict_iter, "BSSID",
672 (const char *) wpa_s->current_ssid->bssid,
c2b8c674 673 ETH_ALEN))
8fc2fb56 674 goto nomem;
8fc2fb56
WS
675 }
676
88ba1f72
JM
677 if (!wpa_dbus_dict_append_byte_array(&dict_iter, "SSID",
678 (const char *) cred->ssid,
679 cred->ssid_len) ||
680 !wpa_dbus_dict_append_string_array(&dict_iter, "AuthType",
681 (const char **) auth_type,
682 at_num) ||
683 !wpa_dbus_dict_append_string_array(&dict_iter, "EncrType",
684 (const char **) encr_type,
685 et_num) ||
686 !wpa_dbus_dict_append_byte_array(&dict_iter, "Key",
687 (const char *) cred->key,
688 cred->key_len) ||
689 !wpa_dbus_dict_append_uint32(&dict_iter, "KeyIndex",
690 cred->key_idx) ||
691 !wpa_dbus_dict_close_write(&iter, &dict_iter))
8fc2fb56 692 goto nomem;
8fc2fb56 693
88ba1f72 694 dbus_connection_send(iface->con, msg, NULL);
8fc2fb56
WS
695
696nomem:
88ba1f72 697 dbus_message_unref(msg);
8fc2fb56
WS
698}
699
700#endif /* CONFIG_WPS */
701
ade74830
MC
702void wpas_dbus_signal_certification(struct wpa_supplicant *wpa_s,
703 int depth, const char *subject,
704 const char *cert_hash,
705 const struct wpabuf *cert)
706{
707 struct wpas_dbus_priv *iface;
708 DBusMessage *msg;
709 DBusMessageIter iter, dict_iter;
710
711 iface = wpa_s->global->dbus;
712
713 /* Do nothing if the control interface is not turned on */
714 if (iface == NULL)
715 return;
716
717 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
718 WPAS_DBUS_NEW_IFACE_INTERFACE,
719 "Certification");
720 if (msg == NULL)
721 return;
722
723 dbus_message_iter_init_append(msg, &iter);
724 if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
725 goto nomem;
726
727 if (!wpa_dbus_dict_append_uint32(&dict_iter, "depth", depth) ||
728 !wpa_dbus_dict_append_string(&dict_iter, "subject", subject))
729 goto nomem;
730
731 if (cert_hash &&
732 !wpa_dbus_dict_append_string(&dict_iter, "cert_hash", cert_hash))
733 goto nomem;
734
735 if (cert &&
736 !wpa_dbus_dict_append_byte_array(&dict_iter, "cert",
737 wpabuf_head(cert),
738 wpabuf_len(cert)))
739 goto nomem;
740
741 if (!wpa_dbus_dict_close_write(&iter, &dict_iter))
742 goto nomem;
743
744 dbus_connection_send(iface->con, msg, NULL);
745
746nomem:
747 dbus_message_unref(msg);
748}
749
9abafccc 750#ifdef CONFIG_P2P
8fc2fb56
WS
751
752/**
9abafccc 753 * wpas_dbus_signal_p2p_group_removed - Signals P2P group was removed
8fc2fb56 754 * @wpa_s: %wpa_supplicant network interface data
9abafccc
JB
755 * @role: role of this device (client or GO)
756 * Sends signal with i/f name and role as string arguments
8fc2fb56 757 */
9abafccc
JB
758void wpas_dbus_signal_p2p_group_removed(struct wpa_supplicant *wpa_s,
759 const char *role)
8fc2fb56 760{
8fc2fb56 761
9abafccc
JB
762 DBusMessage *msg;
763 DBusMessageIter iter;
764 struct wpas_dbus_priv *iface = wpa_s->global->dbus;
765 char *ifname = wpa_s->ifname;
7cc59958 766
9abafccc
JB
767 /* Do nothing if the control interface is not turned on */
768 if (iface == NULL)
769 return;
770
771 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
772 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
773 "GroupFinished");
774 if (msg == NULL)
8fc2fb56 775 return;
9abafccc
JB
776
777 dbus_message_iter_init_append(msg, &iter);
778
779 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &ifname)) {
780 wpa_printf(MSG_ERROR, "dbus: Failed to construct GroupFinished"
781 "signal -not enough memory for ifname ");
782 goto err;
8fc2fb56
WS
783 }
784
9abafccc
JB
785 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &role))
786 wpa_printf(MSG_ERROR, "dbus: Failed to construct GroupFinished"
787 "signal -not enough memory for role ");
788 else
789 dbus_connection_send(iface->con, msg, NULL);
790
791err:
792 dbus_message_unref(msg);
8fc2fb56
WS
793}
794
795
158c6c74 796/**
9abafccc 797 * wpas_dbus_signal_p2p_provision_discovery - Signals various PD events
158c6c74 798 *
9abafccc
JB
799 * @dev_addr - who sent the request or responded to our request.
800 * @request - Will be 1 if request, 0 for response.
801 * @status - valid only in case of response
802 * @config_methods - wps config methods
803 * @generated_pin - pin to be displayed in case of WPS_CONFIG_DISPLAY method
804 *
805 * Sends following provision discovery related events:
806 * ProvisionDiscoveryRequestDisplayPin
807 * ProvisionDiscoveryResponseDisplayPin
808 * ProvisionDiscoveryRequestEnterPin
809 * ProvisionDiscoveryResponseEnterPin
810 * ProvisionDiscoveryPBCRequest
811 * ProvisionDiscoveryPBCResponse
812 *
813 * TODO::
814 * ProvisionDiscoveryFailure (timeout case)
158c6c74 815 */
9abafccc
JB
816void wpas_dbus_signal_p2p_provision_discovery(struct wpa_supplicant *wpa_s,
817 const u8 *dev_addr, int request,
818 enum p2p_prov_disc_status status,
819 u16 config_methods,
820 unsigned int generated_pin)
158c6c74 821{
9abafccc
JB
822 DBusMessage *msg;
823 DBusMessageIter iter;
824 struct wpas_dbus_priv *iface;
825 char *_signal;
826 int add_pin = 0;
827 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
828 int error_ret = 1;
829 char pin[9], *p_pin = NULL;
158c6c74 830
9abafccc
JB
831 iface = wpa_s->global->dbus;
832
833 /* Do nothing if the control interface is not turned on */
834 if (iface == NULL)
158c6c74 835 return;
9abafccc
JB
836
837 if (request || !status) {
838 if (config_methods & WPS_CONFIG_DISPLAY)
839 _signal = request ?
840 "ProvisionDiscoveryRequestDisplayPin" :
841 "ProvisionDiscoveryResponseEnterPin";
842 else if (config_methods & WPS_CONFIG_KEYPAD)
843 _signal = request ?
844 "ProvisionDiscoveryRequestEnterPin" :
845 "ProvisionDiscoveryResponseDisplayPin";
846 else if (config_methods & WPS_CONFIG_PUSHBUTTON)
847 _signal = request ? "ProvisionDiscoveryPBCRequest" :
848 "ProvisionDiscoveryPBCResponse";
849 else
850 return; /* Unknown or un-supported method */
851 } else if (!request && status)
852 /* Explicit check for failure response */
853 _signal = "ProvisionDiscoveryFailure";
854
855 add_pin = ((request && (config_methods & WPS_CONFIG_DISPLAY)) ||
856 (!request && !status &&
857 (config_methods & WPS_CONFIG_KEYPAD)));
858
859 if (add_pin) {
860 os_snprintf(pin, sizeof(pin), "%08d", generated_pin);
861 p_pin = pin;
158c6c74
WS
862 }
863
9abafccc
JB
864 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
865 WPAS_DBUS_NEW_IFACE_P2PDEVICE, _signal);
866 if (msg == NULL)
867 return;
158c6c74 868
9abafccc 869 /* Check if this is a known peer */
b3bcc0f5 870 if (!p2p_peer_known(wpa_s->global->p2p, dev_addr))
9abafccc
JB
871 goto error;
872
873 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
874 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
875 COMPACT_MACSTR,
876 wpa_s->dbus_new_path, MAC2STR(dev_addr));
877
878 path = peer_obj_path;
879
880 dbus_message_iter_init_append(msg, &iter);
881
882 if (!dbus_message_iter_append_basic(&iter,
883 DBUS_TYPE_OBJECT_PATH,
884 &path))
885 goto error;
886
887 if (!request && status)
888 /* Attach status to ProvisionDiscoveryFailure */
889 error_ret = !dbus_message_iter_append_basic(&iter,
890 DBUS_TYPE_INT32,
891 &status);
892 else
893 error_ret = (add_pin &&
894 !dbus_message_iter_append_basic(&iter,
895 DBUS_TYPE_STRING,
896 &p_pin));
897
898error:
899 if (!error_ret)
900 dbus_connection_send(iface->con, msg, NULL);
901 else
902 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
903
904 dbus_message_unref(msg);
158c6c74
WS
905}
906
907
9abafccc
JB
908void wpas_dbus_signal_p2p_go_neg_req(struct wpa_supplicant *wpa_s,
909 const u8 *src, u16 dev_passwd_id)
8fc2fb56 910{
9abafccc
JB
911 DBusMessage *msg;
912 DBusMessageIter iter;
913 struct wpas_dbus_priv *iface;
914 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
915
916 iface = wpa_s->global->dbus;
917
918 /* Do nothing if the control interface is not turned on */
919 if (iface == NULL)
920 return;
921
922 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
923 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
924 wpa_s->dbus_new_path, MAC2STR(src));
925 path = peer_obj_path;
926
927 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
928 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
929 "GONegotiationRequest");
930 if (msg == NULL)
931 return;
932
933 dbus_message_iter_init_append(msg, &iter);
934
935 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
936 &path) ||
937 !dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT16,
938 &dev_passwd_id))
939 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
940 else
941 dbus_connection_send(iface->con, msg, NULL);
942
943 dbus_message_unref(msg);
db9133ac
WS
944}
945
946
9abafccc
JB
947static int wpas_dbus_get_group_obj_path(struct wpa_supplicant *wpa_s,
948 const struct wpa_ssid *ssid,
949 char *group_obj_path)
db9133ac 950{
9abafccc
JB
951 char group_name[3];
952
953 if (os_memcmp(ssid->ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN))
954 return -1;
955
024d018b 956 os_memcpy(group_name, ssid->ssid + P2P_WILDCARD_SSID_LEN, 2);
9abafccc
JB
957 group_name[2] = '\0';
958
959 os_snprintf(group_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
960 "%s/" WPAS_DBUS_NEW_P2P_GROUPS_PART "/%s",
961 wpa_s->dbus_new_path, group_name);
962
963 return 0;
db9133ac
WS
964}
965
8fc2fb56 966
db9133ac 967/**
9abafccc 968 * wpas_dbus_signal_p2p_group_started - Signals P2P group has
ffbf1eaa 969 * started. Emitted when a group is successfully started
9abafccc 970 * irrespective of the role (client/GO) of the current device
db9133ac 971 *
9abafccc
JB
972 * @wpa_s: %wpa_supplicant network interface data
973 * @ssid: SSID object
974 * @client: this device is P2P client
975 * @network_id: network id of the group started, use instead of ssid->id
976 * to account for persistent groups
db9133ac 977 */
9abafccc
JB
978void wpas_dbus_signal_p2p_group_started(struct wpa_supplicant *wpa_s,
979 const struct wpa_ssid *ssid,
980 int client, int network_id)
db9133ac 981{
9abafccc
JB
982 DBusMessage *msg;
983 DBusMessageIter iter, dict_iter;
984 struct wpas_dbus_priv *iface;
985 char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
986 char group_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
8fc2fb56 987
9abafccc 988 iface = wpa_s->parent->global->dbus;
8fc2fb56 989
9abafccc
JB
990 /* Do nothing if the control interface is not turned on */
991 if (iface == NULL)
992 return;
abd7a4e3 993
9abafccc
JB
994 if (wpas_dbus_get_group_obj_path(wpa_s, ssid, group_obj_path) < 0)
995 return;
abd7a4e3 996
9abafccc
JB
997 /* New interface has been created for this group */
998 msg = dbus_message_new_signal(wpa_s->parent->dbus_new_path,
999 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1000 "GroupStarted");
abd7a4e3 1001
9abafccc
JB
1002 if (msg == NULL)
1003 return;
7ae7b192 1004
9abafccc
JB
1005 dbus_message_iter_init_append(msg, &iter);
1006 if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
1007 goto nomem;
7ae7b192 1008
9abafccc
JB
1009 /*
1010 * In case the device supports creating a separate interface the
1011 * DBus client will need to know the object path for the interface
1012 * object this group was created on, so include it here.
1013 */
1014 if (!wpa_dbus_dict_append_object_path(&dict_iter,
1015 "interface_object",
1016 wpa_s->dbus_new_path))
1017 goto nomem;
9b61515c 1018
9abafccc
JB
1019 if (!wpa_dbus_dict_append_string(&dict_iter, "role",
1020 client ? "client" : "GO"))
1021 goto nomem;
9b61515c 1022
9abafccc
JB
1023 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1024 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
1025 wpa_s->parent->dbus_new_path, network_id);
1026
1027 if (!wpa_dbus_dict_append_object_path(&dict_iter, "group_object",
1028 group_obj_path) ||
1029 !wpa_dbus_dict_append_object_path(&dict_iter, "network_object",
1030 net_obj_path) ||
1031 !wpa_dbus_dict_close_write(&iter, &dict_iter))
1032 goto nomem;
1033
1034 dbus_connection_send(iface->con, msg, NULL);
1035
1036nomem:
1037 dbus_message_unref(msg);
1038}
7ae7b192
JM
1039
1040
1041/**
7ae7b192 1042 *
9abafccc
JB
1043 * Method to emit GONeogtiation Success or Failure signals based
1044 * on status.
1045 * @status: Status of the GO neg request. 0 for success, other for errors.
7ae7b192 1046 */
e5a359cf
RC
1047void wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s,
1048 struct p2p_go_neg_results *res)
7ae7b192 1049{
9abafccc 1050 DBusMessage *msg;
e5a359cf
RC
1051 DBusMessageIter iter, dict_iter;
1052 DBusMessageIter iter_dict_entry, iter_dict_val, iter_dict_array;
9abafccc 1053 struct wpas_dbus_priv *iface;
e5a359cf
RC
1054 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1055 dbus_int32_t freqs[P2P_MAX_CHANNELS];
1056 dbus_int32_t *f_array = freqs;
1057
8fc2fb56 1058
9abafccc 1059 iface = wpa_s->global->dbus;
8fc2fb56 1060
e5a359cf 1061 os_memset(freqs, 0, sizeof(freqs));
9abafccc
JB
1062 /* Do nothing if the control interface is not turned on */
1063 if (iface == NULL)
1064 return;
8fc2fb56 1065
e5a359cf
RC
1066 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1067 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
1068 wpa_s->dbus_new_path, MAC2STR(res->peer_device_addr));
1069 path = peer_obj_path;
1070
9abafccc
JB
1071 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1072 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
e5a359cf
RC
1073 res->status ? "GONegotiationFailure" :
1074 "GONegotiationSuccess");
9abafccc
JB
1075 if (msg == NULL)
1076 return;
8fc2fb56 1077
e5a359cf
RC
1078 dbus_message_iter_init_append(msg, &iter);
1079 if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
1080 goto err;
1081 if (!wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
1082 path) ||
1083 !wpa_dbus_dict_append_int32(&dict_iter, "status", res->status))
1084 goto err;
1085
1086 if (!res->status) {
1087 int i = 0;
1088 int freq_list_num = 0;
1089
1090 if (res->role_go) {
1091 if (!wpa_dbus_dict_append_byte_array(
1092 &dict_iter, "passphrase",
1093 (const char *) res->passphrase,
1094 sizeof(res->passphrase)))
1095 goto err;
1096 }
1097
1098 if (!wpa_dbus_dict_append_string(&dict_iter, "role_go",
1099 res->role_go ? "GO" :
1100 "client") ||
1101 !wpa_dbus_dict_append_int32(&dict_iter, "frequency",
1102 res->freq) ||
1103 !wpa_dbus_dict_append_byte_array(&dict_iter, "ssid",
1104 (const char *) res->ssid,
1105 res->ssid_len) ||
1106 !wpa_dbus_dict_append_byte_array(&dict_iter,
1107 "peer_device_addr",
1108 (const char *)
1109 res->peer_device_addr,
1110 ETH_ALEN) ||
1111 !wpa_dbus_dict_append_byte_array(&dict_iter,
1112 "peer_interface_addr",
1113 (const char *)
1114 res->peer_interface_addr,
1115 ETH_ALEN) ||
1116 !wpa_dbus_dict_append_string(&dict_iter, "wps_method",
1117 p2p_wps_method_text(
1118 res->wps_method)))
9abafccc 1119 goto err;
e5a359cf
RC
1120
1121 for (i = 0; i < P2P_MAX_CHANNELS; i++) {
1122 if (res->freq_list[i]) {
1123 freqs[i] = res->freq_list[i];
1124 freq_list_num++;
1125 }
9abafccc 1126 }
e5a359cf
RC
1127
1128 if (!wpa_dbus_dict_begin_array(&dict_iter,
1129 "frequency_list",
1130 DBUS_TYPE_INT32_AS_STRING,
1131 &iter_dict_entry,
1132 &iter_dict_val,
1133 &iter_dict_array))
1134 goto err;
1135
1136 if (!dbus_message_iter_append_fixed_array(&iter_dict_array,
1137 DBUS_TYPE_INT32,
1138 &f_array,
1139 freq_list_num))
1140 goto err;
1141
1142 if (!wpa_dbus_dict_end_array(&dict_iter,
1143 &iter_dict_entry,
1144 &iter_dict_val,
1145 &iter_dict_array))
1146 goto err;
1147
1148 if (!wpa_dbus_dict_append_int32(&dict_iter, "persistent_group",
1149 res->persistent_group) ||
1150 !wpa_dbus_dict_append_uint32(&dict_iter,
1151 "peer_config_timeout",
1152 res->peer_config_timeout))
1153 goto err;
9abafccc
JB
1154 }
1155
e5a359cf
RC
1156 if (!wpa_dbus_dict_close_write(&iter, &dict_iter))
1157 goto err;
1158
9abafccc
JB
1159 dbus_connection_send(iface->con, msg, NULL);
1160err:
1161 dbus_message_unref(msg);
8fc2fb56
WS
1162}
1163
1164
1165/**
8fc2fb56 1166 *
9abafccc
JB
1167 * Method to emit Invitation Result signal based on status and
1168 * bssid
1169 * @status: Status of the Invite request. 0 for success, other
1170 * for errors
1171 * @bssid : Basic Service Set Identifier
8fc2fb56 1172 */
9abafccc
JB
1173void wpas_dbus_signal_p2p_invitation_result(struct wpa_supplicant *wpa_s,
1174 int status, const u8 *bssid)
8fc2fb56 1175{
9abafccc
JB
1176 DBusMessage *msg;
1177 DBusMessageIter iter, dict_iter;
1178 struct wpas_dbus_priv *iface;
1179
1180 wpa_printf(MSG_INFO, "%s\n", __func__);
1181
1182 iface = wpa_s->global->dbus;
1183 /* Do nothing if the control interface is not turned on */
1184 if (iface == NULL)
26e054ce 1185 return;
8fc2fb56 1186
9abafccc
JB
1187 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1188 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1189 "InvitationResult");
8fc2fb56 1190
9abafccc
JB
1191 if (msg == NULL)
1192 return;
d114fcab 1193
9abafccc
JB
1194 dbus_message_iter_init_append(msg, &iter);
1195 if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
1196 goto nomem;
d114fcab 1197
9abafccc
JB
1198 if (!wpa_dbus_dict_append_int32(&dict_iter, "status", status))
1199 goto nomem;
1200 if (bssid) {
1201 if (!wpa_dbus_dict_append_byte_array(&dict_iter, "BSSID",
1202 (const char *) bssid,
1203 ETH_ALEN))
1204 goto nomem;
1205 }
1206 if (!wpa_dbus_dict_close_write(&iter, &dict_iter))
1207 goto nomem;
1fa5995b 1208
9abafccc 1209 dbus_connection_send(iface->con, msg, NULL);
1fa5995b 1210
9abafccc
JB
1211nomem:
1212 dbus_message_unref(msg);
1213}
1fa5995b
WS
1214
1215
8fc2fb56 1216/**
8fc2fb56 1217 *
9abafccc
JB
1218 * Method to emit a signal for a peer joining the group.
1219 * The signal will carry path to the group member object
1220 * constructed using p2p i/f addr used for connecting.
1221 *
1222 * @wpa_s: %wpa_supplicant network interface data
1223 * @member_addr: addr (p2p i/f) of the peer joining the group
8fc2fb56 1224 */
9abafccc
JB
1225void wpas_dbus_signal_p2p_peer_joined(struct wpa_supplicant *wpa_s,
1226 const u8 *member)
8fc2fb56 1227{
9abafccc
JB
1228 struct wpas_dbus_priv *iface;
1229 DBusMessage *msg;
1230 DBusMessageIter iter;
1231 char groupmember_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
8fc2fb56 1232
9abafccc 1233 iface = wpa_s->global->dbus;
8fc2fb56 1234
9abafccc
JB
1235 /* Do nothing if the control interface is not turned on */
1236 if (iface == NULL)
1237 return;
8fc2fb56 1238
9abafccc
JB
1239 if (!wpa_s->dbus_groupobj_path)
1240 return;
8fc2fb56 1241
9abafccc
JB
1242 os_snprintf(groupmember_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1243 "%s/" WPAS_DBUS_NEW_P2P_GROUPMEMBERS_PART "/"
1244 COMPACT_MACSTR,
1245 wpa_s->dbus_groupobj_path, MAC2STR(member));
1fa5995b 1246
9abafccc
JB
1247 msg = dbus_message_new_signal(wpa_s->dbus_groupobj_path,
1248 WPAS_DBUS_NEW_IFACE_P2P_GROUP,
1249 "PeerJoined");
1250 if (msg == NULL)
1251 return;
8fc2fb56 1252
9abafccc
JB
1253 dbus_message_iter_init_append(msg, &iter);
1254 path = groupmember_obj_path;
1255 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1256 &path))
8fc2fb56
WS
1257 goto err;
1258
9abafccc 1259 dbus_connection_send(iface->con, msg, NULL);
8fc2fb56 1260
9abafccc
JB
1261 dbus_message_unref(msg);
1262 return;
8fc2fb56
WS
1263
1264err:
9abafccc
JB
1265 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1266 dbus_message_unref(msg);
8fc2fb56
WS
1267}
1268
1269
1270/**
8fc2fb56 1271 *
9abafccc
JB
1272 * Method to emit a signal for a peer disconnecting the group.
1273 * The signal will carry path to the group member object
1274 * constructed using p2p i/f addr used for connecting.
1275 *
1276 * @wpa_s: %wpa_supplicant network interface data
1277 * @member_addr: addr (p2p i/f) of the peer joining the group
8fc2fb56 1278 */
9abafccc
JB
1279void wpas_dbus_signal_p2p_peer_disconnected(struct wpa_supplicant *wpa_s,
1280 const u8 *member)
8fc2fb56 1281{
9abafccc
JB
1282 struct wpas_dbus_priv *iface;
1283 DBusMessage *msg;
1284 DBusMessageIter iter;
1285 char groupmember_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1286
1287 iface = wpa_s->global->dbus;
8fc2fb56
WS
1288
1289 /* Do nothing if the control interface is not turned on */
9abafccc
JB
1290 if (iface == NULL)
1291 return;
8fc2fb56 1292
9abafccc
JB
1293 if (!wpa_s->dbus_groupobj_path)
1294 return;
8fc2fb56 1295
9abafccc
JB
1296 os_snprintf(groupmember_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1297 "%s/" WPAS_DBUS_NEW_P2P_GROUPMEMBERS_PART "/"
1298 COMPACT_MACSTR,
1299 wpa_s->dbus_groupobj_path, MAC2STR(member));
8fc2fb56 1300
9abafccc
JB
1301 msg = dbus_message_new_signal(wpa_s->dbus_groupobj_path,
1302 WPAS_DBUS_NEW_IFACE_P2P_GROUP,
1303 "PeerDisconnected");
1304 if (msg == NULL)
1305 return;
8fc2fb56 1306
9abafccc
JB
1307 dbus_message_iter_init_append(msg, &iter);
1308 path = groupmember_obj_path;
1309 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1310 &path))
1311 goto err;
8fc2fb56 1312
9abafccc 1313 dbus_connection_send(iface->con, msg, NULL);
1fa5995b 1314
9abafccc
JB
1315 dbus_message_unref(msg);
1316 return;
1fa5995b 1317
9abafccc
JB
1318err:
1319 wpa_printf(MSG_ERROR, "dbus: Failed to construct PeerDisconnected "
1320 "signal");
1321 dbus_message_unref(msg);
1322}
1fa5995b
WS
1323
1324
8fc2fb56 1325/**
8fc2fb56 1326 *
9abafccc
JB
1327 * Method to emit a signal for a service discovery request.
1328 * The signal will carry station address, frequency, dialog token,
1329 * update indicator and it tlvs
1330 *
1331 * @wpa_s: %wpa_supplicant network interface data
1332 * @sa: station addr (p2p i/f) of the peer
1333 * @dialog_token: service discovery request dialog token
1334 * @update_indic: service discovery request update indicator
1335 * @tlvs: service discovery request genrated byte array of tlvs
1336 * @tlvs_len: service discovery request tlvs length
8fc2fb56 1337 */
9abafccc
JB
1338void wpas_dbus_signal_p2p_sd_request(struct wpa_supplicant *wpa_s,
1339 int freq, const u8 *sa, u8 dialog_token,
1340 u16 update_indic, const u8 *tlvs,
1341 size_t tlvs_len)
8fc2fb56 1342{
9abafccc
JB
1343 DBusMessage *msg;
1344 DBusMessageIter iter, dict_iter;
1345 struct wpas_dbus_priv *iface;
1346 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1347 iface = wpa_s->global->dbus;
8fc2fb56
WS
1348
1349 /* Do nothing if the control interface is not turned on */
9abafccc
JB
1350 if (iface == NULL)
1351 return;
8fc2fb56 1352
9abafccc
JB
1353 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1354 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1355 "ServiceDiscoveryRequest");
1356 if (msg == NULL)
1357 return;
8fc2fb56 1358
9abafccc 1359 /* Check if this is a known peer */
b3bcc0f5 1360 if (!p2p_peer_known(wpa_s->global->p2p, sa))
9abafccc 1361 goto error;
8fc2fb56 1362
9abafccc
JB
1363 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1364 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1365 COMPACT_MACSTR, wpa_s->dbus_new_path, MAC2STR(sa));
8fc2fb56 1366
9abafccc
JB
1367 path = peer_obj_path;
1368
1369 dbus_message_iter_init_append(msg, &iter);
1370 if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
1371 goto error;
1372
1373
1374 if (!wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
1375 path) ||
1376 !wpa_dbus_dict_append_int32(&dict_iter, "frequency", freq) ||
1377 !wpa_dbus_dict_append_int32(&dict_iter, "dialog_token",
1378 dialog_token) ||
1379 !wpa_dbus_dict_append_uint16(&dict_iter, "update_indicator",
1380 update_indic) ||
1381 !wpa_dbus_dict_append_byte_array(&dict_iter, "tlvs",
1382 (const char *) tlvs,
1383 tlvs_len) ||
1384 !wpa_dbus_dict_close_write(&iter, &dict_iter))
1385 goto error;
1386
1387 dbus_connection_send(iface->con, msg, NULL);
1388 dbus_message_unref(msg);
1389 return;
1390error:
1391 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1392 dbus_message_unref(msg);
8fc2fb56
WS
1393}
1394
1395
17efbfac 1396/**
17efbfac 1397 *
9abafccc
JB
1398 * Method to emit a signal for a service discovery response.
1399 * The signal will carry station address, update indicator and it
1400 * tlvs
1401 *
1402 * @wpa_s: %wpa_supplicant network interface data
1403 * @sa: station addr (p2p i/f) of the peer
1404 * @update_indic: service discovery request update indicator
1405 * @tlvs: service discovery request genrated byte array of tlvs
1406 * @tlvs_len: service discovery request tlvs length
17efbfac 1407 */
9abafccc
JB
1408void wpas_dbus_signal_p2p_sd_response(struct wpa_supplicant *wpa_s,
1409 const u8 *sa, u16 update_indic,
1410 const u8 *tlvs, size_t tlvs_len)
8fc2fb56 1411{
9abafccc
JB
1412 DBusMessage *msg;
1413 DBusMessageIter iter, dict_iter;
1414 struct wpas_dbus_priv *iface;
1415 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1416 iface = wpa_s->global->dbus;
8fc2fb56
WS
1417
1418 /* Do nothing if the control interface is not turned on */
9abafccc
JB
1419 if (iface == NULL)
1420 return;
8fc2fb56 1421
9abafccc
JB
1422 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1423 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1424 "ServiceDiscoveryResponse");
1425 if (msg == NULL)
1426 return;
8fc2fb56 1427
9abafccc 1428 /* Check if this is a known peer */
b3bcc0f5 1429 if (!p2p_peer_known(wpa_s->global->p2p, sa))
9abafccc 1430 goto error;
8fc2fb56 1431
9abafccc
JB
1432 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1433 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
1434 COMPACT_MACSTR, wpa_s->dbus_new_path, MAC2STR(sa));
8fc2fb56 1435
9abafccc 1436 path = peer_obj_path;
8fc2fb56 1437
9abafccc
JB
1438 dbus_message_iter_init_append(msg, &iter);
1439 if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
1440 goto error;
1441
1442 if (!wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
1443 path) ||
1444 !wpa_dbus_dict_append_uint16(&dict_iter, "update_indicator",
1445 update_indic) ||
1446 !wpa_dbus_dict_append_byte_array(&dict_iter, "tlvs",
1447 (const char *) tlvs,
1448 tlvs_len) ||
1449 !wpa_dbus_dict_close_write(&iter, &dict_iter))
1450 goto error;
8fc2fb56 1451
8fc2fb56 1452
9abafccc
JB
1453 dbus_connection_send(iface->con, msg, NULL);
1454 dbus_message_unref(msg);
1455 return;
1456error:
1457 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1458 dbus_message_unref(msg);
8fc2fb56
WS
1459}
1460
c2762e41
JS
1461/**
1462 * wpas_dbus_signal_persistent_group - Send a persistent group related
1463 * event signal
1464 * @wpa_s: %wpa_supplicant network interface data
1465 * @id: new persistent group id
1466 * @sig_name: signal name - PersistentGroupAdded, PersistentGroupRemoved
1467 * @properties: determines if add second argument with object properties
1468 *
1469 * Notify listeners about an event related to persistent groups.
1470 */
1471static void wpas_dbus_signal_persistent_group(struct wpa_supplicant *wpa_s,
1472 int id, const char *sig_name,
1473 int properties)
1474{
1475 struct wpas_dbus_priv *iface;
1476 DBusMessage *msg;
6aeeb6fa 1477 DBusMessageIter iter;
c2762e41
JS
1478 char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
1479
1480 iface = wpa_s->global->dbus;
1481
1482 /* Do nothing if the control interface is not turned on */
1483 if (iface == NULL)
1484 return;
1485
1486 os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1487 "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
1488 wpa_s->dbus_new_path, id);
1489
1490 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1491 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1492 sig_name);
1493 if (msg == NULL)
1494 return;
1495
1496 dbus_message_iter_init_append(msg, &iter);
1497 path = pgrp_obj_path;
1498 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1499 &path))
1500 goto err;
1501
1502 if (properties) {
6aeeb6fa
DW
1503 if (!wpa_dbus_get_object_properties(
1504 iface, pgrp_obj_path,
1505 WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, &iter))
c2762e41
JS
1506 goto err;
1507 }
1508
1509 dbus_connection_send(iface->con, msg, NULL);
1510
1511 dbus_message_unref(msg);
1512 return;
1513
1514err:
1515 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1516 dbus_message_unref(msg);
1517}
1518
1519
1520/**
1521 * wpas_dbus_signal_persistent_group_added - Send a persistent_group
1522 * added signal
1523 * @wpa_s: %wpa_supplicant network interface data
1524 * @id: new persistent group id
1525 *
1526 * Notify listeners about addition of a new persistent group.
1527 */
1528static void wpas_dbus_signal_persistent_group_added(
1529 struct wpa_supplicant *wpa_s, int id)
1530{
1531 wpas_dbus_signal_persistent_group(wpa_s, id, "PersistentGroupAdded",
1532 TRUE);
1533}
1534
1535
1536/**
1537 * wpas_dbus_signal_persistent_group_removed - Send a persistent_group
1538 * removed signal
1539 * @wpa_s: %wpa_supplicant network interface data
1540 * @id: persistent group id
1541 *
1542 * Notify listeners about removal of a persistent group.
1543 */
1544static void wpas_dbus_signal_persistent_group_removed(
1545 struct wpa_supplicant *wpa_s, int id)
1546{
1547 wpas_dbus_signal_persistent_group(wpa_s, id, "PersistentGroupRemoved",
28550706 1548 FALSE);
c2762e41
JS
1549}
1550
3734552f
JS
1551
1552/**
1553 * wpas_dbus_signal_p2p_wps_failed - Signals WpsFailed event
1554 * @wpa_s: %wpa_supplicant network interface data
1555 *
1556 * Sends Event dbus signal with name "fail" and dictionary containing
1557 * "msg" field with fail message number (int32) as arguments
1558 */
1559void wpas_dbus_signal_p2p_wps_failed(struct wpa_supplicant *wpa_s,
1560 struct wps_event_fail *fail)
1561{
1562
1563 DBusMessage *msg;
1564 DBusMessageIter iter, dict_iter;
1565 struct wpas_dbus_priv *iface;
1566 char *key = "fail";
1567
1568 iface = wpa_s->global->dbus;
1569
1570 /* Do nothing if the control interface is not turned on */
1571 if (iface == NULL)
1572 return;
1573
1574 msg = dbus_message_new_signal(wpa_s->dbus_new_path,
1575 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
1576 "WpsFailed");
1577 if (msg == NULL)
1578 return;
1579
1580 dbus_message_iter_init_append(msg, &iter);
1581
1582 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
1583 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
1584 !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
1585 !wpa_dbus_dict_append_int16(&dict_iter, "config_error",
1586 fail->config_error) ||
1587 !wpa_dbus_dict_close_write(&iter, &dict_iter))
1588 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
1589 else
1590 dbus_connection_send(iface->con, msg, NULL);
1591
1592 dbus_message_unref(msg);
1593}
1594
9abafccc 1595#endif /*CONFIG_P2P*/
8fc2fb56 1596
9abafccc
JB
1597
1598/**
1599 * wpas_dbus_signal_prop_changed - Signals change of property
1600 * @wpa_s: %wpa_supplicant network interface data
1601 * @property: indicates which property has changed
1602 *
83fa0722 1603 * Sends PropertyChanged signals with path, interface and arguments
9abafccc
JB
1604 * depending on which property has changed.
1605 */
1606void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
1607 enum wpas_dbus_prop property)
1608{
9abafccc
JB
1609 char *prop;
1610
1611 if (wpa_s->dbus_new_path == NULL)
1612 return; /* Skip signal since D-Bus setup is not yet ready */
1613
1614 switch (property) {
1615 case WPAS_DBUS_PROP_AP_SCAN:
9abafccc
JB
1616 prop = "ApScan";
1617 break;
1618 case WPAS_DBUS_PROP_SCANNING:
9abafccc
JB
1619 prop = "Scanning";
1620 break;
1621 case WPAS_DBUS_PROP_STATE:
9abafccc
JB
1622 prop = "State";
1623 break;
1624 case WPAS_DBUS_PROP_CURRENT_BSS:
9abafccc
JB
1625 prop = "CurrentBSS";
1626 break;
1627 case WPAS_DBUS_PROP_CURRENT_NETWORK:
9abafccc
JB
1628 prop = "CurrentNetwork";
1629 break;
1630 case WPAS_DBUS_PROP_BSSS:
9abafccc
JB
1631 prop = "BSSs";
1632 break;
1633 case WPAS_DBUS_PROP_CURRENT_AUTH_MODE:
9abafccc
JB
1634 prop = "CurrentAuthMode";
1635 break;
1636 default:
1637 wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
1638 __func__, property);
1639 return;
1640 }
1641
1642 wpa_dbus_mark_property_changed(wpa_s->global->dbus,
1643 wpa_s->dbus_new_path,
1644 WPAS_DBUS_NEW_IFACE_INTERFACE, prop);
1645}
1646
1647
1648/**
1649 * wpas_dbus_bss_signal_prop_changed - Signals change of BSS property
1650 * @wpa_s: %wpa_supplicant network interface data
1651 * @property: indicates which property has changed
1652 * @id: unique BSS identifier
1653 *
1654 * Sends PropertyChanged signals with path, interface, and arguments depending
1655 * on which property has changed.
1656 */
1657void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant *wpa_s,
1658 enum wpas_dbus_bss_prop property,
1659 unsigned int id)
1660{
1661 char path[WPAS_DBUS_OBJECT_PATH_MAX];
1662 char *prop;
1663
1664 switch (property) {
1665 case WPAS_DBUS_BSS_PROP_SIGNAL:
1666 prop = "Signal";
1667 break;
1668 case WPAS_DBUS_BSS_PROP_FREQ:
1669 prop = "Frequency";
1670 break;
1671 case WPAS_DBUS_BSS_PROP_MODE:
1672 prop = "Mode";
1673 break;
1674 case WPAS_DBUS_BSS_PROP_PRIVACY:
1675 prop = "Privacy";
1676 break;
1677 case WPAS_DBUS_BSS_PROP_RATES:
1678 prop = "Rates";
1679 break;
1680 case WPAS_DBUS_BSS_PROP_WPA:
1681 prop = "WPA";
1682 break;
1683 case WPAS_DBUS_BSS_PROP_RSN:
1684 prop = "RSN";
1685 break;
1686 case WPAS_DBUS_BSS_PROP_IES:
1687 prop = "IEs";
1688 break;
1689 default:
1690 wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
1691 __func__, property);
1692 return;
1693 }
1694
1695 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
1696 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
1697 wpa_s->dbus_new_path, id);
1698
1699 wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
1700 WPAS_DBUS_NEW_IFACE_BSS, prop);
1701}
1702
1703
1704/**
1705 * wpas_dbus_signal_debug_level_changed - Signals change of debug param
1706 * @global: wpa_global structure
1707 *
83fa0722 1708 * Sends PropertyChanged signals informing that debug level has changed.
9abafccc
JB
1709 */
1710void wpas_dbus_signal_debug_level_changed(struct wpa_global *global)
1711{
1712 wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
1713 WPAS_DBUS_NEW_INTERFACE,
1714 "DebugLevel");
1715}
1716
1717
1718/**
1719 * wpas_dbus_signal_debug_timestamp_changed - Signals change of debug param
1720 * @global: wpa_global structure
1721 *
83fa0722 1722 * Sends PropertyChanged signals informing that debug timestamp has changed.
9abafccc
JB
1723 */
1724void wpas_dbus_signal_debug_timestamp_changed(struct wpa_global *global)
1725{
1726 wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
1727 WPAS_DBUS_NEW_INTERFACE,
1728 "DebugTimestamp");
1729}
1730
1731
1732/**
1733 * wpas_dbus_signal_debug_show_keys_changed - Signals change of debug param
1734 * @global: wpa_global structure
1735 *
83fa0722 1736 * Sends PropertyChanged signals informing that debug show_keys has changed.
9abafccc
JB
1737 */
1738void wpas_dbus_signal_debug_show_keys_changed(struct wpa_global *global)
1739{
1740 wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
1741 WPAS_DBUS_NEW_INTERFACE,
1742 "DebugShowKeys");
1743}
1744
1745
1746static void wpas_dbus_register(struct wpa_dbus_object_desc *obj_desc,
1747 void *priv,
1748 WPADBusArgumentFreeFunction priv_free,
1749 const struct wpa_dbus_method_desc *methods,
1750 const struct wpa_dbus_property_desc *properties,
1751 const struct wpa_dbus_signal_desc *signals)
1752{
1753 int n;
1754
1755 obj_desc->user_data = priv;
1756 obj_desc->user_data_free_func = priv_free;
1757 obj_desc->methods = methods;
1758 obj_desc->properties = properties;
1759 obj_desc->signals = signals;
1760
1761 for (n = 0; properties && properties->dbus_property; properties++)
1762 n++;
1763
1764 obj_desc->prop_changed_flags = os_zalloc(n);
1765 if (!obj_desc->prop_changed_flags)
1766 wpa_printf(MSG_DEBUG, "dbus: %s: can't register handlers",
1767 __func__);
1768}
1769
1770
1771static const struct wpa_dbus_method_desc wpas_dbus_global_methods[] = {
1772 { "CreateInterface", WPAS_DBUS_NEW_INTERFACE,
1773 (WPADBusMethodHandler) &wpas_dbus_handler_create_interface,
1774 {
1775 { "args", "a{sv}", ARG_IN },
1776 { "path", "o", ARG_OUT },
1777 END_ARGS
1778 }
1779 },
1780 { "RemoveInterface", WPAS_DBUS_NEW_INTERFACE,
1781 (WPADBusMethodHandler) &wpas_dbus_handler_remove_interface,
1782 {
1783 { "path", "o", ARG_IN },
1784 END_ARGS
1785 }
1786 },
1787 { "GetInterface", WPAS_DBUS_NEW_INTERFACE,
1788 (WPADBusMethodHandler) &wpas_dbus_handler_get_interface,
1789 {
1790 { "ifname", "s", ARG_IN },
1791 { "path", "o", ARG_OUT },
1792 END_ARGS
1793 }
1794 },
1795 { NULL, NULL, NULL, { END_ARGS } }
1796};
1797
1798static const struct wpa_dbus_property_desc wpas_dbus_global_properties[] = {
1799 { "DebugLevel", WPAS_DBUS_NEW_INTERFACE, "s",
6aeeb6fa 1800 wpas_dbus_getter_debug_level,
33206664 1801 wpas_dbus_setter_debug_level
9abafccc
JB
1802 },
1803 { "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE, "b",
6aeeb6fa 1804 wpas_dbus_getter_debug_timestamp,
33206664 1805 wpas_dbus_setter_debug_timestamp
9abafccc
JB
1806 },
1807 { "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE, "b",
6aeeb6fa 1808 wpas_dbus_getter_debug_show_keys,
33206664 1809 wpas_dbus_setter_debug_show_keys
9abafccc
JB
1810 },
1811 { "Interfaces", WPAS_DBUS_NEW_INTERFACE, "ao",
6aeeb6fa 1812 wpas_dbus_getter_interfaces,
33206664 1813 NULL
9abafccc
JB
1814 },
1815 { "EapMethods", WPAS_DBUS_NEW_INTERFACE, "as",
6aeeb6fa 1816 wpas_dbus_getter_eap_methods,
33206664 1817 NULL
9abafccc 1818 },
33206664 1819 { NULL, NULL, NULL, NULL, NULL }
9abafccc
JB
1820};
1821
1822static const struct wpa_dbus_signal_desc wpas_dbus_global_signals[] = {
1823 { "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE,
1824 {
1825 { "path", "o", ARG_OUT },
1826 { "properties", "a{sv}", ARG_OUT },
1827 END_ARGS
1828 }
1829 },
1830 { "InterfaceRemoved", WPAS_DBUS_NEW_INTERFACE,
1831 {
1832 { "path", "o", ARG_OUT },
1833 END_ARGS
1834 }
1835 },
a9022616
DW
1836 { "NetworkRequest", WPAS_DBUS_NEW_IFACE_INTERFACE,
1837 {
1838 { "path", "o", ARG_OUT },
1839 { "field", "s", ARG_OUT },
1840 { "text", "s", ARG_OUT },
1841 END_ARGS
1842 }
1843 },
4483f23e 1844 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
9abafccc
JB
1845 { "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE,
1846 {
1847 { "properties", "a{sv}", ARG_OUT },
1848 END_ARGS
1849 }
1850 },
1851 { NULL, NULL, { END_ARGS } }
1852};
1853
1854
1855/**
1856 * wpas_dbus_ctrl_iface_init - Initialize dbus control interface
1857 * @global: Pointer to global data from wpa_supplicant_init()
1858 * Returns: 0 on success or -1 on failure
1859 *
1860 * Initialize the dbus control interface for wpa_supplicantand and start
1861 * receiving commands from external programs over the bus.
1862 */
1863int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv *priv)
1864{
1865 struct wpa_dbus_object_desc *obj_desc;
1866 int ret;
1867
1868 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
1869 if (!obj_desc) {
1870 wpa_printf(MSG_ERROR, "Not enough memory "
1871 "to create object description");
1872 return -1;
1873 }
1874
1875 wpas_dbus_register(obj_desc, priv->global, NULL,
1876 wpas_dbus_global_methods,
1877 wpas_dbus_global_properties,
1878 wpas_dbus_global_signals);
1879
1880 wpa_printf(MSG_DEBUG, "dbus: Register D-Bus object '%s'",
1881 WPAS_DBUS_NEW_PATH);
1882 ret = wpa_dbus_ctrl_iface_init(priv, WPAS_DBUS_NEW_PATH,
1883 WPAS_DBUS_NEW_SERVICE,
1884 obj_desc);
1885 if (ret < 0)
1886 free_dbus_object_desc(obj_desc);
1887 else
1888 priv->dbus_new_initialized = 1;
1889
1890 return ret;
1891}
1892
1893
1894/**
1895 * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for
1896 * wpa_supplicant
1897 * @iface: Pointer to dbus private data from wpas_dbus_init()
1898 *
1899 * Deinitialize the dbus control interface that was initialized with
1900 * wpas_dbus_ctrl_iface_init().
1901 */
1902void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv *iface)
1903{
1904 if (!iface->dbus_new_initialized)
1905 return;
1906 wpa_printf(MSG_DEBUG, "dbus: Unregister D-Bus object '%s'",
1907 WPAS_DBUS_NEW_PATH);
1908 dbus_connection_unregister_object_path(iface->con,
1909 WPAS_DBUS_NEW_PATH);
1910}
1911
1912
1913static void wpa_dbus_free(void *ptr)
1914{
1915 os_free(ptr);
1916}
1917
1918
1919static const struct wpa_dbus_property_desc wpas_dbus_network_properties[] = {
1920 { "Properties", WPAS_DBUS_NEW_IFACE_NETWORK, "a{sv}",
6aeeb6fa 1921 wpas_dbus_getter_network_properties,
33206664 1922 wpas_dbus_setter_network_properties
9abafccc
JB
1923 },
1924 { "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK, "b",
6aeeb6fa 1925 wpas_dbus_getter_enabled,
33206664 1926 wpas_dbus_setter_enabled
9abafccc 1927 },
33206664 1928 { NULL, NULL, NULL, NULL, NULL }
9abafccc
JB
1929};
1930
1931
1932static const struct wpa_dbus_signal_desc wpas_dbus_network_signals[] = {
4483f23e 1933 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
9abafccc
JB
1934 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK,
1935 {
1936 { "properties", "a{sv}", ARG_OUT },
1937 END_ARGS
1938 }
1939 },
1940 { NULL, NULL, { END_ARGS } }
1941};
1942
1943
1944/**
1945 * wpas_dbus_register_network - Register a configured network with dbus
1946 * @wpa_s: wpa_supplicant interface structure
1947 * @ssid: network configuration data
1948 * Returns: 0 on success, -1 on failure
1949 *
1950 * Registers network representing object with dbus
1951 */
1952int wpas_dbus_register_network(struct wpa_supplicant *wpa_s,
1953 struct wpa_ssid *ssid)
1954{
1955 struct wpas_dbus_priv *ctrl_iface;
1956 struct wpa_dbus_object_desc *obj_desc;
1957 struct network_handler_args *arg;
1958 char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
1959
7a2b53b4 1960#ifdef CONFIG_P2P
c2762e41
JS
1961 /*
1962 * If it is a persistent group register it as such.
1963 * This is to handle cases where an interface is being initialized
1964 * with a list of networks read from config.
1965 */
1966 if (network_is_persistent_group(ssid))
1967 return wpas_dbus_register_persistent_group(wpa_s, ssid);
7a2b53b4 1968#endif /* CONFIG_P2P */
c2762e41 1969
9abafccc
JB
1970 /* Do nothing if the control interface is not turned on */
1971 if (wpa_s == NULL || wpa_s->global == NULL)
1972 return 0;
1973 ctrl_iface = wpa_s->global->dbus;
1974 if (ctrl_iface == NULL)
1975 return 0;
1976
1977 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1978 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
1979 wpa_s->dbus_new_path, ssid->id);
1980
1981 wpa_printf(MSG_DEBUG, "dbus: Register network object '%s'",
1982 net_obj_path);
1983 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
1984 if (!obj_desc) {
1985 wpa_printf(MSG_ERROR, "Not enough memory "
1986 "to create object description");
1987 goto err;
1988 }
1989
1990 /* allocate memory for handlers arguments */
1991 arg = os_zalloc(sizeof(struct network_handler_args));
1992 if (!arg) {
1993 wpa_printf(MSG_ERROR, "Not enough memory "
1994 "to create arguments for method");
1995 goto err;
1996 }
1997
1998 arg->wpa_s = wpa_s;
1999 arg->ssid = ssid;
2000
2001 wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
2002 wpas_dbus_network_properties,
2003 wpas_dbus_network_signals);
2004
2005 if (wpa_dbus_register_object_per_iface(ctrl_iface, net_obj_path,
2006 wpa_s->ifname, obj_desc))
2007 goto err;
2008
2009 wpas_dbus_signal_network_added(wpa_s, ssid->id);
2010
2011 return 0;
2012
2013err:
2014 free_dbus_object_desc(obj_desc);
2015 return -1;
2016}
2017
2018
2019/**
2020 * wpas_dbus_unregister_network - Unregister a configured network from dbus
2021 * @wpa_s: wpa_supplicant interface structure
2022 * @nid: network id
2023 * Returns: 0 on success, -1 on failure
2024 *
2025 * Unregisters network representing object from dbus
2026 */
2027int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid)
2028{
2029 struct wpas_dbus_priv *ctrl_iface;
2030 char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2031 int ret;
c2762e41
JS
2032 struct wpa_ssid *ssid;
2033
2034 ssid = wpa_config_get_network(wpa_s->conf, nid);
2035
7a2b53b4 2036#ifdef CONFIG_P2P
c2762e41
JS
2037 /* If it is a persistent group unregister it as such */
2038 if (ssid && network_is_persistent_group(ssid))
2039 return wpas_dbus_unregister_persistent_group(wpa_s, nid);
7a2b53b4 2040#endif /* CONFIG_P2P */
9abafccc
JB
2041
2042 /* Do nothing if the control interface is not turned on */
86c6626c 2043 if (wpa_s->global == NULL || wpa_s->dbus_new_path == NULL)
9abafccc
JB
2044 return 0;
2045 ctrl_iface = wpa_s->global->dbus;
2046 if (ctrl_iface == NULL)
2047 return 0;
2048
2049 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2050 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
2051 wpa_s->dbus_new_path, nid);
2052
2053 wpa_printf(MSG_DEBUG, "dbus: Unregister network object '%s'",
2054 net_obj_path);
2055 ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, net_obj_path);
2056
2057 if (!ret)
2058 wpas_dbus_signal_network_removed(wpa_s, nid);
2059
2060 return ret;
2061}
2062
2063
2064static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = {
2065 { "SSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
6aeeb6fa 2066 wpas_dbus_getter_bss_ssid,
33206664 2067 NULL
9abafccc
JB
2068 },
2069 { "BSSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
6aeeb6fa 2070 wpas_dbus_getter_bss_bssid,
33206664 2071 NULL
9abafccc
JB
2072 },
2073 { "Privacy", WPAS_DBUS_NEW_IFACE_BSS, "b",
6aeeb6fa 2074 wpas_dbus_getter_bss_privacy,
33206664 2075 NULL
9abafccc
JB
2076 },
2077 { "Mode", WPAS_DBUS_NEW_IFACE_BSS, "s",
6aeeb6fa 2078 wpas_dbus_getter_bss_mode,
33206664 2079 NULL
9abafccc
JB
2080 },
2081 { "Signal", WPAS_DBUS_NEW_IFACE_BSS, "n",
6aeeb6fa 2082 wpas_dbus_getter_bss_signal,
33206664 2083 NULL
9abafccc
JB
2084 },
2085 { "Frequency", WPAS_DBUS_NEW_IFACE_BSS, "q",
6aeeb6fa 2086 wpas_dbus_getter_bss_frequency,
33206664 2087 NULL
9abafccc
JB
2088 },
2089 { "Rates", WPAS_DBUS_NEW_IFACE_BSS, "au",
6aeeb6fa 2090 wpas_dbus_getter_bss_rates,
33206664 2091 NULL
9abafccc
JB
2092 },
2093 { "WPA", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
6aeeb6fa 2094 wpas_dbus_getter_bss_wpa,
33206664 2095 NULL
9abafccc
JB
2096 },
2097 { "RSN", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
6aeeb6fa 2098 wpas_dbus_getter_bss_rsn,
33206664 2099 NULL
9abafccc
JB
2100 },
2101 { "IEs", WPAS_DBUS_NEW_IFACE_BSS, "ay",
6aeeb6fa 2102 wpas_dbus_getter_bss_ies,
33206664 2103 NULL
9abafccc 2104 },
33206664 2105 { NULL, NULL, NULL, NULL, NULL }
9abafccc
JB
2106};
2107
2108
2109static const struct wpa_dbus_signal_desc wpas_dbus_bss_signals[] = {
4483f23e 2110 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
9abafccc
JB
2111 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSS,
2112 {
2113 { "properties", "a{sv}", ARG_OUT },
2114 END_ARGS
2115 }
2116 },
2117 { NULL, NULL, { END_ARGS } }
2118};
2119
2120
2121/**
2122 * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus
2123 * @wpa_s: wpa_supplicant interface structure
2124 * @bssid: scanned network bssid
2125 * @id: unique BSS identifier
2126 * Returns: 0 on success, -1 on failure
2127 *
2128 * Unregisters BSS representing object from dbus
2129 */
2130int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s,
2131 u8 bssid[ETH_ALEN], unsigned int id)
2132{
2133 struct wpas_dbus_priv *ctrl_iface;
2134 char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2135
2136 /* Do nothing if the control interface is not turned on */
2137 if (wpa_s == NULL || wpa_s->global == NULL)
2138 return 0;
2139 ctrl_iface = wpa_s->global->dbus;
2140 if (ctrl_iface == NULL)
2141 return 0;
2142
2143 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2144 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
2145 wpa_s->dbus_new_path, id);
2146
2147 wpa_printf(MSG_DEBUG, "dbus: Unregister BSS object '%s'",
2148 bss_obj_path);
2149 if (wpa_dbus_unregister_object_per_iface(ctrl_iface, bss_obj_path)) {
2150 wpa_printf(MSG_ERROR, "dbus: Cannot unregister BSS object %s",
2151 bss_obj_path);
2152 return -1;
2153 }
2154
2155 wpas_dbus_signal_bss_removed(wpa_s, bss_obj_path);
2156 wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSSS);
2157
2158 return 0;
2159}
2160
2161
2162/**
2163 * wpas_dbus_register_bss - Register a scanned BSS with dbus
2164 * @wpa_s: wpa_supplicant interface structure
2165 * @bssid: scanned network bssid
2166 * @id: unique BSS identifier
2167 * Returns: 0 on success, -1 on failure
2168 *
2169 * Registers BSS representing object with dbus
2170 */
2171int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s,
2172 u8 bssid[ETH_ALEN], unsigned int id)
2173{
2174 struct wpas_dbus_priv *ctrl_iface;
2175 struct wpa_dbus_object_desc *obj_desc;
2176 char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
2177 struct bss_handler_args *arg;
2178
2179 /* Do nothing if the control interface is not turned on */
2180 if (wpa_s == NULL || wpa_s->global == NULL)
2181 return 0;
2182 ctrl_iface = wpa_s->global->dbus;
2183 if (ctrl_iface == NULL)
2184 return 0;
2185
2186 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2187 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
2188 wpa_s->dbus_new_path, id);
2189
2190 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
2191 if (!obj_desc) {
2192 wpa_printf(MSG_ERROR, "Not enough memory "
2193 "to create object description");
2194 goto err;
2195 }
2196
2197 arg = os_zalloc(sizeof(struct bss_handler_args));
2198 if (!arg) {
2199 wpa_printf(MSG_ERROR, "Not enough memory "
2200 "to create arguments for handler");
2201 goto err;
2202 }
2203 arg->wpa_s = wpa_s;
2204 arg->id = id;
2205
2206 wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
2207 wpas_dbus_bss_properties,
2208 wpas_dbus_bss_signals);
2209
2210 wpa_printf(MSG_DEBUG, "dbus: Register BSS object '%s'",
2211 bss_obj_path);
2212 if (wpa_dbus_register_object_per_iface(ctrl_iface, bss_obj_path,
2213 wpa_s->ifname, obj_desc)) {
2214 wpa_printf(MSG_ERROR,
2215 "Cannot register BSSID dbus object %s.",
2216 bss_obj_path);
2217 goto err;
2218 }
2219
2220 wpas_dbus_signal_bss_added(wpa_s, bss_obj_path);
2221 wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSSS);
2222
2223 return 0;
2224
2225err:
2226 free_dbus_object_desc(obj_desc);
2227 return -1;
2228}
2229
2230
2231static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
2232 { "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE,
2233 (WPADBusMethodHandler) &wpas_dbus_handler_scan,
2234 {
2235 { "args", "a{sv}", ARG_IN },
2236 END_ARGS
2237 }
2238 },
2239 { "Disconnect", WPAS_DBUS_NEW_IFACE_INTERFACE,
2240 (WPADBusMethodHandler) &wpas_dbus_handler_disconnect,
2241 {
2242 END_ARGS
2243 }
2244 },
2245 { "AddNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
2246 (WPADBusMethodHandler) &wpas_dbus_handler_add_network,
2247 {
2248 { "args", "a{sv}", ARG_IN },
2249 { "path", "o", ARG_OUT },
2250 END_ARGS
2251 }
2252 },
2253 { "RemoveNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
2254 (WPADBusMethodHandler) &wpas_dbus_handler_remove_network,
2255 {
2256 { "path", "o", ARG_IN },
2257 END_ARGS
2258 }
2259 },
2260 { "RemoveAllNetworks", WPAS_DBUS_NEW_IFACE_INTERFACE,
2261 (WPADBusMethodHandler) &wpas_dbus_handler_remove_all_networks,
2262 {
2263 END_ARGS
2264 }
2265 },
2266 { "SelectNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
2267 (WPADBusMethodHandler) &wpas_dbus_handler_select_network,
2268 {
2269 { "path", "o", ARG_IN },
2270 END_ARGS
2271 }
2272 },
e9c3c1af
DW
2273 { "NetworkReply", WPAS_DBUS_NEW_IFACE_INTERFACE,
2274 (WPADBusMethodHandler) &wpas_dbus_handler_network_reply,
2275 {
2276 { "path", "o", ARG_IN },
2277 { "field", "s", ARG_IN },
2278 { "value", "s", ARG_IN },
2279 END_ARGS
2280 }
2281 },
9abafccc
JB
2282 { "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
2283 (WPADBusMethodHandler) &wpas_dbus_handler_add_blob,
2284 {
2285 { "name", "s", ARG_IN },
2286 { "data", "ay", ARG_IN },
2287 END_ARGS
2288 }
2289 },
2290 { "GetBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
2291 (WPADBusMethodHandler) &wpas_dbus_handler_get_blob,
2292 {
2293 { "name", "s", ARG_IN },
2294 { "data", "ay", ARG_OUT },
2295 END_ARGS
2296 }
2297 },
2298 { "RemoveBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
2299 (WPADBusMethodHandler) &wpas_dbus_handler_remove_blob,
2300 {
2301 { "name", "s", ARG_IN },
2302 END_ARGS
2303 }
2304 },
2305#ifdef CONFIG_WPS
2306 { "Start", WPAS_DBUS_NEW_IFACE_WPS,
2307 (WPADBusMethodHandler) &wpas_dbus_handler_wps_start,
2308 {
2309 { "args", "a{sv}", ARG_IN },
2310 { "output", "a{sv}", ARG_OUT },
2311 END_ARGS
2312 }
2313 },
2314#endif /* CONFIG_WPS */
2315#ifdef CONFIG_P2P
2316 { "Find", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2317 (WPADBusMethodHandler)wpas_dbus_handler_p2p_find,
2318 {
2319 { "args", "a{sv}", ARG_IN },
2320 END_ARGS
2321 }
2322 },
2323 { "StopFind", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2324 (WPADBusMethodHandler)wpas_dbus_handler_p2p_stop_find,
2325 {
2326 END_ARGS
2327 }
2328 },
2329 { "Listen", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2330 (WPADBusMethodHandler)wpas_dbus_handler_p2p_listen,
2331 {
2332 { "timeout", "i", ARG_IN },
2333 END_ARGS
2334 }
2335 },
2336 { "ExtendedListen", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2337 (WPADBusMethodHandler)wpas_dbus_handler_p2p_extendedlisten,
2338 {
2339 { "args", "a{sv}", ARG_IN },
2340 END_ARGS
2341 }
2342 },
2343 { "PresenceRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2344 (WPADBusMethodHandler)wpas_dbus_handler_p2p_presence_request,
2345 {
2346 { "args", "a{sv}", ARG_IN },
2347 END_ARGS
2348 }
2349 },
2350 { "ProvisionDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2351 (WPADBusMethodHandler)wpas_dbus_handler_p2p_prov_disc_req,
2352 {
2353 { "peer", "o", ARG_IN },
2354 { "config_method", "s", ARG_IN },
2355 END_ARGS
2356 }
2357 },
2358 { "Connect", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2359 (WPADBusMethodHandler)wpas_dbus_handler_p2p_connect,
2360 {
2361 { "args", "a{sv}", ARG_IN },
97a8cbb8 2362 { "generated_pin", "s", ARG_OUT },
9abafccc
JB
2363 END_ARGS
2364 }
2365 },
2366 { "GroupAdd", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2367 (WPADBusMethodHandler)wpas_dbus_handler_p2p_group_add,
2368 {
2369 { "args", "a{sv}", ARG_IN },
2370 END_ARGS
2371 }
2372 },
2373 { "Invite", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2374 (WPADBusMethodHandler)wpas_dbus_handler_p2p_invite,
2375 {
2376 { "args", "a{sv}", ARG_IN },
2377 END_ARGS
2378 }
2379 },
2380 { "Disconnect", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2381 (WPADBusMethodHandler)wpas_dbus_handler_p2p_disconnect,
2382 {
2383 END_ARGS
2384 }
2385 },
2386 { "RejectPeer", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2387 (WPADBusMethodHandler)wpas_dbus_handler_p2p_rejectpeer,
2388 {
2389 { "peer", "o", ARG_IN },
2390 END_ARGS
2391 }
2392 },
2393 { "Flush", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2394 (WPADBusMethodHandler)wpas_dbus_handler_p2p_flush,
2395 {
2396 END_ARGS
2397 }
2398 },
2399 { "AddService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2400 (WPADBusMethodHandler)wpas_dbus_handler_p2p_add_service,
2401 {
2402 { "args", "a{sv}", ARG_IN },
2403 END_ARGS
2404 }
2405 },
2406 { "DeleteService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2407 (WPADBusMethodHandler)wpas_dbus_handler_p2p_delete_service,
2408 {
2409 { "args", "a{sv}", ARG_IN },
2410 END_ARGS
2411 }
2412 },
2413 { "FlushService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2414 (WPADBusMethodHandler)wpas_dbus_handler_p2p_flush_service,
2415 {
2416 END_ARGS
2417 }
2418 },
2419 { "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2420 (WPADBusMethodHandler)wpas_dbus_handler_p2p_service_sd_req,
2421 {
2422 { "args", "a{sv}", ARG_IN },
2423 END_ARGS
2424 }
2425 },
2426 { "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2427 (WPADBusMethodHandler)wpas_dbus_handler_p2p_service_sd_res,
2428 {
2429 { "args", "a{sv}", ARG_IN },
2430 END_ARGS
2431 }
2432 },
2433 { "ServiceDiscoveryCancelRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2434 (WPADBusMethodHandler)wpas_dbus_handler_p2p_service_sd_cancel_req,
2435 {
2436 { "args", "t", ARG_IN },
2437 END_ARGS
2438 }
2439 },
2440 { "ServiceUpdate", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2441 (WPADBusMethodHandler)wpas_dbus_handler_p2p_service_update,
2442 {
2443 END_ARGS
2444 }
2445 },
2446 { "ServiceDiscoveryExternal", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2447 (WPADBusMethodHandler)wpas_dbus_handler_p2p_serv_disc_external,
2448 {
2449 { "arg", "i", ARG_IN },
2450 END_ARGS
2451 }
2452 },
2453 { "ServiceDiscoveryExternal", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2454 (WPADBusMethodHandler)wpas_dbus_handler_p2p_serv_disc_external,
2455 {
2456 { "arg", "i", ARG_IN },
2457 END_ARGS
2458 }
2459 },
28550706
JS
2460 { "AddPersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2461 (WPADBusMethodHandler) wpas_dbus_handler_add_persistent_group,
2462 {
2463 { "args", "a{sv}", ARG_IN },
2464 { "path", "o", ARG_OUT },
2465 END_ARGS
2466 }
2467 },
2468 { "RemovePersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2469 (WPADBusMethodHandler) wpas_dbus_handler_remove_persistent_group,
2470 {
2471 { "path", "o", ARG_IN },
2472 END_ARGS
2473 }
2474 },
2475 { "RemoveAllPersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2476 (WPADBusMethodHandler)
2477 wpas_dbus_handler_remove_all_persistent_groups,
2478 {
2479 END_ARGS
2480 }
2481 },
9abafccc
JB
2482#endif /* CONFIG_P2P */
2483 { "FlushBSS", WPAS_DBUS_NEW_IFACE_INTERFACE,
2484 (WPADBusMethodHandler) &wpas_dbus_handler_flush_bss,
2485 {
2486 { "age", "u", ARG_IN },
2487 END_ARGS
2488 }
2489 },
2490 { NULL, NULL, NULL, { END_ARGS } }
2491};
2492
2493static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = {
2494 { "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}",
6aeeb6fa 2495 wpas_dbus_getter_capabilities,
33206664 2496 NULL
9abafccc
JB
2497 },
2498 { "State", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
6aeeb6fa 2499 wpas_dbus_getter_state,
33206664 2500 NULL
9abafccc
JB
2501 },
2502 { "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
6aeeb6fa 2503 wpas_dbus_getter_scanning,
33206664 2504 NULL
9abafccc
JB
2505 },
2506 { "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
6aeeb6fa 2507 wpas_dbus_getter_ap_scan,
33206664 2508 wpas_dbus_setter_ap_scan
9abafccc
JB
2509 },
2510 { "BSSExpireAge", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
6aeeb6fa 2511 wpas_dbus_getter_bss_expire_age,
33206664 2512 wpas_dbus_setter_bss_expire_age
9abafccc
JB
2513 },
2514 { "BSSExpireCount", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
6aeeb6fa 2515 wpas_dbus_getter_bss_expire_count,
33206664 2516 wpas_dbus_setter_bss_expire_count
9abafccc
JB
2517 },
2518 { "Country", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
6aeeb6fa 2519 wpas_dbus_getter_country,
33206664 2520 wpas_dbus_setter_country
9abafccc
JB
2521 },
2522 { "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
6aeeb6fa 2523 wpas_dbus_getter_ifname,
33206664 2524 NULL
9abafccc
JB
2525 },
2526 { "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
6aeeb6fa 2527 wpas_dbus_getter_driver,
33206664 2528 NULL
9abafccc
JB
2529 },
2530 { "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
6aeeb6fa 2531 wpas_dbus_getter_bridge_ifname,
33206664 2532 NULL
9abafccc
JB
2533 },
2534 { "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
6aeeb6fa 2535 wpas_dbus_getter_current_bss,
33206664 2536 NULL
9abafccc
JB
2537 },
2538 { "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
6aeeb6fa 2539 wpas_dbus_getter_current_network,
33206664 2540 NULL
9abafccc
JB
2541 },
2542 { "CurrentAuthMode", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
6aeeb6fa 2543 wpas_dbus_getter_current_auth_mode,
33206664 2544 NULL
9abafccc
JB
2545 },
2546 { "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{say}",
6aeeb6fa 2547 wpas_dbus_getter_blobs,
33206664 2548 NULL
9abafccc
JB
2549 },
2550 { "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
6aeeb6fa 2551 wpas_dbus_getter_bsss,
33206664 2552 NULL
9abafccc
JB
2553 },
2554 { "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
6aeeb6fa 2555 wpas_dbus_getter_networks,
33206664 2556 NULL
9abafccc 2557 },
a4bbb606
PS
2558 { "FastReauth", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
2559 wpas_dbus_getter_fast_reauth,
2560 wpas_dbus_setter_fast_reauth
2561 },
c6e86b63
MA
2562 { "ScanInterval", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
2563 wpas_dbus_getter_scan_interval,
2564 wpas_dbus_setter_scan_interval
2565 },
9abafccc
JB
2566#ifdef CONFIG_WPS
2567 { "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b",
6aeeb6fa 2568 wpas_dbus_getter_process_credentials,
33206664 2569 wpas_dbus_setter_process_credentials
9abafccc
JB
2570 },
2571#endif /* CONFIG_WPS */
2572#ifdef CONFIG_P2P
2573 { "P2PDeviceProperties", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "a{sv}",
6aeeb6fa 2574 wpas_dbus_getter_p2p_device_properties,
33206664 2575 wpas_dbus_setter_p2p_device_properties
9abafccc
JB
2576 },
2577 { "Peers", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
6aeeb6fa 2578 wpas_dbus_getter_p2p_peers,
33206664 2579 NULL
9abafccc
JB
2580 },
2581 { "Role", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "s",
6aeeb6fa 2582 wpas_dbus_getter_p2p_role,
33206664 2583 NULL
9abafccc
JB
2584 },
2585 { "Group", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
6aeeb6fa 2586 wpas_dbus_getter_p2p_group,
33206664 2587 NULL
9abafccc
JB
2588 },
2589 { "PeerGO", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
6aeeb6fa 2590 wpas_dbus_getter_p2p_peergo,
33206664 2591 NULL
9abafccc 2592 },
28550706 2593 { "PersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
6aeeb6fa 2594 wpas_dbus_getter_persistent_groups,
33206664 2595 NULL
c2762e41 2596 },
9abafccc 2597#endif /* CONFIG_P2P */
33206664 2598 { NULL, NULL, NULL, NULL, NULL }
9abafccc
JB
2599};
2600
2601static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = {
2602 { "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE,
2603 {
2604 { "success", "b", ARG_OUT },
2605 END_ARGS
2606 }
2607 },
2608 { "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
2609 {
2610 { "path", "o", ARG_OUT },
2611 { "properties", "a{sv}", ARG_OUT },
2612 END_ARGS
2613 }
2614 },
2615 { "BSSRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
2616 {
2617 { "path", "o", ARG_OUT },
2618 END_ARGS
2619 }
2620 },
2621 { "BlobAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
2622 {
2623 { "name", "s", ARG_OUT },
2624 END_ARGS
2625 }
2626 },
2627 { "BlobRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
2628 {
2629 { "name", "s", ARG_OUT },
2630 END_ARGS
2631 }
2632 },
2633 { "NetworkAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
2634 {
2635 { "path", "o", ARG_OUT },
2636 { "properties", "a{sv}", ARG_OUT },
2637 END_ARGS
2638 }
2639 },
2640 { "NetworkRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
2641 {
2642 { "path", "o", ARG_OUT },
2643 END_ARGS
2644 }
2645 },
2646 { "NetworkSelected", WPAS_DBUS_NEW_IFACE_INTERFACE,
2647 {
2648 { "path", "o", ARG_OUT },
2649 END_ARGS
2650 }
2651 },
4483f23e 2652 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
9abafccc
JB
2653 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE,
2654 {
2655 { "properties", "a{sv}", ARG_OUT },
2656 END_ARGS
2657 }
2658 },
2659#ifdef CONFIG_WPS
2660 { "Event", WPAS_DBUS_NEW_IFACE_WPS,
2661 {
2662 { "name", "s", ARG_OUT },
2663 { "args", "a{sv}", ARG_OUT },
2664 END_ARGS
2665 }
2666 },
2667 { "Credentials", WPAS_DBUS_NEW_IFACE_WPS,
2668 {
2669 { "credentials", "a{sv}", ARG_OUT },
2670 END_ARGS
2671 }
2672 },
4483f23e 2673 /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
9abafccc
JB
2674 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS,
2675 {
2676 { "properties", "a{sv}", ARG_OUT },
2677 END_ARGS
2678 }
2679 },
2680#endif /* CONFIG_WPS */
2681#ifdef CONFIG_P2P
2682 { "P2PStateChanged", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2683 {
2684 { "states", "a{ss}", ARG_OUT },
2685 END_ARGS
2686 }
2687 },
2688 { "DeviceFound", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2689 {
2690 { "path", "o", ARG_OUT },
2691 { "properties", "a{sv}", ARG_OUT },
2692 END_ARGS
2693 }
2694 },
2695 { "DeviceLost", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2696 {
2697 { "path", "o", ARG_OUT },
2698 END_ARGS
2699 }
2700 },
2701 { "ProvisionDiscoveryRequestDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2702 {
2703 { "peer_object", "o", ARG_OUT },
2704 { "pin", "s", ARG_OUT },
2705 END_ARGS
2706 }
2707 },
2708 { "ProvisionDiscoveryResponseDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2709 {
2710 { "peer_object", "o", ARG_OUT },
2711 { "pin", "s", ARG_OUT },
2712 END_ARGS
2713 }
2714 },
2715 { "ProvisionDiscoveryRequestEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2716 {
2717 { "peer_object", "o", ARG_OUT },
2718 END_ARGS
2719 }
2720 },
2721 { "ProvisionDiscoveryResponseEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2722 {
2723 { "peer_object", "o", ARG_OUT },
2724 END_ARGS
2725 }
2726 },
2727 { "ProvisionDiscoveryPBCRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2728 {
2729 { "peer_object", "o", ARG_OUT },
2730 END_ARGS
2731 }
2732 },
2733 { "ProvisionDiscoveryPBCResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2734 {
2735 { "peer_object", "o", ARG_OUT },
2736 END_ARGS
2737 }
2738 },
2739 { "ProvisionDiscoveryFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2740 {
2741 { "peer_object", "o", ARG_OUT },
2742 { "status", "i", ARG_OUT },
9b61515c
JM
2743 END_ARGS
2744 }
2745 },
9abafccc 2746 { "GroupStarted", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
9b61515c 2747 {
9abafccc 2748 { "properties", "a{sv}", ARG_OUT },
9b61515c
JM
2749 END_ARGS
2750 }
2751 },
9abafccc 2752 { "GONegotiationSuccess", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
7c49fdd0
SL
2753 {
2754 END_ARGS
2755 }
2756 },
9abafccc 2757 { "GONegotiationFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
9b61515c 2758 {
9abafccc 2759 { "status", "i", ARG_OUT },
9b61515c
JM
2760 END_ARGS
2761 }
2762 },
9abafccc 2763 { "GONegotiationRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
9b61515c 2764 {
9abafccc
JB
2765 { "path", "o", ARG_OUT },
2766 { "dev_passwd_id", "i", ARG_OUT },
9b61515c
JM
2767 END_ARGS
2768 }
2769 },
9abafccc 2770 { "InvitationResult", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
9b61515c 2771 {
9abafccc 2772 { "invite_result", "a{sv}", ARG_OUT },
9b61515c
JM
2773 END_ARGS
2774 }
2775 },
9abafccc 2776 { "GroupFinished", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
9b61515c 2777 {
9abafccc
JB
2778 { "ifname", "s", ARG_OUT },
2779 { "role", "s", ARG_OUT },
9b61515c
JM
2780 END_ARGS
2781 }
2782 },
9abafccc 2783 { "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
9b61515c 2784 {
9abafccc 2785 { "sd_request", "a{sv}", ARG_OUT },
9b61515c
JM
2786 END_ARGS
2787 }
2788 },
9abafccc 2789 { "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2b65b30d 2790 {
9abafccc 2791 { "sd_response", "a{sv}", ARG_OUT },
2b65b30d
SL
2792 END_ARGS
2793 }
2794 },
c2762e41
JS
2795 { "PersistentGroupAdded", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2796 {
2797 { "path", "o", ARG_OUT },
2798 { "properties", "a{sv}", ARG_OUT },
2799 END_ARGS
2800 }
2801 },
b05fe0e5
JS
2802 { "PersistentGroupRemoved", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2803 {
2804 { "path", "o", ARG_OUT },
2805 END_ARGS
2806 }
2807 },
3734552f
JS
2808 { "WpsFailed", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
2809 {
2810 { "name", "s", ARG_OUT },
2811 { "args", "a{sv}", ARG_OUT },
2812 END_ARGS
2813 }
2814 },
9abafccc 2815#endif /* CONFIG_P2P */
ade74830
MC
2816 { "Certification", WPAS_DBUS_NEW_IFACE_INTERFACE,
2817 {
2818 { "certification", "a{sv}", ARG_OUT },
2819 END_ARGS
2820 }
2821 },
9abafccc 2822 { NULL, NULL, { END_ARGS } }
9b61515c
JM
2823};
2824
9abafccc
JB
2825
2826int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s)
2827{
2828
2829 struct wpa_dbus_object_desc *obj_desc = NULL;
2830 struct wpas_dbus_priv *ctrl_iface = wpa_s->global->dbus;
2831 int next;
2832
2833 /* Do nothing if the control interface is not turned on */
2834 if (ctrl_iface == NULL)
2835 return 0;
2836
2837 /* Create and set the interface's object path */
2838 wpa_s->dbus_new_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
2839 if (wpa_s->dbus_new_path == NULL)
2840 return -1;
2841 next = ctrl_iface->next_objid++;
2842 os_snprintf(wpa_s->dbus_new_path, WPAS_DBUS_OBJECT_PATH_MAX,
2843 WPAS_DBUS_NEW_PATH_INTERFACES "/%u",
2844 next);
2845
2846 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
2847 if (!obj_desc) {
2848 wpa_printf(MSG_ERROR, "Not enough memory "
2849 "to create object description");
2850 goto err;
2851 }
2852
2853 wpas_dbus_register(obj_desc, wpa_s, NULL, wpas_dbus_interface_methods,
2854 wpas_dbus_interface_properties,
2855 wpas_dbus_interface_signals);
2856
2857 wpa_printf(MSG_DEBUG, "dbus: Register interface object '%s'",
2858 wpa_s->dbus_new_path);
2859 if (wpa_dbus_register_object_per_iface(ctrl_iface,
2860 wpa_s->dbus_new_path,
2861 wpa_s->ifname, obj_desc))
2862 goto err;
2863
2864 wpas_dbus_signal_interface_added(wpa_s);
2865
2866 return 0;
2867
2868err:
2869 os_free(wpa_s->dbus_new_path);
2870 wpa_s->dbus_new_path = NULL;
2871 free_dbus_object_desc(obj_desc);
2872 return -1;
2873}
2874
2875
2876int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s)
2877{
2878 struct wpas_dbus_priv *ctrl_iface;
2879
2880 /* Do nothing if the control interface is not turned on */
2881 if (wpa_s == NULL || wpa_s->global == NULL)
2882 return 0;
2883 ctrl_iface = wpa_s->global->dbus;
2884 if (ctrl_iface == NULL)
2885 return 0;
2886
2887 wpa_printf(MSG_DEBUG, "dbus: Unregister interface object '%s'",
2888 wpa_s->dbus_new_path);
2889 if (wpa_dbus_unregister_object_per_iface(ctrl_iface,
2890 wpa_s->dbus_new_path))
2891 return -1;
2892
2893 wpas_dbus_signal_interface_removed(wpa_s);
2894
2895 os_free(wpa_s->dbus_new_path);
2896 wpa_s->dbus_new_path = NULL;
2897
2898 return 0;
2899}
2900
2901#ifdef CONFIG_P2P
2902
2903static const struct wpa_dbus_property_desc wpas_dbus_p2p_peer_properties[] = {
3f6e50ac
FC
2904 { "DeviceName", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
2905 wpas_dbus_getter_p2p_peer_device_name,
2906 NULL
2907 },
2908 { "PrimaryDeviceType", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
2909 wpas_dbus_getter_p2p_peer_primary_device_type,
2910 NULL
2911 },
2912 { "config_method", WPAS_DBUS_NEW_IFACE_P2P_PEER, "q",
2913 wpas_dbus_getter_p2p_peer_config_method,
2914 NULL
2915 },
2916 { "level", WPAS_DBUS_NEW_IFACE_P2P_PEER, "i",
2917 wpas_dbus_getter_p2p_peer_level,
2918 NULL
2919 },
2920 { "devicecapability", WPAS_DBUS_NEW_IFACE_P2P_PEER, "y",
2921 wpas_dbus_getter_p2p_peer_device_capability,
2922 NULL
2923 },
2924 { "groupcapability", WPAS_DBUS_NEW_IFACE_P2P_PEER, "y",
2925 wpas_dbus_getter_p2p_peer_group_capability,
2926 NULL
2927 },
ca298427 2928 { "SecondaryDeviceTypes", WPAS_DBUS_NEW_IFACE_P2P_PEER, "aay",
3f6e50ac
FC
2929 wpas_dbus_getter_p2p_peer_secondary_device_types,
2930 NULL
2931 },
ca298427 2932 { "VendorExtension", WPAS_DBUS_NEW_IFACE_P2P_PEER, "aay",
3f6e50ac 2933 wpas_dbus_getter_p2p_peer_vendor_extension,
33206664 2934 NULL
9b61515c 2935 },
9abafccc 2936 { "IEs", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
6aeeb6fa 2937 wpas_dbus_getter_p2p_peer_ies,
33206664 2938 NULL
9b61515c 2939 },
33206664 2940 { NULL, NULL, NULL, NULL, NULL }
9abafccc
JB
2941};
2942
2943static const struct wpa_dbus_signal_desc wpas_dbus_p2p_peer_signals[] = {
2944
2945 { NULL, NULL, { END_ARGS } }
2946};
2947
2948/**
2949 * wpas_dbus_signal_peer - Send a peer related event signal
2950 * @wpa_s: %wpa_supplicant network interface data
2951 * @dev: peer device object
2952 * @interface: name of the interface emitting this signal.
2953 * In case of peer objects, it would be emitted by either
2954 * the "interface object" or by "peer objects"
2955 * @sig_name: signal name - DeviceFound
2956 *
2957 * Notify listeners about event related with newly found p2p peer device
2958 */
2959static void wpas_dbus_signal_peer(struct wpa_supplicant *wpa_s,
2960 const u8 *dev_addr, const char *interface,
2961 const char *sig_name)
2962{
2963 struct wpas_dbus_priv *iface;
2964 DBusMessage *msg;
2965 DBusMessageIter iter;
2966 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
2967
2968 iface = wpa_s->global->dbus;
2969
2970 /* Do nothing if the control interface is not turned on */
2971 if (iface == NULL)
2972 return;
2973
2974 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2975 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
2976 wpa_s->dbus_new_path, MAC2STR(dev_addr));
2977
2978 msg = dbus_message_new_signal(wpa_s->dbus_new_path, interface,
2979 sig_name);
2980 if (msg == NULL)
2981 return;
2982
2983 dbus_message_iter_init_append(msg, &iter);
2984 path = peer_obj_path;
2985 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
2986 &path))
2987 goto err;
2988
2989 dbus_connection_send(iface->con, msg, NULL);
2990
2991 dbus_message_unref(msg);
2992 return;
2993
2994err:
2995 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
2996 dbus_message_unref(msg);
2997}
2998
2999
3000/**
3001 * wpas_dbus_signal_peer_found - Send a peer found signal
3002 * @wpa_s: %wpa_supplicant network interface data
3003 * @dev: peer device object
3004 *
3005 * Notify listeners about find a p2p peer device found
3006 */
3007void wpas_dbus_signal_peer_device_found(struct wpa_supplicant *wpa_s,
3008 const u8 *dev_addr)
3009{
3010 wpas_dbus_signal_peer(wpa_s, dev_addr,
3011 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3012 "DeviceFound");
3013}
3014
3015/**
3016 * wpas_dbus_signal_peer_lost - Send a peer lost signal
3017 * @wpa_s: %wpa_supplicant network interface data
3018 * @dev: peer device object
3019 *
3020 * Notify listeners about lost a p2p peer device
3021 */
3022void wpas_dbus_signal_peer_device_lost(struct wpa_supplicant *wpa_s,
3023 const u8 *dev_addr)
3024{
3025 wpas_dbus_signal_peer(wpa_s, dev_addr,
3026 WPAS_DBUS_NEW_IFACE_P2PDEVICE,
3027 "DeviceLost");
3028}
3029
3030/**
3031 * wpas_dbus_register_peer - Register a discovered peer object with dbus
3032 * @wpa_s: wpa_supplicant interface structure
3033 * @ssid: network configuration data
3034 * Returns: 0 on success, -1 on failure
3035 *
3036 * Registers network representing object with dbus
3037 */
3038int wpas_dbus_register_peer(struct wpa_supplicant *wpa_s, const u8 *dev_addr)
3039{
3040 struct wpas_dbus_priv *ctrl_iface;
3041 struct wpa_dbus_object_desc *obj_desc;
3042 struct peer_handler_args *arg;
3043 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3044
3045 /* Do nothing if the control interface is not turned on */
3046 if (wpa_s == NULL || wpa_s->global == NULL)
3047 return 0;
3048
3049 ctrl_iface = wpa_s->global->dbus;
3050 if (ctrl_iface == NULL)
3051 return 0;
3052
3053 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3054 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
3055 wpa_s->dbus_new_path, MAC2STR(dev_addr));
3056
3057 wpa_printf(MSG_INFO, "dbus: Register peer object '%s'",
3058 peer_obj_path);
3059 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
3060 if (!obj_desc) {
3061 wpa_printf(MSG_ERROR, "Not enough memory "
3062 "to create object description");
3063 goto err;
3064 }
3065
3066 /* allocate memory for handlers arguments */
3067 arg = os_zalloc(sizeof(struct peer_handler_args));
3068 if (!arg) {
3069 wpa_printf(MSG_ERROR, "Not enough memory "
3070 "to create arguments for method");
3071 goto err;
3072 }
3073
3074 arg->wpa_s = wpa_s;
3075 os_memcpy(arg->p2p_device_addr, dev_addr, ETH_ALEN);
3076
3077 wpas_dbus_register(obj_desc, arg, wpa_dbus_free,
3078 NULL,
3079 wpas_dbus_p2p_peer_properties,
3080 wpas_dbus_p2p_peer_signals);
3081
3082 if (wpa_dbus_register_object_per_iface(ctrl_iface, peer_obj_path,
3083 wpa_s->ifname, obj_desc))
3084 goto err;
3085
3086 return 0;
3087
3088err:
3089 free_dbus_object_desc(obj_desc);
3090 return -1;
3091}
3092
3093/**
3094 * wpas_dbus_unregister_peer - Unregister a peer object with dbus
3095 * @wpa_s: wpa_supplicant interface structure
3096 * @dev_addr: p2p device addr
3097 * Returns: 0 on success, -1 on failure
3098 *
3099 * Registers network representing object with dbus
3100 */
3101int wpas_dbus_unregister_peer(struct wpa_supplicant *wpa_s,
3102 const u8 *dev_addr)
3103{
3104 struct wpas_dbus_priv *ctrl_iface;
3105 char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3106 int ret;
3107
3108 /* Do nothing if the control interface is not turned on */
3109 if (wpa_s == NULL || wpa_s->global == NULL ||
3110 wpa_s->dbus_new_path == NULL)
3111 return 0;
3112 ctrl_iface = wpa_s->global->dbus;
3113 if (ctrl_iface == NULL)
3114 return 0;
3115
3116 os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3117 "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
3118 wpa_s->dbus_new_path, MAC2STR(dev_addr));
3119
3120 wpa_printf(MSG_INFO, "dbus: Unregister peer object '%s'",
3121 peer_obj_path);
3122 ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, peer_obj_path);
3123
3124 return ret;
3125}
3126
3127
3128static const struct wpa_dbus_property_desc wpas_dbus_p2p_group_properties[] = {
3129 { "Members", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ao",
6aeeb6fa 3130 wpas_dbus_getter_p2p_group_members,
33206664 3131 NULL
9b61515c 3132 },
7d39d9c9
TP
3133 { "Group", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "o",
3134 wpas_dbus_getter_p2p_group,
3135 NULL
3136 },
3137 { "Role", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "s",
3138 wpas_dbus_getter_p2p_role,
3139 NULL
3140 },
3141 { "SSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
3142 wpas_dbus_getter_p2p_group_ssid,
3143 NULL
3144 },
3145 { "BSSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
3146 wpas_dbus_getter_p2p_group_bssid,
3147 NULL
3148 },
3149 { "Frequency", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "q",
3150 wpas_dbus_getter_p2p_group_frequency,
3151 NULL
3152 },
3153 { "Passphrase", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "s",
3154 wpas_dbus_getter_p2p_group_passphrase,
3155 NULL
3156 },
3157 { "PSK", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
3158 wpas_dbus_getter_p2p_group_psk,
3159 NULL
3160 },
3161 { "WPSVendorExtensions", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "aay",
3162 wpas_dbus_getter_p2p_group_vendor_ext,
3163 wpas_dbus_setter_p2p_group_vendor_ext
9b61515c 3164 },
33206664 3165 { NULL, NULL, NULL, NULL, NULL }
9b61515c
JM
3166};
3167
9abafccc
JB
3168static const struct wpa_dbus_signal_desc wpas_dbus_p2p_group_signals[] = {
3169 { "PeerJoined", WPAS_DBUS_NEW_IFACE_P2P_GROUP,
9b61515c 3170 {
9abafccc 3171 { "peer", "o", ARG_OUT },
9b61515c
JM
3172 END_ARGS
3173 }
3174 },
9abafccc 3175 { "PeerDisconnected", WPAS_DBUS_NEW_IFACE_P2P_GROUP,
9b61515c 3176 {
9abafccc 3177 { "peer", "o", ARG_OUT },
9b61515c
JM
3178 END_ARGS
3179 }
3180 },
9b61515c
JM
3181 { NULL, NULL, { END_ARGS } }
3182};
3183
9abafccc
JB
3184/**
3185 * wpas_dbus_register_p2p_group - Register a p2p group object with dbus
3186 * @wpa_s: wpa_supplicant interface structure
3187 * @ssid: SSID struct
3188 * Returns: 0 on success, -1 on failure
3189 *
3190 * Registers p2p group representing object with dbus
3191 */
3192void wpas_dbus_register_p2p_group(struct wpa_supplicant *wpa_s,
3193 struct wpa_ssid *ssid)
3194{
3195 struct wpas_dbus_priv *ctrl_iface;
3196 struct wpa_dbus_object_desc *obj_desc;
3197 char group_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
9b61515c 3198
9abafccc
JB
3199 /* Do nothing if the control interface is not turned on */
3200 if (wpa_s == NULL || wpa_s->global == NULL)
3201 return;
3202
3203 ctrl_iface = wpa_s->global->dbus;
3204 if (ctrl_iface == NULL)
3205 return;
3206
3207 if (wpa_s->dbus_groupobj_path) {
3208 wpa_printf(MSG_INFO, "%s: Group object '%s' already exists",
3209 __func__, wpa_s->dbus_groupobj_path);
3210 return;
3211 }
3212
3213 if (wpas_dbus_get_group_obj_path(wpa_s, ssid, group_obj_path) < 0)
3214 return;
3215
3216 wpa_s->dbus_groupobj_path = os_strdup(group_obj_path);
3217 if (wpa_s->dbus_groupobj_path == NULL)
3218 return;
3219
3220 wpa_printf(MSG_INFO, "dbus: Register group object '%s'",
3221 group_obj_path);
3222 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
3223 if (!obj_desc) {
3224 wpa_printf(MSG_ERROR, "Not enough memory "
3225 "to create object description");
3226 goto err;
3227 }
3228
3229 wpas_dbus_register(obj_desc, wpa_s, NULL, NULL,
3230 wpas_dbus_p2p_group_properties,
3231 wpas_dbus_p2p_group_signals);
3232
3233 if (wpa_dbus_register_object_per_iface(ctrl_iface, group_obj_path,
3234 wpa_s->ifname, obj_desc))
3235 goto err;
3236
3237 return;
3238
3239err:
3240 if (wpa_s->dbus_groupobj_path) {
3241 os_free(wpa_s->dbus_groupobj_path);
3242 wpa_s->dbus_groupobj_path = NULL;
3243 }
3244
3245 free_dbus_object_desc(obj_desc);
3246}
3247
3248/**
3249 * wpas_dbus_unregister_p2p_group - Unregister a p2p group object from dbus
3250 * @wpa_s: wpa_supplicant interface structure
3251 * @ssid: network name of the p2p group started
3252 */
3253void wpas_dbus_unregister_p2p_group(struct wpa_supplicant *wpa_s,
3254 const struct wpa_ssid *ssid)
8fc2fb56 3255{
9abafccc
JB
3256 struct wpas_dbus_priv *ctrl_iface;
3257
3258 /* Do nothing if the control interface is not turned on */
3259 if (wpa_s == NULL || wpa_s->global == NULL)
3260 return;
3261
3262 ctrl_iface = wpa_s->global->dbus;
3263 if (ctrl_iface == NULL)
3264 return;
3265
3266 if (!wpa_s->dbus_groupobj_path) {
3267 wpa_printf(MSG_DEBUG,
3268 "%s: Group object '%s' already unregistered",
3269 __func__, wpa_s->dbus_groupobj_path);
3270 return;
3271 }
3272
3273 wpa_printf(MSG_DEBUG, "dbus: Unregister group object '%s'",
3274 wpa_s->dbus_groupobj_path);
3275
3276 wpa_dbus_unregister_object_per_iface(ctrl_iface,
3277 wpa_s->dbus_groupobj_path);
3278
3279 os_free(wpa_s->dbus_groupobj_path);
3280 wpa_s->dbus_groupobj_path = NULL;
3281}
3282
3283static const struct wpa_dbus_property_desc
3284wpas_dbus_p2p_groupmember_properties[] = {
33206664 3285 { NULL, NULL, NULL, NULL, NULL }
9abafccc 3286};
8fc2fb56 3287
9abafccc
JB
3288/**
3289 * wpas_dbus_register_p2p_groupmember - Register a p2p groupmember
3290 * object with dbus
3291 * @wpa_s: wpa_supplicant interface structure
3292 * @p2p_if_addr: i/f addr of the device joining this group
3293 *
3294 * Registers p2p groupmember representing object with dbus
3295 */
3296void wpas_dbus_register_p2p_groupmember(struct wpa_supplicant *wpa_s,
3297 const u8 *p2p_if_addr)
3298{
3299 struct wpas_dbus_priv *ctrl_iface;
8fc2fb56 3300 struct wpa_dbus_object_desc *obj_desc = NULL;
9abafccc
JB
3301 struct groupmember_handler_args *arg;
3302 char groupmember_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
8fc2fb56 3303
8fc2fb56 3304 /* Do nothing if the control interface is not turned on */
9abafccc
JB
3305 if (wpa_s == NULL || wpa_s->global == NULL)
3306 return;
3307
3308 ctrl_iface = wpa_s->global->dbus;
8fc2fb56 3309 if (ctrl_iface == NULL)
9abafccc 3310 return;
8fc2fb56 3311
9abafccc
JB
3312 if (!wpa_s->dbus_groupobj_path)
3313 return;
3314
3315 os_snprintf(groupmember_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3316 "%s/" WPAS_DBUS_NEW_P2P_GROUPMEMBERS_PART "/" COMPACT_MACSTR,
3317 wpa_s->dbus_groupobj_path, MAC2STR(p2p_if_addr));
8fc2fb56
WS
3318
3319 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
3320 if (!obj_desc) {
3321 wpa_printf(MSG_ERROR, "Not enough memory "
3322 "to create object description");
3323 goto err;
3324 }
3325
9abafccc
JB
3326 /* allocate memory for handlers arguments */
3327 arg = os_zalloc(sizeof(struct groupmember_handler_args));
3328 if (!arg) {
3329 wpa_printf(MSG_ERROR, "Not enough memory "
3330 "to create arguments for method");
3331 goto err;
3332 }
8fc2fb56 3333
9abafccc
JB
3334 arg->wpa_s = wpa_s;
3335 os_memcpy(arg->member_addr, p2p_if_addr, ETH_ALEN);
3336
3337 wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
3338 wpas_dbus_p2p_groupmember_properties, NULL);
3339
3340 if (wpa_dbus_register_object_per_iface(ctrl_iface, groupmember_obj_path,
19120498 3341 wpa_s->ifname, obj_desc))
8fc2fb56
WS
3342 goto err;
3343
9abafccc
JB
3344 wpa_printf(MSG_INFO,
3345 "dbus: Registered group member object '%s' successfully",
3346 groupmember_obj_path);
3347 return;
8fc2fb56
WS
3348
3349err:
2f1a9018 3350 free_dbus_object_desc(obj_desc);
8fc2fb56
WS
3351}
3352
9abafccc
JB
3353/**
3354 * wpas_dbus_unregister_p2p_groupmember - Unregister a p2p groupmember
3355 * object with dbus
3356 * @wpa_s: wpa_supplicant interface structure
3357 * @p2p_if_addr: i/f addr of the device joining this group
3358 *
3359 * Unregisters p2p groupmember representing object with dbus
3360 */
3361void wpas_dbus_unregister_p2p_groupmember(struct wpa_supplicant *wpa_s,
3362 const u8 *p2p_if_addr)
8fc2fb56 3363{
8ddef94b 3364 struct wpas_dbus_priv *ctrl_iface;
9abafccc 3365 char groupmember_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
8fc2fb56
WS
3366
3367 /* Do nothing if the control interface is not turned on */
3368 if (wpa_s == NULL || wpa_s->global == NULL)
9abafccc
JB
3369 return;
3370
8ddef94b 3371 ctrl_iface = wpa_s->global->dbus;
8fc2fb56 3372 if (ctrl_iface == NULL)
9abafccc 3373 return;
8fc2fb56 3374
9abafccc
JB
3375 if (!wpa_s->dbus_groupobj_path)
3376 return;
8fc2fb56 3377
9abafccc
JB
3378 os_snprintf(groupmember_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3379 "%s/" WPAS_DBUS_NEW_P2P_GROUPMEMBERS_PART "/" COMPACT_MACSTR,
3380 wpa_s->dbus_groupobj_path, MAC2STR(p2p_if_addr));
8fc2fb56 3381
9abafccc 3382 wpa_dbus_unregister_object_per_iface(ctrl_iface, groupmember_obj_path);
8fc2fb56 3383}
c2762e41
JS
3384
3385
3386static const struct wpa_dbus_property_desc
3387 wpas_dbus_persistent_group_properties[] = {
3388 { "Properties", WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, "a{sv}",
c2762e41 3389 wpas_dbus_getter_persistent_group_properties,
33206664 3390 wpas_dbus_setter_persistent_group_properties
c2762e41 3391 },
33206664 3392 { NULL, NULL, NULL, NULL, NULL }
c2762e41
JS
3393};
3394
3395/* No signals intended for persistent group objects */
3396
3397/**
3398 * wpas_dbus_register_persistent_group - Register a configured(saved)
3399 * persistent group with dbus
3400 * @wpa_s: wpa_supplicant interface structure
3401 * @ssid: persistent group (still represented as a network within wpa)
3402 * configuration data
3403 * Returns: 0 on success, -1 on failure
3404 *
3405 * Registers a persistent group representing object with dbus.
3406 */
3407int wpas_dbus_register_persistent_group(struct wpa_supplicant *wpa_s,
3408 struct wpa_ssid *ssid)
3409{
3410 struct wpas_dbus_priv *ctrl_iface;
3411 struct wpa_dbus_object_desc *obj_desc;
3412 struct network_handler_args *arg;
3413 char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3414
3415 /* Do nothing if the control interface is not turned on */
3416 if (wpa_s == NULL || wpa_s->global == NULL)
3417 return 0;
3418
3419 /* Make sure ssid is a persistent group */
3420 if (ssid->disabled != 2 && !ssid->p2p_persistent_group)
3421 return -1; /* should we return w/o complaining? */
3422
3423 ctrl_iface = wpa_s->global->dbus;
3424 if (ctrl_iface == NULL)
3425 return 0;
3426
3427 /*
3428 * Intentionally not coming up with different numbering scheme
3429 * for persistent groups.
3430 */
3431 os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3432 "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
3433 wpa_s->dbus_new_path, ssid->id);
3434
3435 wpa_printf(MSG_DEBUG, "dbus: Register persistent group object '%s'",
3436 pgrp_obj_path);
3437 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
3438 if (!obj_desc) {
3439 wpa_printf(MSG_ERROR, "dbus: Not enough memory to create "
3440 "object description");
3441 goto err;
3442 }
3443
3444 /*
3445 * Reusing the same context structure as that for networks
3446 * since these are represented using same data structure.
3447 */
3448 /* allocate memory for handlers arguments */
3449 arg = os_zalloc(sizeof(struct network_handler_args));
3450 if (!arg) {
3451 wpa_printf(MSG_ERROR, "dbus: Not enough memory to create "
3452 "arguments for method");
3453 goto err;
3454 }
3455
3456 arg->wpa_s = wpa_s;
3457 arg->ssid = ssid;
3458
3459 wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
3460 wpas_dbus_persistent_group_properties,
3461 NULL);
3462
3463 if (wpa_dbus_register_object_per_iface(ctrl_iface, pgrp_obj_path,
3464 wpa_s->ifname, obj_desc))
3465 goto err;
3466
3467 wpas_dbus_signal_persistent_group_added(wpa_s, ssid->id);
3468
3469 return 0;
3470
3471err:
3472 free_dbus_object_desc(obj_desc);
3473 return -1;
3474}
3475
3476
3477/**
3478 * wpas_dbus_unregister_persistent_group - Unregister a persistent_group
3479 * from dbus
3480 * @wpa_s: wpa_supplicant interface structure
3481 * @nid: network id
3482 * Returns: 0 on success, -1 on failure
3483 *
3484 * Unregisters persistent group representing object from dbus
3485 *
3486 * NOTE: There is a slight issue with the semantics here. While the
3487 * implementation simply means the persistent group is unloaded from memory,
3488 * it should not get interpreted as the group is actually being erased/removed
3489 * from persistent storage as well.
3490 */
3491int wpas_dbus_unregister_persistent_group(struct wpa_supplicant *wpa_s,
3492 int nid)
3493{
3494 struct wpas_dbus_priv *ctrl_iface;
3495 char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
3496 int ret;
3497
3498 /* Do nothing if the control interface is not turned on */
3499 if (wpa_s == NULL || wpa_s->global == NULL ||
3500 wpa_s->dbus_new_path == NULL)
3501 return 0;
3502 ctrl_iface = wpa_s->global->dbus;
3503 if (ctrl_iface == NULL)
3504 return 0;
3505
3506 os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3507 "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
3508 wpa_s->dbus_new_path, nid);
3509
3510 wpa_printf(MSG_DEBUG, "dbus: Unregister persistent group object '%s'",
3511 pgrp_obj_path);
3512 ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, pgrp_obj_path);
3513
3514 if (!ret)
3515 wpas_dbus_signal_persistent_group_removed(wpa_s, nid);
3516
3517 return ret;
3518}
3519
9abafccc 3520#endif /* CONFIG_P2P */