dbus: Split wpas_dbus_ctrl_iface_init() into helper functions
[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 static void wpas_dbus_meth_reg_create_interface(
918         struct wpa_global *global, struct wpa_dbus_object_desc *obj_desc)
919 {
920         struct wpa_dbus_argument margs[] = {
921                 { "args", "a{sv}", ARG_IN },
922                 { "path", "o", ARG_OUT },
923                 END_ARGS
924         };
925         wpa_dbus_method_register(obj_desc, WPAS_DBUS_NEW_INTERFACE,
926                                  "CreateInterface",
927                                  (WPADBusMethodHandler)
928                                  &wpas_dbus_handler_create_interface,
929                                  global, NULL, margs);
930 }
931
932
933 static void wpas_dbus_meth_reg_remove_interface(
934         struct wpa_global *global, struct wpa_dbus_object_desc *obj_desc)
935 {
936         struct wpa_dbus_argument margs[] = {
937                 { "path", "o", ARG_IN },
938                 END_ARGS
939         };
940         wpa_dbus_method_register(obj_desc, WPAS_DBUS_NEW_INTERFACE,
941                                  "RemoveInterface",
942                                  (WPADBusMethodHandler)
943                                  &wpas_dbus_handler_remove_interface,
944                                  global, NULL, margs);
945 }
946
947
948 static void wpas_dbus_meth_reg_get_interface(
949         struct wpa_global *global, struct wpa_dbus_object_desc *obj_desc)
950 {
951         struct wpa_dbus_argument margs[] = {
952                 { "ifname", "s", ARG_IN },
953                 { "path", "o", ARG_OUT },
954                 END_ARGS
955         };
956         wpa_dbus_method_register(obj_desc, WPAS_DBUS_NEW_INTERFACE,
957                                  "GetInterface",
958                                  (WPADBusMethodHandler)
959                                  &wpas_dbus_handler_get_interface,
960                                  global, NULL, margs);
961 }
962
963
964 static void wpas_dbus_prop_reg_debug_params(
965         struct wpa_global *global, struct wpa_dbus_object_desc *obj_desc)
966 {
967         wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_INTERFACE,
968                                    "DebugParams", "(ibb)",
969                                    (WPADBusPropertyAccessor)
970                                    &wpas_dbus_getter_debug_params,
971                                    (WPADBusPropertyAccessor)
972                                    &wpas_dbus_setter_debug_params,
973                                    global, NULL, RW);
974 }
975
976
977 static void wpas_dbus_prop_reg_interfaces(
978         struct wpa_global *global, struct wpa_dbus_object_desc *obj_desc)
979 {
980         wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_INTERFACE,
981                                    "Interfaces", "ao",
982                                    (WPADBusPropertyAccessor)
983                                    &wpas_dbus_getter_interfaces,
984                                    NULL, global, NULL, R);
985 }
986
987
988 static void wpas_dbus_prop_reg_eap_methods(
989         struct wpa_dbus_object_desc *obj_desc)
990 {
991         wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_INTERFACE,
992                                    "EapMethods", "as",
993                                    wpas_dbus_getter_eap_methods,
994                                    NULL, NULL, NULL, R);
995 }
996
997
998 static void wpas_dbus_sign_reg_interface_added(
999         struct wpa_global *global, struct wpa_dbus_object_desc *obj_desc)
1000 {
1001         struct wpa_dbus_argument sargs[] = {
1002                 { "path", "o", ARG_OUT },
1003                 END_ARGS
1004         };
1005         wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_INTERFACE,
1006                                  "InterfaceAdded", sargs);
1007 }
1008
1009
1010 static void wpas_dbus_sign_reg_interface_removed(
1011         struct wpa_global *global, struct wpa_dbus_object_desc *obj_desc)
1012 {
1013         struct wpa_dbus_argument sargs[] = {
1014                 { "path", "o", ARG_OUT },
1015                 END_ARGS
1016         };
1017         wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_INTERFACE,
1018                                  "InterfaceRemoved", sargs);
1019 }
1020
1021
1022 static void wpas_dbus_sign_reg_properties_changed(
1023         struct wpa_global *global, struct wpa_dbus_object_desc *obj_desc)
1024 {
1025         struct wpa_dbus_argument sargs[] = {
1026                 { "properties", "a{sv}", ARG_OUT },
1027                 END_ARGS
1028         };
1029         wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_INTERFACE,
1030                                  "PropertiesChanged", sargs);
1031 }
1032
1033
1034 /**
1035  * wpas_dbus_ctrl_iface_init - Initialize dbus control interface
1036  * @global: Pointer to global data from wpa_supplicant_init()
1037  * Returns: Pointer to dbus_new_ctrl_iface date or %NULL on failure
1038  *
1039  * Initialize the dbus control interface for wpa_supplicantand and start
1040  * receiving commands from external programs over the bus.
1041  */
1042 static struct ctrl_iface_dbus_new_priv * wpas_dbus_ctrl_iface_init(
1043         struct wpa_global *global)
1044 {
1045         struct ctrl_iface_dbus_new_priv *ctrl_iface;
1046         struct wpa_dbus_object_desc *obj_desc;
1047
1048         obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
1049         if (!obj_desc) {
1050                 wpa_printf(MSG_ERROR, "Not enough memory "
1051                            "to create object description");
1052                 return NULL;
1053         }
1054
1055         wpas_dbus_meth_reg_create_interface(global, obj_desc);
1056         wpas_dbus_meth_reg_remove_interface(global, obj_desc);
1057         wpas_dbus_meth_reg_get_interface(global, obj_desc);
1058
1059         wpas_dbus_prop_reg_debug_params(global, obj_desc);
1060         wpas_dbus_prop_reg_interfaces(global, obj_desc);
1061         wpas_dbus_prop_reg_eap_methods(obj_desc);
1062
1063         wpas_dbus_sign_reg_interface_added(global, obj_desc);
1064         wpas_dbus_sign_reg_interface_removed(global, obj_desc);
1065         wpas_dbus_sign_reg_properties_changed(global, obj_desc);
1066
1067         ctrl_iface = wpa_dbus_ctrl_iface_init(global, WPAS_DBUS_NEW_PATH,
1068                                               WPAS_DBUS_NEW_SERVICE,
1069                                               obj_desc);
1070         if (!ctrl_iface)
1071                 free_dbus_object_desc(obj_desc);
1072
1073         return ctrl_iface;
1074 }
1075
1076
1077 /**
1078  * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for
1079  * wpa_supplicant
1080  * @iface: Pointer to dbus private data from
1081  * wpas_dbus_ctrl_iface_init()
1082  *
1083  * Deinitialize the dbus control interface that was initialized with
1084  * wpas_dbus_ctrl_iface_init().
1085  */
1086 static void wpas_dbus_ctrl_iface_deinit(struct ctrl_iface_dbus_new_priv *iface)
1087 {
1088         if (iface) {
1089                 dbus_connection_unregister_object_path(iface->con,
1090                                                        WPAS_DBUS_NEW_PATH);
1091                 wpa_dbus_ctrl_iface_deinit(iface);
1092         }
1093 }
1094
1095
1096 /**
1097  * wpas_dbus_register_network - Register a configured network with dbus
1098  * @wpa_s: wpa_supplicant interface structure
1099  * @ssid: network configuration data
1100  * Returns: 0 on success, -1 on failure
1101  *
1102  * Registers network representing object with dbus
1103  */
1104 static int wpas_dbus_register_network(struct wpa_supplicant *wpa_s,
1105                                       struct wpa_ssid *ssid)
1106 {
1107         struct ctrl_iface_dbus_new_priv *ctrl_iface;
1108         struct wpa_dbus_object_desc *obj_desc;
1109
1110         struct network_handler_args *arg1 = NULL;
1111         struct network_handler_args *arg2 = NULL;
1112         struct network_handler_args *arg3 = NULL;
1113
1114         char *net_obj_path;
1115
1116         struct wpa_dbus_argument sargs[] = {
1117                 { "properties", "a{sv}", ARG_OUT },
1118                 END_ARGS
1119         };
1120
1121         /* Do nothing if the control interface is not turned on */
1122         if (wpa_s == NULL || wpa_s->global == NULL)
1123                 return 0;
1124         ctrl_iface = wpa_s->global->dbus_new_ctrl_iface;
1125         if (ctrl_iface == NULL)
1126                 return 0;
1127
1128         net_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1129         if (net_obj_path == NULL)
1130                 return -1;
1131         os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1132                     "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
1133                     wpas_dbus_get_path(wpa_s), ssid->id);
1134
1135         obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
1136         if (!obj_desc) {
1137                 wpa_printf(MSG_ERROR, "Not enough memory "
1138                            "to create object description");
1139                 goto err;
1140         }
1141
1142         /* allocate memory for handlers arguments */
1143         arg1 =  os_zalloc(sizeof(struct network_handler_args));
1144         if (!arg1) {
1145                 wpa_printf(MSG_ERROR, "Not enough memory "
1146                            "to create arguments for method");
1147                 goto err;
1148         }
1149         arg2 =  os_zalloc(sizeof(struct network_handler_args));
1150         if (!arg2) {
1151                 wpa_printf(MSG_ERROR, "Not enough memory "
1152                            "to create arguments for method");
1153                 goto err;
1154         }
1155
1156         arg1->wpa_s = wpa_s;
1157         arg1->ssid = ssid;
1158         arg2->wpa_s = wpa_s;
1159         arg2->ssid = ssid;
1160
1161         /* Enabled property */
1162         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_NETWORK,
1163                                        "Enabled", "b",
1164                                        (WPADBusPropertyAccessor)
1165                                        wpas_dbus_getter_enabled,
1166                                        (WPADBusPropertyAccessor)
1167                                        wpas_dbus_setter_enabled,
1168                                        arg1, free, RW)) {
1169                 wpa_printf(MSG_ERROR,
1170                            "Failed to register dbus property %s"
1171                            "in interface %s", "Enabled",
1172                            WPAS_DBUS_NEW_IFACE_NETWORK);
1173         }
1174
1175         /* Properties property */
1176         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_NETWORK,
1177                                        "Properties", "a{sv}",
1178                                        (WPADBusPropertyAccessor)
1179                                        wpas_dbus_getter_network_properties,
1180                                        (WPADBusPropertyAccessor)
1181                                        wpas_dbus_setter_network_properties,
1182                                        arg2, free, RW)) {
1183                 wpa_printf(MSG_ERROR,
1184                            "Failed to register dbus property %s"
1185                            "in interface %s", "Properties",
1186                            WPAS_DBUS_NEW_IFACE_NETWORK);
1187         }
1188
1189         /* PropertiesChanged signal */
1190         if (wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_IFACE_NETWORK,
1191                                      "PropertiesChanged", sargs)) {
1192                 wpa_printf(MSG_ERROR,
1193                            "Failed to register dbus signal %s"
1194                            "in interface %s", "PropertiesChanged",
1195                            WPAS_DBUS_NEW_IFACE_NETWORK);
1196         }
1197
1198
1199         if (wpa_dbus_register_object_per_iface(ctrl_iface, net_obj_path,
1200                                                wpa_s->ifname, obj_desc))
1201                 goto err;
1202
1203         wpas_dbus_signal_network_added(wpa_s, ssid->id);
1204
1205         os_free(net_obj_path);
1206         return 0;
1207
1208 err:
1209         os_free(net_obj_path);
1210         os_free(obj_desc);
1211         os_free(arg1);
1212         os_free(arg2);
1213         os_free(arg3);
1214         return -1;
1215 }
1216
1217
1218 /**
1219  * wpas_dbus_unregister_network - Unregister a configured network from dbus
1220  * @wpa_s: wpa_supplicant interface structure
1221  * @nid: network id
1222  * Returns: 0 on success, -1 on failure
1223  *
1224  * Unregisters network representing object from dbus
1225  */
1226 static int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid)
1227 {
1228         struct ctrl_iface_dbus_new_priv *ctrl_iface;
1229         char *net_obj_path;
1230         int ret;
1231
1232         /* Do nothing if the control interface is not turned on */
1233         if (wpa_s == NULL || wpa_s->global == NULL)
1234                 return 0;
1235         ctrl_iface = wpa_s->global->dbus_new_ctrl_iface;
1236         if (ctrl_iface == NULL)
1237                 return 0;
1238
1239         net_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1240         if (net_obj_path == NULL)
1241                 return -1;
1242         os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1243                     "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
1244                     wpas_dbus_get_path(wpa_s), nid);
1245
1246         ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, net_obj_path);
1247
1248         if (!ret)
1249                 wpas_dbus_signal_network_removed(wpa_s, nid);
1250
1251         os_free(net_obj_path);
1252         return ret;
1253 }
1254
1255
1256 /**
1257  * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus
1258  * @wpa_s: wpa_supplicant interface structure
1259  * @bssid: scanned network bssid
1260  * Returns: 0 on success, -1 on failure
1261  *
1262  * Unregisters BSS representing object from dbus
1263  */
1264 static int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s,
1265                                     u8 bssid[ETH_ALEN])
1266 {
1267         struct ctrl_iface_dbus_new_priv *ctrl_iface;
1268         char *bss_obj_path;
1269
1270         /* Do nothing if the control interface is not turned on */
1271         if (wpa_s == NULL || wpa_s->global == NULL)
1272                 return 0;
1273         ctrl_iface = wpa_s->global->dbus_new_ctrl_iface;
1274         if (ctrl_iface == NULL)
1275                 return 0;
1276
1277         bss_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1278         if (bss_obj_path == NULL)
1279                 return -1;
1280
1281         os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1282                     "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/" WPAS_DBUS_BSSID_FORMAT,
1283                     wpas_dbus_get_path(wpa_s), MAC2STR(bssid));
1284
1285         if (wpa_dbus_unregister_object_per_iface(ctrl_iface, bss_obj_path)) {
1286                 wpa_printf(MSG_ERROR,
1287                            "Cannot unregister BSSID dbus object %s.",
1288                            bss_obj_path);
1289                 os_free(bss_obj_path);
1290                 return -1;
1291         }
1292
1293         wpas_dbus_signal_bss_removed(wpa_s, bss_obj_path);
1294
1295         os_free(bss_obj_path);
1296         return 0;
1297 }
1298
1299
1300 /**
1301  * wpas_dbus_register_bss - Register a scanned BSS with dbus
1302  * @wpa_s: wpa_supplicant interface structure
1303  * @bssid: scanned network bssid
1304  * Returns: 0 on success, -1 on failure
1305  *
1306  * Registers BSS representing object with dbus
1307  */
1308 static int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s,
1309                                   u8 bssid[ETH_ALEN])
1310 {
1311         struct ctrl_iface_dbus_new_priv *ctrl_iface;
1312         struct wpa_dbus_object_desc *obj_desc;
1313         char *bss_obj_path;
1314
1315         struct bss_handler_args *arg = NULL;
1316
1317         /* Do nothing if the control interface is not turned on */
1318         if (wpa_s == NULL || wpa_s->global == NULL)
1319                 return 0;
1320         ctrl_iface = wpa_s->global->dbus_new_ctrl_iface;
1321         if (ctrl_iface == NULL)
1322                 return 0;
1323
1324         bss_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1325         if (bss_obj_path == NULL)
1326                 return -1;
1327
1328         os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
1329                     "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/" WPAS_DBUS_BSSID_FORMAT,
1330                     wpas_dbus_get_path(wpa_s), MAC2STR(bssid));
1331
1332         obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
1333         if (!obj_desc) {
1334                 wpa_printf(MSG_ERROR, "Not enough memory "
1335                            "to create object description");
1336                 goto err;
1337         }
1338
1339         arg = os_zalloc(sizeof(struct bss_handler_args));
1340         if (!arg) {
1341                 wpa_printf(MSG_ERROR, "Not enough memory "
1342                            "to create arguments for handler");
1343                 goto err;
1344         }
1345         arg->wpa_s = wpa_s;
1346         os_memcpy(arg->bssid, bssid, ETH_ALEN);
1347
1348         /* Properties property */
1349         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_BSSID,
1350                                        "Properties", "a{sv}",
1351                                        (WPADBusPropertyAccessor)
1352                                        wpas_dbus_getter_bss_properties, NULL,
1353                                        arg, free, R)) {
1354                 wpa_printf(MSG_ERROR,
1355                            "Failed to register dbus property %s"
1356                            "in interface %s", "Properties",
1357                            WPAS_DBUS_NEW_IFACE_BSSID);
1358         }
1359
1360         if (wpa_dbus_register_object_per_iface(ctrl_iface, bss_obj_path,
1361                                                wpa_s->ifname, obj_desc)) {
1362                 wpa_printf(MSG_ERROR,
1363                            "Cannot register BSSID dbus object %s.",
1364                            bss_obj_path);
1365                 goto err;
1366         }
1367
1368         wpas_dbus_signal_bss_added(wpa_s, bss_obj_path);
1369
1370         os_free(bss_obj_path);
1371         return 0;
1372
1373 err:
1374         os_free(bss_obj_path);
1375         os_free(obj_desc);
1376         os_free(arg);
1377         return -1;
1378 }
1379
1380
1381 static int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s)
1382 {
1383
1384         struct wpa_dbus_object_desc *obj_desc = NULL;
1385         char *path;
1386         struct ctrl_iface_dbus_new_priv *ctrl_iface =
1387                 wpa_s->global->dbus_new_ctrl_iface;
1388         int next;
1389
1390         struct wpa_dbus_argument args1[] = {
1391                 { "args", "a{sv}", ARG_IN },
1392                 END_ARGS
1393         };
1394         struct wpa_dbus_argument args3[] = {
1395                 { "args", "a{sv}", ARG_IN },
1396                 { "path", "o", ARG_OUT },
1397                 END_ARGS
1398         };
1399         struct wpa_dbus_argument args4[] = {
1400                 { "path", "o", ARG_IN },
1401                 END_ARGS
1402         };
1403         struct wpa_dbus_argument args5[] = {
1404                 { "path", "o", ARG_IN },
1405                 END_ARGS
1406         };
1407         struct wpa_dbus_argument args6[] = {
1408                 { "name", "s", ARG_IN },
1409                 { "data", "ay", ARG_IN },
1410                 END_ARGS
1411         };
1412         struct wpa_dbus_argument args7[] = {
1413                 { "name", "s", ARG_IN },
1414                 { "data", "ay", ARG_OUT },
1415                 END_ARGS
1416         };
1417         struct wpa_dbus_argument args8[] = {
1418                 { "name", "s", ARG_IN },
1419                 END_ARGS
1420         };
1421         struct wpa_dbus_argument sargs1[] = {
1422                 { "success", "b", ARG_OUT },
1423                 END_ARGS
1424         };
1425         struct wpa_dbus_argument sargs2[] = {
1426                 { "newState", "s", ARG_OUT },
1427                 { "oldState", "s", ARG_OUT },
1428                 END_ARGS
1429         };
1430         struct wpa_dbus_argument sargs3[] = {
1431                 { "path", "o", ARG_OUT },
1432                 END_ARGS
1433         };
1434         struct wpa_dbus_argument sargs4[] = {
1435                 { "path", "o", ARG_OUT },
1436                 END_ARGS
1437         };
1438         struct wpa_dbus_argument sargs5[] = {
1439                 { "name", "s", ARG_OUT },
1440                 END_ARGS
1441         };
1442         struct wpa_dbus_argument sargs6[] = {
1443                 { "name", "s", ARG_OUT },
1444                 END_ARGS
1445         };
1446         struct wpa_dbus_argument sargs7[] = {
1447                 { "path", "o", ARG_OUT },
1448                 END_ARGS
1449         };
1450         struct wpa_dbus_argument sargs8[] = {
1451                 { "path", "o", ARG_OUT },
1452                 END_ARGS
1453         };
1454         struct wpa_dbus_argument sargs9[] = {
1455                 { "path", "o", ARG_OUT },
1456                 END_ARGS
1457         };
1458         struct wpa_dbus_argument sargs10[] = {
1459                 { "properties", "a{sv}", ARG_OUT },
1460                 END_ARGS
1461         };
1462
1463 #ifdef CONFIG_WPS
1464         struct wpa_dbus_argument args9[] = {
1465                 { "args", "a{sv}", ARG_IN },
1466                 { "output", "a{sv}", ARG_OUT },
1467                 END_ARGS
1468         };
1469         struct wpa_dbus_argument sargs11[] = {
1470                 { "name", "s", ARG_OUT },
1471                 { "args", "a{sv}", ARG_OUT },
1472                 END_ARGS
1473         };
1474         struct wpa_dbus_argument sargs12[] = {
1475                 { "credentials", "a{sv}", ARG_OUT },
1476                 END_ARGS
1477         };
1478         struct wpa_dbus_argument sargs13[] = {
1479                 { "properties", "a{sv}", ARG_OUT },
1480                 END_ARGS
1481         };
1482 #endif /* CONFIG_WPS */
1483         /* Do nothing if the control interface is not turned on */
1484         if (ctrl_iface == NULL)
1485                 return 0;
1486
1487         /* Create and set the interface's object path */
1488         path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1489         if (path == NULL)
1490                 return -1;
1491         next = wpa_dbus_next_objid(ctrl_iface);
1492         os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
1493                     WPAS_DBUS_NEW_PATH_INTERFACES "/%u",
1494                     next);
1495         if (wpas_dbus_set_path(wpa_s, path)) {
1496                 wpa_printf(MSG_DEBUG,
1497                            "Failed to set dbus path for interface %s",
1498                            wpa_s->ifname);
1499                 goto err;
1500         }
1501
1502         obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
1503         if (!obj_desc) {
1504                 wpa_printf(MSG_ERROR, "Not enough memory "
1505                            "to create object description");
1506                 goto err;
1507         }
1508
1509         /* Scan method */
1510         if (wpa_dbus_method_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1511                                      "Scan",
1512                                      (WPADBusMethodHandler)
1513                                      &wpas_dbus_handler_scan,
1514                                      wpa_s, NULL, args1)) {
1515                 wpa_printf(MSG_DEBUG,
1516                            "Failed to register dbus method %s"
1517                            "in interface %s", "Scan",
1518                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1519         }
1520
1521         /* Disconnect method */
1522         if (wpa_dbus_method_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1523                                      "Disconnect",
1524                                      (WPADBusMethodHandler)
1525                                      &wpas_dbus_handler_disconnect,
1526                                      wpa_s, NULL, NULL)) {
1527                 wpa_printf(MSG_DEBUG,
1528                            "Failed to register dbus method %s"
1529                            "in interface %s", "Disconnect",
1530                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1531         }
1532
1533         /* AddNetwork method */
1534         if (wpa_dbus_method_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1535                                      "AddNetwork",
1536                                      (WPADBusMethodHandler)
1537                                      &wpas_dbus_handler_add_network,
1538                                      wpa_s, NULL, args3)) {
1539                 wpa_printf(MSG_DEBUG,
1540                            "Failed to register dbus method %s"
1541                            "in interface %s", "AddNetwork",
1542                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1543         }
1544
1545         /* RemoveNetwork method */
1546         if (wpa_dbus_method_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1547                                      "RemoveNetwork",
1548                                      (WPADBusMethodHandler)
1549                                      &wpas_dbus_handler_remove_network,
1550                                      wpa_s, NULL, args4)) {
1551                 wpa_printf(MSG_DEBUG,
1552                            "Failed to register dbus method %s"
1553                            "in interface %s", "RemoveNetwork",
1554                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1555         }
1556
1557         /* SelectNetwork method */
1558         if (wpa_dbus_method_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1559                                      "SelectNetwork",
1560                                      (WPADBusMethodHandler)
1561                                      &wpas_dbus_handler_select_network,
1562                                      wpa_s, NULL, args5)) {
1563                 wpa_printf(MSG_DEBUG,
1564                            "Failed to register dbus method %s"
1565                            "in interface %s", "SelectNetwork",
1566                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1567         }
1568
1569         /* AddBlob method */
1570         if (wpa_dbus_method_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1571                                      "AddBlob",
1572                                      (WPADBusMethodHandler)
1573                                      &wpas_dbus_handler_add_blob,
1574                                      wpa_s, NULL, args6)) {
1575                 wpa_printf(MSG_DEBUG,
1576                            "Failed to register dbus method %s"
1577                            "in interface %s", "AddBlob",
1578                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1579         }
1580
1581         /* GetBlob method */
1582         if (wpa_dbus_method_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1583                                      "GetBlob",
1584                                      (WPADBusMethodHandler)
1585                                      &wpas_dbus_handler_get_blob,
1586                                      wpa_s, NULL, args7)) {
1587                 wpa_printf(MSG_DEBUG,
1588                            "Failed to register dbus method %s"
1589                            "in interface %s", "GetBlob",
1590                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1591         }
1592
1593         /* RemoveBlob method */
1594         if (wpa_dbus_method_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1595                                      "RemoveBlob",
1596                                      (WPADBusMethodHandler)
1597                                      &wpas_dbus_handler_remove_blob,
1598                                      wpa_s, NULL, args8)) {
1599                 wpa_printf(MSG_DEBUG,
1600                            "Failed to register dbus method %s"
1601                            "in interface %s", "RemoveBlob",
1602                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1603         }
1604
1605         /* Capabilities property */
1606         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1607                                        "Capabilities", "a{sv}",
1608                                        (WPADBusPropertyAccessor)
1609                                        wpas_dbus_getter_capabilities, NULL,
1610                                        wpa_s, NULL, R)) {
1611                 wpa_printf(MSG_ERROR,
1612                            "Failed to register dbus property %s"
1613                            "in interface %s", "Capabilities",
1614                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1615         }
1616
1617         /* State property */
1618         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1619                                        "State", "s",
1620                                        (WPADBusPropertyAccessor)
1621                                        wpas_dbus_getter_state, NULL,
1622                                        wpa_s, NULL, R)) {
1623                 wpa_printf(MSG_ERROR,
1624                            "Failed to register dbus property %s"
1625                            "in interface %s", "State",
1626                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1627         }
1628
1629         /* Scanning property */
1630         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1631                                        "Scanning", "b",
1632                                        (WPADBusPropertyAccessor)
1633                                        wpas_dbus_getter_scanning, NULL,
1634                                        wpa_s, NULL, R)) {
1635                 wpa_printf(MSG_ERROR,
1636                            "Failed to register dbus property %s"
1637                            "in interface %s", "Scanning",
1638                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1639         }
1640
1641         /* ApScan property */
1642         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1643                                        "ApScan", "u",
1644                                        (WPADBusPropertyAccessor)
1645                                        wpas_dbus_getter_ap_scan,
1646                                        (WPADBusPropertyAccessor)
1647                                        wpas_dbus_setter_ap_scan,
1648                                        wpa_s, NULL, RW)) {
1649                 wpa_printf(MSG_ERROR,
1650                            "Failed to register dbus property %s"
1651                            "in interface %s", "ApScan",
1652                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1653         }
1654
1655         /* Ifname property */
1656         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1657                                        "Ifname", "s",
1658                                        (WPADBusPropertyAccessor)
1659                                        wpas_dbus_getter_ifname, NULL,
1660                                        wpa_s, NULL, R)) {
1661                 wpa_printf(MSG_ERROR,
1662                            "Failed to register dbus property %s"
1663                            "in interface %s", "Ifname",
1664                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1665         }
1666
1667         /* Driver property */
1668         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1669                                        "Driver", "s",
1670                                        (WPADBusPropertyAccessor)
1671                                        wpas_dbus_getter_driver, NULL,
1672                                        wpa_s, NULL, R)) {
1673                 wpa_printf(MSG_ERROR,
1674                            "Failed to register dbus property %s"
1675                            "in interface %s", "Driver",
1676                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1677         }
1678
1679         /* BridgeIfname property */
1680         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1681                                        "BridgeIfname", "s",
1682                                        (WPADBusPropertyAccessor)
1683                                        wpas_dbus_getter_bridge_ifname, NULL,
1684                                        wpa_s, NULL, R)) {
1685                 wpa_printf(MSG_ERROR,
1686                            "Failed to register dbus property %s"
1687                            "in interface %s", "BridgeIfname",
1688                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1689         }
1690
1691         /* CurrentBSS property */
1692         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1693                                        "CurrentBSS", "o",
1694                                        (WPADBusPropertyAccessor)
1695                                        wpas_dbus_getter_current_bss, NULL,
1696                                        wpa_s, NULL, R)) {
1697                 wpa_printf(MSG_ERROR,
1698                            "Failed to register dbus property %s"
1699                            "in interface %s", "CurrentBSS",
1700                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1701         }
1702
1703         /* CurrentNetwork property */
1704         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1705                                        "CurrentNetwork", "o",
1706                                        (WPADBusPropertyAccessor)
1707                                        wpas_dbus_getter_current_network, NULL,
1708                                        wpa_s, NULL, R)) {
1709                 wpa_printf(MSG_ERROR,
1710                            "Failed to register dbus property %s"
1711                            "in interface %s", "CurrentNetwork",
1712                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1713         }
1714
1715         /* Blobs property */
1716         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1717                                        "Blobs", "a{say}",
1718                                        (WPADBusPropertyAccessor)
1719                                        wpas_dbus_getter_blobs, NULL,
1720                                        wpa_s, NULL, R)) {
1721                 wpa_printf(MSG_ERROR,
1722                            "Failed to register dbus property %s"
1723                            "in interface %s", "Blobs",
1724                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1725         }
1726
1727         /* BSSs property */
1728         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1729                                        "BSSs", "ao",
1730                                        (WPADBusPropertyAccessor)
1731                                        wpas_dbus_getter_bsss, NULL,
1732                                        wpa_s, NULL, R)) {
1733                 wpa_printf(MSG_ERROR,
1734                            "Failed to register dbus property %s"
1735                            "in interface %s", "BSSs",
1736                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1737         }
1738
1739         /* Networks property */
1740         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1741                                        "Networks", "ao",
1742                                        (WPADBusPropertyAccessor)
1743                                        wpas_dbus_getter_networks, NULL,
1744                                        wpa_s, NULL, R)) {
1745                 wpa_printf(MSG_ERROR,
1746                            "Failed to register dbus property %s"
1747                            "in interface %s", "Networks",
1748                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1749         }
1750
1751         /* ScanDone signal */
1752         if (wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1753                                      "ScanDone", sargs1)) {
1754                 wpa_printf(MSG_ERROR,
1755                            "Failed to register dbus signal %s"
1756                            "in interface %s", "ScanDone",
1757                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1758         }
1759
1760         /* StateChanged signal */
1761         if (wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1762                                      "StateChanged", sargs2)) {
1763                 wpa_printf(MSG_ERROR,
1764                            "Failed to register dbus signal %s"
1765                            "in interface %s", "StateChanged",
1766                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1767         }
1768
1769         /* BSSAdded signal */
1770         if (wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1771                                      "BSSAdded", sargs3)) {
1772                 wpa_printf(MSG_ERROR,
1773                            "Failed to register dbus signal %s"
1774                            "in interface %s", "BSSAdded",
1775                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1776         }
1777
1778         /* BSSRemoved signal */
1779         if (wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1780                                      "BSSRemoved", sargs4)) {
1781                 wpa_printf(MSG_ERROR,
1782                            "Failed to register dbus signal %s"
1783                            "in interface %s", "BSSRemoved",
1784                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1785         }
1786
1787         /* BlobAdded signal */
1788         if (wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1789                                      "BlobAdded", sargs5)) {
1790                 wpa_printf(MSG_ERROR,
1791                            "Failed to register dbus signal %s"
1792                            "in interface %s", "BlobAdded",
1793                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1794         }
1795
1796         /* BlobRemoved signal */
1797         if (wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1798                                      "BlobRemoved", sargs6)) {
1799                 wpa_printf(MSG_ERROR,
1800                            "Failed to register dbus signal %s"
1801                            "in interface %s", "BlobRemoved",
1802                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1803         }
1804
1805         /* NetworkAdded signal */
1806         if (wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1807                                      "NetworkAdded", sargs7)) {
1808                 wpa_printf(MSG_ERROR,
1809                            "Failed to register dbus signal %s"
1810                            "in interface %s", "NetworkAdded",
1811                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1812         }
1813
1814         /* NetworkRemoved signal */
1815         if (wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1816                                      "NetworkRemoved", sargs8)) {
1817                 wpa_printf(MSG_ERROR,
1818                            "Failed to register dbus signal %s"
1819                            "in interface %s", "NetworkRemoved",
1820                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1821         }
1822
1823         /* NetworkSelected signal */
1824         if (wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1825                                      "NetworkSelected", sargs9)) {
1826                 wpa_printf(MSG_ERROR,
1827                            "Failed to register dbus signal %s"
1828                            "in interface %s", "NetworkSelected",
1829                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1830         }
1831
1832         /* PropertiesChanged signal */
1833         if (wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_IFACE_INTERFACE,
1834                                      "PropertiesChanged", sargs10)) {
1835                 wpa_printf(MSG_ERROR,
1836                            "Failed to register dbus signal %s"
1837                            "in interface %s", "PropertiesChanged",
1838                            WPAS_DBUS_NEW_IFACE_INTERFACE);
1839         }
1840
1841 #ifdef CONFIG_WPS
1842         /* Start method */
1843         if (wpa_dbus_method_register(obj_desc, WPAS_DBUS_NEW_IFACE_WPS,
1844                                      "Start",
1845                                      (WPADBusMethodHandler)
1846                                      &wpas_dbus_handler_wps_start,
1847                                      wpa_s, NULL, args9)) {
1848                 wpa_printf(MSG_DEBUG,
1849                            "Failed to register dbus method %s"
1850                            "in interface %s", "Start",
1851                            WPAS_DBUS_NEW_IFACE_WPS);
1852         }
1853
1854         /* ProcessCredentials property */
1855         if (wpa_dbus_property_register(obj_desc, WPAS_DBUS_NEW_IFACE_WPS,
1856                                        "ProcessCredentials", "b",
1857                                        (WPADBusPropertyAccessor)
1858                                        wpas_dbus_getter_process_credentials,
1859                                        (WPADBusPropertyAccessor)
1860                                        wpas_dbus_setter_process_credentials,
1861                                        wpa_s, NULL, RW)) {
1862                 wpa_printf(MSG_ERROR,
1863                            "Failed to register dbus property %s"
1864                            "in interface %s", "ProcessCredentials",
1865                            WPAS_DBUS_NEW_IFACE_WPS);
1866         }
1867
1868         /* Event signal */
1869         if (wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_IFACE_WPS,
1870                                      "Event", sargs11)) {
1871                 wpa_printf(MSG_ERROR,
1872                            "Failed to register dbus signal %s"
1873                            "in interface %s", "Event",
1874                            WPAS_DBUS_NEW_IFACE_WPS);
1875         }
1876
1877         /* Credentials signal */
1878         if (wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_IFACE_WPS,
1879                                      "Credentials", sargs12)) {
1880                 wpa_printf(MSG_ERROR,
1881                            "Failed to register dbus signal %s"
1882                            "in interface %s", "Credentials",
1883                            WPAS_DBUS_NEW_IFACE_WPS);
1884         }
1885
1886         /* PropertiesChanged signal */
1887         if (wpa_dbus_signal_register(obj_desc, WPAS_DBUS_NEW_IFACE_WPS,
1888                                      "PropertiesChanged", sargs13)) {
1889                 wpa_printf(MSG_ERROR,
1890                            "Failed to register dbus signal %s"
1891                            "in interface %s", "PropertiesChanged",
1892                            WPAS_DBUS_NEW_IFACE_WPS);
1893         }
1894 #endif /* CONFIG_WPS */
1895
1896         if (wpa_dbus_register_object_per_iface(ctrl_iface, path, wpa_s->ifname,
1897                                                obj_desc))
1898                 goto err;
1899
1900         wpas_dbus_signal_interface_created(wpa_s);
1901
1902         os_free(path);
1903         return 0;
1904
1905 err:
1906         os_free(obj_desc);
1907         os_free(path);
1908         return -1;
1909 }
1910
1911
1912 static int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s)
1913 {
1914         struct ctrl_iface_dbus_new_priv *ctrl_iface;
1915         struct wpa_ssid *ssid;
1916         size_t i;
1917
1918         /* Do nothing if the control interface is not turned on */
1919         if (wpa_s == NULL || wpa_s->global == NULL)
1920                 return 0;
1921         ctrl_iface = wpa_s->global->dbus_new_ctrl_iface;
1922         if (ctrl_iface == NULL)
1923                 return 0;
1924
1925         /* unregister all BSSs and networks from dbus */
1926         for (i = 0; i < wpa_s->scan_res->num; i++) {
1927                 wpas_dbus_unregister_bss(wpa_s,
1928                                          wpa_s->scan_res->res[i]->bssid);
1929         }
1930
1931         ssid = wpa_s->conf->ssid;
1932         while (ssid) {
1933                 wpas_dbus_unregister_network(wpa_s, ssid->id);
1934                 ssid = ssid->next;
1935         }
1936
1937         if (wpa_dbus_unregister_object_per_iface(ctrl_iface,
1938                                                  wpas_dbus_get_path(wpa_s)))
1939                 return -1;
1940
1941         wpas_dbus_signal_interface_removed(wpa_s);
1942
1943         os_free(wpa_s->dbus_new_path);
1944         wpa_s->dbus_new_path = NULL;
1945
1946         return 0;
1947 }
1948
1949
1950 static struct wpas_dbus_callbacks callbacks =
1951 {
1952         .dbus_ctrl_init = wpas_dbus_ctrl_iface_init,
1953         .dbus_ctrl_deinit = wpas_dbus_ctrl_iface_deinit,
1954
1955         .signal_interface_created = wpas_dbus_signal_interface_created,
1956         .signal_interface_removed = wpas_dbus_signal_interface_removed,
1957
1958         .register_interface = wpas_dbus_register_interface,
1959         .unregister_interface = wpas_dbus_unregister_interface,
1960
1961         .signal_scan_done = wpas_dbus_signal_scan_done,
1962
1963         .signal_blob_added = wpas_dbus_signal_blob_added,
1964         .signal_blob_removed = wpas_dbus_signal_blob_removed,
1965
1966         .signal_network_selected = wpas_dbus_signal_network_selected,
1967
1968         .signal_state_changed = wpas_dbus_signal_state_changed,
1969         .register_network = wpas_dbus_register_network,
1970         .unregister_network = wpas_dbus_unregister_network,
1971
1972         .signal_network_enabled_changed =
1973         wpas_dbus_signal_network_enabled_changed,
1974
1975         .register_bss = wpas_dbus_register_bss,
1976         .unregister_bss = wpas_dbus_unregister_bss,
1977
1978         .signal_prop_changed = wpas_dbus_signal_prop_changed,
1979         .signal_debug_params_changed = wpas_dbus_signal_debug_params_changed,
1980
1981 #ifdef CONFIG_WPS
1982         .signal_wps_event_success = wpas_dbus_signal_wps_event_success,
1983         .signal_wps_event_fail = wpas_dbus_signal_wps_event_fail,
1984         .signal_wps_event_m2d = wpas_dbus_signal_wps_event_m2d,
1985         .signal_wps_credentials = wpas_dbus_signal_wps_cred,
1986 #endif /* CONFIG_WPS */
1987 };
1988
1989
1990 struct wpas_dbus_callbacks * wpas_dbus_get_callbacks(void)
1991 {
1992         return &callbacks;
1993 }
1994
1995
1996 /**
1997  * wpas_dbus_get_path - Get an interface's dbus path
1998  * @wpa_s: %wpa_supplicant interface structure
1999  * Returns: Interface's dbus object path, or %NULL on error
2000  */
2001 const char * wpas_dbus_get_path(struct wpa_supplicant *wpa_s)
2002 {
2003         return wpa_s->dbus_new_path;
2004 }