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