]>
Commit | Line | Data |
---|---|---|
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 | */ | |
43 | static 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 | ||
77 | err: | |
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 | 89 | static 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 | */ | |
101 | static 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 | 115 | void 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 | */ | |
152 | static 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 | ||
188 | err: | |
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 | */ | |
201 | static 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 | */ | |
215 | static 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 | */ | |
230 | static 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 |
264 | void 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 |
278 | void 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 | */ | |
294 | static 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 | ||
337 | err: | |
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 | */ | |
350 | static 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 | */ | |
364 | static 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 | 378 | void 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 |
392 | void 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 | 414 | void 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 |
453 | void 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 |
494 | void 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 |
558 | void 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 | |
635 | nomem: | |
88ba1f72 | 636 | dbus_message_unref(msg); |
8fc2fb56 WS |
637 | } |
638 | ||
639 | #endif /* CONFIG_WPS */ | |
640 | ||
ade74830 MC |
641 | void 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 | ||
685 | nomem: | |
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 |
697 | void 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 | ||
730 | err: | |
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 |
755 | void 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 | ||
837 | error: | |
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 |
847 | void 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 |
886 | static 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 |
917 | void 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 | ||
975 | nomem: | |
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 | 986 | void 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); | |
1016 | err: | |
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 |
1029 | void 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 |
1067 | nomem: |
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 |
1081 | void 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 | |
1120 | err: | |
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 |
1135 | void 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 |
1174 | err: |
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 |
1194 | void 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; | |
1246 | error: | |
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 |
1264 | void 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; | |
1312 | error: | |
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 | */ | |
1327 | static 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 | ||
1370 | err: | |
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 | */ | |
1384 | static 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 | */ | |
1400 | static 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 | */ | |
1415 | void 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 | */ | |
1462 | void 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 | */ | |
1513 | void 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 | */ |
1566 | void 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 | */ |
1580 | void 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 | */ |
1594 | void 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 | ||
1602 | static 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 | ||
1627 | static 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 | ||
1654 | static 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 | ||
1678 | static 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 | */ | |
1711 | int 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 | */ | |
1750 | void 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 | ||
1761 | static void wpa_dbus_free(void *ptr) | |
1762 | { | |
1763 | os_free(ptr); | |
1764 | } | |
1765 | ||
1766 | ||
1767 | static 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 | ||
1780 | static 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 | */ | |
1800 | int 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 | ||
1861 | err: | |
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 | */ | |
1875 | int 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 | ||
1912 | static 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 | ||
1957 | static 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 | */ | |
1978 | int 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 | */ | |
2019 | int 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 | ||
2073 | err: | |
2074 | free_dbus_object_desc(obj_desc); | |
2075 | return -1; | |
2076 | } | |
2077 | ||
2078 | ||
2079 | static 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 | ||
2332 | static 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 | ||
2432 | static 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 | |
2657 | int 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 | ||
2699 | err: | |
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 | ||
2707 | int 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 | ||
2734 | static 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 | ||
2746 | static 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 | */ | |
2762 | static 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 | ||
2797 | err: | |
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 | */ | |
2810 | void 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 | */ | |
2825 | void 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 | */ | |
2841 | int 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 | ||
2891 | err: | |
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 | */ | |
2904 | int 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 | ||
2931 | static 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 |
2944 | static 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 | */ | |
2968 | void 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 | ||
3015 | err: | |
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 | */ | |
3029 | void 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 | ||
3059 | static const struct wpa_dbus_property_desc | |
3060 | wpas_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 | */ | |
3076 | void 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 | |
3129 | err: | |
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 | */ | |
3141 | void 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 | ||
3166 | static 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 | */ | |
3187 | int 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 | ||
3251 | err: | |
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 | */ | |
3271 | int 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 */ |