dbus: Fix some of the function comment typos
[libeap.git] / wpa_supplicant / ctrl_iface_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, Witold Sowa <witold.sowa@gmail.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * Alternatively, this software may be distributed under the terms of BSD
11  * license.
12  *
13  * See README and COPYING for more details.
14  */
15
16 #include "includes.h"
17
18 #include "common.h"
19 #include "config.h"
20 #include "wpa_supplicant_i.h"
21 #include "drivers/driver.h"
22 #include "wps/wps.h"
23 #include "ctrl_iface_dbus_new_helpers.h"
24 #include "dbus_dict_helpers.h"
25 #include "ctrl_iface_dbus_new.h"
26 #include "ctrl_iface_dbus_new_handlers.h"
27
28 /**
29  * wpas_dbus_set_path - Assign a dbus path to an interface
30  * @wpa_s: wpa_supplicant interface structure
31  * @path: dbus path to set on the interface
32  * Returns: 0 on success, -1 on error
33  */
34 static int wpas_dbus_set_path(struct wpa_supplicant *wpa_s,
35                               const char *path)
36 {
37         u32 len = os_strlen(path);
38         if (len >= WPAS_DBUS_OBJECT_PATH_MAX)
39                 return -1;
40         if (wpa_s->dbus_new_path)
41                 return -1;
42         wpa_s->dbus_new_path = os_strdup(path);
43         return 0;
44 }
45
46
47 /**
48  * wpas_dbus_signal_interface - Send a interface related event signal
49  * @wpa_s: %wpa_supplicant network interface data
50  * @sig_name: signal name - InterfaceAdded or InterfaceRemoved
51  *
52  * Notify listeners about event related with interface
53  */
54 static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s,
55                                        const char *sig_name)
56 {
57         struct ctrl_iface_dbus_new_priv *iface;
58         DBusMessage *_signal;
59         const char *path;
60
61         iface = wpa_s->global->dbus_new_ctrl_iface;
62
63         /* Do nothing if the control interface is not turned on */
64         if (iface == NULL)
65                 return;
66
67         path = wpas_dbus_get_path(wpa_s);
68         if (path == NULL) {
69                 wpa_printf(MSG_ERROR, "wpas_dbus_signal_interface[dbus]: "
70                            "Interface doesn't have a dbus path. "
71                            "Can't send signal.");
72                 return;
73         }
74         _signal = dbus_message_new_signal(WPAS_DBUS_NEW_PATH,
75                                           WPAS_DBUS_NEW_INTERFACE, sig_name);
76         if (_signal == NULL) {
77                 wpa_printf(MSG_ERROR, "wpas_dbus_signal_interface[dbus]: "
78                            "enough memory to send scan results signal.");
79                 return;
80         }
81
82         if (dbus_message_append_args(_signal, DBUS_TYPE_OBJECT_PATH, &path,
83                                      DBUS_TYPE_INVALID)) {
84                 dbus_connection_send(iface->con, _signal, NULL);
85         } else {
86                 wpa_printf(MSG_ERROR, "wpas_dbus_signal_interface[dbus]: "
87                            "not enough memory to construct signal.");
88         }
89         dbus_message_unref(_signal);
90 }
91
92
93 /**
94  * wpas_dbus_signal_interface_created - Send a interface created signal
95  * @wpa_s: %wpa_supplicant network interface data
96  *
97  * Notify listeners about creating new interface
98  */
99 static void wpas_dbus_signal_interface_created(struct wpa_supplicant *wpa_s)
100 {
101         wpas_dbus_signal_interface(wpa_s, "InterfaceCreated");
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  */
111 static void wpas_dbus_signal_interface_removed(struct wpa_supplicant *wpa_s)
112 {
113         wpas_dbus_signal_interface(wpa_s, "InterfaceRemoved");
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  */
125 static void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s,
126                                        int success)
127 {
128         struct ctrl_iface_dbus_new_priv *iface;
129         DBusMessage *_signal;
130         const char *path;
131         dbus_bool_t succ;
132
133         iface = wpa_s->global->dbus_new_ctrl_iface;
134
135         /* Do nothing if the control interface is not turned on */
136         if (iface == NULL)
137                 return;
138
139         path = wpas_dbus_get_path(wpa_s);
140         if (path == NULL) {
141                 wpa_printf(MSG_ERROR, "wpas_dbus_signal_scan_done[dbus]: "
142                            "Interface doesn't have a dbus path. "
143                            "Can't send signal.");
144                 return;
145         }
146         _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_INTERFACE,
147                                           "ScanDone");
148         if (_signal == NULL) {
149                 wpa_printf(MSG_ERROR, "wpas_dbus_signal_scan_done[dbus]: "
150                            "enough memory to send signal.");
151                 return;
152         }
153
154         succ = success ? TRUE : FALSE;
155         if (dbus_message_append_args(_signal, DBUS_TYPE_BOOLEAN, &succ,
156                                      DBUS_TYPE_INVALID)) {
157                 dbus_connection_send(iface->con, _signal, NULL);
158         } else {
159                 wpa_printf(MSG_ERROR, "wpas_dbus_signal_scan_done[dbus]: "
160                            "not enough memory to construct signal.");
161         }
162         dbus_message_unref(_signal);
163 }
164
165
166 /**
167  * wpas_dbus_signal_blob - Send a BSS related event signal
168  * @wpa_s: %wpa_supplicant network interface data
169  * @bss_obj_path: BSS object path
170  * @sig_name: signal name - BSSAdded or BSSRemoved
171  *
172  * Notify listeners about event related with BSS
173  */
174 static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s,
175                                  const char *bss_obj_path,
176                                  const char *sig_name)
177 {
178         struct ctrl_iface_dbus_new_priv *iface;
179         DBusMessage *_signal;
180         const char *path;
181
182         iface = wpa_s->global->dbus_new_ctrl_iface;
183
184         /* Do nothing if the control interface is not turned on */
185         if (iface == NULL)
186                 return;
187
188         path = wpas_dbus_get_path(wpa_s);
189         if (path == NULL) {
190                 wpa_printf(MSG_ERROR, "wpas_dbus_signal_bss[dbus]: "
191                            "Interface doesn't have a dbus path. "
192                            "Can't send signal.");
193                 return;
194         }
195         _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_INTERFACE,
196                                           sig_name);
197         if (_signal == NULL) {
198                 wpa_printf(MSG_ERROR, "wpas_dbus_signal_bss[dbus]: "
199                            "enough memory to send signal.");
200                 return;
201         }
202
203         if (dbus_message_append_args(_signal, DBUS_TYPE_OBJECT_PATH,
204                                      &bss_obj_path, DBUS_TYPE_INVALID)) {
205                 dbus_connection_send(iface->con, _signal, NULL);
206         } else {
207                 wpa_printf(MSG_ERROR, "wpas_dbus_signal_bss[dbus]: "
208                            "not enough memory to construct signal.");
209         }
210         dbus_message_unref(_signal);
211 }
212
213
214 /**
215  * wpas_dbus_signal_bss_added - Send a BSS added signal
216  * @wpa_s: %wpa_supplicant network interface data
217  * @bss_obj_path: new BSS object path
218  *
219  * Notify listeners about adding new BSS
220  */
221 static void wpas_dbus_signal_bss_added(struct wpa_supplicant *wpa_s,
222                                        const char *bss_obj_path)
223 {
224         wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSAdded");
225 }
226
227
228 /**
229  * wpas_dbus_signal_bss_removed - Send a BSS removed signal
230  * @wpa_s: %wpa_supplicant network interface data
231  * @bss_obj_path: BSS object path
232  *
233  * Notify listeners about removing BSS
234  */
235 static void wpas_dbus_signal_bss_removed(struct wpa_supplicant *wpa_s,
236                                          const char *bss_obj_path)
237 {
238         wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSRemoved");
239 }
240
241
242 /**
243  * wpas_dbus_signal_blob - Send a blob related event signal
244  * @wpa_s: %wpa_supplicant network interface data
245  * @name: blob name
246  * @sig_name: signal name - BlobAdded or BlobRemoved
247  *
248  * Notify listeners about event related with blob
249  */
250 static void wpas_dbus_signal_blob(struct wpa_supplicant *wpa_s,
251                                   const char *name, const char *sig_name)
252 {
253         struct ctrl_iface_dbus_new_priv *iface;
254         DBusMessage *_signal;
255         const char *path;
256
257         iface = wpa_s->global->dbus_new_ctrl_iface;
258
259         /* Do nothing if the control interface is not turned on */
260         if (iface == NULL)
261                 return;
262
263         path = wpas_dbus_get_path(wpa_s);
264         if (path == NULL) {
265                 wpa_printf(MSG_ERROR, "wpas_dbus_signal_blob[dbus]: "
266                            "Interface doesn't have a dbus path. "
267                            "Can't send signal.");
268                 return;
269         }
270         _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_INTERFACE,
271                                           sig_name);
272         if (_signal == NULL) {
273                 wpa_printf(MSG_ERROR, "wpas_dbus_signal_blob[dbus]: "
274                            "enough memory to send signal.");
275                 return;
276         }
277
278         if (dbus_message_append_args(_signal, DBUS_TYPE_STRING, &name,
279                                      DBUS_TYPE_INVALID)) {
280                 dbus_connection_send(iface->con, _signal, NULL);
281         } else {
282                 wpa_printf(MSG_ERROR, "wpas_dbus_signal_blob[dbus]: "
283                            "not enough memory to construct signal.");
284         }
285         dbus_message_unref(_signal);
286 }
287
288
289 /**
290  * wpas_dbus_signal_blob_added - Send a blob added signal
291  * @wpa_s: %wpa_supplicant network interface data
292  * @name: blob name
293  *
294  * Notify listeners about adding a new blob
295  */
296 static void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s,
297                                         const char *name)
298 {
299         wpas_dbus_signal_blob(wpa_s, name, "BlobAdded");
300 }
301
302
303 /**
304  * wpas_dbus_signal_blob_removed - Send a blob removed signal
305  * @wpa_s: %wpa_supplicant network interface data
306  * @name: blob name
307  *
308  * Notify listeners about removing blob
309  */
310 static void wpas_dbus_signal_blob_removed(struct wpa_supplicant *wpa_s,
311                                           const char *name)
312 {
313         wpas_dbus_signal_blob(wpa_s, name, "BlobRemoved");
314 }
315
316
317 /**
318  * wpas_dbus_signal_network - Send a network related event signal
319  * @wpa_s: %wpa_supplicant network interface data
320  * @id: new network id
321  * @sig_name: signal name - NetworkAdded, NetworkRemoved or NetworkSelected
322  *
323  * Notify listeners about event related with configured network
324  */
325 static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s,
326                                      int id, const char *sig_name)
327 {
328         struct ctrl_iface_dbus_new_priv *iface;
329         DBusMessage *_signal;
330         const char *path;
331         char *net_obj_path;
332
333         iface = wpa_s->global->dbus_new_ctrl_iface;
334
335         /* Do nothing if the control interface is not turned on */
336         if (iface == NULL)
337                 return;
338
339         path = wpas_dbus_get_path(wpa_s);
340         if (path == NULL) {
341                 wpa_printf(MSG_ERROR, "wpas_dbus_signal_network[dbus]: "
342                            "Interface doesn't have a dbus path. "
343                            "Can't send signal.");
344                 return;
345         }
346
347         net_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
348         if (net_obj_path == NULL)
349                 return;
350         os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
351                     "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u", path, id);
352
353         _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_INTERFACE,
354                                           sig_name);
355         if (_signal == NULL) {
356                 wpa_printf(MSG_ERROR, "wpas_dbus_signal_network[dbus]: "
357                            "enough memory to send signal.");
358                 os_free(net_obj_path);
359                 return;
360         }
361
362         if (dbus_message_append_args(_signal, DBUS_TYPE_OBJECT_PATH,
363                                      &net_obj_path, DBUS_TYPE_INVALID)) {
364                 dbus_connection_send(iface->con, _signal, NULL);
365         } else {
366                 wpa_printf(MSG_ERROR, "wpas_dbus_signal_network[dbus]: "
367                            "not enough memory to construct signal.");
368         }
369
370         os_free(net_obj_path);
371         dbus_message_unref(_signal);
372 }
373
374
375 /**
376  * wpas_dbus_signal_network_added - Send a network added signal
377  * @wpa_s: %wpa_supplicant network interface data
378  * @id: new network id
379  *
380  * Notify listeners about adding new network
381  */
382 static void wpas_dbus_signal_network_added(struct wpa_supplicant *wpa_s,
383                                            int id)
384 {
385         wpas_dbus_signal_network(wpa_s, id, "NetworkAdded");
386 }
387
388
389 /**
390  * wpas_dbus_signal_network_removed - Send a network removed signal
391  * @wpa_s: %wpa_supplicant network interface data
392  * @id: network id
393  *
394  * Notify listeners about removing a network
395  */
396 static void wpas_dbus_signal_network_removed(struct wpa_supplicant *wpa_s,
397                                              int id)
398 {
399         wpas_dbus_signal_network(wpa_s, id, "NetworkRemoved");
400 }
401
402
403 /**
404  * wpas_dbus_signal_network_selected - Send a network selected signal
405  * @wpa_s: %wpa_supplicant network interface data
406  * @id: network id
407  *
408  * Notify listeners about selecting a network
409  */
410 static void wpas_dbus_signal_network_selected(struct wpa_supplicant *wpa_s,
411                                               int id)
412 {
413         wpas_dbus_signal_network(wpa_s, id, "NetworkSelected");
414 }
415
416
417 /**
418  * wpas_dbus_signal_state_changed - Send a state changed signal
419  * @wpa_s: %wpa_supplicant network interface data
420  * @new_state: new state wpa_supplicant is entering
421  * @old_state: old state wpa_supplicant is leaving
422  *
423  * Notify listeners that wpa_supplicant has changed state
424  */
425 static void wpas_dbus_signal_state_changed(struct wpa_supplicant *wpa_s,
426                                            wpa_states new_state,
427                                            wpa_states old_state)
428 {
429         struct ctrl_iface_dbus_new_priv *iface;
430         DBusMessage *_signal = NULL;
431         const char *path;
432         char *new_state_str, *old_state_str;
433         char *tmp;
434
435         /* Do nothing if the control interface is not turned on */
436         if (wpa_s->global == NULL)
437                 return;
438         iface = wpa_s->global->dbus_new_ctrl_iface;
439         if (iface == NULL)
440                 return;
441
442         /* Only send signal if state really changed */
443         if (new_state == old_state)
444                 return;
445
446         path = wpas_dbus_get_path(wpa_s);
447         if (path == NULL) {
448                 perror("wpas_dbus_signal_state_changed[dbus]: "
449                        "interface didn't have a dbus path");
450                 wpa_printf(MSG_ERROR,
451                            "wpas_dbus_signal_state_changed[dbus]: "
452                            "interface didn't have a dbus path; can't send "
453                            "signal.");
454                 return;
455         }
456         _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_INTERFACE,
457                                           "StateChanged");
458         if (_signal == NULL) {
459                 perror("wpas_dbus_signal_state_changed[dbus]: "
460                        "couldn't create dbus signal; likely out of memory");
461                 wpa_printf(MSG_ERROR,
462                            "wpas_dbus_signal_state_changed[dbus]: "
463                            "couldn't create dbus signal; likely out of "
464                            "memory.");
465                 return;
466         }
467
468         new_state_str = os_strdup(wpa_supplicant_state_txt(new_state));
469         old_state_str = os_strdup(wpa_supplicant_state_txt(old_state));
470         if (new_state_str == NULL || old_state_str == NULL) {
471                 perror("wpas_dbus_signal_state_changed[dbus]: "
472                        "couldn't convert state strings");
473                 wpa_printf(MSG_ERROR,
474                            "wpas_dbus_signal_state_changed[dbus]: "
475                            "couldn't convert state strings.");
476                 goto out;
477         }
478
479         /* make state string lowercase to fit new DBus API convention */
480         tmp = new_state_str;
481         while (*tmp) {
482                 *tmp = tolower(*tmp);
483                 tmp++;
484         }
485         tmp = old_state_str;
486         while (*tmp) {
487                 *tmp = tolower(*tmp);
488                 tmp++;
489         }
490
491         if (!dbus_message_append_args(_signal,
492                                       DBUS_TYPE_STRING, &new_state_str,
493                                       DBUS_TYPE_STRING, &old_state_str,
494                                       DBUS_TYPE_INVALID)) {
495                 perror("wpas_dbus_signal_state_changed[dbus]: "
496                        "not enough memory to construct state change signal.");
497                 wpa_printf(MSG_ERROR,
498                            "wpas_dbus_signal_state_changed[dbus]: "
499                            "not enough memory to construct state change "
500                            "signal.");
501                 goto out;
502         }
503
504         dbus_connection_send(iface->con, _signal, NULL);
505
506 out:
507         dbus_message_unref(_signal);
508         os_free(new_state_str);
509         os_free(old_state_str);
510 }
511
512
513 /**
514  * wpas_dbus_signal_network_enabled_changed - Signals Enabled property changes
515  * @wpa_s: %wpa_supplicant network interface data
516  * @ssid: configured network which Enabled property has changed
517  *
518  * Sends PropertyChanged signals containing new value of Enabled property
519  * for specified network
520  */
521 static void wpas_dbus_signal_network_enabled_changed(
522         struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
523 {
524
525         struct network_handler_args args = {wpa_s, ssid};
526
527         char path[WPAS_DBUS_OBJECT_PATH_MAX];
528         os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
529                     "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
530                     wpas_dbus_get_path(wpa_s), ssid->id);
531
532         wpa_dbus_signal_property_changed(wpa_s->global->dbus_new_ctrl_iface,
533                                          (WPADBusPropertyAccessor)
534                                          wpas_dbus_getter_enabled, &args,
535                                          path, WPAS_DBUS_NEW_IFACE_NETWORK,
536                                          "Enabled");
537 }
538
539
540 #ifdef CONFIG_WPS
541
542 /**
543  * wpas_dbus_signal_wps_event_success - Signals Success WPS event
544  * @wpa_s: %wpa_supplicant network interface data
545  *
546  * Sends Event dbus signal with name "success" and empty dict as arguments
547  */
548 static void wpas_dbus_signal_wps_event_success(struct wpa_supplicant *wpa_s)
549 {
550
551         DBusMessage * _signal = NULL;
552         DBusMessageIter iter, dict_iter;
553         struct ctrl_iface_dbus_new_priv *iface;
554         char *key = "success";
555         const char * path;
556
557         iface = wpa_s->global->dbus_new_ctrl_iface;
558
559         /* Do nothing if the control interface is not turned on */
560         if (iface == NULL)
561                 return;
562
563         path = wpas_dbus_get_path(wpa_s);
564         if (!path) {
565                 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_success"
566                            "[dbus]: interface has no dbus path set");
567                 return;
568         }
569
570         _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_WPS,
571                                           "Event");
572         if (!_signal) {
573                 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_success"
574                            "[dbus]: out of memory when creating a signal");
575                 return;
576         }
577
578         dbus_message_iter_init_append(_signal, &iter);
579
580         if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
581             !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
582             !wpa_dbus_dict_close_write(&iter, &dict_iter)) {
583                 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_success"
584                            "[dbus]: out of memory");
585                 goto out;
586         }
587
588         dbus_connection_send(iface->con, _signal, NULL);
589 out:
590         dbus_message_unref(_signal);
591 }
592
593
594 /**
595  * wpas_dbus_signal_wps_event_fail - Signals Fail WPS event
596  * @wpa_s: %wpa_supplicant network interface data
597  *
598  * Sends Event dbus signal with name "fail" and dictionary containing
599  * "msg field with fail message number (int32) as arguments
600  */
601 static void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant *wpa_s,
602                                             struct wps_event_fail *fail)
603 {
604
605         DBusMessage * _signal = NULL;
606         DBusMessageIter iter, dict_iter;
607         struct ctrl_iface_dbus_new_priv *iface;
608         char* key = "fail";
609         const char * path;
610
611         iface = wpa_s->global->dbus_new_ctrl_iface;
612
613         /* Do nothing if the control interface is not turned on */
614         if (iface == NULL)
615                 return;
616
617         path = wpas_dbus_get_path(wpa_s);
618         if (!path) {
619                 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_fail[dbus]: "
620                            "interface has no dbus path set");
621                 return;
622         }
623
624         _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_WPS,
625                                           "Event");
626         if (!_signal) {
627                 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_fail[dbus]: "
628                            "out of memory when creating a signal");
629                 return;
630         }
631
632         dbus_message_iter_init_append(_signal, &iter);
633
634         if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
635             !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
636             !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
637             !wpa_dbus_dict_close_write(&iter, &dict_iter)) {
638                 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_fail[dbus]: "
639                            "out of memory");
640                 goto out;
641         }
642
643         dbus_connection_send(iface->con, _signal, NULL);
644 out:
645         dbus_message_unref(_signal);
646 }
647
648
649 /**
650  * wpas_dbus_signal_wps_event_m2d - Signals M2D WPS event
651  * @wpa_s: %wpa_supplicant network interface data
652  *
653  * Sends Event dbus signal with name "m2d" and dictionary containing
654  * fields of wps_event_m2d structure.
655  */
656 static void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant *wpa_s,
657                                            struct wps_event_m2d *m2d)
658 {
659
660         DBusMessage * _signal = NULL;
661         DBusMessageIter iter, dict_iter;
662         struct ctrl_iface_dbus_new_priv *iface;
663         char* key = "m2d";
664         const char * path;
665
666         iface = wpa_s->global->dbus_new_ctrl_iface;
667
668         /* Do nothing if the control interface is not turned on */
669         if (iface == NULL)
670                 return;
671
672         path = wpas_dbus_get_path(wpa_s);
673         if (!path) {
674                 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_m2d[dbus]: "
675                            "interface has no dbus path set");
676                 return;
677         }
678
679         _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_WPS,
680                                           "Event");
681         if (!_signal) {
682                 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_m2d[dbus]: "
683                            "out of memory when creating a signal");
684                 return;
685         }
686
687         dbus_message_iter_init_append(_signal, &iter);
688
689         if (!(dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) &&
690               wpa_dbus_dict_open_write(&iter, &dict_iter) &&
691               wpa_dbus_dict_append_uint16(&dict_iter, "config_methods",
692                                           m2d->config_methods) &&
693               wpa_dbus_dict_append_byte_array(&dict_iter, "manufacturer",
694                                               (const char *) m2d->manufacturer,
695                                               m2d->manufacturer_len) &&
696               wpa_dbus_dict_append_byte_array(&dict_iter, "model_name",
697                                               (const char *) m2d->model_name,
698                                               m2d->model_name_len) &&
699               wpa_dbus_dict_append_byte_array(&dict_iter, "model_number",
700                                               (const char *) m2d->model_number,
701                                               m2d->model_number_len) &&
702               wpa_dbus_dict_append_byte_array(&dict_iter, "serial_number",
703                                               (const char *)
704                                               m2d->serial_number,
705                                               m2d->serial_number_len) &&
706               wpa_dbus_dict_append_byte_array(&dict_iter, "dev_name",
707                                               (const char *) m2d->dev_name,
708                                               m2d->dev_name_len) &&
709               wpa_dbus_dict_append_byte_array(&dict_iter, "primary_dev_type",
710                                               (const char *)
711                                               m2d->primary_dev_type, 8) &&
712               wpa_dbus_dict_append_uint16(&dict_iter, "config_error",
713                                           m2d->config_error) &&
714               wpa_dbus_dict_append_uint16(&dict_iter, "dev_password_id",
715                                           m2d->dev_password_id) &&
716               wpa_dbus_dict_close_write(&iter, &dict_iter))) {
717                 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_m2d[dbus]: "
718                            "out of memory");
719                 goto out;
720         }
721
722         dbus_connection_send(iface->con, _signal, NULL);
723 out:
724         dbus_message_unref(_signal);
725 }
726
727
728 /**
729  * wpas_dbus_signal_wps_cred - Signals new credentials
730  * @wpa_s: %wpa_supplicant network interface data
731  *
732  * Sends signal with credentials in directory argument
733  */
734 static void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s,
735                                       const struct wps_credential *cred)
736 {
737         DBusMessage *_signal = NULL;
738         DBusMessageIter iter, dict_iter;
739         struct ctrl_iface_dbus_new_priv *iface;
740         const char *path;
741         char *auth_type[6]; /* we have six possible authorization types */
742         int at_num = 0;
743         char *encr_type[4]; /* we have four possible encryption types */
744         int et_num = 0;
745
746         iface = wpa_s->global->dbus_new_ctrl_iface;
747
748         /* Do nothing if the control interface is not turned on */
749         if (iface == NULL)
750                 return;
751
752         path = wpas_dbus_get_path(wpa_s);
753         if (!path) {
754                 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_cred[dbus]: "
755                            "interface has no dbus path set");
756                 return;
757         }
758
759         _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_WPS,
760                                           "Credentials");
761         if (!_signal) {
762                 wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_cred[dbus]: "
763                            "out of memory when creating a signal");
764                 return;
765         }
766
767         dbus_message_iter_init_append(_signal, &iter);
768
769         if (!wpa_dbus_dict_open_write(&iter, &dict_iter)) {
770                 perror("wpas_dbus_signal_wps_cred[dbus]: out of memory "
771                        "when opening a dictionary");
772                 goto nomem;
773         }
774
775         if (cred->auth_type & WPS_AUTH_OPEN)
776                 auth_type[at_num++] = "open";
777         if (cred->auth_type & WPS_AUTH_WPAPSK)
778                 auth_type[at_num++] = "wpa-psk";
779         if (cred->auth_type & WPS_AUTH_SHARED)
780                 auth_type[at_num++] = "shared";
781         if (cred->auth_type & WPS_AUTH_WPA)
782                 auth_type[at_num++] = "wpa-eap";
783         if (cred->auth_type & WPS_AUTH_WPA2)
784                 auth_type[at_num++] = "wpa2-eap";
785         if (cred->auth_type & WPS_AUTH_WPA2PSK)
786                 auth_type[at_num++] =
787                 "wpa2-psk";
788
789         if (cred->encr_type & WPS_ENCR_NONE)
790                 encr_type[et_num++] = "none";
791         if (cred->encr_type & WPS_ENCR_WEP)
792                 encr_type[et_num++] = "wep";
793         if (cred->encr_type & WPS_ENCR_TKIP)
794                 encr_type[et_num++] = "tkip";
795         if (cred->encr_type & WPS_ENCR_AES)
796                 encr_type[et_num++] = "aes";
797
798         if (wpa_s->current_ssid) {
799                 if (!wpa_dbus_dict_append_byte_array(
800                             &dict_iter, "BSSID",
801                             (const char *) wpa_s->current_ssid->bssid,
802                             ETH_ALEN)) {
803                         perror("wpas_dbus_signal_wps_cred[dbus]: out of "
804                                "memory when appending bssid to dictionary");
805                         goto nomem;
806                 }
807         }
808
809         if (!(wpa_dbus_dict_append_byte_array(&dict_iter, "SSID",
810                                               (const char *) cred->ssid,
811                                               cred->ssid_len) &&
812               wpa_dbus_dict_append_string_array(&dict_iter, "AuthType",
813                                                 (const char **) auth_type,
814                                                 at_num) &&
815               wpa_dbus_dict_append_string_array(&dict_iter, "EncrType",
816                                                 (const char **) encr_type,
817                                                 et_num) &&
818               wpa_dbus_dict_append_byte_array(&dict_iter, "Key",
819                                               (const char *) cred->key,
820                                               cred->key_len) &&
821               wpa_dbus_dict_append_uint32(&dict_iter, "KeyIndex",
822                                           cred->key_idx))) {
823                 perror("wpas_dbus_signal_wps_cred[dbus]: out of memory "
824                        "when appending to dictionary");
825                 goto nomem;
826         }
827
828         if (!wpa_dbus_dict_close_write(&iter, &dict_iter)) {
829                 perror("wpas_dbus_signal_wps_cred[dbus]: out of memory "
830                        "when closing a dictionary");
831                 goto nomem;
832         }
833
834         dbus_connection_send(iface->con, _signal, NULL);
835
836 nomem:
837         dbus_message_unref(_signal);
838 }
839
840 #endif /* CONFIG_WPS */
841
842
843 /**
844  * wpas_dbus_signal_prop_changed - Signals change of property
845  * @wpa_s: %wpa_supplicant network interface data
846  * @property: indicates which property has changed
847  *
848  * Sends ProertyChanged signals with path, interface and arguments
849  * depending on which property has changed.
850  */
851 static void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
852                                           enum wpas_dbus_prop property)
853 {
854         WPADBusPropertyAccessor getter;
855         char *iface;
856         char *prop;
857         void *arg;
858
859         switch (property) {
860         case WPAS_DBUS_PROP_AP_SCAN:
861                 getter = (WPADBusPropertyAccessor) wpas_dbus_getter_ap_scan;
862                 arg = wpa_s;
863                 iface = WPAS_DBUS_NEW_IFACE_INTERFACE;
864                 prop = "ApScan";
865                 break;
866         case WPAS_DBUS_PROP_SCANNING:
867                 getter = (WPADBusPropertyAccessor) wpas_dbus_getter_scanning;
868                 arg = wpa_s;
869                 iface = WPAS_DBUS_NEW_IFACE_INTERFACE;
870                 prop = "Scanning";
871                 break;
872         case WPAS_DBUS_PROP_CURRENT_BSS:
873                 getter = (WPADBusPropertyAccessor)
874                         wpas_dbus_getter_current_bss;
875                 arg = wpa_s;
876                 iface = WPAS_DBUS_NEW_IFACE_INTERFACE;
877                 prop = "CurrentBSS";
878                 break;
879         case WPAS_DBUS_PROP_CURRENT_NETWORK:
880                 getter = (WPADBusPropertyAccessor)
881                         wpas_dbus_getter_current_network;
882                 arg = wpa_s;
883                 iface = WPAS_DBUS_NEW_IFACE_INTERFACE;
884                 prop = "CurrentNetwork";
885                 break;
886         default:
887                 wpa_printf(MSG_ERROR, "wpas_dbus_signal_prop_changed[dbus]: "
888                            "Unknown Property enum value %d", property);
889                 return;
890         }
891
892         wpa_dbus_signal_property_changed(wpa_s->global->dbus_new_ctrl_iface,
893                                          getter, arg,
894                                          wpas_dbus_get_path(wpa_s), iface,
895                                          prop);
896 }
897
898
899 /**
900  * wpas_dbus_signal_debug_params_changed - Signals change of debug params
901  * @global: wpa_global structure
902  *
903  * Sends ProertyChanged signals informing that debug params has changed.
904  */
905 static void wpas_dbus_signal_debug_params_changed(struct wpa_global *global)
906 {
907
908         wpa_dbus_signal_property_changed(global->dbus_new_ctrl_iface,
909                                          (WPADBusPropertyAccessor)
910                                          wpas_dbus_getter_debug_params,
911                                          global, WPAS_DBUS_NEW_PATH,
912                                          WPAS_DBUS_NEW_INTERFACE,
913                                          "DebugParams");
914 }
915
916
917 /**
918  * wpas_dbus_ctrl_iface_init - Initialize dbus control interface
919  * @global: Pointer to global data from wpa_supplicant_init()
920  * Returns: Pointer to dbus_new_ctrl_iface date or %NULL on failure
921  *
922  * Initialize the dbus control interface for wpa_supplicantand and start
923  * receiving commands from external programs over the bus.
924  */
925 static struct ctrl_iface_dbus_new_priv * wpas_dbus_ctrl_iface_init(
926         struct wpa_global *global)
927 {
928         struct ctrl_iface_dbus_new_priv *ctrl_iface;
929         struct wpa_dbus_object_desc *obj_desc;
930         /* register methods */
931         struct wpa_dbus_argument margs1[] = {
932                 { "args", "a{sv}", ARG_IN },
933                 { "path", "o", ARG_OUT },
934                 END_ARGS
935         };
936         struct wpa_dbus_argument margs2[] = {
937                 { "path", "o", ARG_IN },
938                 END_ARGS
939         };
940         struct wpa_dbus_argument margs3[] = {
941                 { "ifname", "s", ARG_IN },
942                 { "path", "o", ARG_OUT },
943                 END_ARGS
944         };
945         struct wpa_dbus_argument sargs1[] = {
946                 { "path", "o", ARG_OUT },
947                 END_ARGS
948         };
949         struct wpa_dbus_argument sargs2[] = {
950                 { "path", "o", ARG_OUT },
951                 END_ARGS
952         };
953         struct wpa_dbus_argument sargs3[] = {
954                 { "properties", "a{sv}", ARG_OUT },
955                 END_ARGS
956         };
957
958         obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
959         if (!obj_desc) {
960                 wpa_printf(MSG_ERROR, "Not enough memory "
961                            "to create object description");
962                 return NULL;
963         }
964
965         if (wpa_dbus_method_register(obj_desc, WPAS_DBUS_NEW_INTERFACE,
966                                      "CreateInterface",
967                                      (WPADBusMethodHandler)
968                                      &wpas_dbus_handler_create_interface,
969                                      global, NULL, margs1)) {
970                 wpa_printf(MSG_ERROR,
971                            "Failed to register dbus method %s"
972                            "in interface %s", "CreateInterface",
973                            WPAS_DBUS_NEW_INTERFACE);
974         }
975
976         if (wpa_dbus_method_register(obj_desc, WPAS_DBUS_NEW_INTERFACE,
977                         "RemoveInterface",
978                                      (WPADBusMethodHandler)
979                                      &wpas_dbus_handler_remove_interface,
980                                      global, NULL, margs2)) {
981                 wpa_printf(MSG_ERROR,
982                            "Failed to register dbus method %s"
983                            "in interface %s", "RemoveInterface",
984                            WPAS_DBUS_NEW_INTERFACE);
985         }
986
987         if (wpa_dbus_method_register(obj_desc, WPAS_DBUS_NEW_INTERFACE,
988                                      "GetInterface",
989                                      (WPADBusMethodHandler)
990                                      &wpas_dbus_handler_get_interface,
991                                      global, NULL, margs3)) {
992                 wpa_printf(MSG_ERROR,
993                            "Failed to register dbus method %s"
994                            "in interface %s", "global",
995                            WPAS_DBUS_NEW_INTERFACE);
996         }
997
998         /* register properties */
999         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_INTERFACE,
1000                                        "DebugParams", "(ibb)",
1001                                        (WPADBusPropertyAccessor)
1002                                        &wpas_dbus_getter_debug_params,
1003                                        (WPADBusPropertyAccessor)
1004                                        &wpas_dbus_setter_debug_params,
1005                                        global, NULL, RW)) {
1006                 wpa_printf(MSG_ERROR,
1007                            "Failed to register dbus property %s"
1008                            "in interface %s", "DebugParams",
1009                            WPAS_DBUS_NEW_INTERFACE);
1010         }
1011
1012         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_INTERFACE,
1013                                        "Interfaces", "ao",
1014                                        (WPADBusPropertyAccessor)
1015                                        &wpas_dbus_getter_interfaces, NULL,
1016                                        global, NULL, R)) {
1017                 wpa_printf(MSG_ERROR,
1018                            "Failed to register dbus property %s"
1019                            "in interface %s", "Interfaces",
1020                            WPAS_DBUS_NEW_INTERFACE);
1021         }
1022
1023         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_INTERFACE,
1024                                        "EapMethods", "as",
1025                                        wpas_dbus_getter_eap_methods, NULL,
1026                                        NULL, NULL, R)) {
1027                 wpa_printf(MSG_ERROR,
1028                            "Failed to register dbus property %s"
1029                            "in interface %s", "EapMethods",
1030                            WPAS_DBUS_NEW_INTERFACE);
1031         }
1032
1033
1034         /* register signals */
1035         if (wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_INTERFACE,
1036                                      "InterfaceAdded", sargs1)) {
1037                 wpa_printf(MSG_ERROR,
1038                            "Failed to register dbus signal %s"
1039                            "in interface %s", "InterfaceAdded",
1040                            WPAS_DBUS_NEW_INTERFACE);
1041         }
1042
1043         if (wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_INTERFACE,
1044                                      "InterfaceRemoved", sargs2)) {
1045                 wpa_printf(MSG_ERROR,
1046                            "Failed to register dbus signal %s"
1047                            "in interface %s", "InterfaceRemoved",
1048                            WPAS_DBUS_NEW_INTERFACE);
1049         }
1050
1051         if (wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_INTERFACE,
1052                                      "PropertiesChanged", sargs3)) {
1053                 wpa_printf(MSG_ERROR,
1054                            "Failed to register dbus signal %s"
1055                            "in interface %s", "PropertiesChanged",
1056                            WPAS_DBUS_NEW_INTERFACE);
1057         }
1058
1059         ctrl_iface = wpa_dbus_ctrl_iface_init(global, WPAS_DBUS_NEW_PATH,
1060                                               WPAS_DBUS_NEW_SERVICE,
1061                                               obj_desc);
1062
1063         if (!ctrl_iface)
1064                 free_dbus_object_desc(obj_desc);
1065
1066         return ctrl_iface;
1067 }
1068
1069
1070 /**
1071  * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for
1072  * wpa_supplicant
1073  * @iface: Pointer to dbus private data from
1074  * wpas_dbus_ctrl_iface_init()
1075  *
1076  * Deinitialize the dbus control interface that was initialized with
1077  * wpas_dbus_ctrl_iface_init().
1078  */
1079 static void wpas_dbus_ctrl_iface_deinit(struct ctrl_iface_dbus_new_priv *iface)
1080 {
1081         if (iface) {
1082                 dbus_connection_unregister_object_path(iface->con,
1083                                                        WPAS_DBUS_NEW_PATH);
1084                 wpa_dbus_ctrl_iface_deinit(iface);
1085         }
1086 }
1087
1088
1089 /**
1090  * wpas_dbus_register_network - Register a configured network with dbus
1091  * @wpa_s: wpa_supplicant interface structure
1092  * @ssid: network configuration data
1093  * Returns: 0 on success, -1 on failure
1094  *
1095  * Registers network representing object with dbus
1096  */
1097 static int wpas_dbus_register_network(struct wpa_supplicant *wpa_s,
1098                                       struct wpa_ssid *ssid)
1099 {
1100         struct ctrl_iface_dbus_new_priv *ctrl_iface;
1101         struct wpa_dbus_object_desc *obj_desc;
1102
1103         struct network_handler_args *arg1 = NULL;
1104         struct network_handler_args *arg2 = NULL;
1105         struct network_handler_args *arg3 = NULL;
1106
1107         char *net_obj_path;
1108
1109         struct wpa_dbus_argument sargs[] = {
1110                 { "properties", "a{sv}", ARG_OUT },
1111                 END_ARGS
1112         };
1113
1114         /* Do nothing if the control interface is not turned on */
1115         if (wpa_s == NULL || wpa_s->global == NULL)
1116                 return 0;
1117         ctrl_iface = wpa_s->global->dbus_new_ctrl_iface;
1118         if (ctrl_iface == NULL)
1119                 return 0;
1120
1121         net_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1122         if (net_obj_path == NULL)
1123                 return -1;
1124         os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1125                     "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
1126                     wpas_dbus_get_path(wpa_s), ssid->id);
1127
1128         obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
1129         if (!obj_desc) {
1130                 wpa_printf(MSG_ERROR, "Not enough memory "
1131                            "to create object description");
1132                 goto err;
1133         }
1134
1135         /* allocate memory for handlers arguments */
1136         arg1 =  os_zalloc(sizeof(struct network_handler_args));
1137         if (!arg1) {
1138                 wpa_printf(MSG_ERROR, "Not enough memory "
1139                            "to create arguments for method");
1140                 goto err;
1141         }
1142         arg2 =  os_zalloc(sizeof(struct network_handler_args));
1143         if (!arg2) {
1144                 wpa_printf(MSG_ERROR, "Not enough memory "
1145                            "to create arguments for method");
1146                 goto err;
1147         }
1148
1149         arg1->wpa_s = wpa_s;
1150         arg1->ssid = ssid;
1151         arg2->wpa_s = wpa_s;
1152         arg2->ssid = ssid;
1153
1154         /* Enabled property */
1155         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_NETWORK,
1156                                        "Enabled", "b",
1157                                        (WPADBusPropertyAccessor)
1158                                        wpas_dbus_getter_enabled,
1159                                        (WPADBusPropertyAccessor)
1160                                        wpas_dbus_setter_enabled,
1161                                        arg1, free, RW)) {
1162                 wpa_printf(MSG_ERROR,
1163                            "Failed to register dbus property %s"
1164                            "in interface %s", "Enabled",
1165                            WPAS_DBUS_NEW_IFACE_NETWORK);
1166         }
1167
1168         /* Properties property */
1169         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_NETWORK,
1170                                        "Properties", "a{sv}",
1171                                        (WPADBusPropertyAccessor)
1172                                        wpas_dbus_getter_network_properties,
1173                                        (WPADBusPropertyAccessor)
1174                                        wpas_dbus_setter_network_properties,
1175                                        arg2, free, RW)) {
1176                 wpa_printf(MSG_ERROR,
1177                            "Failed to register dbus property %s"
1178                            "in interface %s", "Properties",
1179                            WPAS_DBUS_NEW_IFACE_NETWORK);
1180         }
1181
1182         /* PropertiesChanged signal */
1183         if (wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_IFACE_NETWORK,
1184                                      "PropertiesChanged", sargs)) {
1185                 wpa_printf(MSG_ERROR,
1186                            "Failed to register dbus signal %s"
1187                            "in interface %s", "PropertiesChanged",
1188                            WPAS_DBUS_NEW_IFACE_NETWORK);
1189         }
1190
1191
1192         if (wpa_dbus_register_object_per_iface(ctrl_iface, net_obj_path,
1193                                                wpa_s->ifname, obj_desc))
1194                 goto err;
1195
1196         wpas_dbus_signal_network_added(wpa_s, ssid->id);
1197
1198         os_free(net_obj_path);
1199         return 0;
1200
1201 err:
1202         os_free(net_obj_path);
1203         os_free(obj_desc);
1204         os_free(arg1);
1205         os_free(arg2);
1206         os_free(arg3);
1207         return -1;
1208 }
1209
1210
1211 /**
1212  * wpas_dbus_unregister_network - Unregister a configured network from dbus
1213  * @wpa_s: wpa_supplicant interface structure
1214  * @nid: network id
1215  * Returns: 0 on success, -1 on failure
1216  *
1217  * Unregisters network representing object from dbus
1218  */
1219 static int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid)
1220 {
1221         struct ctrl_iface_dbus_new_priv *ctrl_iface;
1222         char *net_obj_path;
1223         int ret;
1224
1225         /* Do nothing if the control interface is not turned on */
1226         if (wpa_s == NULL || wpa_s->global == NULL)
1227                 return 0;
1228         ctrl_iface = wpa_s->global->dbus_new_ctrl_iface;
1229         if (ctrl_iface == NULL)
1230                 return 0;
1231
1232         net_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1233         if (net_obj_path == NULL)
1234                 return -1;
1235         os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1236                     "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
1237                     wpas_dbus_get_path(wpa_s), nid);
1238
1239         ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, net_obj_path);
1240
1241         if (!ret)
1242                 wpas_dbus_signal_network_removed(wpa_s, nid);
1243
1244         os_free(net_obj_path);
1245         return ret;
1246 }
1247
1248
1249 /**
1250  * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus
1251  * @wpa_s: wpa_supplicant interface structure
1252  * @bssid: scanned network bssid
1253  * Returns: 0 on success, -1 on failure
1254  *
1255  * Unregisters BSS representing object from dbus
1256  */
1257 static int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s,
1258                                     u8 bssid[ETH_ALEN])
1259 {
1260         struct ctrl_iface_dbus_new_priv *ctrl_iface;
1261         char *bss_obj_path;
1262
1263         /* Do nothing if the control interface is not turned on */
1264         if (wpa_s == NULL || wpa_s->global == NULL)
1265                 return 0;
1266         ctrl_iface = wpa_s->global->dbus_new_ctrl_iface;
1267         if (ctrl_iface == NULL)
1268                 return 0;
1269
1270         bss_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1271         if (bss_obj_path == NULL)
1272                 return -1;
1273
1274         os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1275                     "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/" WPAS_DBUS_BSSID_FORMAT,
1276                     wpas_dbus_get_path(wpa_s), MAC2STR(bssid));
1277
1278         if (wpa_dbus_unregister_object_per_iface(ctrl_iface, bss_obj_path)) {
1279                 wpa_printf(MSG_ERROR,
1280                            "Cannot unregister BSSID dbus object %s.",
1281                            bss_obj_path);
1282                 os_free(bss_obj_path);
1283                 return -1;
1284         }
1285
1286         wpas_dbus_signal_bss_removed(wpa_s, bss_obj_path);
1287
1288         os_free(bss_obj_path);
1289         return 0;
1290 }
1291
1292
1293 /**
1294  * wpas_dbus_register_bss - Register a scanned BSS with dbus
1295  * @wpa_s: wpa_supplicant interface structure
1296  * @bssid: scanned network bssid
1297  * Returns: 0 on success, -1 on failure
1298  *
1299  * Registers BSS representing object with dbus
1300  */
1301 static int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s,
1302                                   u8 bssid[ETH_ALEN])
1303 {
1304         struct ctrl_iface_dbus_new_priv *ctrl_iface;
1305         struct wpa_dbus_object_desc *obj_desc;
1306         char *bss_obj_path;
1307
1308         struct bss_handler_args *arg = NULL;
1309
1310         /* Do nothing if the control interface is not turned on */
1311         if (wpa_s == NULL || wpa_s->global == NULL)
1312                 return 0;
1313         ctrl_iface = wpa_s->global->dbus_new_ctrl_iface;
1314         if (ctrl_iface == NULL)
1315                 return 0;
1316
1317         bss_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1318         if (bss_obj_path == NULL)
1319                 return -1;
1320
1321         os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1322                     "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/" WPAS_DBUS_BSSID_FORMAT,
1323                     wpas_dbus_get_path(wpa_s), MAC2STR(bssid));
1324
1325         obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
1326         if (!obj_desc) {
1327                 wpa_printf(MSG_ERROR, "Not enough memory "
1328                            "to create object description");
1329                 goto err;
1330         }
1331
1332         arg = os_zalloc(sizeof(struct bss_handler_args));
1333         if (!arg) {
1334                 wpa_printf(MSG_ERROR, "Not enough memory "
1335                            "to create arguments for handler");
1336                 goto err;
1337         }
1338         arg->wpa_s = wpa_s;
1339         os_memcpy(arg->bssid, bssid, ETH_ALEN);
1340
1341         /* Properties property */
1342         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_BSSID,
1343                                        "Properties", "a{sv}",
1344                                        (WPADBusPropertyAccessor)
1345                                        wpas_dbus_getter_bss_properties, NULL,
1346                                        arg, free, R)) {
1347                 wpa_printf(MSG_ERROR,
1348                            "Failed to register dbus property %s"
1349                            "in interface %s", "Properties",
1350                            WPAS_DBUS_NEW_IFACE_BSSID);
1351         }
1352
1353         if (wpa_dbus_register_object_per_iface(ctrl_iface, bss_obj_path,
1354                                                wpa_s->ifname, obj_desc)) {
1355                 wpa_printf(MSG_ERROR,
1356                            "Cannot register BSSID dbus object %s.",
1357                            bss_obj_path);
1358                 goto err;
1359         }
1360
1361         wpas_dbus_signal_bss_added(wpa_s, bss_obj_path);
1362
1363         os_free(bss_obj_path);
1364         return 0;
1365
1366 err:
1367         os_free(bss_obj_path);
1368         os_free(obj_desc);
1369         os_free(arg);
1370         return -1;
1371 }
1372
1373
1374 static int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s)
1375 {
1376
1377         struct wpa_dbus_object_desc *obj_desc = NULL;
1378         char *path;
1379         struct ctrl_iface_dbus_new_priv *ctrl_iface =
1380                 wpa_s->global->dbus_new_ctrl_iface;
1381         int next;
1382
1383         struct wpa_dbus_argument args1[] = {
1384                 { "args", "a{sv}", ARG_IN },
1385                 END_ARGS
1386         };
1387         struct wpa_dbus_argument args3[] = {
1388                 { "args", "a{sv}", ARG_IN },
1389                 { "path", "o", ARG_OUT },
1390                 END_ARGS
1391         };
1392         struct wpa_dbus_argument args4[] = {
1393                 { "path", "o", ARG_IN },
1394                 END_ARGS
1395         };
1396         struct wpa_dbus_argument args5[] = {
1397                 { "path", "o", ARG_IN },
1398                 END_ARGS
1399         };
1400         struct wpa_dbus_argument args6[] = {
1401                 { "name", "s", ARG_IN },
1402                 { "data", "ay", ARG_IN },
1403                 END_ARGS
1404         };
1405         struct wpa_dbus_argument args7[] = {
1406                 { "name", "s", ARG_IN },
1407                 { "data", "ay", ARG_OUT },
1408                 END_ARGS
1409         };
1410         struct wpa_dbus_argument args8[] = {
1411                 { "name", "s", ARG_IN },
1412                 END_ARGS
1413         };
1414         struct wpa_dbus_argument sargs1[] = {
1415                 { "success", "b", ARG_OUT },
1416                 END_ARGS
1417         };
1418         struct wpa_dbus_argument sargs2[] = {
1419                 { "newState", "s", ARG_OUT },
1420                 { "oldState", "s", ARG_OUT },
1421                 END_ARGS
1422         };
1423         struct wpa_dbus_argument sargs3[] = {
1424                 { "path", "o", ARG_OUT },
1425                 END_ARGS
1426         };
1427         struct wpa_dbus_argument sargs4[] = {
1428                 { "path", "o", ARG_OUT },
1429                 END_ARGS
1430         };
1431         struct wpa_dbus_argument sargs5[] = {
1432                 { "name", "s", ARG_OUT },
1433                 END_ARGS
1434         };
1435         struct wpa_dbus_argument sargs6[] = {
1436                 { "name", "s", ARG_OUT },
1437                 END_ARGS
1438         };
1439         struct wpa_dbus_argument sargs7[] = {
1440                 { "path", "o", ARG_OUT },
1441                 END_ARGS
1442         };
1443         struct wpa_dbus_argument sargs8[] = {
1444                 { "path", "o", ARG_OUT },
1445                 END_ARGS
1446         };
1447         struct wpa_dbus_argument sargs9[] = {
1448                 { "path", "o", ARG_OUT },
1449                 END_ARGS
1450         };
1451         struct wpa_dbus_argument sargs10[] = {
1452                 { "properties", "a{sv}", ARG_OUT },
1453                 END_ARGS
1454         };
1455
1456 #ifdef CONFIG_WPS
1457         struct wpa_dbus_argument args9[] = {
1458                 { "args", "a{sv}", ARG_IN },
1459                 { "output", "a{sv}", ARG_OUT },
1460                 END_ARGS
1461         };
1462         struct wpa_dbus_argument sargs11[] = {
1463                 { "name", "s", ARG_OUT },
1464                 { "args", "a{sv}", ARG_OUT },
1465                 END_ARGS
1466         };
1467         struct wpa_dbus_argument sargs12[] = {
1468                 { "credentials", "a{sv}", ARG_OUT },
1469                 END_ARGS
1470         };
1471         struct wpa_dbus_argument sargs13[] = {
1472                 { "properties", "a{sv}", ARG_OUT },
1473                 END_ARGS
1474         };
1475 #endif /* CONFIG_WPS */
1476         /* Do nothing if the control interface is not turned on */
1477         if (ctrl_iface == NULL)
1478                 return 0;
1479
1480         /* Create and set the interface's object path */
1481         path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1482         if (path == NULL)
1483                 return -1;
1484         next = wpa_dbus_next_objid(ctrl_iface);
1485         os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
1486                     WPAS_DBUS_NEW_PATH_INTERFACES "/%u",
1487                     next);
1488         if (wpas_dbus_set_path(wpa_s, path)) {
1489                 wpa_printf(MSG_DEBUG,
1490                            "Failed to set dbus path for interface %s",
1491                            wpa_s->ifname);
1492                 goto err;
1493         }
1494
1495         obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
1496         if (!obj_desc) {
1497                 wpa_printf(MSG_ERROR, "Not enough memory "
1498                            "to create object description");
1499                 goto err;
1500         }
1501
1502         /* Scan method */
1503         if (wpa_dbus_method_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1504                                      "Scan",
1505                                      (WPADBusMethodHandler)
1506                                      &wpas_dbus_handler_scan,
1507                                      wpa_s, NULL, args1)) {
1508                 wpa_printf(MSG_DEBUG,
1509                            "Failed to register dbus method %s"
1510                            "in interface %s", "Scan",
1511                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1512         }
1513
1514         /* Disconnect method */
1515         if (wpa_dbus_method_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1516                                      "Disconnect",
1517                                      (WPADBusMethodHandler)
1518                                      &wpas_dbus_handler_disconnect,
1519                                      wpa_s, NULL, NULL)) {
1520                 wpa_printf(MSG_DEBUG,
1521                            "Failed to register dbus method %s"
1522                            "in interface %s", "Disconnect",
1523                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1524         }
1525
1526         /* AddNetwork method */
1527         if (wpa_dbus_method_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1528                                      "AddNetwork",
1529                                      (WPADBusMethodHandler)
1530                                      &wpas_dbus_handler_add_network,
1531                                      wpa_s, NULL, args3)) {
1532                 wpa_printf(MSG_DEBUG,
1533                            "Failed to register dbus method %s"
1534                            "in interface %s", "AddNetwork",
1535                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1536         }
1537
1538         /* RemoveNetwork method */
1539         if (wpa_dbus_method_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1540                                      "RemoveNetwork",
1541                                      (WPADBusMethodHandler)
1542                                      &wpas_dbus_handler_remove_network,
1543                                      wpa_s, NULL, args4)) {
1544                 wpa_printf(MSG_DEBUG,
1545                            "Failed to register dbus method %s"
1546                            "in interface %s", "RemoveNetwork",
1547                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1548         }
1549
1550         /* SelectNetwork method */
1551         if (wpa_dbus_method_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1552                                      "SelectNetwork",
1553                                      (WPADBusMethodHandler)
1554                                      &wpas_dbus_handler_select_network,
1555                                      wpa_s, NULL, args5)) {
1556                 wpa_printf(MSG_DEBUG,
1557                            "Failed to register dbus method %s"
1558                            "in interface %s", "SelectNetwork",
1559                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1560         }
1561
1562         /* AddBlob method */
1563         if (wpa_dbus_method_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1564                                      "AddBlob",
1565                                      (WPADBusMethodHandler)
1566                                      &wpas_dbus_handler_add_blob,
1567                                      wpa_s, NULL, args6)) {
1568                 wpa_printf(MSG_DEBUG,
1569                            "Failed to register dbus method %s"
1570                            "in interface %s", "AddBlob",
1571                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1572         }
1573
1574         /* GetBlob method */
1575         if (wpa_dbus_method_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1576                                      "GetBlob",
1577                                      (WPADBusMethodHandler)
1578                                      &wpas_dbus_handler_get_blob,
1579                                      wpa_s, NULL, args7)) {
1580                 wpa_printf(MSG_DEBUG,
1581                            "Failed to register dbus method %s"
1582                            "in interface %s", "GetBlob",
1583                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1584         }
1585
1586         /* RemoveBlob method */
1587         if (wpa_dbus_method_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1588                                      "RemoveBlob",
1589                                      (WPADBusMethodHandler)
1590                                      &wpas_dbus_handler_remove_blob,
1591                                      wpa_s, NULL, args8)) {
1592                 wpa_printf(MSG_DEBUG,
1593                            "Failed to register dbus method %s"
1594                            "in interface %s", "RemoveBlob",
1595                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1596         }
1597
1598         /* Capabilities property */
1599         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1600                                        "Capabilities", "a{sv}",
1601                                        (WPADBusPropertyAccessor)
1602                                        wpas_dbus_getter_capabilities, NULL,
1603                                        wpa_s, NULL, R)) {
1604                 wpa_printf(MSG_ERROR,
1605                            "Failed to register dbus property %s"
1606                            "in interface %s", "Capabilities",
1607                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1608         }
1609
1610         /* State property */
1611         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1612                                        "State", "s",
1613                                        (WPADBusPropertyAccessor)
1614                                        wpas_dbus_getter_state, NULL,
1615                                        wpa_s, NULL, R)) {
1616                 wpa_printf(MSG_ERROR,
1617                            "Failed to register dbus property %s"
1618                            "in interface %s", "State",
1619                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1620         }
1621
1622         /* Scanning property */
1623         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1624                                        "Scanning", "b",
1625                                        (WPADBusPropertyAccessor)
1626                                        wpas_dbus_getter_scanning, NULL,
1627                                        wpa_s, NULL, R)) {
1628                 wpa_printf(MSG_ERROR,
1629                            "Failed to register dbus property %s"
1630                            "in interface %s", "Scanning",
1631                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1632         }
1633
1634         /* ApScan property */
1635         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1636                                        "ApScan", "u",
1637                                        (WPADBusPropertyAccessor)
1638                                        wpas_dbus_getter_ap_scan,
1639                                        (WPADBusPropertyAccessor)
1640                                        wpas_dbus_setter_ap_scan,
1641                                        wpa_s, NULL, RW)) {
1642                 wpa_printf(MSG_ERROR,
1643                            "Failed to register dbus property %s"
1644                            "in interface %s", "ApScan",
1645                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1646         }
1647
1648         /* Ifname property */
1649         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1650                                        "Ifname", "s",
1651                                        (WPADBusPropertyAccessor)
1652                                        wpas_dbus_getter_ifname, NULL,
1653                                        wpa_s, NULL, R)) {
1654                 wpa_printf(MSG_ERROR,
1655                            "Failed to register dbus property %s"
1656                            "in interface %s", "Ifname",
1657                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1658         }
1659
1660         /* Driver property */
1661         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1662                                        "Driver", "s",
1663                                        (WPADBusPropertyAccessor)
1664                                        wpas_dbus_getter_driver, NULL,
1665                                        wpa_s, NULL, R)) {
1666                 wpa_printf(MSG_ERROR,
1667                            "Failed to register dbus property %s"
1668                            "in interface %s", "Driver",
1669                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1670         }
1671
1672         /* BridgeIfname property */
1673         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1674                                        "BridgeIfname", "s",
1675                                        (WPADBusPropertyAccessor)
1676                                        wpas_dbus_getter_bridge_ifname, NULL,
1677                                        wpa_s, NULL, R)) {
1678                 wpa_printf(MSG_ERROR,
1679                            "Failed to register dbus property %s"
1680                            "in interface %s", "BridgeIfname",
1681                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1682         }
1683
1684         /* CurrentBSS property */
1685         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1686                                        "CurrentBSS", "o",
1687                                        (WPADBusPropertyAccessor)
1688                                        wpas_dbus_getter_current_bss, NULL,
1689                                        wpa_s, NULL, R)) {
1690                 wpa_printf(MSG_ERROR,
1691                            "Failed to register dbus property %s"
1692                            "in interface %s", "CurrentBSS",
1693                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1694         }
1695
1696         /* CurrentNetwork property */
1697         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1698                                        "CurrentNetwork", "o",
1699                                        (WPADBusPropertyAccessor)
1700                                        wpas_dbus_getter_current_network, NULL,
1701                                        wpa_s, NULL, R)) {
1702                 wpa_printf(MSG_ERROR,
1703                            "Failed to register dbus property %s"
1704                            "in interface %s", "CurrentNetwork",
1705                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1706         }
1707
1708         /* Blobs property */
1709         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1710                                        "Blobs", "a{say}",
1711                                        (WPADBusPropertyAccessor)
1712                                        wpas_dbus_getter_blobs, NULL,
1713                                        wpa_s, NULL, R)) {
1714                 wpa_printf(MSG_ERROR,
1715                            "Failed to register dbus property %s"
1716                            "in interface %s", "Blobs",
1717                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1718         }
1719
1720         /* BSSs property */
1721         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1722                                        "BSSs", "ao",
1723                                        (WPADBusPropertyAccessor)
1724                                        wpas_dbus_getter_bsss, NULL,
1725                                        wpa_s, NULL, R)) {
1726                 wpa_printf(MSG_ERROR,
1727                            "Failed to register dbus property %s"
1728                            "in interface %s", "BSSs",
1729                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1730         }
1731
1732         /* Networks property */
1733         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1734                                        "Networks", "ao",
1735                                        (WPADBusPropertyAccessor)
1736                                        wpas_dbus_getter_networks, NULL,
1737                                        wpa_s, NULL, R)) {
1738                 wpa_printf(MSG_ERROR,
1739                            "Failed to register dbus property %s"
1740                            "in interface %s", "Networks",
1741                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1742         }
1743
1744         /* ScanDone signal */
1745         if (wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1746                                      "ScanDone", sargs1)) {
1747                 wpa_printf(MSG_ERROR,
1748                            "Failed to register dbus signal %s"
1749                            "in interface %s", "ScanDone",
1750                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1751         }
1752
1753         /* StateChanged signal */
1754         if (wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1755                                      "StateChanged", sargs2)) {
1756                 wpa_printf(MSG_ERROR,
1757                            "Failed to register dbus signal %s"
1758                            "in interface %s", "StateChanged",
1759                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1760         }
1761
1762         /* BSSAdded signal */
1763         if (wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1764                                      "BSSAdded", sargs3)) {
1765                 wpa_printf(MSG_ERROR,
1766                            "Failed to register dbus signal %s"
1767                            "in interface %s", "BSSAdded",
1768                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1769         }
1770
1771         /* BSSRemoved signal */
1772         if (wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1773                                      "BSSRemoved", sargs4)) {
1774                 wpa_printf(MSG_ERROR,
1775                            "Failed to register dbus signal %s"
1776                            "in interface %s", "BSSRemoved",
1777                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1778         }
1779
1780         /* BlobAdded signal */
1781         if (wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1782                                      "BlobAdded", sargs5)) {
1783                 wpa_printf(MSG_ERROR,
1784                            "Failed to register dbus signal %s"
1785                            "in interface %s", "BlobAdded",
1786                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1787         }
1788
1789         /* BlobRemoved signal */
1790         if (wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1791                                      "BlobRemoved", sargs6)) {
1792                 wpa_printf(MSG_ERROR,
1793                            "Failed to register dbus signal %s"
1794                            "in interface %s", "BlobRemoved",
1795                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1796         }
1797
1798         /* NetworkAdded signal */
1799         if (wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1800                                      "NetworkAdded", sargs7)) {
1801                 wpa_printf(MSG_ERROR,
1802                            "Failed to register dbus signal %s"
1803                            "in interface %s", "NetworkAdded",
1804                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1805         }
1806
1807         /* NetworkRemoved signal */
1808         if (wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1809                                      "NetworkRemoved", sargs8)) {
1810                 wpa_printf(MSG_ERROR,
1811                            "Failed to register dbus signal %s"
1812                            "in interface %s", "NetworkRemoved",
1813                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1814         }
1815
1816         /* NetworkSelected signal */
1817         if (wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1818                                      "NetworkSelected", sargs9)) {
1819                 wpa_printf(MSG_ERROR,
1820                            "Failed to register dbus signal %s"
1821                            "in interface %s", "NetworkSelected",
1822                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1823         }
1824
1825         /* PropertiesChanged signal */
1826         if (wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1827                                      "PropertiesChanged", sargs10)) {
1828                 wpa_printf(MSG_ERROR,
1829                            "Failed to register dbus signal %s"
1830                            "in interface %s", "PropertiesChanged",
1831                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1832         }
1833
1834 #ifdef CONFIG_WPS
1835         /* Start method */
1836         if (wpa_dbus_method_register(obj_desc, WPAS_DBUS_NEW_IFACE_WPS,
1837                                      "Start",
1838                                      (WPADBusMethodHandler)
1839                                      &wpas_dbus_handler_wps_start,
1840                                      wpa_s, NULL, args9)) {
1841                 wpa_printf(MSG_DEBUG,
1842                            "Failed to register dbus method %s"
1843                            "in interface %s", "Start",
1844                            WPAS_DBUS_NEW_IFACE_WPS);
1845         }
1846
1847         /* ProcessCredentials property */
1848         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_WPS,
1849                                        "ProcessCredentials", "b",
1850                                        (WPADBusPropertyAccessor)
1851                                        wpas_dbus_getter_process_credentials,
1852                                        (WPADBusPropertyAccessor)
1853                                        wpas_dbus_setter_process_credentials,
1854                                        wpa_s, NULL, RW)) {
1855                 wpa_printf(MSG_ERROR,
1856                            "Failed to register dbus property %s"
1857                            "in interface %s", "ProcessCredentials",
1858                            WPAS_DBUS_NEW_IFACE_WPS);
1859         }
1860
1861         /* Event signal */
1862         if (wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_IFACE_WPS,
1863                                      "Event", sargs11)) {
1864                 wpa_printf(MSG_ERROR,
1865                            "Failed to register dbus signal %s"
1866                            "in interface %s", "Event",
1867                            WPAS_DBUS_NEW_IFACE_WPS);
1868         }
1869
1870         /* Credentials signal */
1871         if (wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_IFACE_WPS,
1872                                      "Credentials", sargs12)) {
1873                 wpa_printf(MSG_ERROR,
1874                            "Failed to register dbus signal %s"
1875                            "in interface %s", "Credentials",
1876                            WPAS_DBUS_NEW_IFACE_WPS);
1877         }
1878
1879         /* PropertiesChanged signal */
1880         if (wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_IFACE_WPS,
1881                                      "PropertiesChanged", sargs13)) {
1882                 wpa_printf(MSG_ERROR,
1883                            "Failed to register dbus signal %s"
1884                            "in interface %s", "PropertiesChanged",
1885                            WPAS_DBUS_NEW_IFACE_WPS);
1886         }
1887 #endif /* CONFIG_WPS */
1888
1889         if (wpa_dbus_register_object_per_iface(ctrl_iface, path, wpa_s->ifname,
1890                                                obj_desc))
1891                 goto err;
1892
1893         wpas_dbus_signal_interface_created(wpa_s);
1894
1895         os_free(path);
1896         return 0;
1897
1898 err:
1899         os_free(obj_desc);
1900         os_free(path);
1901         return -1;
1902 }
1903
1904
1905 static int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s)
1906 {
1907         struct ctrl_iface_dbus_new_priv *ctrl_iface;
1908         struct wpa_ssid *ssid;
1909         size_t i;
1910
1911         /* Do nothing if the control interface is not turned on */
1912         if (wpa_s == NULL || wpa_s->global == NULL)
1913                 return 0;
1914         ctrl_iface = wpa_s->global->dbus_new_ctrl_iface;
1915         if (ctrl_iface == NULL)
1916                 return 0;
1917
1918         /* unregister all BSSs and networks from dbus */
1919         for (i = 0; i < wpa_s->scan_res->num; i++) {
1920                 wpas_dbus_unregister_bss(wpa_s,
1921                                          wpa_s->scan_res->res[i]->bssid);
1922         }
1923
1924         ssid = wpa_s->conf->ssid;
1925         while (ssid) {
1926                 wpas_dbus_unregister_network(wpa_s, ssid->id);
1927                 ssid = ssid->next;
1928         }
1929
1930         if (wpa_dbus_unregister_object_per_iface(ctrl_iface,
1931                                                  wpas_dbus_get_path(wpa_s)))
1932                 return -1;
1933
1934         wpas_dbus_signal_interface_removed(wpa_s);
1935
1936         os_free(wpa_s->dbus_new_path);
1937         wpa_s->dbus_new_path = NULL;
1938
1939         return 0;
1940 }
1941
1942
1943 static struct wpas_dbus_callbacks callbacks =
1944 {
1945         .dbus_ctrl_init = wpas_dbus_ctrl_iface_init,
1946         .dbus_ctrl_deinit = wpas_dbus_ctrl_iface_deinit,
1947
1948         .signal_interface_created = wpas_dbus_signal_interface_created,
1949         .signal_interface_removed = wpas_dbus_signal_interface_removed,
1950
1951         .register_interface = wpas_dbus_register_interface,
1952         .unregister_interface = wpas_dbus_unregister_interface,
1953
1954         .signal_scan_done = wpas_dbus_signal_scan_done,
1955
1956         .signal_blob_added = wpas_dbus_signal_blob_added,
1957         .signal_blob_removed = wpas_dbus_signal_blob_removed,
1958
1959         .signal_network_selected = wpas_dbus_signal_network_selected,
1960
1961         .signal_state_changed = wpas_dbus_signal_state_changed,
1962         .register_network = wpas_dbus_register_network,
1963         .unregister_network = wpas_dbus_unregister_network,
1964
1965         .signal_network_enabled_changed =
1966         wpas_dbus_signal_network_enabled_changed,
1967
1968         .register_bss = wpas_dbus_register_bss,
1969         .unregister_bss = wpas_dbus_unregister_bss,
1970
1971         .signal_prop_changed = wpas_dbus_signal_prop_changed,
1972         .signal_debug_params_changed = wpas_dbus_signal_debug_params_changed,
1973
1974 #ifdef CONFIG_WPS
1975         .signal_wps_event_success = wpas_dbus_signal_wps_event_success,
1976         .signal_wps_event_fail = wpas_dbus_signal_wps_event_fail,
1977         .signal_wps_event_m2d = wpas_dbus_signal_wps_event_m2d,
1978         .signal_wps_credentials = wpas_dbus_signal_wps_cred,
1979 #endif /* CONFIG_WPS */
1980 };
1981
1982
1983 struct wpas_dbus_callbacks * wpas_dbus_get_callbacks(void)
1984 {
1985         return &callbacks;
1986 }
1987
1988
1989 /**
1990  * wpas_dbus_get_path - Get an interface's dbus path
1991  * @wpa_s: %wpa_supplicant interface structure
1992  * Returns: Interface's dbus object path, or %NULL on error
1993  */
1994 const char * wpas_dbus_get_path(struct wpa_supplicant *wpa_s)
1995 {
1996         return wpa_s->dbus_new_path;
1997 }