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