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