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