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