]> git.ipfire.org Git - thirdparty/hostap.git/blame - wpa_supplicant/dbus/dbus_new.c
dbus: Simplify _wpa_dbus_dict_fill_value_from_variant() a bit
[thirdparty/hostap.git] / wpa_supplicant / dbus / dbus_new.c
CommitLineData
8fc2fb56
WS
1/*
2 * WPA Supplicant / dbus-based control interface
3 * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
4 * Copyright (c) 2009, Witold Sowa <witold.sowa@gmail.com>
ccd286d0 5 * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
8fc2fb56
WS
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * Alternatively, this software may be distributed under the terms of BSD
12 * license.
13 *
14 * See README and COPYING for more details.
15 */
16
17#include "includes.h"
18
19#include "common.h"
8fc2fb56 20#include "wps/wps.h"
a206a29a
JM
21#include "../config.h"
22#include "../wpa_supplicant_i.h"
ccd286d0 23#include "../bss.h"
a206a29a 24#include "dbus_new_helpers.h"
8fc2fb56 25#include "dbus_dict_helpers.h"
a206a29a
JM
26#include "dbus_new.h"
27#include "dbus_new_handlers.h"
8ddef94b
JM
28#include "dbus_common.h"
29#include "dbus_common_i.h"
8fc2fb56 30
8fc2fb56
WS
31
32/**
33 * wpas_dbus_signal_interface - Send a interface related event signal
34 * @wpa_s: %wpa_supplicant network interface data
35 * @sig_name: signal name - InterfaceAdded or InterfaceRemoved
e376f119 36 * @properties: determines if add second argument with object properties
8fc2fb56
WS
37 *
38 * Notify listeners about event related with interface
39 */
40static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s,
e376f119 41 const char *sig_name, int properties)
8fc2fb56 42{
8ddef94b 43 struct wpas_dbus_priv *iface;
8fc2fb56 44 DBusMessage *_signal;
e376f119 45 DBusMessageIter iter, iter_dict;
8fc2fb56
WS
46 const char *path;
47
8ddef94b 48 iface = wpa_s->global->dbus;
8fc2fb56
WS
49
50 /* Do nothing if the control interface is not turned on */
51 if (iface == NULL)
52 return;
53
8fc2fb56
WS
54 _signal = dbus_message_new_signal(WPAS_DBUS_NEW_PATH,
55 WPAS_DBUS_NEW_INTERFACE, sig_name);
56 if (_signal == NULL) {
57 wpa_printf(MSG_ERROR, "wpas_dbus_signal_interface[dbus]: "
58 "enough memory to send scan results signal.");
59 return;
60 }
61
e376f119
WS
62 dbus_message_iter_init_append(_signal, &iter);
63
c49cf2d6
JM
64 path = wpa_s->dbus_new_path;
65 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
e376f119
WS
66 &path))
67 goto err;
68
69 if (properties) {
70 if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
71 goto err;
72
73 wpa_dbus_get_object_properties(iface, path,
74 WPAS_DBUS_NEW_IFACE_INTERFACE,
75 &iter_dict);
76
77 if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
78 goto err;
8fc2fb56 79 }
e376f119
WS
80
81 dbus_connection_send(iface->con, _signal, NULL);
82
83 dbus_message_unref(_signal);
84 return;
85
86err:
87 wpa_printf(MSG_ERROR, "wpas_dbus_signal_interface[dbus]: "
88 "not enough memory to construct signal.");
8fc2fb56
WS
89 dbus_message_unref(_signal);
90}
91
92
93/**
b7e8feec 94 * wpas_dbus_signal_interface_added - Send a interface created signal
8fc2fb56
WS
95 * @wpa_s: %wpa_supplicant network interface data
96 *
97 * Notify listeners about creating new interface
98 */
b7e8feec 99static void wpas_dbus_signal_interface_added(struct wpa_supplicant *wpa_s)
8fc2fb56 100{
b7e8feec 101 wpas_dbus_signal_interface(wpa_s, "InterfaceAdded", TRUE);
8fc2fb56
WS
102}
103
104
105/**
106 * wpas_dbus_signal_interface_removed - Send a interface removed signal
107 * @wpa_s: %wpa_supplicant network interface data
108 *
109 * Notify listeners about removing interface
110 */
111static void wpas_dbus_signal_interface_removed(struct wpa_supplicant *wpa_s)
112{
e376f119 113 wpas_dbus_signal_interface(wpa_s, "InterfaceRemoved", FALSE);
8fc2fb56
WS
114
115}
116
117
118/**
119 * wpas_dbus_signal_scan_done - send scan done signal
120 * @wpa_s: %wpa_supplicant network interface data
121 * @success: indicates if scanning succeed or failed
122 *
123 * Notify listeners about finishing a scan
124 */
52bdd880 125void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s, int success)
8fc2fb56 126{
8ddef94b 127 struct wpas_dbus_priv *iface;
8fc2fb56 128 DBusMessage *_signal;
8fc2fb56
WS
129 dbus_bool_t succ;
130
8ddef94b 131 iface = wpa_s->global->dbus;
8fc2fb56
WS
132
133 /* Do nothing if the control interface is not turned on */
134 if (iface == NULL)
135 return;
136
c49cf2d6
JM
137 _signal = dbus_message_new_signal(wpa_s->dbus_new_path,
138 WPAS_DBUS_NEW_IFACE_INTERFACE,
8fc2fb56
WS
139 "ScanDone");
140 if (_signal == NULL) {
141 wpa_printf(MSG_ERROR, "wpas_dbus_signal_scan_done[dbus]: "
142 "enough memory to send signal.");
143 return;
144 }
145
146 succ = success ? TRUE : FALSE;
147 if (dbus_message_append_args(_signal, DBUS_TYPE_BOOLEAN, &succ,
148 DBUS_TYPE_INVALID)) {
149 dbus_connection_send(iface->con, _signal, NULL);
150 } else {
151 wpa_printf(MSG_ERROR, "wpas_dbus_signal_scan_done[dbus]: "
152 "not enough memory to construct signal.");
153 }
154 dbus_message_unref(_signal);
155}
156
157
158/**
159 * wpas_dbus_signal_blob - Send a BSS related event signal
160 * @wpa_s: %wpa_supplicant network interface data
161 * @bss_obj_path: BSS object path
162 * @sig_name: signal name - BSSAdded or BSSRemoved
e376f119 163 * @properties: determines if add second argument with object properties
8fc2fb56
WS
164 *
165 * Notify listeners about event related with BSS
166 */
167static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s,
168 const char *bss_obj_path,
e376f119 169 const char *sig_name, int properties)
8fc2fb56 170{
8ddef94b 171 struct wpas_dbus_priv *iface;
8fc2fb56 172 DBusMessage *_signal;
e376f119 173 DBusMessageIter iter, iter_dict;
8fc2fb56 174
8ddef94b 175 iface = wpa_s->global->dbus;
8fc2fb56
WS
176
177 /* Do nothing if the control interface is not turned on */
178 if (iface == NULL)
179 return;
180
c49cf2d6
JM
181 _signal = dbus_message_new_signal(wpa_s->dbus_new_path,
182 WPAS_DBUS_NEW_IFACE_INTERFACE,
8fc2fb56
WS
183 sig_name);
184 if (_signal == NULL) {
185 wpa_printf(MSG_ERROR, "wpas_dbus_signal_bss[dbus]: "
186 "enough memory to send signal.");
187 return;
188 }
189
e376f119
WS
190 dbus_message_iter_init_append(_signal, &iter);
191
192 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
193 &bss_obj_path))
194 goto err;
195
196 if (properties) {
197 if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
198 goto err;
199
200 wpa_dbus_get_object_properties(iface, bss_obj_path,
201 WPAS_DBUS_NEW_IFACE_BSSID,
202 &iter_dict);
203
204 if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
205 goto err;
8fc2fb56 206 }
e376f119
WS
207
208 dbus_connection_send(iface->con, _signal, NULL);
209
210 dbus_message_unref(_signal);
211 return;
212
213err:
214 wpa_printf(MSG_ERROR, "wpas_dbus_signal_bss[dbus]: "
215 "not enough memory to construct signal.");
8fc2fb56
WS
216 dbus_message_unref(_signal);
217}
218
219
220/**
221 * wpas_dbus_signal_bss_added - Send a BSS added signal
222 * @wpa_s: %wpa_supplicant network interface data
223 * @bss_obj_path: new BSS object path
224 *
225 * Notify listeners about adding new BSS
226 */
227static void wpas_dbus_signal_bss_added(struct wpa_supplicant *wpa_s,
228 const char *bss_obj_path)
229{
e376f119 230 wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSAdded", TRUE);
8fc2fb56
WS
231}
232
233
234/**
235 * wpas_dbus_signal_bss_removed - Send a BSS removed signal
236 * @wpa_s: %wpa_supplicant network interface data
237 * @bss_obj_path: BSS object path
238 *
239 * Notify listeners about removing BSS
240 */
241static void wpas_dbus_signal_bss_removed(struct wpa_supplicant *wpa_s,
242 const char *bss_obj_path)
243{
e376f119 244 wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSRemoved", FALSE);
8fc2fb56
WS
245}
246
247
248/**
249 * wpas_dbus_signal_blob - Send a blob related event signal
250 * @wpa_s: %wpa_supplicant network interface data
251 * @name: blob name
252 * @sig_name: signal name - BlobAdded or BlobRemoved
253 *
254 * Notify listeners about event related with blob
255 */
256static void wpas_dbus_signal_blob(struct wpa_supplicant *wpa_s,
257 const char *name, const char *sig_name)
258{
8ddef94b 259 struct wpas_dbus_priv *iface;
8fc2fb56 260 DBusMessage *_signal;
8fc2fb56 261
8ddef94b 262 iface = wpa_s->global->dbus;
8fc2fb56
WS
263
264 /* Do nothing if the control interface is not turned on */
265 if (iface == NULL)
266 return;
267
c49cf2d6
JM
268 _signal = dbus_message_new_signal(wpa_s->dbus_new_path,
269 WPAS_DBUS_NEW_IFACE_INTERFACE,
8fc2fb56
WS
270 sig_name);
271 if (_signal == NULL) {
272 wpa_printf(MSG_ERROR, "wpas_dbus_signal_blob[dbus]: "
273 "enough memory to send signal.");
274 return;
275 }
276
277 if (dbus_message_append_args(_signal, DBUS_TYPE_STRING, &name,
278 DBUS_TYPE_INVALID)) {
279 dbus_connection_send(iface->con, _signal, NULL);
280 } else {
281 wpa_printf(MSG_ERROR, "wpas_dbus_signal_blob[dbus]: "
282 "not enough memory to construct signal.");
283 }
284 dbus_message_unref(_signal);
285}
286
287
288/**
289 * wpas_dbus_signal_blob_added - Send a blob added signal
290 * @wpa_s: %wpa_supplicant network interface data
291 * @name: blob name
292 *
293 * Notify listeners about adding a new blob
294 */
52bdd880
JM
295void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s,
296 const char *name)
8fc2fb56
WS
297{
298 wpas_dbus_signal_blob(wpa_s, name, "BlobAdded");
299}
300
301
302/**
303 * wpas_dbus_signal_blob_removed - Send a blob removed signal
304 * @wpa_s: %wpa_supplicant network interface data
305 * @name: blob name
306 *
307 * Notify listeners about removing blob
308 */
52bdd880
JM
309void wpas_dbus_signal_blob_removed(struct wpa_supplicant *wpa_s,
310 const char *name)
8fc2fb56
WS
311{
312 wpas_dbus_signal_blob(wpa_s, name, "BlobRemoved");
313}
314
315
316/**
317 * wpas_dbus_signal_network - Send a network related event signal
318 * @wpa_s: %wpa_supplicant network interface data
319 * @id: new network id
320 * @sig_name: signal name - NetworkAdded, NetworkRemoved or NetworkSelected
e376f119 321 * @properties: determines if add second argument with object properties
8fc2fb56
WS
322 *
323 * Notify listeners about event related with configured network
324 */
325static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s,
e376f119
WS
326 int id, const char *sig_name,
327 int properties)
8fc2fb56 328{
8ddef94b 329 struct wpas_dbus_priv *iface;
8fc2fb56 330 DBusMessage *_signal;
e376f119 331 DBusMessageIter iter, iter_dict;
8fc2fb56
WS
332 char *net_obj_path;
333
8ddef94b 334 iface = wpa_s->global->dbus;
8fc2fb56
WS
335
336 /* Do nothing if the control interface is not turned on */
337 if (iface == NULL)
338 return;
339
8fc2fb56
WS
340 net_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
341 if (net_obj_path == NULL)
342 return;
343 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
c49cf2d6
JM
344 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
345 wpa_s->dbus_new_path, id);
8fc2fb56 346
c49cf2d6
JM
347 _signal = dbus_message_new_signal(wpa_s->dbus_new_path,
348 WPAS_DBUS_NEW_IFACE_INTERFACE,
8fc2fb56
WS
349 sig_name);
350 if (_signal == NULL) {
351 wpa_printf(MSG_ERROR, "wpas_dbus_signal_network[dbus]: "
352 "enough memory to send signal.");
353 os_free(net_obj_path);
354 return;
355 }
356
e376f119
WS
357 dbus_message_iter_init_append(_signal, &iter);
358
359 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
360 &net_obj_path))
361 goto err;
362
363 if (properties) {
364 if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
365 goto err;
366
367 wpa_dbus_get_object_properties(iface, net_obj_path,
368 WPAS_DBUS_NEW_IFACE_NETWORK,
369 &iter_dict);
370
371 if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
372 goto err;
8fc2fb56
WS
373 }
374
e376f119
WS
375 dbus_connection_send(iface->con, _signal, NULL);
376
377 os_free(net_obj_path);
378 dbus_message_unref(_signal);
379 return;
380
381err:
382 wpa_printf(MSG_ERROR, "wpas_dbus_signal_network[dbus]: "
383 "not enough memory to construct signal.");
8fc2fb56
WS
384 os_free(net_obj_path);
385 dbus_message_unref(_signal);
386}
387
388
389/**
390 * wpas_dbus_signal_network_added - Send a network added signal
391 * @wpa_s: %wpa_supplicant network interface data
392 * @id: new network id
393 *
394 * Notify listeners about adding new network
395 */
396static void wpas_dbus_signal_network_added(struct wpa_supplicant *wpa_s,
397 int id)
398{
e376f119 399 wpas_dbus_signal_network(wpa_s, id, "NetworkAdded", TRUE);
8fc2fb56
WS
400}
401
402
403/**
17efbfac 404 * wpas_dbus_signal_network_removed - Send a network removed signal
8fc2fb56
WS
405 * @wpa_s: %wpa_supplicant network interface data
406 * @id: network id
407 *
408 * Notify listeners about removing a network
409 */
410static void wpas_dbus_signal_network_removed(struct wpa_supplicant *wpa_s,
411 int id)
412{
e376f119 413 wpas_dbus_signal_network(wpa_s, id, "NetworkRemoved", FALSE);
8fc2fb56
WS
414}
415
416
417/**
418 * wpas_dbus_signal_network_selected - Send a network selected signal
419 * @wpa_s: %wpa_supplicant network interface data
420 * @id: network id
421 *
422 * Notify listeners about selecting a network
423 */
52bdd880 424void wpas_dbus_signal_network_selected(struct wpa_supplicant *wpa_s, int id)
8fc2fb56 425{
e376f119 426 wpas_dbus_signal_network(wpa_s, id, "NetworkSelected", FALSE);
8fc2fb56
WS
427}
428
429
430/**
431 * wpas_dbus_signal_state_changed - Send a state changed signal
432 * @wpa_s: %wpa_supplicant network interface data
433 * @new_state: new state wpa_supplicant is entering
434 * @old_state: old state wpa_supplicant is leaving
435 *
436 * Notify listeners that wpa_supplicant has changed state
437 */
52bdd880
JM
438void wpas_dbus_signal_state_changed(struct wpa_supplicant *wpa_s,
439 enum wpa_states new_state,
440 enum wpa_states old_state)
8fc2fb56 441{
8ddef94b 442 struct wpas_dbus_priv *iface;
8fc2fb56 443 DBusMessage *_signal = NULL;
8fc2fb56
WS
444 char *new_state_str, *old_state_str;
445 char *tmp;
446
447 /* Do nothing if the control interface is not turned on */
448 if (wpa_s->global == NULL)
449 return;
8ddef94b 450 iface = wpa_s->global->dbus;
8fc2fb56
WS
451 if (iface == NULL)
452 return;
453
454 /* Only send signal if state really changed */
455 if (new_state == old_state)
456 return;
457
c49cf2d6
JM
458 _signal = dbus_message_new_signal(wpa_s->dbus_new_path,
459 WPAS_DBUS_NEW_IFACE_INTERFACE,
8fc2fb56 460 "StateChanged");
c2b8c674 461 if (_signal == NULL)
8fc2fb56 462 return;
8fc2fb56
WS
463
464 new_state_str = os_strdup(wpa_supplicant_state_txt(new_state));
465 old_state_str = os_strdup(wpa_supplicant_state_txt(old_state));
c2b8c674 466 if (new_state_str == NULL || old_state_str == NULL)
8fc2fb56 467 goto out;
8fc2fb56
WS
468
469 /* make state string lowercase to fit new DBus API convention */
470 tmp = new_state_str;
471 while (*tmp) {
472 *tmp = tolower(*tmp);
473 tmp++;
474 }
475 tmp = old_state_str;
476 while (*tmp) {
477 *tmp = tolower(*tmp);
478 tmp++;
479 }
480
481 if (!dbus_message_append_args(_signal,
482 DBUS_TYPE_STRING, &new_state_str,
483 DBUS_TYPE_STRING, &old_state_str,
484 DBUS_TYPE_INVALID)) {
8fc2fb56 485 wpa_printf(MSG_ERROR,
c2b8c674 486 "dbus: wpas_dbus_signal_state_changed: "
8fc2fb56 487 "not enough memory to construct state change "
c2b8c674 488 "signal");
8fc2fb56
WS
489 goto out;
490 }
491
492 dbus_connection_send(iface->con, _signal, NULL);
493
494out:
495 dbus_message_unref(_signal);
496 os_free(new_state_str);
497 os_free(old_state_str);
498}
499
500
501/**
17efbfac 502 * wpas_dbus_signal_network_enabled_changed - Signals Enabled property changes
8fc2fb56
WS
503 * @wpa_s: %wpa_supplicant network interface data
504 * @ssid: configured network which Enabled property has changed
505 *
506 * Sends PropertyChanged signals containing new value of Enabled property
507 * for specified network
508 */
52bdd880
JM
509void wpas_dbus_signal_network_enabled_changed(struct wpa_supplicant *wpa_s,
510 struct wpa_ssid *ssid)
8fc2fb56
WS
511{
512
513 struct network_handler_args args = {wpa_s, ssid};
514
515 char path[WPAS_DBUS_OBJECT_PATH_MAX];
516 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
517 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
c49cf2d6 518 wpa_s->dbus_new_path, ssid->id);
8fc2fb56 519
8ddef94b 520 wpa_dbus_signal_property_changed(wpa_s->global->dbus,
8fc2fb56
WS
521 (WPADBusPropertyAccessor)
522 wpas_dbus_getter_enabled, &args,
523 path, WPAS_DBUS_NEW_IFACE_NETWORK,
524 "Enabled");
525}
526
527
528#ifdef CONFIG_WPS
529
530/**
531 * wpas_dbus_signal_wps_event_success - Signals Success WPS event
532 * @wpa_s: %wpa_supplicant network interface data
533 *
534 * Sends Event dbus signal with name "success" and empty dict as arguments
535 */
52bdd880 536void wpas_dbus_signal_wps_event_success(struct wpa_supplicant *wpa_s)
8fc2fb56
WS
537{
538
3864e6ea 539 DBusMessage *_signal = NULL;
8fc2fb56 540 DBusMessageIter iter, dict_iter;
8ddef94b 541 struct wpas_dbus_priv *iface;
8fc2fb56 542 char *key = "success";
8fc2fb56 543
8ddef94b 544 iface = wpa_s->global->dbus;
8fc2fb56
WS
545
546 /* Do nothing if the control interface is not turned on */
547 if (iface == NULL)
548 return;
549
c49cf2d6
JM
550 _signal = dbus_message_new_signal(wpa_s->dbus_new_path,
551 WPAS_DBUS_NEW_IFACE_WPS, "Event");
8fc2fb56
WS
552 if (!_signal) {
553 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_success"
554 "[dbus]: out of memory when creating a signal");
555 return;
556 }
557
558 dbus_message_iter_init_append(_signal, &iter);
559
560 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
561 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
562 !wpa_dbus_dict_close_write(&iter, &dict_iter)) {
563 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_success"
564 "[dbus]: out of memory");
565 goto out;
566 }
567
568 dbus_connection_send(iface->con, _signal, NULL);
569out:
570 dbus_message_unref(_signal);
571}
572
573
574/**
575 * wpas_dbus_signal_wps_event_fail - Signals Fail WPS event
576 * @wpa_s: %wpa_supplicant network interface data
577 *
578 * Sends Event dbus signal with name "fail" and dictionary containing
579 * "msg field with fail message number (int32) as arguments
580 */
52bdd880
JM
581void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant *wpa_s,
582 struct wps_event_fail *fail)
8fc2fb56
WS
583{
584
3864e6ea 585 DBusMessage *_signal = NULL;
8fc2fb56 586 DBusMessageIter iter, dict_iter;
8ddef94b 587 struct wpas_dbus_priv *iface;
3864e6ea 588 char *key = "fail";
8fc2fb56 589
8ddef94b 590 iface = wpa_s->global->dbus;
8fc2fb56
WS
591
592 /* Do nothing if the control interface is not turned on */
593 if (iface == NULL)
594 return;
595
c49cf2d6
JM
596 _signal = dbus_message_new_signal(wpa_s->dbus_new_path,
597 WPAS_DBUS_NEW_IFACE_WPS, "Event");
8fc2fb56
WS
598 if (!_signal) {
599 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_fail[dbus]: "
600 "out of memory when creating a signal");
601 return;
602 }
603
604 dbus_message_iter_init_append(_signal, &iter);
605
606 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
607 !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
608 !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
609 !wpa_dbus_dict_close_write(&iter, &dict_iter)) {
610 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_fail[dbus]: "
611 "out of memory");
612 goto out;
613 }
614
615 dbus_connection_send(iface->con, _signal, NULL);
616out:
617 dbus_message_unref(_signal);
618}
619
620
621/**
622 * wpas_dbus_signal_wps_event_m2d - Signals M2D WPS event
623 * @wpa_s: %wpa_supplicant network interface data
624 *
625 * Sends Event dbus signal with name "m2d" and dictionary containing
626 * fields of wps_event_m2d structure.
627 */
52bdd880
JM
628void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant *wpa_s,
629 struct wps_event_m2d *m2d)
8fc2fb56
WS
630{
631
3864e6ea 632 DBusMessage *_signal = NULL;
8fc2fb56 633 DBusMessageIter iter, dict_iter;
8ddef94b 634 struct wpas_dbus_priv *iface;
3864e6ea 635 char *key = "m2d";
8fc2fb56 636
8ddef94b 637 iface = wpa_s->global->dbus;
8fc2fb56
WS
638
639 /* Do nothing if the control interface is not turned on */
640 if (iface == NULL)
641 return;
642
c49cf2d6
JM
643 _signal = dbus_message_new_signal(wpa_s->dbus_new_path,
644 WPAS_DBUS_NEW_IFACE_WPS, "Event");
8fc2fb56
WS
645 if (!_signal) {
646 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_m2d[dbus]: "
647 "out of memory when creating a signal");
648 return;
649 }
650
651 dbus_message_iter_init_append(_signal, &iter);
652
653 if (!(dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) &&
654 wpa_dbus_dict_open_write(&iter, &dict_iter) &&
655 wpa_dbus_dict_append_uint16(&dict_iter, "config_methods",
656 m2d->config_methods) &&
657 wpa_dbus_dict_append_byte_array(&dict_iter, "manufacturer",
658 (const char *) m2d->manufacturer,
659 m2d->manufacturer_len) &&
660 wpa_dbus_dict_append_byte_array(&dict_iter, "model_name",
661 (const char *) m2d->model_name,
662 m2d->model_name_len) &&
663 wpa_dbus_dict_append_byte_array(&dict_iter, "model_number",
664 (const char *) m2d->model_number,
665 m2d->model_number_len) &&
666 wpa_dbus_dict_append_byte_array(&dict_iter, "serial_number",
667 (const char *)
668 m2d->serial_number,
669 m2d->serial_number_len) &&
670 wpa_dbus_dict_append_byte_array(&dict_iter, "dev_name",
671 (const char *) m2d->dev_name,
672 m2d->dev_name_len) &&
673 wpa_dbus_dict_append_byte_array(&dict_iter, "primary_dev_type",
674 (const char *)
675 m2d->primary_dev_type, 8) &&
676 wpa_dbus_dict_append_uint16(&dict_iter, "config_error",
677 m2d->config_error) &&
678 wpa_dbus_dict_append_uint16(&dict_iter, "dev_password_id",
679 m2d->dev_password_id) &&
680 wpa_dbus_dict_close_write(&iter, &dict_iter))) {
681 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_m2d[dbus]: "
682 "out of memory");
683 goto out;
684 }
685
686 dbus_connection_send(iface->con, _signal, NULL);
687out:
688 dbus_message_unref(_signal);
689}
690
691
692/**
693 * wpas_dbus_signal_wps_cred - Signals new credentials
694 * @wpa_s: %wpa_supplicant network interface data
695 *
696 * Sends signal with credentials in directory argument
697 */
52bdd880
JM
698void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s,
699 const struct wps_credential *cred)
8fc2fb56
WS
700{
701 DBusMessage *_signal = NULL;
702 DBusMessageIter iter, dict_iter;
8ddef94b 703 struct wpas_dbus_priv *iface;
8fc2fb56
WS
704 char *auth_type[6]; /* we have six possible authorization types */
705 int at_num = 0;
706 char *encr_type[4]; /* we have four possible encryption types */
707 int et_num = 0;
708
8ddef94b 709 iface = wpa_s->global->dbus;
8fc2fb56
WS
710
711 /* Do nothing if the control interface is not turned on */
712 if (iface == NULL)
713 return;
714
c49cf2d6
JM
715 _signal = dbus_message_new_signal(wpa_s->dbus_new_path,
716 WPAS_DBUS_NEW_IFACE_WPS,
8fc2fb56 717 "Credentials");
c2b8c674 718 if (!_signal)
8fc2fb56 719 return;
8fc2fb56
WS
720
721 dbus_message_iter_init_append(_signal, &iter);
722
c2b8c674 723 if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
8fc2fb56 724 goto nomem;
8fc2fb56
WS
725
726 if (cred->auth_type & WPS_AUTH_OPEN)
727 auth_type[at_num++] = "open";
728 if (cred->auth_type & WPS_AUTH_WPAPSK)
729 auth_type[at_num++] = "wpa-psk";
730 if (cred->auth_type & WPS_AUTH_SHARED)
731 auth_type[at_num++] = "shared";
732 if (cred->auth_type & WPS_AUTH_WPA)
733 auth_type[at_num++] = "wpa-eap";
734 if (cred->auth_type & WPS_AUTH_WPA2)
735 auth_type[at_num++] = "wpa2-eap";
736 if (cred->auth_type & WPS_AUTH_WPA2PSK)
737 auth_type[at_num++] =
738 "wpa2-psk";
739
740 if (cred->encr_type & WPS_ENCR_NONE)
741 encr_type[et_num++] = "none";
742 if (cred->encr_type & WPS_ENCR_WEP)
743 encr_type[et_num++] = "wep";
744 if (cred->encr_type & WPS_ENCR_TKIP)
745 encr_type[et_num++] = "tkip";
746 if (cred->encr_type & WPS_ENCR_AES)
747 encr_type[et_num++] = "aes";
748
749 if (wpa_s->current_ssid) {
750 if (!wpa_dbus_dict_append_byte_array(
751 &dict_iter, "BSSID",
752 (const char *) wpa_s->current_ssid->bssid,
c2b8c674 753 ETH_ALEN))
8fc2fb56 754 goto nomem;
8fc2fb56
WS
755 }
756
757 if (!(wpa_dbus_dict_append_byte_array(&dict_iter, "SSID",
758 (const char *) cred->ssid,
759 cred->ssid_len) &&
760 wpa_dbus_dict_append_string_array(&dict_iter, "AuthType",
761 (const char **) auth_type,
762 at_num) &&
763 wpa_dbus_dict_append_string_array(&dict_iter, "EncrType",
764 (const char **) encr_type,
765 et_num) &&
766 wpa_dbus_dict_append_byte_array(&dict_iter, "Key",
767 (const char *) cred->key,
768 cred->key_len) &&
769 wpa_dbus_dict_append_uint32(&dict_iter, "KeyIndex",
c2b8c674 770 cred->key_idx)))
8fc2fb56 771 goto nomem;
8fc2fb56 772
c2b8c674 773 if (!wpa_dbus_dict_close_write(&iter, &dict_iter))
8fc2fb56 774 goto nomem;
8fc2fb56
WS
775
776 dbus_connection_send(iface->con, _signal, NULL);
777
778nomem:
779 dbus_message_unref(_signal);
780}
781
782#endif /* CONFIG_WPS */
783
784
785/**
786 * wpas_dbus_signal_prop_changed - Signals change of property
787 * @wpa_s: %wpa_supplicant network interface data
788 * @property: indicates which property has changed
789 *
790 * Sends ProertyChanged signals with path, interface and arguments
791 * depending on which property has changed.
792 */
52bdd880
JM
793void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
794 enum wpas_dbus_prop property)
8fc2fb56
WS
795{
796 WPADBusPropertyAccessor getter;
797 char *iface;
798 char *prop;
799 void *arg;
800
801 switch (property) {
802 case WPAS_DBUS_PROP_AP_SCAN:
803 getter = (WPADBusPropertyAccessor) wpas_dbus_getter_ap_scan;
804 arg = wpa_s;
805 iface = WPAS_DBUS_NEW_IFACE_INTERFACE;
806 prop = "ApScan";
807 break;
808 case WPAS_DBUS_PROP_SCANNING:
809 getter = (WPADBusPropertyAccessor) wpas_dbus_getter_scanning;
810 arg = wpa_s;
811 iface = WPAS_DBUS_NEW_IFACE_INTERFACE;
812 prop = "Scanning";
813 break;
814 case WPAS_DBUS_PROP_CURRENT_BSS:
815 getter = (WPADBusPropertyAccessor)
816 wpas_dbus_getter_current_bss;
817 arg = wpa_s;
818 iface = WPAS_DBUS_NEW_IFACE_INTERFACE;
819 prop = "CurrentBSS";
820 break;
821 case WPAS_DBUS_PROP_CURRENT_NETWORK:
822 getter = (WPADBusPropertyAccessor)
823 wpas_dbus_getter_current_network;
824 arg = wpa_s;
825 iface = WPAS_DBUS_NEW_IFACE_INTERFACE;
826 prop = "CurrentNetwork";
827 break;
828 default:
829 wpa_printf(MSG_ERROR, "wpas_dbus_signal_prop_changed[dbus]: "
830 "Unknown Property enum value %d", property);
831 return;
832 }
833
8ddef94b 834 wpa_dbus_signal_property_changed(wpa_s->global->dbus,
c49cf2d6
JM
835 getter, arg, wpa_s->dbus_new_path,
836 iface, prop);
8fc2fb56
WS
837}
838
839
840/**
db9133ac 841 * wpas_dbus_signal_debug_level_changed - Signals change of debug param
8fc2fb56
WS
842 * @global: wpa_global structure
843 *
db9133ac 844 * Sends ProertyChanged signals informing that debug level has changed.
8fc2fb56 845 */
52bdd880 846void wpas_dbus_signal_debug_level_changed(struct wpa_global *global)
8fc2fb56 847{
db9133ac
WS
848 wpa_dbus_signal_property_changed(global->dbus,
849 (WPADBusPropertyAccessor)
850 wpas_dbus_getter_debug_level,
851 global, WPAS_DBUS_NEW_PATH,
852 WPAS_DBUS_NEW_INTERFACE,
853 "DebugLevel");
854}
855
856
857/**
858 * wpas_dbus_signal_debug_timestamp_changed - Signals change of debug param
859 * @global: wpa_global structure
860 *
861 * Sends ProertyChanged signals informing that debug timestamp has changed.
862 */
52bdd880 863void wpas_dbus_signal_debug_timestamp_changed(struct wpa_global *global)
db9133ac
WS
864{
865 wpa_dbus_signal_property_changed(global->dbus,
866 (WPADBusPropertyAccessor)
867 wpas_dbus_getter_debug_timestamp,
868 global, WPAS_DBUS_NEW_PATH,
869 WPAS_DBUS_NEW_INTERFACE,
870 "DebugTimestamp");
871}
872
8fc2fb56 873
db9133ac
WS
874/**
875 * wpas_dbus_signal_debug_show_keys_changed - Signals change of debug param
876 * @global: wpa_global structure
877 *
878 * Sends ProertyChanged signals informing that debug show_keys has changed.
879 */
52bdd880 880void wpas_dbus_signal_debug_show_keys_changed(struct wpa_global *global)
db9133ac 881{
8ddef94b 882 wpa_dbus_signal_property_changed(global->dbus,
8fc2fb56 883 (WPADBusPropertyAccessor)
db9133ac 884 wpas_dbus_getter_debug_show_keys,
8fc2fb56
WS
885 global, WPAS_DBUS_NEW_PATH,
886 WPAS_DBUS_NEW_INTERFACE,
db9133ac 887 "DebugShowKeys");
8fc2fb56
WS
888}
889
890
9b61515c
JM
891struct wpas_dbus_method {
892 const char *name;
893 const char *iface;
894 WPADBusMethodHandler handler;
895 struct wpa_dbus_argument args[3];
896};
897
898struct wpas_dbus_property {
899 const char *name;
900 const char *iface;
901 const char *type;
902 WPADBusPropertyAccessor getter;
903 WPADBusPropertyAccessor setter;
904 enum dbus_prop_access _access;
905};
906
907struct wpas_dbus_signal {
908 const char *name;
909 const char *iface;
910 struct wpa_dbus_argument args[3];
911};
912
913
914static void wpas_dbus_register(struct wpa_dbus_object_desc *obj_desc,
915 void *priv,
1fa5995b 916 WPADBusArgumentFreeFunction priv_free,
9b61515c
JM
917 const struct wpas_dbus_method *methods,
918 const struct wpas_dbus_property *properties,
919 const struct wpas_dbus_signal *signals)
7ae7b192 920{
9b61515c 921 int i;
7ae7b192 922
1fa5995b
WS
923 obj_desc->user_data = priv;
924 obj_desc->user_data_free_func = priv_free;
925
9b61515c
JM
926 for (i = 0; methods && methods[i].name; i++) {
927 wpa_dbus_method_register(obj_desc, methods[i].iface,
928 methods[i].name, methods[i].handler,
1fa5995b 929 methods[i].args);
9b61515c 930 }
7ae7b192 931
9b61515c
JM
932 for (i = 0; properties && properties[i].name; i++) {
933 wpa_dbus_property_register(obj_desc, properties[i].iface,
934 properties[i].name,
935 properties[i].type,
936 properties[i].getter,
937 properties[i].setter,
1fa5995b 938 properties[i]._access);
9b61515c 939 }
7ae7b192 940
9b61515c
JM
941 for (i = 0; signals && signals[i].name; i++) {
942 wpa_dbus_signal_register(obj_desc, signals[i].iface,
943 signals[i].name, signals[i].args);
944 }
7ae7b192
JM
945}
946
947
9b61515c
JM
948static const struct wpas_dbus_method wpas_dbus_global_methods[] = {
949 { "CreateInterface", WPAS_DBUS_NEW_INTERFACE,
950 (WPADBusMethodHandler) &wpas_dbus_handler_create_interface,
951 {
952 { "args", "a{sv}", ARG_IN },
953 { "path", "o", ARG_OUT },
954 END_ARGS
955 }
956 },
957 { "RemoveInterface", WPAS_DBUS_NEW_INTERFACE,
958 (WPADBusMethodHandler) &wpas_dbus_handler_remove_interface,
959 {
960 { "path", "o", ARG_IN },
961 END_ARGS
962 }
963 },
964 { "GetInterface", WPAS_DBUS_NEW_INTERFACE,
965 (WPADBusMethodHandler) &wpas_dbus_handler_get_interface,
966 {
967 { "ifname", "s", ARG_IN },
968 { "path", "o", ARG_OUT },
969 END_ARGS
970 }
971 },
972 { NULL, NULL, NULL, { END_ARGS } }
973};
974
975static const struct wpas_dbus_property wpas_dbus_global_properties[] = {
db9133ac
WS
976 { "DebugLevel", WPAS_DBUS_NEW_INTERFACE, "y",
977 (WPADBusPropertyAccessor) wpas_dbus_getter_debug_level,
978 (WPADBusPropertyAccessor) wpas_dbus_setter_debug_level,
979 RW
980 },
981 { "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE, "b",
982 (WPADBusPropertyAccessor) wpas_dbus_getter_debug_timestamp,
983 (WPADBusPropertyAccessor) wpas_dbus_setter_debug_timestamp,
984 RW
985 },
986 { "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE, "b",
987 (WPADBusPropertyAccessor) wpas_dbus_getter_debug_show_keys,
988 (WPADBusPropertyAccessor) wpas_dbus_setter_debug_show_keys,
9b61515c
JM
989 RW
990 },
991 { "Interfaces", WPAS_DBUS_NEW_INTERFACE, "ao",
992 (WPADBusPropertyAccessor) &wpas_dbus_getter_interfaces,
993 NULL,
994 R
995 },
996 { "EapMethods", WPAS_DBUS_NEW_INTERFACE, "as",
e376f119 997 (WPADBusPropertyAccessor) wpas_dbus_getter_eap_methods,
9b61515c
JM
998 NULL,
999 R
1000 },
1001 { NULL, NULL, NULL, NULL, NULL, 0 }
1002};
1003
1004static const struct wpas_dbus_signal wpas_dbus_global_signals[] = {
1005 { "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE,
1006 {
1007 { "path", "o", ARG_OUT },
e376f119 1008 { "properties", "a{sv}", ARG_OUT },
9b61515c
JM
1009 END_ARGS
1010 }
1011 },
1012 { "InterfaceRemoved", WPAS_DBUS_NEW_INTERFACE,
1013 {
1014 { "path", "o", ARG_OUT },
1015 END_ARGS
1016 }
1017 },
1018 { "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE,
1019 {
1020 { "properties", "a{sv}", ARG_OUT },
1021 END_ARGS
1022 }
1023 },
1024 { NULL, NULL, { END_ARGS } }
1025};
7ae7b192
JM
1026
1027
1028/**
1029 * wpas_dbus_ctrl_iface_init - Initialize dbus control interface
1030 * @global: Pointer to global data from wpa_supplicant_init()
8ddef94b 1031 * Returns: 0 on success or -1 on failure
7ae7b192
JM
1032 *
1033 * Initialize the dbus control interface for wpa_supplicantand and start
1034 * receiving commands from external programs over the bus.
1035 */
8ddef94b 1036int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv *priv)
7ae7b192 1037{
7ae7b192 1038 struct wpa_dbus_object_desc *obj_desc;
8ddef94b 1039 int ret;
8fc2fb56
WS
1040
1041 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
1042 if (!obj_desc) {
1043 wpa_printf(MSG_ERROR, "Not enough memory "
1044 "to create object description");
8ddef94b 1045 return -1;
8fc2fb56
WS
1046 }
1047
1fa5995b
WS
1048 wpas_dbus_register(obj_desc, priv->global, NULL,
1049 wpas_dbus_global_methods,
9b61515c
JM
1050 wpas_dbus_global_properties,
1051 wpas_dbus_global_signals);
8fc2fb56 1052
8e56d189
JM
1053 wpa_printf(MSG_DEBUG, "dbus: Register D-Bus object '%s'",
1054 WPAS_DBUS_NEW_PATH);
8ddef94b
JM
1055 ret = wpa_dbus_ctrl_iface_init(priv, WPAS_DBUS_NEW_PATH,
1056 WPAS_DBUS_NEW_SERVICE,
1057 obj_desc);
1058 if (ret < 0)
8fc2fb56 1059 free_dbus_object_desc(obj_desc);
26e054ce
JM
1060 else
1061 priv->dbus_new_initialized = 1;
8fc2fb56 1062
8ddef94b 1063 return ret;
8fc2fb56
WS
1064}
1065
1066
1067/**
1068 * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for
1069 * wpa_supplicant
8ddef94b 1070 * @iface: Pointer to dbus private data from wpas_dbus_init()
8fc2fb56
WS
1071 *
1072 * Deinitialize the dbus control interface that was initialized with
1073 * wpas_dbus_ctrl_iface_init().
1074 */
8ddef94b 1075void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv *iface)
8fc2fb56 1076{
26e054ce
JM
1077 if (!iface->dbus_new_initialized)
1078 return;
8ddef94b
JM
1079 wpa_printf(MSG_DEBUG, "dbus: Unregister D-Bus object '%s'",
1080 WPAS_DBUS_NEW_PATH);
1081 dbus_connection_unregister_object_path(iface->con,
1082 WPAS_DBUS_NEW_PATH);
8fc2fb56
WS
1083}
1084
1085
d114fcab
JM
1086static void wpa_dbus_free(void *ptr)
1087{
1088 os_free(ptr);
1089}
1090
1091
1fa5995b
WS
1092static const struct wpas_dbus_property wpas_dbus_network_properties[] = {
1093 { "Properties", WPAS_DBUS_NEW_IFACE_NETWORK, "a{sv}",
1094 (WPADBusPropertyAccessor) wpas_dbus_getter_network_properties,
1095 (WPADBusPropertyAccessor) wpas_dbus_setter_network_properties,
1096 RW
1097 },
1098 { "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK, "b",
1099 (WPADBusPropertyAccessor) wpas_dbus_getter_enabled,
1100 (WPADBusPropertyAccessor) wpas_dbus_setter_enabled,
1101 RW
1102 },
1103 { NULL, NULL, NULL, NULL, NULL, 0 }
1104};
1105
1106
1107static const struct wpas_dbus_signal wpas_dbus_network_signals[] = {
1108 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK,
1109 {
1110 { "properties", "a{sv}", ARG_OUT },
1111 END_ARGS
1112 }
1113 },
1114 { NULL, NULL, { END_ARGS } }
1115};
1116
1117
8fc2fb56
WS
1118/**
1119 * wpas_dbus_register_network - Register a configured network with dbus
1120 * @wpa_s: wpa_supplicant interface structure
1121 * @ssid: network configuration data
1122 * Returns: 0 on success, -1 on failure
1123 *
1124 * Registers network representing object with dbus
1125 */
52bdd880
JM
1126int wpas_dbus_register_network(struct wpa_supplicant *wpa_s,
1127 struct wpa_ssid *ssid)
8fc2fb56 1128{
8ddef94b 1129 struct wpas_dbus_priv *ctrl_iface;
8fc2fb56
WS
1130 struct wpa_dbus_object_desc *obj_desc;
1131
1fa5995b 1132 struct network_handler_args *arg = NULL;
8fc2fb56 1133
8fc2fb56
WS
1134 char *net_obj_path;
1135
8fc2fb56
WS
1136 /* Do nothing if the control interface is not turned on */
1137 if (wpa_s == NULL || wpa_s->global == NULL)
1138 return 0;
8ddef94b 1139 ctrl_iface = wpa_s->global->dbus;
8fc2fb56
WS
1140 if (ctrl_iface == NULL)
1141 return 0;
1142
1143 net_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1144 if (net_obj_path == NULL)
1145 return -1;
1146 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
d69780dc 1147 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
c49cf2d6 1148 wpa_s->dbus_new_path, ssid->id);
8fc2fb56 1149
8e56d189
JM
1150 wpa_printf(MSG_DEBUG, "dbus: Register network object '%s'",
1151 net_obj_path);
8fc2fb56
WS
1152 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
1153 if (!obj_desc) {
1154 wpa_printf(MSG_ERROR, "Not enough memory "
1155 "to create object description");
1156 goto err;
1157 }
1158
1159 /* allocate memory for handlers arguments */
1fa5995b
WS
1160 arg = os_zalloc(sizeof(struct network_handler_args));
1161 if (!arg) {
8fc2fb56
WS
1162 wpa_printf(MSG_ERROR, "Not enough memory "
1163 "to create arguments for method");
1164 goto err;
1165 }
1166
1fa5995b
WS
1167 arg->wpa_s = wpa_s;
1168 arg->ssid = ssid;
1169
1170 wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
1171 wpas_dbus_network_properties,
1172 wpas_dbus_network_signals);
8fc2fb56
WS
1173
1174 if (wpa_dbus_register_object_per_iface(ctrl_iface, net_obj_path,
1175 wpa_s->ifname, obj_desc))
1176 goto err;
1177
1178 wpas_dbus_signal_network_added(wpa_s, ssid->id);
1179
1180 os_free(net_obj_path);
1181 return 0;
1182
1183err:
1184 os_free(net_obj_path);
1185 os_free(obj_desc);
1fa5995b 1186 os_free(arg);
8fc2fb56
WS
1187 return -1;
1188}
1189
1190
1191/**
1192 * wpas_dbus_unregister_network - Unregister a configured network from dbus
1193 * @wpa_s: wpa_supplicant interface structure
1194 * @nid: network id
1195 * Returns: 0 on success, -1 on failure
1196 *
1197 * Unregisters network representing object from dbus
1198 */
52bdd880 1199int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid)
8fc2fb56 1200{
8ddef94b 1201 struct wpas_dbus_priv *ctrl_iface;
8fc2fb56
WS
1202 char *net_obj_path;
1203 int ret;
1204
1205 /* Do nothing if the control interface is not turned on */
1206 if (wpa_s == NULL || wpa_s->global == NULL)
1207 return 0;
8ddef94b 1208 ctrl_iface = wpa_s->global->dbus;
8fc2fb56
WS
1209 if (ctrl_iface == NULL)
1210 return 0;
1211
1212 net_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1213 if (net_obj_path == NULL)
1214 return -1;
1215 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
d69780dc 1216 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
c49cf2d6 1217 wpa_s->dbus_new_path, nid);
8fc2fb56 1218
8e56d189
JM
1219 wpa_printf(MSG_DEBUG, "dbus: Unregister network object '%s'",
1220 net_obj_path);
8fc2fb56
WS
1221 ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, net_obj_path);
1222
1223 if (!ret)
1224 wpas_dbus_signal_network_removed(wpa_s, nid);
1225
1226 os_free(net_obj_path);
1227 return ret;
1228}
1229
1230
1fa5995b 1231static const struct wpas_dbus_property wpas_dbus_bss_properties[] = {
58605c6e
WS
1232 { "SSID", WPAS_DBUS_NEW_IFACE_BSSID, "ay",
1233 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_ssid,
1234 NULL,
1235 R
1236 },
1237 { "BSSID", WPAS_DBUS_NEW_IFACE_BSSID, "ay",
1238 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_bssid,
1239 NULL,
1240 R
1241 },
1242 { "Privacy", WPAS_DBUS_NEW_IFACE_BSSID, "b",
1243 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_privacy,
1244 NULL,
1245 R
1246 },
1247 { "Mode", WPAS_DBUS_NEW_IFACE_BSSID, "s",
1248 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_mode,
1249 NULL,
1250 R
1251 },
1252 { "Signal", WPAS_DBUS_NEW_IFACE_BSSID, "n",
1253 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_signal,
1254 NULL,
1255 R
1256 },
1257 { "Frequency", WPAS_DBUS_NEW_IFACE_BSSID, "q",
1258 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_frequency,
1259 NULL,
1260 R
1261 },
1262 { "MaxRate", WPAS_DBUS_NEW_IFACE_BSSID, "q",
1263 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_max_rate,
1264 NULL,
1265 R
1266 },
1267 { "WPAIE", WPAS_DBUS_NEW_IFACE_BSSID, "ay",
1268 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_wpaie,
1269 NULL,
1270 R
1271 },
1272 { "RSNIE", WPAS_DBUS_NEW_IFACE_BSSID, "ay",
1273 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_rsnie,
1274 NULL,
1275 R
1276 },
1277 { "WPSIE", WPAS_DBUS_NEW_IFACE_BSSID, "ay",
1278 (WPADBusPropertyAccessor) wpas_dbus_getter_bss_wpsie,
1fa5995b
WS
1279 NULL,
1280 R
1281 },
1282 { NULL, NULL, NULL, NULL, NULL, 0 }
1283};
1284
1285
1286static const struct wpas_dbus_signal wpas_dbus_bss_signals[] = {
1287 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSSID,
1288 {
1289 { "properties", "a{sv}", ARG_OUT },
1290 END_ARGS
1291 }
1292 },
1293 { NULL, NULL, { END_ARGS } }
1294};
1295
1296
8fc2fb56 1297/**
17efbfac 1298 * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus
8fc2fb56
WS
1299 * @wpa_s: wpa_supplicant interface structure
1300 * @bssid: scanned network bssid
ccd286d0 1301 * @id: unique BSS identifier
8fc2fb56
WS
1302 * Returns: 0 on success, -1 on failure
1303 *
17efbfac 1304 * Unregisters BSS representing object from dbus
8fc2fb56 1305 */
52bdd880
JM
1306int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s,
1307 u8 bssid[ETH_ALEN], unsigned int id)
8fc2fb56 1308{
8ddef94b 1309 struct wpas_dbus_priv *ctrl_iface;
8fc2fb56
WS
1310 char *bss_obj_path;
1311
1312 /* Do nothing if the control interface is not turned on */
1313 if (wpa_s == NULL || wpa_s->global == NULL)
1314 return 0;
8ddef94b 1315 ctrl_iface = wpa_s->global->dbus;
8fc2fb56
WS
1316 if (ctrl_iface == NULL)
1317 return 0;
1318
1319 bss_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1320 if (bss_obj_path == NULL)
1321 return -1;
1322
1323 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
ccd286d0 1324 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
c49cf2d6 1325 wpa_s->dbus_new_path, id);
8fc2fb56 1326
8e56d189
JM
1327 wpa_printf(MSG_DEBUG, "dbus: Unregister BSS object '%s'",
1328 bss_obj_path);
8fc2fb56
WS
1329 if (wpa_dbus_unregister_object_per_iface(ctrl_iface, bss_obj_path)) {
1330 wpa_printf(MSG_ERROR,
1331 "Cannot unregister BSSID dbus object %s.",
1332 bss_obj_path);
1333 os_free(bss_obj_path);
1334 return -1;
1335 }
1336
1337 wpas_dbus_signal_bss_removed(wpa_s, bss_obj_path);
1338
1339 os_free(bss_obj_path);
1340 return 0;
1341}
1342
1343
17efbfac
JM
1344/**
1345 * wpas_dbus_register_bss - Register a scanned BSS with dbus
1346 * @wpa_s: wpa_supplicant interface structure
1347 * @bssid: scanned network bssid
ccd286d0 1348 * @id: unique BSS identifier
17efbfac
JM
1349 * Returns: 0 on success, -1 on failure
1350 *
1351 * Registers BSS representing object with dbus
1352 */
52bdd880
JM
1353int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s,
1354 u8 bssid[ETH_ALEN], unsigned int id)
8fc2fb56 1355{
8ddef94b 1356 struct wpas_dbus_priv *ctrl_iface;
8fc2fb56 1357 struct wpa_dbus_object_desc *obj_desc;
8fc2fb56
WS
1358 char *bss_obj_path;
1359
1360 struct bss_handler_args *arg = NULL;
1361
1362 /* Do nothing if the control interface is not turned on */
1363 if (wpa_s == NULL || wpa_s->global == NULL)
1364 return 0;
8ddef94b 1365 ctrl_iface = wpa_s->global->dbus;
8fc2fb56
WS
1366 if (ctrl_iface == NULL)
1367 return 0;
1368
1369 bss_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1370 if (bss_obj_path == NULL)
1371 return -1;
1372
1373 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
ccd286d0 1374 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
c49cf2d6 1375 wpa_s->dbus_new_path, id);
8fc2fb56
WS
1376
1377 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
1378 if (!obj_desc) {
1379 wpa_printf(MSG_ERROR, "Not enough memory "
1380 "to create object description");
1381 goto err;
1382 }
1383
1384 arg = os_zalloc(sizeof(struct bss_handler_args));
1385 if (!arg) {
1386 wpa_printf(MSG_ERROR, "Not enough memory "
1387 "to create arguments for handler");
1388 goto err;
1389 }
1390 arg->wpa_s = wpa_s;
ccd286d0 1391 arg->id = id;
8fc2fb56 1392
1fa5995b
WS
1393 wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
1394 wpas_dbus_bss_properties,
1395 wpas_dbus_bss_signals);
8fc2fb56 1396
8e56d189
JM
1397 wpa_printf(MSG_DEBUG, "dbus: Register BSS object '%s'",
1398 bss_obj_path);
8fc2fb56
WS
1399 if (wpa_dbus_register_object_per_iface(ctrl_iface, bss_obj_path,
1400 wpa_s->ifname, obj_desc)) {
1401 wpa_printf(MSG_ERROR,
1402 "Cannot register BSSID dbus object %s.",
1403 bss_obj_path);
1404 goto err;
1405 }
1406
1407 wpas_dbus_signal_bss_added(wpa_s, bss_obj_path);
1408
1409 os_free(bss_obj_path);
1410 return 0;
1411
1412err:
1413 os_free(bss_obj_path);
1414 os_free(obj_desc);
1415 os_free(arg);
1416 return -1;
1417}
1418
1419
9b61515c
JM
1420static const struct wpas_dbus_method wpas_dbus_interface_methods[] = {
1421 { "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE,
1422 (WPADBusMethodHandler) &wpas_dbus_handler_scan,
1423 {
1424 { "args", "a{sv}", ARG_IN },
1425 END_ARGS
1426 }
1427 },
1428 { "Disconnect", WPAS_DBUS_NEW_IFACE_INTERFACE,
1429 (WPADBusMethodHandler) &wpas_dbus_handler_disconnect,
1430 {
1431 END_ARGS
1432 }
1433 },
1434 { "AddNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
1435 (WPADBusMethodHandler) &wpas_dbus_handler_add_network,
1436 {
1437 { "args", "a{sv}", ARG_IN },
1438 { "path", "o", ARG_OUT },
1439 END_ARGS
1440 }
1441 },
1442 { "RemoveNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
1443 (WPADBusMethodHandler) &wpas_dbus_handler_remove_network,
1444 {
1445 { "path", "o", ARG_IN },
1446 END_ARGS
1447 }
1448 },
1449 { "SelectNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
1450 (WPADBusMethodHandler) &wpas_dbus_handler_select_network,
1451 {
1452 { "path", "o", ARG_IN },
1453 END_ARGS
1454 }
1455 },
1456 { "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
1457 (WPADBusMethodHandler) &wpas_dbus_handler_add_blob,
1458 {
1459 { "name", "s", ARG_IN },
1460 { "data", "ay", ARG_IN },
1461 END_ARGS
1462 }
1463 },
1464 { "GetBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
1465 (WPADBusMethodHandler) &wpas_dbus_handler_get_blob,
1466 {
1467 { "name", "s", ARG_IN },
1468 { "data", "ay", ARG_OUT },
1469 END_ARGS
1470 }
1471 },
1472 { "RemoveBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
1473 (WPADBusMethodHandler) &wpas_dbus_handler_remove_blob,
1474 {
1475 { "name", "s", ARG_IN },
1476 END_ARGS
1477 }
1478 },
1479#ifdef CONFIG_WPS
1480 { "Start", WPAS_DBUS_NEW_IFACE_WPS,
1481 (WPADBusMethodHandler) &wpas_dbus_handler_wps_start,
1482 {
1483 { "args", "a{sv}", ARG_IN },
1484 { "output", "a{sv}", ARG_OUT },
1485 END_ARGS
1486 }
1487 },
1488#endif /* CONFIG_WPS */
1489 { NULL, NULL, NULL, { END_ARGS } }
1490};
1491
1492static const struct wpas_dbus_property wpas_dbus_interface_properties[] = {
1493 { "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}",
1494 (WPADBusPropertyAccessor) wpas_dbus_getter_capabilities,
1495 NULL, R
1496 },
1497 { "State", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
1498 (WPADBusPropertyAccessor) wpas_dbus_getter_state,
1499 NULL, R
1500 },
1501 { "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
1502 (WPADBusPropertyAccessor) wpas_dbus_getter_scanning,
1503 NULL, R
1504 },
1505 { "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
1506 (WPADBusPropertyAccessor) wpas_dbus_getter_ap_scan,
1507 (WPADBusPropertyAccessor) wpas_dbus_setter_ap_scan,
1508 RW
1509 },
1510 { "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
1511 (WPADBusPropertyAccessor) wpas_dbus_getter_ifname,
1512 NULL, R
1513 },
1514 { "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
1515 (WPADBusPropertyAccessor) wpas_dbus_getter_driver,
1516 NULL, R
1517 },
1518 { "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
1519 (WPADBusPropertyAccessor) wpas_dbus_getter_bridge_ifname,
1520 NULL, R
1521 },
1522 { "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
1523 (WPADBusPropertyAccessor) wpas_dbus_getter_current_bss,
1524 NULL, R
1525 },
1526 { "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
1527 (WPADBusPropertyAccessor) wpas_dbus_getter_current_network,
1528 NULL, R
1529 },
1530 { "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{say}",
1531 (WPADBusPropertyAccessor) wpas_dbus_getter_blobs,
1532 NULL, R
1533 },
1534 { "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
1535 (WPADBusPropertyAccessor) wpas_dbus_getter_bsss,
1536 NULL, R
1537 },
1538 { "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
1539 (WPADBusPropertyAccessor) wpas_dbus_getter_networks,
1540 NULL, R
1541 },
1542#ifdef CONFIG_WPS
1543 { "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b",
1544 (WPADBusPropertyAccessor) wpas_dbus_getter_process_credentials,
1545 (WPADBusPropertyAccessor) wpas_dbus_setter_process_credentials,
1546 RW
1547 },
1548#endif /* CONFIG_WPS */
1549 { NULL, NULL, NULL, NULL, NULL, 0 }
1550};
1551
1552static const struct wpas_dbus_signal wpas_dbus_interface_signals[] = {
1553 { "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE,
1554 {
1555 { "success", "b", ARG_OUT },
1556 END_ARGS
1557 }
1558 },
1559 { "StateChanged", WPAS_DBUS_NEW_IFACE_INTERFACE,
1560 {
1561 { "newState", "s", ARG_OUT },
1562 { "oldState", "s", ARG_OUT },
1563 END_ARGS
1564 }
1565 },
1566 { "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
1567 {
1568 { "path", "o", ARG_OUT },
e376f119 1569 { "properties", "a{sv}", ARG_OUT },
9b61515c
JM
1570 END_ARGS
1571 }
1572 },
1573 { "BSSRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
1574 {
1575 { "path", "o", ARG_OUT },
1576 END_ARGS
1577 }
1578 },
1579 { "BlobAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
1580 {
1581 { "name", "s", ARG_OUT },
1582 END_ARGS
1583 }
1584 },
1585 { "BlobRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
1586 {
1587 { "name", "s", ARG_OUT },
1588 END_ARGS
1589 }
1590 },
1591 { "NetworkAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
1592 {
1593 { "path", "o", ARG_OUT },
e376f119 1594 { "properties", "a{sv}", ARG_OUT },
9b61515c
JM
1595 END_ARGS
1596 }
1597 },
1598 { "NetworkRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
1599 {
1600 { "path", "o", ARG_OUT },
1601 END_ARGS
1602 }
1603 },
1604 { "NetworkSelected", WPAS_DBUS_NEW_IFACE_INTERFACE,
1605 {
1606 { "path", "o", ARG_OUT },
1607 END_ARGS
1608 }
1609 },
1610 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE,
1611 {
1612 { "properties", "a{sv}", ARG_OUT },
1613 END_ARGS
1614 }
1615 },
1616#ifdef CONFIG_WPS
1617 { "Event", WPAS_DBUS_NEW_IFACE_WPS,
1618 {
1619 { "name", "s", ARG_OUT },
1620 { "args", "a{sv}", ARG_OUT },
1621 END_ARGS
1622 }
1623 },
1624 { "Credentials", WPAS_DBUS_NEW_IFACE_WPS,
1625 {
1626 { "credentials", "a{sv}", ARG_OUT },
1627 END_ARGS
1628 }
1629 },
1630 { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS,
1631 {
1632 { "properties", "a{sv}", ARG_OUT },
1633 END_ARGS
1634 }
1635 },
1636#endif /* CONFIG_WPS */
1637 { NULL, NULL, { END_ARGS } }
1638};
1639
1640
52bdd880 1641int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s)
8fc2fb56
WS
1642{
1643
1644 struct wpa_dbus_object_desc *obj_desc = NULL;
8ddef94b 1645 struct wpas_dbus_priv *ctrl_iface = wpa_s->global->dbus;
8fc2fb56
WS
1646 int next;
1647
8fc2fb56
WS
1648 /* Do nothing if the control interface is not turned on */
1649 if (ctrl_iface == NULL)
1650 return 0;
1651
1652 /* Create and set the interface's object path */
19120498
JM
1653 wpa_s->dbus_new_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1654 if (wpa_s->dbus_new_path == NULL)
8fc2fb56 1655 return -1;
8ddef94b 1656 next = ctrl_iface->next_objid++;
19120498 1657 os_snprintf(wpa_s->dbus_new_path, WPAS_DBUS_OBJECT_PATH_MAX,
8fc2fb56
WS
1658 WPAS_DBUS_NEW_PATH_INTERFACES "/%u",
1659 next);
8fc2fb56
WS
1660
1661 obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
1662 if (!obj_desc) {
1663 wpa_printf(MSG_ERROR, "Not enough memory "
1664 "to create object description");
1665 goto err;
1666 }
1667
1fa5995b 1668 wpas_dbus_register(obj_desc, wpa_s, NULL, wpas_dbus_interface_methods,
9b61515c
JM
1669 wpas_dbus_interface_properties,
1670 wpas_dbus_interface_signals);
8fc2fb56 1671
19120498
JM
1672 wpa_printf(MSG_DEBUG, "dbus: Register interface object '%s'",
1673 wpa_s->dbus_new_path);
1674 if (wpa_dbus_register_object_per_iface(ctrl_iface,
1675 wpa_s->dbus_new_path,
1676 wpa_s->ifname, obj_desc))
8fc2fb56
WS
1677 goto err;
1678
b7e8feec 1679 wpas_dbus_signal_interface_added(wpa_s);
8fc2fb56 1680
8fc2fb56
WS
1681 return 0;
1682
1683err:
19120498
JM
1684 os_free(wpa_s->dbus_new_path);
1685 wpa_s->dbus_new_path = NULL;
8fc2fb56 1686 os_free(obj_desc);
8fc2fb56
WS
1687 return -1;
1688}
1689
1690
52bdd880 1691int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s)
8fc2fb56 1692{
8ddef94b 1693 struct wpas_dbus_priv *ctrl_iface;
8fc2fb56
WS
1694
1695 /* Do nothing if the control interface is not turned on */
1696 if (wpa_s == NULL || wpa_s->global == NULL)
1697 return 0;
8ddef94b 1698 ctrl_iface = wpa_s->global->dbus;
8fc2fb56
WS
1699 if (ctrl_iface == NULL)
1700 return 0;
1701
8e56d189 1702 wpa_printf(MSG_DEBUG, "dbus: Unregister interface object '%s'",
c49cf2d6 1703 wpa_s->dbus_new_path);
d69780dc 1704 if (wpa_dbus_unregister_object_per_iface(ctrl_iface,
c49cf2d6 1705 wpa_s->dbus_new_path))
8fc2fb56
WS
1706 return -1;
1707
1708 wpas_dbus_signal_interface_removed(wpa_s);
1709
1710 os_free(wpa_s->dbus_new_path);
1711 wpa_s->dbus_new_path = NULL;
1712
1713 return 0;
1714}