LCOV - code coverage report
Current view: top level - wpa_supplicant/dbus - dbus_new.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1426431149 Lines: 921 1081 85.2 %
Date: 2015-03-15 Functions: 71 71 100.0 %

          Line data    Source code
       1             : /*
       2             :  * WPA Supplicant / dbus-based control interface
       3             :  * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
       4             :  * Copyright (c) 2009-2010, Witold Sowa <witold.sowa@gmail.com>
       5             :  * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
       6             :  *
       7             :  * This software may be distributed under the terms of the BSD license.
       8             :  * See README for more details.
       9             :  */
      10             : 
      11             : #include "includes.h"
      12             : 
      13             : #include "common.h"
      14             : #include "common/ieee802_11_defs.h"
      15             : #include "wps/wps.h"
      16             : #include "../config.h"
      17             : #include "../wpa_supplicant_i.h"
      18             : #include "../bss.h"
      19             : #include "../wpas_glue.h"
      20             : #include "dbus_new_helpers.h"
      21             : #include "dbus_dict_helpers.h"
      22             : #include "dbus_new.h"
      23             : #include "dbus_new_handlers.h"
      24             : #include "dbus_common_i.h"
      25             : #include "dbus_new_handlers_p2p.h"
      26             : #include "p2p/p2p.h"
      27             : #include "../p2p_supplicant.h"
      28             : 
      29             : #ifdef CONFIG_AP /* until needed by something else */
      30             : 
      31             : /*
      32             :  * NameOwnerChanged handling
      33             :  *
      34             :  * Some services we provide allow an application to register for
      35             :  * a signal that it needs. While it can also unregister, we must
      36             :  * be prepared for the case where the application simply crashes
      37             :  * and thus doesn't clean up properly. The way to handle this in
      38             :  * DBus is to register for the NameOwnerChanged signal which will
      39             :  * signal an owner change to NULL if the peer closes the socket
      40             :  * for whatever reason.
      41             :  *
      42             :  * Handle this signal via a filter function whenever necessary.
      43             :  * The code below also handles refcounting in case in the future
      44             :  * there will be multiple instances of this subscription scheme.
      45             :  */
      46             : static const char wpas_dbus_noc_filter_str[] =
      47             :         "interface=org.freedesktop.DBus,member=NameOwnerChanged";
      48             : 
      49             : 
      50         258 : static DBusHandlerResult noc_filter(DBusConnection *conn,
      51             :                                     DBusMessage *message, void *data)
      52             : {
      53         258 :         struct wpas_dbus_priv *priv = data;
      54             : 
      55         258 :         if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_SIGNAL)
      56         257 :                 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
      57             : 
      58           1 :         if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS,
      59             :                                    "NameOwnerChanged")) {
      60             :                 const char *name;
      61             :                 const char *prev_owner;
      62             :                 const char *new_owner;
      63             :                 DBusError derr;
      64             :                 struct wpa_supplicant *wpa_s;
      65             : 
      66           1 :                 dbus_error_init(&derr);
      67             : 
      68           1 :                 if (!dbus_message_get_args(message, &derr,
      69             :                                            DBUS_TYPE_STRING, &name,
      70             :                                            DBUS_TYPE_STRING, &prev_owner,
      71             :                                            DBUS_TYPE_STRING, &new_owner,
      72             :                                            DBUS_TYPE_INVALID)) {
      73             :                         /* Ignore this error */
      74           0 :                         dbus_error_free(&derr);
      75           0 :                         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
      76             :                 }
      77             : 
      78           2 :                 for (wpa_s = priv->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
      79           2 :                         if (wpa_s->preq_notify_peer != NULL &&
      80           2 :                             os_strcmp(name, wpa_s->preq_notify_peer) == 0 &&
      81           2 :                             (new_owner == NULL || os_strlen(new_owner) == 0)) {
      82             :                                 /* probe request owner disconnected */
      83           1 :                                 os_free(wpa_s->preq_notify_peer);
      84           1 :                                 wpa_s->preq_notify_peer = NULL;
      85           1 :                                 wpas_dbus_unsubscribe_noc(priv);
      86             :                         }
      87             :                 }
      88             :         }
      89             : 
      90           1 :         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
      91             : }
      92             : 
      93             : 
      94           3 : void wpas_dbus_subscribe_noc(struct wpas_dbus_priv *priv)
      95             : {
      96           3 :         priv->dbus_noc_refcnt++;
      97           3 :         if (priv->dbus_noc_refcnt > 1)
      98           0 :                 return;
      99             : 
     100           3 :         if (!dbus_connection_add_filter(priv->con, noc_filter, priv, NULL)) {
     101           0 :                 wpa_printf(MSG_ERROR, "dbus: failed to add filter");
     102           0 :                 return;
     103             :         }
     104             : 
     105           3 :         dbus_bus_add_match(priv->con, wpas_dbus_noc_filter_str, NULL);
     106             : }
     107             : 
     108             : 
     109           3 : void wpas_dbus_unsubscribe_noc(struct wpas_dbus_priv *priv)
     110             : {
     111           3 :         priv->dbus_noc_refcnt--;
     112           3 :         if (priv->dbus_noc_refcnt > 0)
     113           3 :                 return;
     114             : 
     115           3 :         dbus_bus_remove_match(priv->con, wpas_dbus_noc_filter_str, NULL);
     116           3 :         dbus_connection_remove_filter(priv->con, noc_filter, priv);
     117             : }
     118             : 
     119             : #endif /* CONFIG_AP */
     120             : 
     121             : 
     122             : /**
     123             :  * wpas_dbus_signal_interface - Send a interface related event signal
     124             :  * @wpa_s: %wpa_supplicant network interface data
     125             :  * @sig_name: signal name - InterfaceAdded or InterfaceRemoved
     126             :  * @properties: Whether to add second argument with object properties
     127             :  *
     128             :  * Notify listeners about event related with interface
     129             :  */
     130         238 : static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s,
     131             :                                        const char *sig_name, int properties)
     132             : {
     133             :         struct wpas_dbus_priv *iface;
     134             :         DBusMessage *msg;
     135             :         DBusMessageIter iter;
     136             : 
     137         238 :         iface = wpa_s->global->dbus;
     138             : 
     139             :         /* Do nothing if the control interface is not turned on */
     140         238 :         if (iface == NULL)
     141           0 :                 return;
     142             : 
     143         238 :         msg = dbus_message_new_signal(WPAS_DBUS_NEW_PATH,
     144             :                                       WPAS_DBUS_NEW_INTERFACE, sig_name);
     145         238 :         if (msg == NULL)
     146           0 :                 return;
     147             : 
     148         238 :         dbus_message_iter_init_append(msg, &iter);
     149         238 :         if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
     150         476 :                                             &wpa_s->dbus_new_path) ||
     151         119 :             (properties &&
     152         119 :              !wpa_dbus_get_object_properties(
     153         119 :                      iface, wpa_s->dbus_new_path,
     154             :                      WPAS_DBUS_NEW_IFACE_INTERFACE, &iter)))
     155           3 :                 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
     156             :         else
     157         235 :                 dbus_connection_send(iface->con, msg, NULL);
     158         238 :         dbus_message_unref(msg);
     159             : }
     160             : 
     161             : 
     162             : /**
     163             :  * wpas_dbus_signal_interface_added - Send a interface created signal
     164             :  * @wpa_s: %wpa_supplicant network interface data
     165             :  *
     166             :  * Notify listeners about creating new interface
     167             :  */
     168         119 : static void wpas_dbus_signal_interface_added(struct wpa_supplicant *wpa_s)
     169             : {
     170         119 :         wpas_dbus_signal_interface(wpa_s, "InterfaceAdded", TRUE);
     171         119 : }
     172             : 
     173             : 
     174             : /**
     175             :  * wpas_dbus_signal_interface_removed - Send a interface removed signal
     176             :  * @wpa_s: %wpa_supplicant network interface data
     177             :  *
     178             :  * Notify listeners about removing interface
     179             :  */
     180         119 : static void wpas_dbus_signal_interface_removed(struct wpa_supplicant *wpa_s)
     181             : {
     182         119 :         wpas_dbus_signal_interface(wpa_s, "InterfaceRemoved", FALSE);
     183             : 
     184         119 : }
     185             : 
     186             : 
     187             : /**
     188             :  * wpas_dbus_signal_scan_done - send scan done signal
     189             :  * @wpa_s: %wpa_supplicant network interface data
     190             :  * @success: indicates if scanning succeed or failed
     191             :  *
     192             :  * Notify listeners about finishing a scan
     193             :  */
     194        1934 : void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s, int success)
     195             : {
     196             :         struct wpas_dbus_priv *iface;
     197             :         DBusMessage *msg;
     198             :         dbus_bool_t succ;
     199             : 
     200        1934 :         iface = wpa_s->global->dbus;
     201             : 
     202             :         /* Do nothing if the control interface is not turned on */
     203        1934 :         if (iface == NULL)
     204        1374 :                 return;
     205             : 
     206        1247 :         msg = dbus_message_new_signal(wpa_s->dbus_new_path,
     207             :                                       WPAS_DBUS_NEW_IFACE_INTERFACE,
     208             :                                       "ScanDone");
     209        1247 :         if (msg == NULL)
     210           0 :                 return;
     211             : 
     212        1247 :         succ = success ? TRUE : FALSE;
     213        1247 :         if (dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &succ,
     214             :                                      DBUS_TYPE_INVALID))
     215        1247 :                 dbus_connection_send(iface->con, msg, NULL);
     216             :         else
     217           0 :                 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
     218        1247 :         dbus_message_unref(msg);
     219             : }
     220             : 
     221             : 
     222             : /**
     223             :  * wpas_dbus_signal_bss - Send a BSS related event signal
     224             :  * @wpa_s: %wpa_supplicant network interface data
     225             :  * @bss_obj_path: BSS object path
     226             :  * @sig_name: signal name - BSSAdded or BSSRemoved
     227             :  * @properties: Whether to add second argument with object properties
     228             :  *
     229             :  * Notify listeners about event related with BSS
     230             :  */
     231        2114 : static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s,
     232             :                                  const char *bss_obj_path,
     233             :                                  const char *sig_name, int properties)
     234             : {
     235             :         struct wpas_dbus_priv *iface;
     236             :         DBusMessage *msg;
     237             :         DBusMessageIter iter;
     238             : 
     239        2114 :         iface = wpa_s->global->dbus;
     240             : 
     241             :         /* Do nothing if the control interface is not turned on */
     242        2114 :         if (iface == NULL)
     243           0 :                 return;
     244             : 
     245        2114 :         msg = dbus_message_new_signal(wpa_s->dbus_new_path,
     246             :                                       WPAS_DBUS_NEW_IFACE_INTERFACE,
     247             :                                       sig_name);
     248        2114 :         if (msg == NULL)
     249           0 :                 return;
     250             : 
     251        2114 :         dbus_message_iter_init_append(msg, &iter);
     252        2114 :         if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
     253        2114 :                                             &bss_obj_path) ||
     254        1057 :             (properties &&
     255        1057 :              !wpa_dbus_get_object_properties(iface, bss_obj_path,
     256             :                                              WPAS_DBUS_NEW_IFACE_BSS,
     257             :                                              &iter)))
     258           0 :                 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
     259             :         else
     260        2114 :                 dbus_connection_send(iface->con, msg, NULL);
     261        2114 :         dbus_message_unref(msg);
     262             : }
     263             : 
     264             : 
     265             : /**
     266             :  * wpas_dbus_signal_bss_added - Send a BSS added signal
     267             :  * @wpa_s: %wpa_supplicant network interface data
     268             :  * @bss_obj_path: new BSS object path
     269             :  *
     270             :  * Notify listeners about adding new BSS
     271             :  */
     272        1057 : static void wpas_dbus_signal_bss_added(struct wpa_supplicant *wpa_s,
     273             :                                        const char *bss_obj_path)
     274             : {
     275        1057 :         wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSAdded", TRUE);
     276        1057 : }
     277             : 
     278             : 
     279             : /**
     280             :  * wpas_dbus_signal_bss_removed - Send a BSS removed signal
     281             :  * @wpa_s: %wpa_supplicant network interface data
     282             :  * @bss_obj_path: BSS object path
     283             :  *
     284             :  * Notify listeners about removing BSS
     285             :  */
     286        1057 : static void wpas_dbus_signal_bss_removed(struct wpa_supplicant *wpa_s,
     287             :                                          const char *bss_obj_path)
     288             : {
     289        1057 :         wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSRemoved", FALSE);
     290        1057 : }
     291             : 
     292             : 
     293             : /**
     294             :  * wpas_dbus_signal_blob - Send a blob related event signal
     295             :  * @wpa_s: %wpa_supplicant network interface data
     296             :  * @name: blob name
     297             :  * @sig_name: signal name - BlobAdded or BlobRemoved
     298             :  *
     299             :  * Notify listeners about event related with blob
     300             :  */
     301           8 : static void wpas_dbus_signal_blob(struct wpa_supplicant *wpa_s,
     302             :                                   const char *name, const char *sig_name)
     303             : {
     304             :         struct wpas_dbus_priv *iface;
     305             :         DBusMessage *msg;
     306             : 
     307           8 :         iface = wpa_s->global->dbus;
     308             : 
     309             :         /* Do nothing if the control interface is not turned on */
     310           8 :         if (iface == NULL)
     311           0 :                 return;
     312             : 
     313           8 :         msg = dbus_message_new_signal(wpa_s->dbus_new_path,
     314             :                                       WPAS_DBUS_NEW_IFACE_INTERFACE,
     315             :                                       sig_name);
     316           8 :         if (msg == NULL)
     317           0 :                 return;
     318             : 
     319           8 :         if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &name,
     320             :                                      DBUS_TYPE_INVALID))
     321           8 :                 dbus_connection_send(iface->con, msg, NULL);
     322             :         else
     323           0 :                 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
     324           8 :         dbus_message_unref(msg);
     325             : }
     326             : 
     327             : 
     328             : /**
     329             :  * wpas_dbus_signal_blob_added - Send a blob added signal
     330             :  * @wpa_s: %wpa_supplicant network interface data
     331             :  * @name: blob name
     332             :  *
     333             :  * Notify listeners about adding a new blob
     334             :  */
     335           4 : void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s,
     336             :                                  const char *name)
     337             : {
     338           4 :         wpas_dbus_signal_blob(wpa_s, name, "BlobAdded");
     339           4 : }
     340             : 
     341             : 
     342             : /**
     343             :  * wpas_dbus_signal_blob_removed - Send a blob removed signal
     344             :  * @wpa_s: %wpa_supplicant network interface data
     345             :  * @name: blob name
     346             :  *
     347             :  * Notify listeners about removing blob
     348             :  */
     349           4 : void wpas_dbus_signal_blob_removed(struct wpa_supplicant *wpa_s,
     350             :                                    const char *name)
     351             : {
     352           4 :         wpas_dbus_signal_blob(wpa_s, name, "BlobRemoved");
     353           4 : }
     354             : 
     355             : 
     356             : /**
     357             :  * wpas_dbus_signal_network - Send a network related event signal
     358             :  * @wpa_s: %wpa_supplicant network interface data
     359             :  * @id: new network id
     360             :  * @sig_name: signal name - NetworkAdded, NetworkRemoved or NetworkSelected
     361             :  * @properties: determines if add second argument with object properties
     362             :  *
     363             :  * Notify listeners about event related with configured network
     364             :  */
     365        6403 : static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s,
     366             :                                      int id, const char *sig_name,
     367             :                                      int properties)
     368             : {
     369             :         struct wpas_dbus_priv *iface;
     370             :         DBusMessage *msg;
     371             :         DBusMessageIter iter;
     372             :         char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
     373             : 
     374        6403 :         iface = wpa_s->global->dbus;
     375             : 
     376             :         /* Do nothing if the control interface is not turned on */
     377        6403 :         if (iface == NULL)
     378         682 :                 return;
     379             : 
     380        6062 :         os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
     381             :                     "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
     382             :                     wpa_s->dbus_new_path, id);
     383             : 
     384        6062 :         msg = dbus_message_new_signal(wpa_s->dbus_new_path,
     385             :                                       WPAS_DBUS_NEW_IFACE_INTERFACE,
     386             :                                       sig_name);
     387        6062 :         if (msg == NULL)
     388           0 :                 return;
     389             : 
     390        6062 :         dbus_message_iter_init_append(msg, &iter);
     391        6062 :         path = net_obj_path;
     392        6062 :         if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
     393        6062 :                                             &path) ||
     394        2401 :             (properties &&
     395        2401 :              !wpa_dbus_get_object_properties(
     396             :                      iface, net_obj_path, WPAS_DBUS_NEW_IFACE_NETWORK,
     397             :                      &iter)))
     398           0 :                 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
     399             :         else
     400        6062 :                 dbus_connection_send(iface->con, msg, NULL);
     401        6062 :         dbus_message_unref(msg);
     402             : }
     403             : 
     404             : 
     405             : /**
     406             :  * wpas_dbus_signal_network_added - Send a network added signal
     407             :  * @wpa_s: %wpa_supplicant network interface data
     408             :  * @id: new network id
     409             :  *
     410             :  * Notify listeners about adding new network
     411             :  */
     412        2401 : static void wpas_dbus_signal_network_added(struct wpa_supplicant *wpa_s,
     413             :                                            int id)
     414             : {
     415        2401 :         wpas_dbus_signal_network(wpa_s, id, "NetworkAdded", TRUE);
     416        2401 : }
     417             : 
     418             : 
     419             : /**
     420             :  * wpas_dbus_signal_network_removed - Send a network removed signal
     421             :  * @wpa_s: %wpa_supplicant network interface data
     422             :  * @id: network id
     423             :  *
     424             :  * Notify listeners about removing a network
     425             :  */
     426        2403 : static void wpas_dbus_signal_network_removed(struct wpa_supplicant *wpa_s,
     427             :                                              int id)
     428             : {
     429        2403 :         wpas_dbus_signal_network(wpa_s, id, "NetworkRemoved", FALSE);
     430        2403 : }
     431             : 
     432             : 
     433             : /**
     434             :  * wpas_dbus_signal_network_selected - Send a network selected signal
     435             :  * @wpa_s: %wpa_supplicant network interface data
     436             :  * @id: network id
     437             :  *
     438             :  * Notify listeners about selecting a network
     439             :  */
     440        1599 : void wpas_dbus_signal_network_selected(struct wpa_supplicant *wpa_s, int id)
     441             : {
     442        1599 :         wpas_dbus_signal_network(wpa_s, id, "NetworkSelected", FALSE);
     443        1599 : }
     444             : 
     445             : 
     446             : /**
     447             :  * wpas_dbus_signal_network_request - Indicate that additional information
     448             :  * (EAP password, etc.) is required to complete the association to this SSID
     449             :  * @wpa_s: %wpa_supplicant network interface data
     450             :  * @rtype: The specific additional information required
     451             :  * @default_text: Optional description of required information
     452             :  *
     453             :  * Request additional information or passwords to complete an association
     454             :  * request.
     455             :  */
     456          32 : void wpas_dbus_signal_network_request(struct wpa_supplicant *wpa_s,
     457             :                                       struct wpa_ssid *ssid,
     458             :                                       enum wpa_ctrl_req_type rtype,
     459             :                                       const char *default_txt)
     460             : {
     461             :         struct wpas_dbus_priv *iface;
     462             :         DBusMessage *msg;
     463             :         DBusMessageIter iter;
     464             :         char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
     465          32 :         const char *field, *txt = NULL, *net_ptr;
     466             : 
     467          32 :         iface = wpa_s->global->dbus;
     468             : 
     469             :         /* Do nothing if the control interface is not turned on */
     470          32 :         if (iface == NULL)
     471           0 :                 return;
     472             : 
     473          32 :         field = wpa_supplicant_ctrl_req_to_string(rtype, default_txt, &txt);
     474          32 :         if (field == NULL)
     475           0 :                 return;
     476             : 
     477          32 :         msg = dbus_message_new_signal(wpa_s->dbus_new_path,
     478             :                                       WPAS_DBUS_NEW_IFACE_INTERFACE,
     479             :                                       "NetworkRequest");
     480          32 :         if (msg == NULL)
     481           0 :                 return;
     482             : 
     483          32 :         os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
     484             :                     "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
     485             :                     wpa_s->dbus_new_path, ssid->id);
     486          32 :         net_ptr = &net_obj_path[0];
     487             : 
     488          32 :         dbus_message_iter_init_append(msg, &iter);
     489          32 :         if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
     490          32 :                                             &net_ptr) ||
     491          64 :             !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &field) ||
     492          32 :             !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &txt))
     493           0 :                 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
     494             :         else
     495          32 :                 dbus_connection_send(iface->con, msg, NULL);
     496          32 :         dbus_message_unref(msg);
     497             : }
     498             : 
     499             : 
     500             : /**
     501             :  * wpas_dbus_signal_network_enabled_changed - Signals Enabled property changes
     502             :  * @wpa_s: %wpa_supplicant network interface data
     503             :  * @ssid: configured network which Enabled property has changed
     504             :  *
     505             :  * Sends PropertyChanged signals containing new value of Enabled property
     506             :  * for specified network
     507             :  */
     508        1530 : void wpas_dbus_signal_network_enabled_changed(struct wpa_supplicant *wpa_s,
     509             :                                               struct wpa_ssid *ssid)
     510             : {
     511             : 
     512             :         char path[WPAS_DBUS_OBJECT_PATH_MAX];
     513             : 
     514        1530 :         os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
     515             :                     "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
     516             :                     wpa_s->dbus_new_path, ssid->id);
     517             : 
     518        1530 :         wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
     519             :                                        WPAS_DBUS_NEW_IFACE_NETWORK, "Enabled");
     520        1530 : }
     521             : 
     522             : 
     523             : #ifdef CONFIG_WPS
     524             : 
     525             : /**
     526             :  * wpas_dbus_signal_wps_event_success - Signals Success WPS event
     527             :  * @wpa_s: %wpa_supplicant network interface data
     528             :  *
     529             :  * Sends Event dbus signal with name "success" and empty dict as arguments
     530             :  */
     531         235 : void wpas_dbus_signal_wps_event_success(struct wpa_supplicant *wpa_s)
     532             : {
     533             : 
     534             :         DBusMessage *msg;
     535             :         DBusMessageIter iter, dict_iter;
     536             :         struct wpas_dbus_priv *iface;
     537         235 :         char *key = "success";
     538             : 
     539         235 :         iface = wpa_s->global->dbus;
     540             : 
     541             :         /* Do nothing if the control interface is not turned on */
     542         235 :         if (iface == NULL)
     543         294 :                 return;
     544             : 
     545          88 :         msg = dbus_message_new_signal(wpa_s->dbus_new_path,
     546             :                                       WPAS_DBUS_NEW_IFACE_WPS, "Event");
     547          88 :         if (msg == NULL)
     548           0 :                 return;
     549             : 
     550          88 :         dbus_message_iter_init_append(msg, &iter);
     551             : 
     552         176 :         if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
     553         176 :             !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
     554          88 :             !wpa_dbus_dict_close_write(&iter, &dict_iter))
     555           0 :                 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
     556             :         else
     557          88 :                 dbus_connection_send(iface->con, msg, NULL);
     558             : 
     559          88 :         dbus_message_unref(msg);
     560             : }
     561             : 
     562             : 
     563             : /**
     564             :  * wpas_dbus_signal_wps_event_fail - Signals Fail WPS event
     565             :  * @wpa_s: %wpa_supplicant network interface data
     566             :  *
     567             :  * Sends Event dbus signal with name "fail" and dictionary containing
     568             :  * "msg field with fail message number (int32) as arguments
     569             :  */
     570          43 : void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant *wpa_s,
     571             :                                      struct wps_event_fail *fail)
     572             : {
     573             : 
     574             :         DBusMessage *msg;
     575             :         DBusMessageIter iter, dict_iter;
     576             :         struct wpas_dbus_priv *iface;
     577          43 :         char *key = "fail";
     578             : 
     579          43 :         iface = wpa_s->global->dbus;
     580             : 
     581             :         /* Do nothing if the control interface is not turned on */
     582          43 :         if (iface == NULL)
     583          28 :                 return;
     584             : 
     585          29 :         msg = dbus_message_new_signal(wpa_s->dbus_new_path,
     586             :                                       WPAS_DBUS_NEW_IFACE_WPS, "Event");
     587          29 :         if (msg == NULL)
     588           0 :                 return;
     589             : 
     590          29 :         dbus_message_iter_init_append(msg, &iter);
     591             : 
     592          58 :         if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
     593          58 :             !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
     594          58 :             !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
     595          29 :             !wpa_dbus_dict_close_write(&iter, &dict_iter))
     596           0 :                 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
     597             :         else
     598          29 :                 dbus_connection_send(iface->con, msg, NULL);
     599             : 
     600          29 :         dbus_message_unref(msg);
     601             : }
     602             : 
     603             : 
     604             : /**
     605             :  * wpas_dbus_signal_wps_event_m2d - Signals M2D WPS event
     606             :  * @wpa_s: %wpa_supplicant network interface data
     607             :  *
     608             :  * Sends Event dbus signal with name "m2d" and dictionary containing
     609             :  * fields of wps_event_m2d structure.
     610             :  */
     611          25 : void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant *wpa_s,
     612             :                                     struct wps_event_m2d *m2d)
     613             : {
     614             : 
     615             :         DBusMessage *msg;
     616             :         DBusMessageIter iter, dict_iter;
     617             :         struct wpas_dbus_priv *iface;
     618          25 :         char *key = "m2d";
     619             : 
     620          25 :         iface = wpa_s->global->dbus;
     621             : 
     622             :         /* Do nothing if the control interface is not turned on */
     623          25 :         if (iface == NULL)
     624          38 :                 return;
     625             : 
     626           6 :         msg = dbus_message_new_signal(wpa_s->dbus_new_path,
     627             :                                       WPAS_DBUS_NEW_IFACE_WPS, "Event");
     628           6 :         if (msg == NULL)
     629           0 :                 return;
     630             : 
     631           6 :         dbus_message_iter_init_append(msg, &iter);
     632             : 
     633          12 :         if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
     634          12 :             !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
     635           6 :             !wpa_dbus_dict_append_uint16(&dict_iter, "config_methods",
     636          12 :                                          m2d->config_methods) ||
     637          12 :             !wpa_dbus_dict_append_byte_array(&dict_iter, "manufacturer",
     638           6 :                                              (const char *) m2d->manufacturer,
     639          12 :                                              m2d->manufacturer_len) ||
     640          12 :             !wpa_dbus_dict_append_byte_array(&dict_iter, "model_name",
     641           6 :                                              (const char *) m2d->model_name,
     642          12 :                                              m2d->model_name_len) ||
     643          12 :             !wpa_dbus_dict_append_byte_array(&dict_iter, "model_number",
     644           6 :                                              (const char *) m2d->model_number,
     645          12 :                                              m2d->model_number_len) ||
     646          12 :             !wpa_dbus_dict_append_byte_array(&dict_iter, "serial_number",
     647             :                                              (const char *)
     648           6 :                                              m2d->serial_number,
     649          12 :                                              m2d->serial_number_len) ||
     650          12 :             !wpa_dbus_dict_append_byte_array(&dict_iter, "dev_name",
     651           6 :                                              (const char *) m2d->dev_name,
     652          12 :                                              m2d->dev_name_len) ||
     653           6 :             !wpa_dbus_dict_append_byte_array(&dict_iter, "primary_dev_type",
     654             :                                              (const char *)
     655          12 :                                              m2d->primary_dev_type, 8) ||
     656           6 :             !wpa_dbus_dict_append_uint16(&dict_iter, "config_error",
     657          12 :                                          m2d->config_error) ||
     658           6 :             !wpa_dbus_dict_append_uint16(&dict_iter, "dev_password_id",
     659          12 :                                          m2d->dev_password_id) ||
     660           6 :             !wpa_dbus_dict_close_write(&iter, &dict_iter))
     661           0 :                 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
     662             :         else
     663           6 :                 dbus_connection_send(iface->con, msg, NULL);
     664             : 
     665           6 :         dbus_message_unref(msg);
     666             : }
     667             : 
     668             : 
     669             : /**
     670             :  * wpas_dbus_signal_wps_cred - Signals new credentials
     671             :  * @wpa_s: %wpa_supplicant network interface data
     672             :  *
     673             :  * Sends signal with credentials in directory argument
     674             :  */
     675          11 : void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s,
     676             :                                const struct wps_credential *cred)
     677             : {
     678             :         DBusMessage *msg;
     679             :         DBusMessageIter iter, dict_iter;
     680             :         struct wpas_dbus_priv *iface;
     681             :         char *auth_type[5]; /* we have five possible authentication types */
     682          11 :         int at_num = 0;
     683             :         char *encr_type[3]; /* we have three possible encryption types */
     684          11 :         int et_num = 0;
     685             : 
     686          11 :         iface = wpa_s->global->dbus;
     687             : 
     688             :         /* Do nothing if the control interface is not turned on */
     689          11 :         if (iface == NULL)
     690           0 :                 return;
     691             : 
     692          11 :         msg = dbus_message_new_signal(wpa_s->dbus_new_path,
     693             :                                       WPAS_DBUS_NEW_IFACE_WPS,
     694             :                                       "Credentials");
     695          11 :         if (msg == NULL)
     696           0 :                 return;
     697             : 
     698          11 :         dbus_message_iter_init_append(msg, &iter);
     699          11 :         if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
     700           0 :                 goto nomem;
     701             : 
     702          11 :         if (cred->auth_type & WPS_AUTH_OPEN)
     703           0 :                 auth_type[at_num++] = "open";
     704          11 :         if (cred->auth_type & WPS_AUTH_WPAPSK)
     705           0 :                 auth_type[at_num++] = "wpa-psk";
     706          11 :         if (cred->auth_type & WPS_AUTH_WPA)
     707           0 :                 auth_type[at_num++] = "wpa-eap";
     708          11 :         if (cred->auth_type & WPS_AUTH_WPA2)
     709           0 :                 auth_type[at_num++] = "wpa2-eap";
     710          11 :         if (cred->auth_type & WPS_AUTH_WPA2PSK)
     711          11 :                 auth_type[at_num++] = "wpa2-psk";
     712             : 
     713          11 :         if (cred->encr_type & WPS_ENCR_NONE)
     714           0 :                 encr_type[et_num++] = "none";
     715          11 :         if (cred->encr_type & WPS_ENCR_TKIP)
     716           0 :                 encr_type[et_num++] = "tkip";
     717          11 :         if (cred->encr_type & WPS_ENCR_AES)
     718          11 :                 encr_type[et_num++] = "aes";
     719             : 
     720          22 :         if ((wpa_s->current_ssid &&
     721          11 :              !wpa_dbus_dict_append_byte_array(
     722             :                      &dict_iter, "BSSID",
     723          22 :                      (const char *) wpa_s->current_ssid->bssid, ETH_ALEN)) ||
     724          22 :             !wpa_dbus_dict_append_byte_array(&dict_iter, "SSID",
     725          11 :                                              (const char *) cred->ssid,
     726          22 :                                              cred->ssid_len) ||
     727          11 :             !wpa_dbus_dict_append_string_array(&dict_iter, "AuthType",
     728             :                                                (const char **) auth_type,
     729          11 :                                                at_num) ||
     730          11 :             !wpa_dbus_dict_append_string_array(&dict_iter, "EncrType",
     731             :                                                (const char **) encr_type,
     732          11 :                                                et_num) ||
     733          22 :             !wpa_dbus_dict_append_byte_array(&dict_iter, "Key",
     734          11 :                                              (const char *) cred->key,
     735          22 :                                              cred->key_len) ||
     736          11 :             !wpa_dbus_dict_append_uint32(&dict_iter, "KeyIndex",
     737          22 :                                          cred->key_idx) ||
     738          11 :             !wpa_dbus_dict_close_write(&iter, &dict_iter))
     739             :                 goto nomem;
     740             : 
     741          11 :         dbus_connection_send(iface->con, msg, NULL);
     742             : 
     743             : nomem:
     744          11 :         dbus_message_unref(msg);
     745             : }
     746             : 
     747             : #endif /* CONFIG_WPS */
     748             : 
     749         479 : void wpas_dbus_signal_certification(struct wpa_supplicant *wpa_s,
     750             :                                     int depth, const char *subject,
     751             :                                     const char *altsubject[],
     752             :                                     int num_altsubject,
     753             :                                     const char *cert_hash,
     754             :                                     const struct wpabuf *cert)
     755             : {
     756             :         struct wpas_dbus_priv *iface;
     757             :         DBusMessage *msg;
     758             :         DBusMessageIter iter, dict_iter;
     759             : 
     760         479 :         iface = wpa_s->global->dbus;
     761             : 
     762             :         /* Do nothing if the control interface is not turned on */
     763         479 :         if (iface == NULL)
     764         102 :                 return;
     765             : 
     766         428 :         msg = dbus_message_new_signal(wpa_s->dbus_new_path,
     767             :                                       WPAS_DBUS_NEW_IFACE_INTERFACE,
     768             :                                       "Certification");
     769         428 :         if (msg == NULL)
     770           0 :                 return;
     771             : 
     772         428 :         dbus_message_iter_init_append(msg, &iter);
     773         856 :         if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
     774         856 :             !wpa_dbus_dict_append_uint32(&dict_iter, "depth", depth) ||
     775         856 :             !wpa_dbus_dict_append_string(&dict_iter, "subject", subject) ||
     776         623 :             (altsubject && num_altsubject &&
     777         195 :              !wpa_dbus_dict_append_string_array(&dict_iter, "altsubject",
     778         428 :                                                 altsubject, num_altsubject)) ||
     779         428 :             (cert_hash &&
     780         428 :              !wpa_dbus_dict_append_string(&dict_iter, "cert_hash",
     781         428 :                                           cert_hash)) ||
     782         428 :             (cert &&
     783         856 :              !wpa_dbus_dict_append_byte_array(&dict_iter, "cert",
     784         428 :                                               wpabuf_head(cert),
     785         856 :                                               wpabuf_len(cert))) ||
     786         428 :             !wpa_dbus_dict_close_write(&iter, &dict_iter))
     787           0 :                 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
     788             :         else
     789         428 :                 dbus_connection_send(iface->con, msg, NULL);
     790         428 :         dbus_message_unref(msg);
     791             : }
     792             : 
     793             : 
     794        4367 : void wpas_dbus_signal_eap_status(struct wpa_supplicant *wpa_s,
     795             :                                  const char *status, const char *parameter)
     796             : {
     797             :         struct wpas_dbus_priv *iface;
     798             :         DBusMessage *msg;
     799             :         DBusMessageIter iter;
     800             : 
     801        4367 :         iface = wpa_s->global->dbus;
     802             : 
     803             :         /* Do nothing if the control interface is not turned on */
     804        4367 :         if (iface == NULL)
     805        1616 :                 return;
     806             : 
     807        3559 :         msg = dbus_message_new_signal(wpa_s->dbus_new_path,
     808             :                                       WPAS_DBUS_NEW_IFACE_INTERFACE,
     809             :                                       "EAP");
     810        3559 :         if (msg == NULL)
     811           0 :                 return;
     812             : 
     813        3559 :         dbus_message_iter_init_append(msg, &iter);
     814             : 
     815        7118 :         if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &status) ||
     816        3559 :             !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
     817             :                                             &parameter))
     818           0 :                 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
     819             :         else
     820        3559 :                 dbus_connection_send(iface->con, msg, NULL);
     821        3559 :         dbus_message_unref(msg);
     822             : }
     823             : 
     824             : 
     825             : /**
     826             :  * wpas_dbus_signal_sta - Send a station related event signal
     827             :  * @wpa_s: %wpa_supplicant network interface data
     828             :  * @sta: station mac address
     829             :  * @sig_name: signal name - StaAuthorized or StaDeauthorized
     830             :  *
     831             :  * Notify listeners about event related with station
     832             :  */
     833         430 : static void wpas_dbus_signal_sta(struct wpa_supplicant *wpa_s,
     834             :                                  const u8 *sta, const char *sig_name)
     835             : {
     836             :         struct wpas_dbus_priv *iface;
     837             :         DBusMessage *msg;
     838             :         char sta_mac[WPAS_DBUS_OBJECT_PATH_MAX];
     839             :         char *dev_mac;
     840             : 
     841         430 :         os_snprintf(sta_mac, WPAS_DBUS_OBJECT_PATH_MAX, MACSTR, MAC2STR(sta));
     842         430 :         dev_mac = sta_mac;
     843             : 
     844         430 :         iface = wpa_s->global->dbus;
     845             : 
     846             :         /* Do nothing if the control interface is not turned on */
     847         430 :         if (iface == NULL)
     848         184 :                 return;
     849             : 
     850         338 :         msg = dbus_message_new_signal(wpa_s->dbus_new_path,
     851             :                                       WPAS_DBUS_NEW_IFACE_INTERFACE, sig_name);
     852         338 :         if (msg == NULL)
     853           0 :                 return;
     854             : 
     855         338 :         if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &dev_mac,
     856             :                                      DBUS_TYPE_INVALID))
     857         338 :                 dbus_connection_send(iface->con, msg, NULL);
     858             :         else
     859           0 :                 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
     860         338 :         dbus_message_unref(msg);
     861             : 
     862         338 :         wpa_printf(MSG_DEBUG, "dbus: Station MAC address '%s' '%s'",
     863             :                    sta_mac, sig_name);
     864             : }
     865             : 
     866             : 
     867             : /**
     868             :  * wpas_dbus_signal_sta_authorized - Send a STA authorized signal
     869             :  * @wpa_s: %wpa_supplicant network interface data
     870             :  * @sta: station mac address
     871             :  *
     872             :  * Notify listeners a new station has been authorized
     873             :  */
     874         215 : void wpas_dbus_signal_sta_authorized(struct wpa_supplicant *wpa_s,
     875             :                                      const u8 *sta)
     876             : {
     877         215 :         wpas_dbus_signal_sta(wpa_s, sta, "StaAuthorized");
     878         215 : }
     879             : 
     880             : 
     881             : /**
     882             :  * wpas_dbus_signal_sta_deauthorized - Send a STA deauthorized signal
     883             :  * @wpa_s: %wpa_supplicant network interface data
     884             :  * @sta: station mac address
     885             :  *
     886             :  * Notify listeners a station has been deauthorized
     887             :  */
     888         215 : void wpas_dbus_signal_sta_deauthorized(struct wpa_supplicant *wpa_s,
     889             :                                        const u8 *sta)
     890             : {
     891         215 :         wpas_dbus_signal_sta(wpa_s, sta, "StaDeauthorized");
     892         215 : }
     893             : 
     894             : 
     895             : #ifdef CONFIG_P2P
     896             : 
     897             : /**
     898             :  * wpas_dbus_signal_p2p_group_removed - Signals P2P group was removed
     899             :  * @wpa_s: %wpa_supplicant network interface data
     900             :  * @role: role of this device (client or GO)
     901             :  * Sends signal with i/f name and role as string arguments
     902             :  */
     903         499 : void wpas_dbus_signal_p2p_group_removed(struct wpa_supplicant *wpa_s,
     904             :                                         const char *role)
     905             : {
     906             :         DBusMessage *msg;
     907             :         DBusMessageIter iter, dict_iter;
     908         499 :         struct wpas_dbus_priv *iface = wpa_s->global->dbus;
     909             :         struct wpa_supplicant *parent;
     910             : 
     911             :         /* Do nothing if the control interface is not turned on */
     912         499 :         if (iface == NULL)
     913         442 :                 return;
     914             : 
     915         280 :         parent = wpa_s->parent;
     916         280 :         if (parent->p2p_mgmt)
     917           0 :                 parent = parent->parent;
     918             : 
     919         280 :         if (!wpa_s->dbus_groupobj_path)
     920           4 :                 return;
     921             : 
     922         276 :         msg = dbus_message_new_signal(parent->dbus_new_path,
     923             :                                       WPAS_DBUS_NEW_IFACE_P2PDEVICE,
     924             :                                       "GroupFinished");
     925         276 :         if (msg == NULL)
     926           0 :                 return;
     927             : 
     928         276 :         dbus_message_iter_init_append(msg, &iter);
     929         552 :         if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
     930         276 :             !wpa_dbus_dict_append_object_path(&dict_iter,
     931             :                                               "interface_object",
     932         552 :                                               wpa_s->dbus_new_path) ||
     933         552 :             !wpa_dbus_dict_append_string(&dict_iter, "role", role) ||
     934         276 :             !wpa_dbus_dict_append_object_path(&dict_iter, "group_object",
     935         552 :                                               wpa_s->dbus_groupobj_path) ||
     936         276 :             !wpa_dbus_dict_close_write(&iter, &dict_iter))
     937           0 :                 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
     938             :         else
     939         276 :                 dbus_connection_send(iface->con, msg, NULL);
     940         276 :         dbus_message_unref(msg);
     941             : }
     942             : 
     943             : 
     944             : /**
     945             :  * wpas_dbus_signal_p2p_provision_discovery - Signals various PD events
     946             :  *
     947             :  * @dev_addr - who sent the request or responded to our request.
     948             :  * @request - Will be 1 if request, 0 for response.
     949             :  * @status - valid only in case of response
     950             :  * @config_methods - wps config methods
     951             :  * @generated_pin - pin to be displayed in case of WPS_CONFIG_DISPLAY method
     952             :  *
     953             :  * Sends following provision discovery related events:
     954             :  *      ProvisionDiscoveryRequestDisplayPin
     955             :  *      ProvisionDiscoveryResponseDisplayPin
     956             :  *      ProvisionDiscoveryRequestEnterPin
     957             :  *      ProvisionDiscoveryResponseEnterPin
     958             :  *      ProvisionDiscoveryPBCRequest
     959             :  *      ProvisionDiscoveryPBCResponse
     960             :  *
     961             :  *      TODO::
     962             :  *      ProvisionDiscoveryFailure (timeout case)
     963             :  */
     964         114 : void wpas_dbus_signal_p2p_provision_discovery(struct wpa_supplicant *wpa_s,
     965             :                                               const u8 *dev_addr, int request,
     966             :                                               enum p2p_prov_disc_status status,
     967             :                                               u16 config_methods,
     968             :                                               unsigned int generated_pin)
     969             : {
     970             :         DBusMessage *msg;
     971             :         DBusMessageIter iter;
     972             :         struct wpas_dbus_priv *iface;
     973             :         char *_signal;
     974         114 :         int add_pin = 0;
     975             :         char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
     976         114 :         int error_ret = 1;
     977         114 :         char pin[9], *p_pin = NULL;
     978             : 
     979         114 :         iface = wpa_s->global->dbus;
     980             : 
     981             :         /* Do nothing if the control interface is not turned on */
     982         114 :         if (iface == NULL)
     983          89 :                 return;
     984             : 
     985          74 :         if (wpa_s->p2p_mgmt)
     986           0 :                 wpa_s = wpa_s->parent;
     987             : 
     988          74 :         if (request || !status) {
     989         135 :                 if (config_methods & WPS_CONFIG_DISPLAY)
     990          56 :                         _signal = request ?
     991          56 :                                  "ProvisionDiscoveryRequestDisplayPin" :
     992             :                                  "ProvisionDiscoveryResponseEnterPin";
     993          16 :                 else if (config_methods & WPS_CONFIG_KEYPAD)
     994           2 :                         _signal = request ?
     995           2 :                                  "ProvisionDiscoveryRequestEnterPin" :
     996             :                                  "ProvisionDiscoveryResponseDisplayPin";
     997          14 :                 else if (config_methods & WPS_CONFIG_PUSHBUTTON)
     998           5 :                         _signal = request ? "ProvisionDiscoveryPBCRequest" :
     999             :                                    "ProvisionDiscoveryPBCResponse";
    1000             :                 else
    1001           9 :                         return; /* Unknown or un-supported method */
    1002             :         } else {
    1003             :                 /* Explicit check for failure response */
    1004           2 :                 _signal = "ProvisionDiscoveryFailure";
    1005             :         }
    1006             : 
    1007         117 :         add_pin = ((request && (config_methods & WPS_CONFIG_DISPLAY)) ||
    1008          20 :                    (!request && !status &&
    1009           9 :                         (config_methods & WPS_CONFIG_KEYPAD)));
    1010             : 
    1011          65 :         if (add_pin) {
    1012          52 :                 os_snprintf(pin, sizeof(pin), "%08d", generated_pin);
    1013          52 :                 p_pin = pin;
    1014             :         }
    1015             : 
    1016          65 :         msg = dbus_message_new_signal(wpa_s->dbus_new_path,
    1017             :                                       WPAS_DBUS_NEW_IFACE_P2PDEVICE, _signal);
    1018          65 :         if (msg == NULL)
    1019           0 :                 return;
    1020             : 
    1021             :         /* Check if this is a known peer */
    1022          65 :         if (!p2p_peer_known(wpa_s->global->p2p, dev_addr))
    1023           0 :                 goto error;
    1024             : 
    1025         390 :         os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
    1026             :                         "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
    1027             :                         COMPACT_MACSTR,
    1028         390 :                         wpa_s->dbus_new_path, MAC2STR(dev_addr));
    1029             : 
    1030          65 :         path = peer_obj_path;
    1031             : 
    1032          65 :         dbus_message_iter_init_append(msg, &iter);
    1033             : 
    1034          65 :         if (!dbus_message_iter_append_basic(&iter,
    1035             :                                             DBUS_TYPE_OBJECT_PATH,
    1036             :                                             &path))
    1037           0 :                         goto error;
    1038             : 
    1039          65 :         if (!request && status)
    1040             :                 /* Attach status to ProvisionDiscoveryFailure */
    1041           2 :                 error_ret = !dbus_message_iter_append_basic(&iter,
    1042             :                                                     DBUS_TYPE_INT32,
    1043             :                                                     &status);
    1044             :         else
    1045         115 :                 error_ret = (add_pin &&
    1046          52 :                                  !dbus_message_iter_append_basic(&iter,
    1047             :                                                         DBUS_TYPE_STRING,
    1048             :                                                         &p_pin));
    1049             : 
    1050             : error:
    1051          65 :         if (!error_ret)
    1052          65 :                 dbus_connection_send(iface->con, msg, NULL);
    1053             :         else
    1054           0 :                 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
    1055             : 
    1056          65 :         dbus_message_unref(msg);
    1057             : }
    1058             : 
    1059             : 
    1060          38 : void wpas_dbus_signal_p2p_go_neg_req(struct wpa_supplicant *wpa_s,
    1061             :                                      const u8 *src, u16 dev_passwd_id)
    1062             : {
    1063             :         DBusMessage *msg;
    1064             :         DBusMessageIter iter;
    1065             :         struct wpas_dbus_priv *iface;
    1066             :         char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
    1067             : 
    1068          38 :         iface = wpa_s->global->dbus;
    1069             : 
    1070             :         /* Do nothing if the control interface is not turned on */
    1071          38 :         if (iface == NULL)
    1072          46 :                 return;
    1073             : 
    1074          15 :         if (wpa_s->p2p_mgmt)
    1075           0 :                 wpa_s = wpa_s->parent;
    1076             : 
    1077          90 :         os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
    1078             :                     "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
    1079          90 :                     wpa_s->dbus_new_path, MAC2STR(src));
    1080          15 :         path = peer_obj_path;
    1081             : 
    1082          15 :         msg = dbus_message_new_signal(wpa_s->dbus_new_path,
    1083             :                                       WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    1084             :                                       "GONegotiationRequest");
    1085          15 :         if (msg == NULL)
    1086           0 :                 return;
    1087             : 
    1088          15 :         dbus_message_iter_init_append(msg, &iter);
    1089             : 
    1090          15 :         if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
    1091          15 :                                             &path) ||
    1092          15 :             !dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT16,
    1093             :                                             &dev_passwd_id))
    1094           0 :                 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
    1095             :         else
    1096          15 :                 dbus_connection_send(iface->con, msg, NULL);
    1097             : 
    1098          15 :         dbus_message_unref(msg);
    1099             : }
    1100             : 
    1101             : 
    1102         276 : static int wpas_dbus_get_group_obj_path(struct wpa_supplicant *wpa_s,
    1103             :                                         const struct wpa_ssid *ssid,
    1104             :                                         char *group_obj_path)
    1105             : {
    1106             :         char group_name[3];
    1107             : 
    1108         276 :         if (os_memcmp(ssid->ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN))
    1109           0 :                 return -1;
    1110             : 
    1111         276 :         os_memcpy(group_name, ssid->ssid + P2P_WILDCARD_SSID_LEN, 2);
    1112         276 :         group_name[2] = '\0';
    1113             : 
    1114         276 :         os_snprintf(group_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
    1115             :                     "%s/" WPAS_DBUS_NEW_P2P_GROUPS_PART "/%s",
    1116             :                     wpa_s->dbus_new_path, group_name);
    1117             : 
    1118         276 :         return 0;
    1119             : }
    1120             : 
    1121             : 
    1122             : struct group_changed_data {
    1123             :         struct wpa_supplicant *wpa_s;
    1124             :         struct p2p_peer_info *info;
    1125             : };
    1126             : 
    1127             : 
    1128         129 : static int match_group_where_peer_is_client(struct p2p_group *group,
    1129             :                                             void *user_data)
    1130             : {
    1131         129 :         struct group_changed_data *data = user_data;
    1132             :         const struct p2p_group_config *cfg;
    1133             :         struct wpa_supplicant *wpa_s_go;
    1134             : 
    1135         129 :         if (!p2p_group_is_client_connected(group, data->info->p2p_device_addr))
    1136          20 :                 return 1;
    1137             : 
    1138         109 :         cfg = p2p_group_get_config(group);
    1139             : 
    1140         109 :         wpa_s_go = wpas_get_p2p_go_iface(data->wpa_s, cfg->ssid,
    1141             :                                          cfg->ssid_len);
    1142         109 :         if (wpa_s_go != NULL && wpa_s_go == data->wpa_s) {
    1143         109 :                 wpas_dbus_signal_peer_groups_changed(
    1144         109 :                         data->wpa_s->parent, data->info->p2p_device_addr);
    1145         109 :                 return 0;
    1146             :         }
    1147             : 
    1148           0 :         return 1;
    1149             : }
    1150             : 
    1151             : 
    1152         195 : static void signal_peer_groups_changed(struct p2p_peer_info *info,
    1153             :                                        void *user_data)
    1154             : {
    1155         195 :         struct group_changed_data *data = user_data;
    1156             :         struct wpa_supplicant *wpa_s_go;
    1157             : 
    1158         195 :         wpa_s_go = wpas_get_p2p_client_iface(data->wpa_s,
    1159         195 :                                              info->p2p_device_addr);
    1160         195 :         if (wpa_s_go != NULL && wpa_s_go == data->wpa_s) {
    1161          62 :                 wpas_dbus_signal_peer_groups_changed(data->wpa_s->parent,
    1162          62 :                                                      info->p2p_device_addr);
    1163         257 :                 return;
    1164             :         }
    1165             : 
    1166         133 :         data->info = info;
    1167         133 :         p2p_loop_on_all_groups(data->wpa_s->global->p2p,
    1168             :                                match_group_where_peer_is_client, data);
    1169         133 :         data->info = NULL;
    1170             : }
    1171             : 
    1172             : 
    1173         311 : static void peer_groups_changed(struct wpa_supplicant *wpa_s)
    1174             : {
    1175             :         struct group_changed_data data;
    1176             : 
    1177         311 :         os_memset(&data, 0, sizeof(data));
    1178         311 :         data.wpa_s = wpa_s;
    1179             : 
    1180         311 :         p2p_loop_on_known_peers(wpa_s->global->p2p,
    1181             :                                 signal_peer_groups_changed, &data);
    1182         311 : }
    1183             : 
    1184             : 
    1185             : /**
    1186             :  * wpas_dbus_signal_p2p_group_started - Signals P2P group has
    1187             :  * started. Emitted when a group is successfully started
    1188             :  * irrespective of the role (client/GO) of the current device
    1189             :  *
    1190             :  * @wpa_s: %wpa_supplicant network interface data
    1191             :  * @ssid: SSID object
    1192             :  * @client: this device is P2P client
    1193             :  * @network_id: network id of the group started, use instead of ssid->id
    1194             :  *      to account for persistent groups
    1195             :  */
    1196         483 : void wpas_dbus_signal_p2p_group_started(struct wpa_supplicant *wpa_s,
    1197             :                                         const struct wpa_ssid *ssid,
    1198             :                                         int client, int network_id)
    1199             : {
    1200             :         DBusMessage *msg;
    1201             :         DBusMessageIter iter, dict_iter;
    1202             :         struct wpas_dbus_priv *iface;
    1203             :         struct wpa_supplicant *parent;
    1204             : 
    1205         483 :         parent = wpa_s->parent;
    1206         483 :         if (parent->p2p_mgmt)
    1207           6 :                 parent = parent->parent;
    1208             : 
    1209         483 :         iface = parent->global->dbus;
    1210             : 
    1211             :         /* Do nothing if the control interface is not turned on */
    1212         483 :         if (iface == NULL)
    1213         414 :                 return;
    1214             : 
    1215         276 :         if (wpa_s->dbus_groupobj_path == NULL)
    1216           0 :                 return;
    1217             : 
    1218             :         /* New interface has been created for this group */
    1219         276 :         msg = dbus_message_new_signal(parent->dbus_new_path,
    1220             :                                       WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    1221             :                                       "GroupStarted");
    1222         276 :         if (msg == NULL)
    1223           0 :                 return;
    1224             : 
    1225         276 :         dbus_message_iter_init_append(msg, &iter);
    1226             :         /*
    1227             :          * In case the device supports creating a separate interface the
    1228             :          * DBus client will need to know the object path for the interface
    1229             :          * object this group was created on, so include it here.
    1230             :          */
    1231         552 :         if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
    1232         276 :             !wpa_dbus_dict_append_object_path(&dict_iter,
    1233             :                                               "interface_object",
    1234         552 :                                               wpa_s->dbus_new_path) ||
    1235         276 :             !wpa_dbus_dict_append_string(&dict_iter, "role",
    1236         276 :                                          client ? "client" : "GO") ||
    1237         276 :             !wpa_dbus_dict_append_object_path(&dict_iter, "group_object",
    1238         552 :                                               wpa_s->dbus_groupobj_path) ||
    1239         276 :             !wpa_dbus_dict_close_write(&iter, &dict_iter)) {
    1240           0 :                 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
    1241             :         } else {
    1242         276 :                 dbus_connection_send(iface->con, msg, NULL);
    1243         276 :                 if (client)
    1244          35 :                         peer_groups_changed(wpa_s);
    1245             :         }
    1246         276 :         dbus_message_unref(msg);
    1247             : }
    1248             : 
    1249             : 
    1250             : /**
    1251             :  *
    1252             :  * Method to emit GONegotiation Success or Failure signals based
    1253             :  * on status.
    1254             :  * @status: Status of the GO neg request. 0 for success, other for errors.
    1255             :  */
    1256         230 : void wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s,
    1257             :                                       struct p2p_go_neg_results *res)
    1258             : {
    1259             :         DBusMessage *msg;
    1260             :         DBusMessageIter iter, dict_iter;
    1261             :         DBusMessageIter iter_dict_entry, iter_dict_val, iter_dict_array;
    1262             :         struct wpas_dbus_priv *iface;
    1263             :         char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
    1264             :         dbus_int32_t freqs[P2P_MAX_CHANNELS];
    1265         230 :         dbus_int32_t *f_array = freqs;
    1266             : 
    1267             : 
    1268         230 :         iface = wpa_s->global->dbus;
    1269             : 
    1270         230 :         if (wpa_s->p2p_mgmt)
    1271           4 :                 wpa_s = wpa_s->parent;
    1272             : 
    1273         230 :         os_memset(freqs, 0, sizeof(freqs));
    1274             :         /* Do nothing if the control interface is not turned on */
    1275         230 :         if (iface == NULL)
    1276         246 :                 return;
    1277             : 
    1278         642 :         os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
    1279             :                     "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
    1280         642 :                     wpa_s->dbus_new_path, MAC2STR(res->peer_device_addr));
    1281         107 :         path = peer_obj_path;
    1282             : 
    1283         107 :         msg = dbus_message_new_signal(wpa_s->dbus_new_path,
    1284             :                                       WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    1285         107 :                                       res->status ? "GONegotiationFailure" :
    1286             :                                                     "GONegotiationSuccess");
    1287         107 :         if (msg == NULL)
    1288           0 :                 return;
    1289             : 
    1290         107 :         dbus_message_iter_init_append(msg, &iter);
    1291         214 :         if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
    1292         107 :             !wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
    1293         107 :                                               path) ||
    1294         107 :             !wpa_dbus_dict_append_int32(&dict_iter, "status", res->status))
    1295             :                 goto err;
    1296             : 
    1297         107 :         if (!res->status) {
    1298          99 :                 int i = 0;
    1299          99 :                 int freq_list_num = 0;
    1300             : 
    1301         171 :                 if ((res->role_go &&
    1302          72 :                      !wpa_dbus_dict_append_string(&dict_iter, "passphrase",
    1303         171 :                                                   res->passphrase)) ||
    1304          99 :                     !wpa_dbus_dict_append_string(&dict_iter, "role_go",
    1305          99 :                                                  res->role_go ? "GO" :
    1306          99 :                                                  "client") ||
    1307          99 :                     !wpa_dbus_dict_append_int32(&dict_iter, "frequency",
    1308          99 :                                                 res->freq) ||
    1309         198 :                     !wpa_dbus_dict_append_byte_array(&dict_iter, "ssid",
    1310          99 :                                                      (const char *) res->ssid,
    1311         198 :                                                      res->ssid_len) ||
    1312          99 :                     !wpa_dbus_dict_append_byte_array(&dict_iter,
    1313             :                                                      "peer_device_addr",
    1314             :                                                      (const char *)
    1315          99 :                                                      res->peer_device_addr,
    1316          99 :                                                      ETH_ALEN) ||
    1317          99 :                     !wpa_dbus_dict_append_byte_array(&dict_iter,
    1318             :                                                      "peer_interface_addr",
    1319             :                                                      (const char *)
    1320          99 :                                                      res->peer_interface_addr,
    1321          99 :                                                      ETH_ALEN) ||
    1322          99 :                     !wpa_dbus_dict_append_string(&dict_iter, "wps_method",
    1323             :                                                  p2p_wps_method_text(
    1324             :                                                          res->wps_method)))
    1325             :                         goto err;
    1326             : 
    1327        5049 :                 for (i = 0; i < P2P_MAX_CHANNELS; i++) {
    1328        4950 :                         if (res->freq_list[i]) {
    1329         952 :                                 freqs[i] = res->freq_list[i];
    1330         952 :                                 freq_list_num++;
    1331             :                         }
    1332             :                 }
    1333             : 
    1334          99 :                 if (!wpa_dbus_dict_begin_array(&dict_iter,
    1335             :                                                "frequency_list",
    1336             :                                                DBUS_TYPE_INT32_AS_STRING,
    1337             :                                                &iter_dict_entry,
    1338             :                                                &iter_dict_val,
    1339          99 :                                                &iter_dict_array) ||
    1340          99 :                     !dbus_message_iter_append_fixed_array(&iter_dict_array,
    1341             :                                                           DBUS_TYPE_INT32,
    1342             :                                                           &f_array,
    1343          99 :                                                           freq_list_num) ||
    1344          99 :                     !wpa_dbus_dict_end_array(&dict_iter,
    1345             :                                              &iter_dict_entry,
    1346             :                                              &iter_dict_val,
    1347          99 :                                              &iter_dict_array) ||
    1348          99 :                     !wpa_dbus_dict_append_int32(&dict_iter, "persistent_group",
    1349          99 :                                                 res->persistent_group) ||
    1350          99 :                     !wpa_dbus_dict_append_uint32(&dict_iter,
    1351             :                                                  "peer_config_timeout",
    1352             :                                                  res->peer_config_timeout))
    1353             :                         goto err;
    1354             :         }
    1355             : 
    1356         107 :         if (!wpa_dbus_dict_close_write(&iter, &dict_iter))
    1357           0 :                 goto err;
    1358             : 
    1359         107 :         dbus_connection_send(iface->con, msg, NULL);
    1360             : err:
    1361         107 :         dbus_message_unref(msg);
    1362             : }
    1363             : 
    1364             : 
    1365             : /**
    1366             :  *
    1367             :  * Method to emit Invitation Result signal based on status and
    1368             :  * bssid
    1369             :  * @status: Status of the Invite request. 0 for success, other
    1370             :  * for errors
    1371             :  * @bssid : Basic Service Set Identifier
    1372             :  */
    1373          41 : void wpas_dbus_signal_p2p_invitation_result(struct wpa_supplicant *wpa_s,
    1374             :                                             int status, const u8 *bssid)
    1375             : {
    1376             :         DBusMessage *msg;
    1377             :         DBusMessageIter iter, dict_iter;
    1378             :         struct wpas_dbus_priv *iface;
    1379             : 
    1380          41 :         wpa_printf(MSG_DEBUG, "%s", __func__);
    1381             : 
    1382          41 :         iface = wpa_s->global->dbus;
    1383             :         /* Do nothing if the control interface is not turned on */
    1384          41 :         if (iface == NULL)
    1385          30 :                 return;
    1386             : 
    1387          26 :         if (wpa_s->p2p_mgmt)
    1388           0 :                 wpa_s = wpa_s->parent;
    1389             : 
    1390          26 :         msg = dbus_message_new_signal(wpa_s->dbus_new_path,
    1391             :                                       WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    1392             :                                       "InvitationResult");
    1393             : 
    1394          26 :         if (msg == NULL)
    1395           0 :                 return;
    1396             : 
    1397          26 :         dbus_message_iter_init_append(msg, &iter);
    1398          52 :         if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
    1399          52 :             !wpa_dbus_dict_append_int32(&dict_iter, "status", status) ||
    1400           0 :             (bssid &&
    1401           0 :              !wpa_dbus_dict_append_byte_array(&dict_iter, "BSSID",
    1402             :                                               (const char *) bssid,
    1403          26 :                                               ETH_ALEN)) ||
    1404          26 :             !wpa_dbus_dict_close_write(&iter, &dict_iter))
    1405           0 :                 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
    1406             :         else
    1407          26 :                 dbus_connection_send(iface->con, msg, NULL);
    1408          26 :         dbus_message_unref(msg);
    1409             : }
    1410             : 
    1411             : 
    1412             : /**
    1413             :  *
    1414             :  * Method to emit a signal for a peer joining the group.
    1415             :  * The signal will carry path to the group member object
    1416             :  * constructed using p2p i/f addr used for connecting.
    1417             :  *
    1418             :  * @wpa_s: %wpa_supplicant network interface data
    1419             :  * @peer_addr: P2P Device Address of the peer joining the group
    1420             :  */
    1421         191 : void wpas_dbus_signal_p2p_peer_joined(struct wpa_supplicant *wpa_s,
    1422             :                                       const u8 *peer_addr)
    1423             : {
    1424             :         struct wpas_dbus_priv *iface;
    1425             :         DBusMessage *msg;
    1426             :         DBusMessageIter iter;
    1427             :         char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
    1428             :         struct wpa_supplicant *parent;
    1429             : 
    1430         191 :         iface = wpa_s->global->dbus;
    1431             : 
    1432             :         /* Do nothing if the control interface is not turned on */
    1433         191 :         if (iface == NULL)
    1434          82 :                 return;
    1435             : 
    1436         150 :         if (!wpa_s->dbus_groupobj_path)
    1437           0 :                 return;
    1438             : 
    1439         150 :         parent = wpa_s->parent;
    1440         150 :         if (parent->p2p_mgmt)
    1441           0 :                 parent = parent->parent;
    1442             : 
    1443         900 :         os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
    1444             :                         "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
    1445             :                         COMPACT_MACSTR,
    1446         900 :                         parent->dbus_new_path, MAC2STR(peer_addr));
    1447             : 
    1448         150 :         msg = dbus_message_new_signal(wpa_s->dbus_groupobj_path,
    1449             :                                       WPAS_DBUS_NEW_IFACE_P2P_GROUP,
    1450             :                                       "PeerJoined");
    1451         150 :         if (msg == NULL)
    1452           0 :                 return;
    1453             : 
    1454         150 :         dbus_message_iter_init_append(msg, &iter);
    1455         150 :         path = peer_obj_path;
    1456         150 :         if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
    1457             :                                             &path)) {
    1458           0 :                 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
    1459             :         } else {
    1460         150 :                 dbus_connection_send(iface->con, msg, NULL);
    1461         150 :                 wpas_dbus_signal_peer_groups_changed(parent, peer_addr);
    1462             :         }
    1463         150 :         dbus_message_unref(msg);
    1464             : }
    1465             : 
    1466             : 
    1467             : /**
    1468             :  *
    1469             :  * Method to emit a signal for a peer disconnecting the group.
    1470             :  * The signal will carry path to the group member object
    1471             :  * constructed using the P2P Device Address of the peer.
    1472             :  *
    1473             :  * @wpa_s: %wpa_supplicant network interface data
    1474             :  * @peer_addr: P2P Device Address of the peer joining the group
    1475             :  */
    1476         191 : void wpas_dbus_signal_p2p_peer_disconnected(struct wpa_supplicant *wpa_s,
    1477             :                                             const u8 *peer_addr)
    1478             : {
    1479             :         struct wpas_dbus_priv *iface;
    1480             :         DBusMessage *msg;
    1481             :         DBusMessageIter iter;
    1482             :         char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
    1483             :         struct wpa_supplicant *parent;
    1484             : 
    1485         191 :         iface = wpa_s->global->dbus;
    1486             : 
    1487             :         /* Do nothing if the control interface is not turned on */
    1488         191 :         if (iface == NULL)
    1489         208 :                 return;
    1490             : 
    1491         150 :         if (!wpa_s->dbus_groupobj_path)
    1492         126 :                 return;
    1493             : 
    1494          24 :         parent = wpa_s->parent;
    1495          24 :         if (parent->p2p_mgmt)
    1496           0 :                 parent = parent->parent;
    1497             : 
    1498         144 :         os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
    1499             :                         "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
    1500             :                         COMPACT_MACSTR,
    1501         144 :                         parent->dbus_new_path, MAC2STR(peer_addr));
    1502             : 
    1503          24 :         msg = dbus_message_new_signal(wpa_s->dbus_groupobj_path,
    1504             :                                       WPAS_DBUS_NEW_IFACE_P2P_GROUP,
    1505             :                                       "PeerDisconnected");
    1506          24 :         if (msg == NULL)
    1507           0 :                 return;
    1508             : 
    1509          24 :         dbus_message_iter_init_append(msg, &iter);
    1510          24 :         path = peer_obj_path;
    1511          24 :         if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
    1512             :                                             &path)) {
    1513           0 :                 wpa_printf(MSG_ERROR,
    1514             :                            "dbus: Failed to construct PeerDisconnected signal");
    1515             :         } else {
    1516          24 :                 dbus_connection_send(iface->con, msg, NULL);
    1517          24 :                 wpas_dbus_signal_peer_groups_changed(parent, peer_addr);
    1518             :         }
    1519          24 :         dbus_message_unref(msg);
    1520             : }
    1521             : 
    1522             : 
    1523             : /**
    1524             :  *
    1525             :  * Method to emit a signal for a service discovery request.
    1526             :  * The signal will carry station address, frequency, dialog token,
    1527             :  * update indicator and it tlvs
    1528             :  *
    1529             :  * @wpa_s: %wpa_supplicant network interface data
    1530             :  * @sa: station addr (p2p i/f) of the peer
    1531             :  * @dialog_token: service discovery request dialog token
    1532             :  * @update_indic: service discovery request update indicator
    1533             :  * @tlvs: service discovery request genrated byte array of tlvs
    1534             :  * @tlvs_len: service discovery request tlvs length
    1535             :  */
    1536          60 : void wpas_dbus_signal_p2p_sd_request(struct wpa_supplicant *wpa_s,
    1537             :                                      int freq, const u8 *sa, u8 dialog_token,
    1538             :                                      u16 update_indic, const u8 *tlvs,
    1539             :                                      size_t tlvs_len)
    1540             : {
    1541             :         DBusMessage *msg;
    1542             :         DBusMessageIter iter, dict_iter;
    1543             :         struct wpas_dbus_priv *iface;
    1544             :         char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
    1545             : 
    1546          60 :         iface = wpa_s->global->dbus;
    1547             : 
    1548             :         /* Do nothing if the control interface is not turned on */
    1549          60 :         if (iface == NULL)
    1550          12 :                 return;
    1551             : 
    1552          54 :         if (wpa_s->p2p_mgmt)
    1553           0 :                 wpa_s = wpa_s->parent;
    1554             : 
    1555             :         /* Check if this is a known peer */
    1556          54 :         if (!p2p_peer_known(wpa_s->global->p2p, sa))
    1557           0 :                 return;
    1558             : 
    1559          54 :         msg = dbus_message_new_signal(wpa_s->dbus_new_path,
    1560             :                                       WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    1561             :                                       "ServiceDiscoveryRequest");
    1562          54 :         if (msg == NULL)
    1563           0 :                 return;
    1564             : 
    1565         324 :         os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
    1566             :                     "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
    1567         324 :                     COMPACT_MACSTR, wpa_s->dbus_new_path, MAC2STR(sa));
    1568             : 
    1569          54 :         path = peer_obj_path;
    1570             : 
    1571          54 :         dbus_message_iter_init_append(msg, &iter);
    1572         108 :         if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
    1573          54 :             !wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
    1574          54 :                                               path) ||
    1575         108 :             !wpa_dbus_dict_append_int32(&dict_iter, "frequency", freq) ||
    1576          54 :             !wpa_dbus_dict_append_int32(&dict_iter, "dialog_token",
    1577          54 :                                         dialog_token) ||
    1578          54 :             !wpa_dbus_dict_append_uint16(&dict_iter, "update_indicator",
    1579          54 :                                          update_indic) ||
    1580          54 :             !wpa_dbus_dict_append_byte_array(&dict_iter, "tlvs",
    1581             :                                              (const char *) tlvs,
    1582          54 :                                              tlvs_len) ||
    1583          54 :             !wpa_dbus_dict_close_write(&iter, &dict_iter))
    1584           0 :                 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
    1585             :         else
    1586          54 :                 dbus_connection_send(iface->con, msg, NULL);
    1587          54 :         dbus_message_unref(msg);
    1588             : }
    1589             : 
    1590             : 
    1591             : /**
    1592             :  *
    1593             :  * Method to emit a signal for a service discovery response.
    1594             :  * The signal will carry station address, update indicator and it
    1595             :  * tlvs
    1596             :  *
    1597             :  * @wpa_s: %wpa_supplicant network interface data
    1598             :  * @sa: station addr (p2p i/f) of the peer
    1599             :  * @update_indic: service discovery request update indicator
    1600             :  * @tlvs: service discovery request genrated byte array of tlvs
    1601             :  * @tlvs_len: service discovery request tlvs length
    1602             :  */
    1603          60 : void wpas_dbus_signal_p2p_sd_response(struct wpa_supplicant *wpa_s,
    1604             :                                       const u8 *sa, u16 update_indic,
    1605             :                                       const u8 *tlvs, size_t tlvs_len)
    1606             : {
    1607             :         DBusMessage *msg;
    1608             :         DBusMessageIter iter, dict_iter;
    1609             :         struct wpas_dbus_priv *iface;
    1610             :         char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
    1611             : 
    1612          60 :         iface = wpa_s->global->dbus;
    1613             : 
    1614             :         /* Do nothing if the control interface is not turned on */
    1615          60 :         if (iface == NULL)
    1616         118 :                 return;
    1617             : 
    1618           1 :         if (wpa_s->p2p_mgmt)
    1619           0 :                 wpa_s = wpa_s->parent;
    1620             : 
    1621             :         /* Check if this is a known peer */
    1622           1 :         if (!p2p_peer_known(wpa_s->global->p2p, sa))
    1623           0 :                 return;
    1624             : 
    1625           1 :         msg = dbus_message_new_signal(wpa_s->dbus_new_path,
    1626             :                                       WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    1627             :                                       "ServiceDiscoveryResponse");
    1628           1 :         if (msg == NULL)
    1629           0 :                 return;
    1630             : 
    1631           6 :         os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
    1632             :                     "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
    1633           6 :                     COMPACT_MACSTR, wpa_s->dbus_new_path, MAC2STR(sa));
    1634             : 
    1635           1 :         path = peer_obj_path;
    1636             : 
    1637           1 :         dbus_message_iter_init_append(msg, &iter);
    1638           2 :         if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
    1639           1 :             !wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
    1640           1 :                                               path) ||
    1641           1 :             !wpa_dbus_dict_append_uint16(&dict_iter, "update_indicator",
    1642           1 :                                          update_indic) ||
    1643           1 :             !wpa_dbus_dict_append_byte_array(&dict_iter, "tlvs",
    1644             :                                              (const char *) tlvs,
    1645           1 :                                              tlvs_len) ||
    1646           1 :             !wpa_dbus_dict_close_write(&iter, &dict_iter))
    1647           0 :                 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
    1648             :         else
    1649           1 :                 dbus_connection_send(iface->con, msg, NULL);
    1650           1 :         dbus_message_unref(msg);
    1651             : }
    1652             : 
    1653             : 
    1654             : /**
    1655             :  * wpas_dbus_signal_persistent_group - Send a persistent group related
    1656             :  *      event signal
    1657             :  * @wpa_s: %wpa_supplicant network interface data
    1658             :  * @id: new persistent group id
    1659             :  * @sig_name: signal name - PersistentGroupAdded, PersistentGroupRemoved
    1660             :  * @properties: determines if add second argument with object properties
    1661             :  *
    1662             :  * Notify listeners about an event related to persistent groups.
    1663             :  */
    1664          86 : static void wpas_dbus_signal_persistent_group(struct wpa_supplicant *wpa_s,
    1665             :                                               int id, const char *sig_name,
    1666             :                                               int properties)
    1667             : {
    1668             :         struct wpas_dbus_priv *iface;
    1669             :         DBusMessage *msg;
    1670             :         DBusMessageIter iter;
    1671             :         char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
    1672             : 
    1673          86 :         iface = wpa_s->global->dbus;
    1674             : 
    1675             :         /* Do nothing if the control interface is not turned on */
    1676          86 :         if (iface == NULL)
    1677           0 :                 return;
    1678             : 
    1679          86 :         if (wpa_s->p2p_mgmt)
    1680           0 :                 wpa_s = wpa_s->parent;
    1681             : 
    1682          86 :         os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
    1683             :                     "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
    1684             :                     wpa_s->dbus_new_path, id);
    1685             : 
    1686          86 :         msg = dbus_message_new_signal(wpa_s->dbus_new_path,
    1687             :                                       WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    1688             :                                       sig_name);
    1689          86 :         if (msg == NULL)
    1690           0 :                 return;
    1691             : 
    1692          86 :         dbus_message_iter_init_append(msg, &iter);
    1693          86 :         path = pgrp_obj_path;
    1694          86 :         if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
    1695          86 :                                             &path) ||
    1696          41 :             (properties &&
    1697          41 :              !wpa_dbus_get_object_properties(
    1698             :                      iface, pgrp_obj_path,
    1699             :                      WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, &iter)))
    1700           0 :                 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
    1701             :         else
    1702          86 :                 dbus_connection_send(iface->con, msg, NULL);
    1703             : 
    1704          86 :         dbus_message_unref(msg);
    1705             : }
    1706             : 
    1707             : 
    1708             : /**
    1709             :  * wpas_dbus_signal_persistent_group_added - Send a persistent_group
    1710             :  *      added signal
    1711             :  * @wpa_s: %wpa_supplicant network interface data
    1712             :  * @id: new persistent group id
    1713             :  *
    1714             :  * Notify listeners about addition of a new persistent group.
    1715             :  */
    1716          41 : static void wpas_dbus_signal_persistent_group_added(
    1717             :         struct wpa_supplicant *wpa_s, int id)
    1718             : {
    1719          41 :         wpas_dbus_signal_persistent_group(wpa_s, id, "PersistentGroupAdded",
    1720             :                                           TRUE);
    1721          41 : }
    1722             : 
    1723             : 
    1724             : /**
    1725             :  * wpas_dbus_signal_persistent_group_removed - Send a persistent_group
    1726             :  *      removed signal
    1727             :  * @wpa_s: %wpa_supplicant network interface data
    1728             :  * @id: persistent group id
    1729             :  *
    1730             :  * Notify listeners about removal of a persistent group.
    1731             :  */
    1732          45 : static void wpas_dbus_signal_persistent_group_removed(
    1733             :         struct wpa_supplicant *wpa_s, int id)
    1734             : {
    1735          45 :         wpas_dbus_signal_persistent_group(wpa_s, id, "PersistentGroupRemoved",
    1736             :                                           FALSE);
    1737          45 : }
    1738             : 
    1739             : 
    1740             : /**
    1741             :  * wpas_dbus_signal_p2p_wps_failed - Signals WpsFailed event
    1742             :  * @wpa_s: %wpa_supplicant network interface data
    1743             :  *
    1744             :  * Sends Event dbus signal with name "fail" and dictionary containing
    1745             :  * "msg" field with fail message number (int32) as arguments
    1746             :  */
    1747           5 : void wpas_dbus_signal_p2p_wps_failed(struct wpa_supplicant *wpa_s,
    1748             :                                      struct wps_event_fail *fail)
    1749             : {
    1750             : 
    1751             :         DBusMessage *msg;
    1752             :         DBusMessageIter iter, dict_iter;
    1753             :         struct wpas_dbus_priv *iface;
    1754           5 :         char *key = "fail";
    1755             : 
    1756           5 :         iface = wpa_s->global->dbus;
    1757             : 
    1758             :         /* Do nothing if the control interface is not turned on */
    1759           5 :         if (iface == NULL)
    1760           6 :                 return;
    1761             : 
    1762           2 :         if (wpa_s->p2p_mgmt)
    1763           0 :                 wpa_s = wpa_s->parent;
    1764             : 
    1765           2 :         msg = dbus_message_new_signal(wpa_s->dbus_new_path,
    1766             :                                       WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    1767             :                                       "WpsFailed");
    1768           2 :         if (msg == NULL)
    1769           0 :                 return;
    1770             : 
    1771           2 :         dbus_message_iter_init_append(msg, &iter);
    1772             : 
    1773           4 :         if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
    1774           4 :             !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
    1775           4 :             !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
    1776           2 :             !wpa_dbus_dict_append_int16(&dict_iter, "config_error",
    1777           4 :                                         fail->config_error) ||
    1778           2 :             !wpa_dbus_dict_close_write(&iter, &dict_iter))
    1779           0 :                 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
    1780             :         else
    1781           2 :                 dbus_connection_send(iface->con, msg, NULL);
    1782             : 
    1783           2 :         dbus_message_unref(msg);
    1784             : }
    1785             : 
    1786             : #endif /* CONFIG_P2P */
    1787             : 
    1788             : 
    1789             : /**
    1790             :  * wpas_dbus_signal_prop_changed - Signals change of property
    1791             :  * @wpa_s: %wpa_supplicant network interface data
    1792             :  * @property: indicates which property has changed
    1793             :  *
    1794             :  * Sends PropertyChanged signals with path, interface and arguments
    1795             :  * depending on which property has changed.
    1796             :  */
    1797       37858 : void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
    1798             :                                    enum wpas_dbus_prop property)
    1799             : {
    1800             :         char *prop;
    1801             :         dbus_bool_t flush;
    1802             : 
    1803       37858 :         if (wpa_s->dbus_new_path == NULL)
    1804        9981 :                 return; /* Skip signal since D-Bus setup is not yet ready */
    1805             : 
    1806       27877 :         flush = FALSE;
    1807       27877 :         switch (property) {
    1808             :         case WPAS_DBUS_PROP_AP_SCAN:
    1809           8 :                 prop = "ApScan";
    1810           8 :                 break;
    1811             :         case WPAS_DBUS_PROP_SCANNING:
    1812        2730 :                 prop = "Scanning";
    1813        2730 :                 break;
    1814             :         case WPAS_DBUS_PROP_STATE:
    1815       13441 :                 prop = "State";
    1816       13441 :                 break;
    1817             :         case WPAS_DBUS_PROP_CURRENT_BSS:
    1818        3890 :                 prop = "CurrentBSS";
    1819        3890 :                 break;
    1820             :         case WPAS_DBUS_PROP_CURRENT_NETWORK:
    1821         569 :                 prop = "CurrentNetwork";
    1822         569 :                 break;
    1823             :         case WPAS_DBUS_PROP_BSSS:
    1824        2114 :                 prop = "BSSs";
    1825        2114 :                 break;
    1826             :         case WPAS_DBUS_PROP_CURRENT_AUTH_MODE:
    1827        3454 :                 prop = "CurrentAuthMode";
    1828        3454 :                 break;
    1829             :         case WPAS_DBUS_PROP_DISCONNECT_REASON:
    1830        1671 :                 prop = "DisconnectReason";
    1831        1671 :                 flush = TRUE;
    1832        1671 :                 break;
    1833             :         default:
    1834           0 :                 wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
    1835             :                            __func__, property);
    1836           0 :                 return;
    1837             :         }
    1838             : 
    1839       27877 :         wpa_dbus_mark_property_changed(wpa_s->global->dbus,
    1840       27877 :                                        wpa_s->dbus_new_path,
    1841             :                                        WPAS_DBUS_NEW_IFACE_INTERFACE, prop);
    1842       27877 :         if (flush) {
    1843        1671 :                 wpa_dbus_flush_object_changed_properties(
    1844        1671 :                         wpa_s->global->dbus->con, wpa_s->dbus_new_path);
    1845             :         }
    1846             : }
    1847             : 
    1848             : 
    1849             : /**
    1850             :  * wpas_dbus_bss_signal_prop_changed - Signals change of BSS property
    1851             :  * @wpa_s: %wpa_supplicant network interface data
    1852             :  * @property: indicates which property has changed
    1853             :  * @id: unique BSS identifier
    1854             :  *
    1855             :  * Sends PropertyChanged signals with path, interface, and arguments depending
    1856             :  * on which property has changed.
    1857             :  */
    1858        1322 : void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant *wpa_s,
    1859             :                                        enum wpas_dbus_bss_prop property,
    1860             :                                        unsigned int id)
    1861             : {
    1862             :         char path[WPAS_DBUS_OBJECT_PATH_MAX];
    1863             :         char *prop;
    1864             : 
    1865        1322 :         switch (property) {
    1866             :         case WPAS_DBUS_BSS_PROP_SIGNAL:
    1867           0 :                 prop = "Signal";
    1868           0 :                 break;
    1869             :         case WPAS_DBUS_BSS_PROP_FREQ:
    1870          10 :                 prop = "Frequency";
    1871          10 :                 break;
    1872             :         case WPAS_DBUS_BSS_PROP_MODE:
    1873           0 :                 prop = "Mode";
    1874           0 :                 break;
    1875             :         case WPAS_DBUS_BSS_PROP_PRIVACY:
    1876           9 :                 prop = "Privacy";
    1877           9 :                 break;
    1878             :         case WPAS_DBUS_BSS_PROP_RATES:
    1879           0 :                 prop = "Rates";
    1880           0 :                 break;
    1881             :         case WPAS_DBUS_BSS_PROP_WPA:
    1882           9 :                 prop = "WPA";
    1883           9 :                 break;
    1884             :         case WPAS_DBUS_BSS_PROP_RSN:
    1885          10 :                 prop = "RSN";
    1886          10 :                 break;
    1887             :         case WPAS_DBUS_BSS_PROP_WPS:
    1888          65 :                 prop = "WPS";
    1889          65 :                 break;
    1890             :         case WPAS_DBUS_BSS_PROP_IES:
    1891          85 :                 prop = "IEs";
    1892          85 :                 break;
    1893             :         case WPAS_DBUS_BSS_PROP_AGE:
    1894        1134 :                 prop = "Age";
    1895        1134 :                 break;
    1896             :         default:
    1897           0 :                 wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
    1898             :                            __func__, property);
    1899        1322 :                 return;
    1900             :         }
    1901             : 
    1902        1322 :         os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
    1903             :                     "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
    1904             :                     wpa_s->dbus_new_path, id);
    1905             : 
    1906        1322 :         wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
    1907             :                                        WPAS_DBUS_NEW_IFACE_BSS, prop);
    1908             : }
    1909             : 
    1910             : 
    1911             : /**
    1912             :  * wpas_dbus_signal_debug_level_changed - Signals change of debug param
    1913             :  * @global: wpa_global structure
    1914             :  *
    1915             :  * Sends PropertyChanged signals informing that debug level has changed.
    1916             :  */
    1917           2 : void wpas_dbus_signal_debug_level_changed(struct wpa_global *global)
    1918             : {
    1919           2 :         wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
    1920             :                                        WPAS_DBUS_NEW_INTERFACE,
    1921             :                                        "DebugLevel");
    1922           2 : }
    1923             : 
    1924             : 
    1925             : /**
    1926             :  * wpas_dbus_signal_debug_timestamp_changed - Signals change of debug param
    1927             :  * @global: wpa_global structure
    1928             :  *
    1929             :  * Sends PropertyChanged signals informing that debug timestamp has changed.
    1930             :  */
    1931           2 : void wpas_dbus_signal_debug_timestamp_changed(struct wpa_global *global)
    1932             : {
    1933           2 :         wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
    1934             :                                        WPAS_DBUS_NEW_INTERFACE,
    1935             :                                        "DebugTimestamp");
    1936           2 : }
    1937             : 
    1938             : 
    1939             : /**
    1940             :  * wpas_dbus_signal_debug_show_keys_changed - Signals change of debug param
    1941             :  * @global: wpa_global structure
    1942             :  *
    1943             :  * Sends PropertyChanged signals informing that debug show_keys has changed.
    1944             :  */
    1945           2 : void wpas_dbus_signal_debug_show_keys_changed(struct wpa_global *global)
    1946             : {
    1947           2 :         wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
    1948             :                                        WPAS_DBUS_NEW_INTERFACE,
    1949             :                                        "DebugShowKeys");
    1950           2 : }
    1951             : 
    1952             : 
    1953        4105 : static void wpas_dbus_register(struct wpa_dbus_object_desc *obj_desc,
    1954             :                                void *priv,
    1955             :                                WPADBusArgumentFreeFunction priv_free,
    1956             :                                const struct wpa_dbus_method_desc *methods,
    1957             :                                const struct wpa_dbus_property_desc *properties,
    1958             :                                const struct wpa_dbus_signal_desc *signals)
    1959             : {
    1960             :         int n;
    1961             : 
    1962        4105 :         obj_desc->user_data = priv;
    1963        4105 :         obj_desc->user_data_free_func = priv_free;
    1964        4105 :         obj_desc->methods = methods;
    1965        4105 :         obj_desc->properties = properties;
    1966        4105 :         obj_desc->signals = signals;
    1967             : 
    1968       29868 :         for (n = 0; properties && properties->dbus_property; properties++)
    1969       25763 :                 n++;
    1970             : 
    1971        4105 :         obj_desc->prop_changed_flags = os_zalloc(n);
    1972        4105 :         if (!obj_desc->prop_changed_flags)
    1973           1 :                 wpa_printf(MSG_DEBUG, "dbus: %s: can't register handlers",
    1974             :                            __func__);
    1975        4105 : }
    1976             : 
    1977             : 
    1978             : static const struct wpa_dbus_method_desc wpas_dbus_global_methods[] = {
    1979             :         { "CreateInterface", WPAS_DBUS_NEW_INTERFACE,
    1980             :           (WPADBusMethodHandler) wpas_dbus_handler_create_interface,
    1981             :           {
    1982             :                   { "args", "a{sv}", ARG_IN },
    1983             :                   { "path", "o", ARG_OUT },
    1984             :                   END_ARGS
    1985             :           }
    1986             :         },
    1987             :         { "RemoveInterface", WPAS_DBUS_NEW_INTERFACE,
    1988             :           (WPADBusMethodHandler) wpas_dbus_handler_remove_interface,
    1989             :           {
    1990             :                   { "path", "o", ARG_IN },
    1991             :                   END_ARGS
    1992             :           }
    1993             :         },
    1994             :         { "GetInterface", WPAS_DBUS_NEW_INTERFACE,
    1995             :           (WPADBusMethodHandler) wpas_dbus_handler_get_interface,
    1996             :           {
    1997             :                   { "ifname", "s", ARG_IN },
    1998             :                   { "path", "o", ARG_OUT },
    1999             :                   END_ARGS
    2000             :           }
    2001             :         },
    2002             :         { NULL, NULL, NULL, { END_ARGS } }
    2003             : };
    2004             : 
    2005             : static const struct wpa_dbus_property_desc wpas_dbus_global_properties[] = {
    2006             :         { "DebugLevel", WPAS_DBUS_NEW_INTERFACE, "s",
    2007             :           wpas_dbus_getter_debug_level,
    2008             :           wpas_dbus_setter_debug_level
    2009             :         },
    2010             :         { "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE, "b",
    2011             :           wpas_dbus_getter_debug_timestamp,
    2012             :           wpas_dbus_setter_debug_timestamp
    2013             :         },
    2014             :         { "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE, "b",
    2015             :           wpas_dbus_getter_debug_show_keys,
    2016             :           wpas_dbus_setter_debug_show_keys
    2017             :         },
    2018             :         { "Interfaces", WPAS_DBUS_NEW_INTERFACE, "ao",
    2019             :           wpas_dbus_getter_interfaces,
    2020             :           NULL
    2021             :         },
    2022             :         { "EapMethods", WPAS_DBUS_NEW_INTERFACE, "as",
    2023             :           wpas_dbus_getter_eap_methods,
    2024             :           NULL
    2025             :         },
    2026             :         { "Capabilities", WPAS_DBUS_NEW_INTERFACE, "as",
    2027             :           wpas_dbus_getter_global_capabilities,
    2028             :           NULL
    2029             :         },
    2030             : #ifdef CONFIG_WIFI_DISPLAY
    2031             :         { "WFDIEs", WPAS_DBUS_NEW_INTERFACE, "ay",
    2032             :           wpas_dbus_getter_global_wfd_ies,
    2033             :           wpas_dbus_setter_global_wfd_ies
    2034             :         },
    2035             : #endif /* CONFIG_WIFI_DISPLAY */
    2036             :         { NULL, NULL, NULL, NULL, NULL }
    2037             : };
    2038             : 
    2039             : static const struct wpa_dbus_signal_desc wpas_dbus_global_signals[] = {
    2040             :         { "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE,
    2041             :           {
    2042             :                   { "path", "o", ARG_OUT },
    2043             :                   { "properties", "a{sv}", ARG_OUT },
    2044             :                   END_ARGS
    2045             :           }
    2046             :         },
    2047             :         { "InterfaceRemoved", WPAS_DBUS_NEW_INTERFACE,
    2048             :           {
    2049             :                   { "path", "o", ARG_OUT },
    2050             :                   END_ARGS
    2051             :           }
    2052             :         },
    2053             :         /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
    2054             :         { "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE,
    2055             :           {
    2056             :                   { "properties", "a{sv}", ARG_OUT },
    2057             :                   END_ARGS
    2058             :           }
    2059             :         },
    2060             :         { NULL, NULL, { END_ARGS } }
    2061             : };
    2062             : 
    2063             : 
    2064             : /**
    2065             :  * wpas_dbus_ctrl_iface_init - Initialize dbus control interface
    2066             :  * @global: Pointer to global data from wpa_supplicant_init()
    2067             :  * Returns: 0 on success or -1 on failure
    2068             :  *
    2069             :  * Initialize the dbus control interface for wpa_supplicantand and start
    2070             :  * receiving commands from external programs over the bus.
    2071             :  */
    2072           5 : int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv *priv)
    2073             : {
    2074             :         struct wpa_dbus_object_desc *obj_desc;
    2075             :         int ret;
    2076             : 
    2077           5 :         obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
    2078           5 :         if (!obj_desc) {
    2079           0 :                 wpa_printf(MSG_ERROR,
    2080             :                            "Not enough memory to create object description");
    2081           0 :                 return -1;
    2082             :         }
    2083             : 
    2084           5 :         wpas_dbus_register(obj_desc, priv->global, NULL,
    2085             :                            wpas_dbus_global_methods,
    2086             :                            wpas_dbus_global_properties,
    2087             :                            wpas_dbus_global_signals);
    2088             : 
    2089           5 :         wpa_printf(MSG_DEBUG, "dbus: Register D-Bus object '%s'",
    2090             :                    WPAS_DBUS_NEW_PATH);
    2091           5 :         ret = wpa_dbus_ctrl_iface_init(priv, WPAS_DBUS_NEW_PATH,
    2092             :                                        WPAS_DBUS_NEW_SERVICE,
    2093             :                                        obj_desc);
    2094           5 :         if (ret < 0)
    2095           0 :                 free_dbus_object_desc(obj_desc);
    2096             :         else
    2097           5 :                 priv->dbus_new_initialized = 1;
    2098             : 
    2099           5 :         return ret;
    2100             : }
    2101             : 
    2102             : 
    2103             : /**
    2104             :  * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for
    2105             :  * wpa_supplicant
    2106             :  * @iface: Pointer to dbus private data from wpas_dbus_init()
    2107             :  *
    2108             :  * Deinitialize the dbus control interface that was initialized with
    2109             :  * wpas_dbus_ctrl_iface_init().
    2110             :  */
    2111           5 : void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv *iface)
    2112             : {
    2113           5 :         if (!iface->dbus_new_initialized)
    2114           5 :                 return;
    2115           5 :         wpa_printf(MSG_DEBUG, "dbus: Unregister D-Bus object '%s'",
    2116             :                    WPAS_DBUS_NEW_PATH);
    2117           5 :         dbus_connection_unregister_object_path(iface->con,
    2118             :                                                WPAS_DBUS_NEW_PATH);
    2119             : }
    2120             : 
    2121             : 
    2122        3705 : static void wpa_dbus_free(void *ptr)
    2123             : {
    2124        3705 :         os_free(ptr);
    2125        3705 : }
    2126             : 
    2127             : 
    2128             : static const struct wpa_dbus_property_desc wpas_dbus_network_properties[] = {
    2129             :         { "Properties", WPAS_DBUS_NEW_IFACE_NETWORK, "a{sv}",
    2130             :           wpas_dbus_getter_network_properties,
    2131             :           wpas_dbus_setter_network_properties
    2132             :         },
    2133             :         { "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK, "b",
    2134             :           wpas_dbus_getter_enabled,
    2135             :           wpas_dbus_setter_enabled
    2136             :         },
    2137             :         { NULL, NULL, NULL, NULL, NULL }
    2138             : };
    2139             : 
    2140             : 
    2141             : static const struct wpa_dbus_signal_desc wpas_dbus_network_signals[] = {
    2142             :         /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
    2143             :         { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK,
    2144             :           {
    2145             :                   { "properties", "a{sv}", ARG_OUT },
    2146             :                   END_ARGS
    2147             :           }
    2148             :         },
    2149             :         { NULL, NULL, { END_ARGS } }
    2150             : };
    2151             : 
    2152             : 
    2153             : /**
    2154             :  * wpas_dbus_register_network - Register a configured network with dbus
    2155             :  * @wpa_s: wpa_supplicant interface structure
    2156             :  * @ssid: network configuration data
    2157             :  * Returns: 0 on success, -1 on failure
    2158             :  *
    2159             :  * Registers network representing object with dbus
    2160             :  */
    2161        2757 : int wpas_dbus_register_network(struct wpa_supplicant *wpa_s,
    2162             :                                struct wpa_ssid *ssid)
    2163             : {
    2164             :         struct wpas_dbus_priv *ctrl_iface;
    2165             :         struct wpa_dbus_object_desc *obj_desc;
    2166             :         struct network_handler_args *arg;
    2167             :         char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
    2168             : 
    2169             : #ifdef CONFIG_P2P
    2170             :         /*
    2171             :          * If it is a persistent group register it as such.
    2172             :          * This is to handle cases where an interface is being initialized
    2173             :          * with a list of networks read from config.
    2174             :          */
    2175        2757 :         if (network_is_persistent_group(ssid))
    2176           0 :                 return wpas_dbus_register_persistent_group(wpa_s, ssid);
    2177             : #endif /* CONFIG_P2P */
    2178             : 
    2179             :         /* Do nothing if the control interface is not turned on */
    2180        2757 :         if (wpa_s == NULL || wpa_s->global == NULL)
    2181           0 :                 return 0;
    2182        2757 :         ctrl_iface = wpa_s->global->dbus;
    2183        2757 :         if (ctrl_iface == NULL)
    2184         354 :                 return 0;
    2185             : 
    2186        2403 :         os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
    2187             :                     "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
    2188             :                     wpa_s->dbus_new_path, ssid->id);
    2189             : 
    2190        2403 :         wpa_printf(MSG_DEBUG, "dbus: Register network object '%s'",
    2191             :                    net_obj_path);
    2192        2403 :         obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
    2193        2403 :         if (!obj_desc) {
    2194           1 :                 wpa_printf(MSG_ERROR,
    2195             :                            "Not enough memory to create object description");
    2196           1 :                 goto err;
    2197             :         }
    2198             : 
    2199             :         /* allocate memory for handlers arguments */
    2200        2402 :         arg = os_zalloc(sizeof(struct network_handler_args));
    2201        2402 :         if (!arg) {
    2202           1 :                 wpa_printf(MSG_ERROR,
    2203             :                            "Not enough memory to create arguments for method");
    2204           1 :                 goto err;
    2205             :         }
    2206             : 
    2207        2401 :         arg->wpa_s = wpa_s;
    2208        2401 :         arg->ssid = ssid;
    2209             : 
    2210        2401 :         wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
    2211             :                            wpas_dbus_network_properties,
    2212             :                            wpas_dbus_network_signals);
    2213             : 
    2214        2401 :         if (wpa_dbus_register_object_per_iface(ctrl_iface, net_obj_path,
    2215        2401 :                                                wpa_s->ifname, obj_desc))
    2216           0 :                 goto err;
    2217             : 
    2218        2401 :         wpas_dbus_signal_network_added(wpa_s, ssid->id);
    2219             : 
    2220        2401 :         return 0;
    2221             : 
    2222             : err:
    2223           2 :         free_dbus_object_desc(obj_desc);
    2224           2 :         return -1;
    2225             : }
    2226             : 
    2227             : 
    2228             : /**
    2229             :  * wpas_dbus_unregister_network - Unregister a configured network from dbus
    2230             :  * @wpa_s: wpa_supplicant interface structure
    2231             :  * @nid: network id
    2232             :  * Returns: 0 on success, -1 on failure
    2233             :  *
    2234             :  * Unregisters network representing object from dbus
    2235             :  */
    2236        2758 : int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid)
    2237             : {
    2238             :         struct wpas_dbus_priv *ctrl_iface;
    2239             :         char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
    2240             :         int ret;
    2241             : #ifdef CONFIG_P2P
    2242             :         struct wpa_ssid *ssid;
    2243             : 
    2244        2758 :         ssid = wpa_config_get_network(wpa_s->conf, nid);
    2245             : 
    2246             :         /* If it is a persistent group unregister it as such */
    2247        2758 :         if (ssid && network_is_persistent_group(ssid))
    2248           1 :                 return wpas_dbus_unregister_persistent_group(wpa_s, nid);
    2249             : #endif /* CONFIG_P2P */
    2250             : 
    2251             :         /* Do nothing if the control interface is not turned on */
    2252        2757 :         if (wpa_s->global == NULL || wpa_s->dbus_new_path == NULL)
    2253         354 :                 return 0;
    2254        2403 :         ctrl_iface = wpa_s->global->dbus;
    2255        2403 :         if (ctrl_iface == NULL)
    2256           0 :                 return 0;
    2257             : 
    2258        2403 :         os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
    2259             :                     "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
    2260             :                     wpa_s->dbus_new_path, nid);
    2261             : 
    2262        2403 :         wpa_printf(MSG_DEBUG, "dbus: Unregister network object '%s'",
    2263             :                    net_obj_path);
    2264        2403 :         ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, net_obj_path);
    2265             : 
    2266        2403 :         if (!ret)
    2267        2403 :                 wpas_dbus_signal_network_removed(wpa_s, nid);
    2268             : 
    2269        2403 :         return ret;
    2270             : }
    2271             : 
    2272             : 
    2273             : static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = {
    2274             :         { "SSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
    2275             :           wpas_dbus_getter_bss_ssid,
    2276             :           NULL
    2277             :         },
    2278             :         { "BSSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
    2279             :           wpas_dbus_getter_bss_bssid,
    2280             :           NULL
    2281             :         },
    2282             :         { "Privacy", WPAS_DBUS_NEW_IFACE_BSS, "b",
    2283             :           wpas_dbus_getter_bss_privacy,
    2284             :           NULL
    2285             :         },
    2286             :         { "Mode", WPAS_DBUS_NEW_IFACE_BSS, "s",
    2287             :           wpas_dbus_getter_bss_mode,
    2288             :           NULL
    2289             :         },
    2290             :         { "Signal", WPAS_DBUS_NEW_IFACE_BSS, "n",
    2291             :           wpas_dbus_getter_bss_signal,
    2292             :           NULL
    2293             :         },
    2294             :         { "Frequency", WPAS_DBUS_NEW_IFACE_BSS, "q",
    2295             :           wpas_dbus_getter_bss_frequency,
    2296             :           NULL
    2297             :         },
    2298             :         { "Rates", WPAS_DBUS_NEW_IFACE_BSS, "au",
    2299             :           wpas_dbus_getter_bss_rates,
    2300             :           NULL
    2301             :         },
    2302             :         { "WPA", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
    2303             :           wpas_dbus_getter_bss_wpa,
    2304             :           NULL
    2305             :         },
    2306             :         { "RSN", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
    2307             :           wpas_dbus_getter_bss_rsn,
    2308             :           NULL
    2309             :         },
    2310             :         { "WPS", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
    2311             :           wpas_dbus_getter_bss_wps,
    2312             :           NULL
    2313             :         },
    2314             :         { "IEs", WPAS_DBUS_NEW_IFACE_BSS, "ay",
    2315             :           wpas_dbus_getter_bss_ies,
    2316             :           NULL
    2317             :         },
    2318             :         { "Age", WPAS_DBUS_NEW_IFACE_BSS, "u",
    2319             :           wpas_dbus_getter_bss_age,
    2320             :           NULL
    2321             :         },
    2322             :         { NULL, NULL, NULL, NULL, NULL }
    2323             : };
    2324             : 
    2325             : 
    2326             : static const struct wpa_dbus_signal_desc wpas_dbus_bss_signals[] = {
    2327             :         /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
    2328             :         { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSS,
    2329             :           {
    2330             :                   { "properties", "a{sv}", ARG_OUT },
    2331             :                   END_ARGS
    2332             :           }
    2333             :         },
    2334             :         { NULL, NULL, { END_ARGS } }
    2335             : };
    2336             : 
    2337             : 
    2338             : /**
    2339             :  * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus
    2340             :  * @wpa_s: wpa_supplicant interface structure
    2341             :  * @bssid: scanned network bssid
    2342             :  * @id: unique BSS identifier
    2343             :  * Returns: 0 on success, -1 on failure
    2344             :  *
    2345             :  * Unregisters BSS representing object from dbus
    2346             :  */
    2347        1827 : int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s,
    2348             :                              u8 bssid[ETH_ALEN], unsigned int id)
    2349             : {
    2350             :         struct wpas_dbus_priv *ctrl_iface;
    2351             :         char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
    2352             : 
    2353             :         /* Do nothing if the control interface is not turned on */
    2354        1827 :         if (wpa_s == NULL || wpa_s->global == NULL)
    2355           0 :                 return 0;
    2356        1827 :         ctrl_iface = wpa_s->global->dbus;
    2357        1827 :         if (ctrl_iface == NULL)
    2358         770 :                 return 0;
    2359             : 
    2360        1057 :         os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
    2361             :                     "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
    2362             :                     wpa_s->dbus_new_path, id);
    2363             : 
    2364        1057 :         wpa_printf(MSG_DEBUG, "dbus: Unregister BSS object '%s'",
    2365             :                    bss_obj_path);
    2366        1057 :         if (wpa_dbus_unregister_object_per_iface(ctrl_iface, bss_obj_path)) {
    2367           0 :                 wpa_printf(MSG_ERROR, "dbus: Cannot unregister BSS object %s",
    2368             :                            bss_obj_path);
    2369           0 :                 return -1;
    2370             :         }
    2371             : 
    2372        1057 :         wpas_dbus_signal_bss_removed(wpa_s, bss_obj_path);
    2373        1057 :         wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSSS);
    2374             : 
    2375        1057 :         return 0;
    2376             : }
    2377             : 
    2378             : 
    2379             : /**
    2380             :  * wpas_dbus_register_bss - Register a scanned BSS with dbus
    2381             :  * @wpa_s: wpa_supplicant interface structure
    2382             :  * @bssid: scanned network bssid
    2383             :  * @id: unique BSS identifier
    2384             :  * Returns: 0 on success, -1 on failure
    2385             :  *
    2386             :  * Registers BSS representing object with dbus
    2387             :  */
    2388        1827 : int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s,
    2389             :                            u8 bssid[ETH_ALEN], unsigned int id)
    2390             : {
    2391             :         struct wpas_dbus_priv *ctrl_iface;
    2392             :         struct wpa_dbus_object_desc *obj_desc;
    2393             :         char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
    2394             :         struct bss_handler_args *arg;
    2395             : 
    2396             :         /* Do nothing if the control interface is not turned on */
    2397        1827 :         if (wpa_s == NULL || wpa_s->global == NULL)
    2398           0 :                 return 0;
    2399        1827 :         ctrl_iface = wpa_s->global->dbus;
    2400        1827 :         if (ctrl_iface == NULL)
    2401         770 :                 return 0;
    2402             : 
    2403        1057 :         os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
    2404             :                     "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
    2405             :                     wpa_s->dbus_new_path, id);
    2406             : 
    2407        1057 :         obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
    2408        1057 :         if (!obj_desc) {
    2409           0 :                 wpa_printf(MSG_ERROR,
    2410             :                            "Not enough memory to create object description");
    2411           0 :                 goto err;
    2412             :         }
    2413             : 
    2414        1057 :         arg = os_zalloc(sizeof(struct bss_handler_args));
    2415        1057 :         if (!arg) {
    2416           0 :                 wpa_printf(MSG_ERROR,
    2417             :                            "Not enough memory to create arguments for handler");
    2418           0 :                 goto err;
    2419             :         }
    2420        1057 :         arg->wpa_s = wpa_s;
    2421        1057 :         arg->id = id;
    2422             : 
    2423        1057 :         wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
    2424             :                            wpas_dbus_bss_properties,
    2425             :                            wpas_dbus_bss_signals);
    2426             : 
    2427        1057 :         wpa_printf(MSG_DEBUG, "dbus: Register BSS object '%s'",
    2428             :                    bss_obj_path);
    2429        1057 :         if (wpa_dbus_register_object_per_iface(ctrl_iface, bss_obj_path,
    2430        1057 :                                                wpa_s->ifname, obj_desc)) {
    2431           0 :                 wpa_printf(MSG_ERROR,
    2432             :                            "Cannot register BSSID dbus object %s.",
    2433             :                            bss_obj_path);
    2434           0 :                 goto err;
    2435             :         }
    2436             : 
    2437        1057 :         wpas_dbus_signal_bss_added(wpa_s, bss_obj_path);
    2438        1057 :         wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSSS);
    2439             : 
    2440        1057 :         return 0;
    2441             : 
    2442             : err:
    2443           0 :         free_dbus_object_desc(obj_desc);
    2444           0 :         return -1;
    2445             : }
    2446             : 
    2447             : 
    2448             : static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
    2449             :         { "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE,
    2450             :           (WPADBusMethodHandler) wpas_dbus_handler_scan,
    2451             :           {
    2452             :                   { "args", "a{sv}", ARG_IN },
    2453             :                   END_ARGS
    2454             :           }
    2455             :         },
    2456             :         { "SignalPoll", WPAS_DBUS_NEW_IFACE_INTERFACE,
    2457             :           (WPADBusMethodHandler) wpas_dbus_handler_signal_poll,
    2458             :           {
    2459             :                   { "args", "a{sv}", ARG_OUT },
    2460             :                   END_ARGS
    2461             :           }
    2462             :         },
    2463             :         { "Disconnect", WPAS_DBUS_NEW_IFACE_INTERFACE,
    2464             :           (WPADBusMethodHandler) wpas_dbus_handler_disconnect,
    2465             :           {
    2466             :                   END_ARGS
    2467             :           }
    2468             :         },
    2469             :         { "AddNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
    2470             :           (WPADBusMethodHandler) wpas_dbus_handler_add_network,
    2471             :           {
    2472             :                   { "args", "a{sv}", ARG_IN },
    2473             :                   { "path", "o", ARG_OUT },
    2474             :                   END_ARGS
    2475             :           }
    2476             :         },
    2477             :         { "Reassociate", WPAS_DBUS_NEW_IFACE_INTERFACE,
    2478             :           (WPADBusMethodHandler) wpas_dbus_handler_reassociate,
    2479             :           {
    2480             :                   END_ARGS
    2481             :           }
    2482             :         },
    2483             :         { "Reattach", WPAS_DBUS_NEW_IFACE_INTERFACE,
    2484             :           (WPADBusMethodHandler) wpas_dbus_handler_reattach,
    2485             :           {
    2486             :                   END_ARGS
    2487             :           }
    2488             :         },
    2489             :         { "RemoveNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
    2490             :           (WPADBusMethodHandler) wpas_dbus_handler_remove_network,
    2491             :           {
    2492             :                   { "path", "o", ARG_IN },
    2493             :                   END_ARGS
    2494             :           }
    2495             :         },
    2496             :         { "RemoveAllNetworks", WPAS_DBUS_NEW_IFACE_INTERFACE,
    2497             :           (WPADBusMethodHandler) wpas_dbus_handler_remove_all_networks,
    2498             :           {
    2499             :                   END_ARGS
    2500             :           }
    2501             :         },
    2502             :         { "SelectNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
    2503             :           (WPADBusMethodHandler) wpas_dbus_handler_select_network,
    2504             :           {
    2505             :                   { "path", "o", ARG_IN },
    2506             :                   END_ARGS
    2507             :           }
    2508             :         },
    2509             :         { "NetworkReply", WPAS_DBUS_NEW_IFACE_INTERFACE,
    2510             :           (WPADBusMethodHandler) wpas_dbus_handler_network_reply,
    2511             :           {
    2512             :                   { "path", "o", ARG_IN },
    2513             :                   { "field", "s", ARG_IN },
    2514             :                   { "value", "s", ARG_IN },
    2515             :                   END_ARGS
    2516             :           }
    2517             :         },
    2518             : #ifndef CONFIG_NO_CONFIG_BLOBS
    2519             :         { "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
    2520             :           (WPADBusMethodHandler) wpas_dbus_handler_add_blob,
    2521             :           {
    2522             :                   { "name", "s", ARG_IN },
    2523             :                   { "data", "ay", ARG_IN },
    2524             :                   END_ARGS
    2525             :           }
    2526             :         },
    2527             :         { "GetBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
    2528             :           (WPADBusMethodHandler) wpas_dbus_handler_get_blob,
    2529             :           {
    2530             :                   { "name", "s", ARG_IN },
    2531             :                   { "data", "ay", ARG_OUT },
    2532             :                   END_ARGS
    2533             :           }
    2534             :         },
    2535             :         { "RemoveBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
    2536             :           (WPADBusMethodHandler) wpas_dbus_handler_remove_blob,
    2537             :           {
    2538             :                   { "name", "s", ARG_IN },
    2539             :                   END_ARGS
    2540             :           }
    2541             :         },
    2542             : #endif /* CONFIG_NO_CONFIG_BLOBS */
    2543             :         { "SetPKCS11EngineAndModulePath", WPAS_DBUS_NEW_IFACE_INTERFACE,
    2544             :           (WPADBusMethodHandler)
    2545             :           wpas_dbus_handler_set_pkcs11_engine_and_module_path,
    2546             :           {
    2547             :                   { "pkcs11_engine_path", "s", ARG_IN },
    2548             :                   { "pkcs11_module_path", "s", ARG_IN },
    2549             :                   END_ARGS
    2550             :           }
    2551             :         },
    2552             : #ifdef CONFIG_WPS
    2553             :         { "Start", WPAS_DBUS_NEW_IFACE_WPS,
    2554             :           (WPADBusMethodHandler) wpas_dbus_handler_wps_start,
    2555             :           {
    2556             :                   { "args", "a{sv}", ARG_IN },
    2557             :                   { "output", "a{sv}", ARG_OUT },
    2558             :                   END_ARGS
    2559             :           }
    2560             :         },
    2561             : #endif /* CONFIG_WPS */
    2562             : #ifdef CONFIG_P2P
    2563             :         { "Find", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    2564             :           (WPADBusMethodHandler) wpas_dbus_handler_p2p_find,
    2565             :           {
    2566             :                   { "args", "a{sv}", ARG_IN },
    2567             :                   END_ARGS
    2568             :           }
    2569             :         },
    2570             :         { "StopFind", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    2571             :           (WPADBusMethodHandler) wpas_dbus_handler_p2p_stop_find,
    2572             :           {
    2573             :                   END_ARGS
    2574             :           }
    2575             :         },
    2576             :         { "Listen", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    2577             :           (WPADBusMethodHandler) wpas_dbus_handler_p2p_listen,
    2578             :           {
    2579             :                   { "timeout", "i", ARG_IN },
    2580             :                   END_ARGS
    2581             :           }
    2582             :         },
    2583             :         { "ExtendedListen", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    2584             :           (WPADBusMethodHandler) wpas_dbus_handler_p2p_extendedlisten,
    2585             :           {
    2586             :                   { "args", "a{sv}", ARG_IN },
    2587             :                   END_ARGS
    2588             :           }
    2589             :         },
    2590             :         { "PresenceRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    2591             :           (WPADBusMethodHandler) wpas_dbus_handler_p2p_presence_request,
    2592             :           {
    2593             :                   { "args", "a{sv}", ARG_IN },
    2594             :                   END_ARGS
    2595             :           }
    2596             :         },
    2597             :         { "ProvisionDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    2598             :           (WPADBusMethodHandler) wpas_dbus_handler_p2p_prov_disc_req,
    2599             :           {
    2600             :                   { "peer", "o", ARG_IN },
    2601             :                   { "config_method", "s", ARG_IN },
    2602             :                   END_ARGS
    2603             :           }
    2604             :         },
    2605             :         { "Connect", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    2606             :           (WPADBusMethodHandler) wpas_dbus_handler_p2p_connect,
    2607             :           {
    2608             :                   { "args", "a{sv}", ARG_IN },
    2609             :                   { "generated_pin", "s", ARG_OUT },
    2610             :                   END_ARGS
    2611             :           }
    2612             :         },
    2613             :         { "GroupAdd", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    2614             :           (WPADBusMethodHandler) wpas_dbus_handler_p2p_group_add,
    2615             :           {
    2616             :                   { "args", "a{sv}", ARG_IN },
    2617             :                   END_ARGS
    2618             :           }
    2619             :         },
    2620             :         { "Invite", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    2621             :           (WPADBusMethodHandler) wpas_dbus_handler_p2p_invite,
    2622             :           {
    2623             :                   { "args", "a{sv}", ARG_IN },
    2624             :                   END_ARGS
    2625             :           }
    2626             :         },
    2627             :         { "Disconnect", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    2628             :           (WPADBusMethodHandler) wpas_dbus_handler_p2p_disconnect,
    2629             :           {
    2630             :                   END_ARGS
    2631             :           }
    2632             :         },
    2633             :         { "RejectPeer", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    2634             :           (WPADBusMethodHandler) wpas_dbus_handler_p2p_rejectpeer,
    2635             :           {
    2636             :                   { "peer", "o", ARG_IN },
    2637             :                   END_ARGS
    2638             :           }
    2639             :         },
    2640             :         { "Flush", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    2641             :           (WPADBusMethodHandler) wpas_dbus_handler_p2p_flush,
    2642             :           {
    2643             :                   END_ARGS
    2644             :           }
    2645             :         },
    2646             :         { "AddService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    2647             :           (WPADBusMethodHandler) wpas_dbus_handler_p2p_add_service,
    2648             :           {
    2649             :                   { "args", "a{sv}", ARG_IN },
    2650             :                   END_ARGS
    2651             :           }
    2652             :         },
    2653             :         { "DeleteService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    2654             :           (WPADBusMethodHandler) wpas_dbus_handler_p2p_delete_service,
    2655             :           {
    2656             :                   { "args", "a{sv}", ARG_IN },
    2657             :                   END_ARGS
    2658             :           }
    2659             :         },
    2660             :         { "FlushService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    2661             :           (WPADBusMethodHandler) wpas_dbus_handler_p2p_flush_service,
    2662             :           {
    2663             :                   END_ARGS
    2664             :           }
    2665             :         },
    2666             :         { "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    2667             :           (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_sd_req,
    2668             :           {
    2669             :                   { "args", "a{sv}", ARG_IN },
    2670             :                   { "ref", "t", ARG_OUT },
    2671             :                   END_ARGS
    2672             :           }
    2673             :         },
    2674             :         { "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    2675             :           (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_sd_res,
    2676             :           {
    2677             :                   { "args", "a{sv}", ARG_IN },
    2678             :                   END_ARGS
    2679             :           }
    2680             :         },
    2681             :         { "ServiceDiscoveryCancelRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    2682             :           (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_sd_cancel_req,
    2683             :           {
    2684             :                   { "args", "t", ARG_IN },
    2685             :                   END_ARGS
    2686             :           }
    2687             :         },
    2688             :         { "ServiceUpdate", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    2689             :           (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_update,
    2690             :           {
    2691             :                   END_ARGS
    2692             :           }
    2693             :         },
    2694             :         { "ServiceDiscoveryExternal", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    2695             :           (WPADBusMethodHandler) wpas_dbus_handler_p2p_serv_disc_external,
    2696             :           {
    2697             :                   { "arg", "i", ARG_IN },
    2698             :                   END_ARGS
    2699             :           }
    2700             :         },
    2701             :         { "AddPersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    2702             :           (WPADBusMethodHandler) wpas_dbus_handler_add_persistent_group,
    2703             :           {
    2704             :                   { "args", "a{sv}", ARG_IN },
    2705             :                   { "path", "o", ARG_OUT },
    2706             :                   END_ARGS
    2707             :           }
    2708             :         },
    2709             :         { "RemovePersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    2710             :           (WPADBusMethodHandler) wpas_dbus_handler_remove_persistent_group,
    2711             :           {
    2712             :                   { "path", "o", ARG_IN },
    2713             :                   END_ARGS
    2714             :           }
    2715             :         },
    2716             :         { "RemoveAllPersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    2717             :           (WPADBusMethodHandler)
    2718             :           wpas_dbus_handler_remove_all_persistent_groups,
    2719             :           {
    2720             :                   END_ARGS
    2721             :           }
    2722             :         },
    2723             : #endif /* CONFIG_P2P */
    2724             :         { "FlushBSS", WPAS_DBUS_NEW_IFACE_INTERFACE,
    2725             :           (WPADBusMethodHandler) wpas_dbus_handler_flush_bss,
    2726             :           {
    2727             :                   { "age", "u", ARG_IN },
    2728             :                   END_ARGS
    2729             :           }
    2730             :         },
    2731             : #ifdef CONFIG_AP
    2732             :         { "SubscribeProbeReq", WPAS_DBUS_NEW_IFACE_INTERFACE,
    2733             :           (WPADBusMethodHandler) wpas_dbus_handler_subscribe_preq,
    2734             :           {
    2735             :                   END_ARGS
    2736             :           }
    2737             :         },
    2738             :         { "UnsubscribeProbeReq", WPAS_DBUS_NEW_IFACE_INTERFACE,
    2739             :           (WPADBusMethodHandler) wpas_dbus_handler_unsubscribe_preq,
    2740             :           {
    2741             :                   END_ARGS
    2742             :           }
    2743             :         },
    2744             : #endif /* CONFIG_AP */
    2745             :         { "EAPLogoff", WPAS_DBUS_NEW_IFACE_INTERFACE,
    2746             :           (WPADBusMethodHandler) wpas_dbus_handler_eap_logoff,
    2747             :           {
    2748             :                   END_ARGS
    2749             :           }
    2750             :         },
    2751             :         { "EAPLogon", WPAS_DBUS_NEW_IFACE_INTERFACE,
    2752             :           (WPADBusMethodHandler) wpas_dbus_handler_eap_logon,
    2753             :           {
    2754             :                   END_ARGS
    2755             :           }
    2756             :         },
    2757             : #ifdef CONFIG_AUTOSCAN
    2758             :         { "AutoScan", WPAS_DBUS_NEW_IFACE_INTERFACE,
    2759             :           (WPADBusMethodHandler) wpas_dbus_handler_autoscan,
    2760             :           {
    2761             :                   { "arg", "s", ARG_IN },
    2762             :                   END_ARGS
    2763             :           }
    2764             :         },
    2765             : #endif /* CONFIG_AUTOSCAN */
    2766             : #ifdef CONFIG_TDLS
    2767             :         { "TDLSDiscover", WPAS_DBUS_NEW_IFACE_INTERFACE,
    2768             :           (WPADBusMethodHandler) wpas_dbus_handler_tdls_discover,
    2769             :           {
    2770             :                   { "peer_address", "s", ARG_IN },
    2771             :                   END_ARGS
    2772             :           }
    2773             :         },
    2774             :         { "TDLSSetup", WPAS_DBUS_NEW_IFACE_INTERFACE,
    2775             :           (WPADBusMethodHandler) wpas_dbus_handler_tdls_setup,
    2776             :           {
    2777             :                   { "peer_address", "s", ARG_IN },
    2778             :                   END_ARGS
    2779             :           }
    2780             :         },
    2781             :         { "TDLSStatus", WPAS_DBUS_NEW_IFACE_INTERFACE,
    2782             :           (WPADBusMethodHandler) wpas_dbus_handler_tdls_status,
    2783             :           {
    2784             :                   { "peer_address", "s", ARG_IN },
    2785             :                   { "status", "s", ARG_OUT },
    2786             :                   END_ARGS
    2787             :           }
    2788             :         },
    2789             :         { "TDLSTeardown", WPAS_DBUS_NEW_IFACE_INTERFACE,
    2790             :           (WPADBusMethodHandler) wpas_dbus_handler_tdls_teardown,
    2791             :           {
    2792             :                   { "peer_address", "s", ARG_IN },
    2793             :                   END_ARGS
    2794             :           }
    2795             :         },
    2796             : #endif /* CONFIG_TDLS */
    2797             :         { NULL, NULL, NULL, { END_ARGS } }
    2798             : };
    2799             : 
    2800             : static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = {
    2801             :         { "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}",
    2802             :           wpas_dbus_getter_capabilities,
    2803             :           NULL
    2804             :         },
    2805             :         { "State", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
    2806             :           wpas_dbus_getter_state,
    2807             :           NULL
    2808             :         },
    2809             :         { "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
    2810             :           wpas_dbus_getter_scanning,
    2811             :           NULL
    2812             :         },
    2813             :         { "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
    2814             :           wpas_dbus_getter_ap_scan,
    2815             :           wpas_dbus_setter_ap_scan
    2816             :         },
    2817             :         { "BSSExpireAge", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
    2818             :           wpas_dbus_getter_bss_expire_age,
    2819             :           wpas_dbus_setter_bss_expire_age
    2820             :         },
    2821             :         { "BSSExpireCount", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
    2822             :           wpas_dbus_getter_bss_expire_count,
    2823             :           wpas_dbus_setter_bss_expire_count
    2824             :         },
    2825             :         { "Country", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
    2826             :           wpas_dbus_getter_country,
    2827             :           wpas_dbus_setter_country
    2828             :         },
    2829             :         { "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
    2830             :           wpas_dbus_getter_ifname,
    2831             :           NULL
    2832             :         },
    2833             :         { "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
    2834             :           wpas_dbus_getter_driver,
    2835             :           NULL
    2836             :         },
    2837             :         { "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
    2838             :           wpas_dbus_getter_bridge_ifname,
    2839             :           NULL
    2840             :         },
    2841             :         { "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
    2842             :           wpas_dbus_getter_current_bss,
    2843             :           NULL
    2844             :         },
    2845             :         { "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
    2846             :           wpas_dbus_getter_current_network,
    2847             :           NULL
    2848             :         },
    2849             :         { "CurrentAuthMode", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
    2850             :           wpas_dbus_getter_current_auth_mode,
    2851             :           NULL
    2852             :         },
    2853             :         { "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{say}",
    2854             :           wpas_dbus_getter_blobs,
    2855             :           NULL
    2856             :         },
    2857             :         { "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
    2858             :           wpas_dbus_getter_bsss,
    2859             :           NULL
    2860             :         },
    2861             :         { "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
    2862             :           wpas_dbus_getter_networks,
    2863             :           NULL
    2864             :         },
    2865             :         { "FastReauth", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
    2866             :           wpas_dbus_getter_fast_reauth,
    2867             :           wpas_dbus_setter_fast_reauth
    2868             :         },
    2869             :         { "ScanInterval", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
    2870             :           wpas_dbus_getter_scan_interval,
    2871             :           wpas_dbus_setter_scan_interval
    2872             :         },
    2873             :         { "PKCS11EnginePath", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
    2874             :           wpas_dbus_getter_pkcs11_engine_path,
    2875             :           NULL
    2876             :         },
    2877             :         { "PKCS11ModulePath", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
    2878             :           wpas_dbus_getter_pkcs11_module_path,
    2879             :           NULL
    2880             :         },
    2881             : #ifdef CONFIG_WPS
    2882             :         { "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b",
    2883             :           wpas_dbus_getter_process_credentials,
    2884             :           wpas_dbus_setter_process_credentials
    2885             :         },
    2886             :         { "ConfigMethods", WPAS_DBUS_NEW_IFACE_WPS, "s",
    2887             :           wpas_dbus_getter_config_methods,
    2888             :           wpas_dbus_setter_config_methods
    2889             :         },
    2890             : #endif /* CONFIG_WPS */
    2891             : #ifdef CONFIG_P2P
    2892             :         { "P2PDeviceConfig", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "a{sv}",
    2893             :           wpas_dbus_getter_p2p_device_config,
    2894             :           wpas_dbus_setter_p2p_device_config
    2895             :         },
    2896             :         { "Peers", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
    2897             :           wpas_dbus_getter_p2p_peers,
    2898             :           NULL
    2899             :         },
    2900             :         { "Role", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "s",
    2901             :           wpas_dbus_getter_p2p_role,
    2902             :           NULL
    2903             :         },
    2904             :         { "Group", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
    2905             :           wpas_dbus_getter_p2p_group,
    2906             :           NULL
    2907             :         },
    2908             :         { "PeerGO", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
    2909             :           wpas_dbus_getter_p2p_peergo,
    2910             :           NULL
    2911             :         },
    2912             :         { "PersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
    2913             :           wpas_dbus_getter_persistent_groups,
    2914             :           NULL
    2915             :         },
    2916             : #endif /* CONFIG_P2P */
    2917             :         { "DisconnectReason", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
    2918             :           wpas_dbus_getter_disconnect_reason,
    2919             :           NULL
    2920             :         },
    2921             :         { NULL, NULL, NULL, NULL, NULL }
    2922             : };
    2923             : 
    2924             : static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = {
    2925             :         { "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE,
    2926             :           {
    2927             :                   { "success", "b", ARG_OUT },
    2928             :                   END_ARGS
    2929             :           }
    2930             :         },
    2931             :         { "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
    2932             :           {
    2933             :                   { "path", "o", ARG_OUT },
    2934             :                   { "properties", "a{sv}", ARG_OUT },
    2935             :                   END_ARGS
    2936             :           }
    2937             :         },
    2938             :         { "BSSRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
    2939             :           {
    2940             :                   { "path", "o", ARG_OUT },
    2941             :                   END_ARGS
    2942             :           }
    2943             :         },
    2944             :         { "BlobAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
    2945             :           {
    2946             :                   { "name", "s", ARG_OUT },
    2947             :                   END_ARGS
    2948             :           }
    2949             :         },
    2950             :         { "BlobRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
    2951             :           {
    2952             :                   { "name", "s", ARG_OUT },
    2953             :                   END_ARGS
    2954             :           }
    2955             :         },
    2956             :         { "NetworkAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
    2957             :           {
    2958             :                   { "path", "o", ARG_OUT },
    2959             :                   { "properties", "a{sv}", ARG_OUT },
    2960             :                   END_ARGS
    2961             :           }
    2962             :         },
    2963             :         { "NetworkRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
    2964             :           {
    2965             :                   { "path", "o", ARG_OUT },
    2966             :                   END_ARGS
    2967             :           }
    2968             :         },
    2969             :         { "NetworkSelected", WPAS_DBUS_NEW_IFACE_INTERFACE,
    2970             :           {
    2971             :                   { "path", "o", ARG_OUT },
    2972             :                   END_ARGS
    2973             :           }
    2974             :         },
    2975             :         /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
    2976             :         { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE,
    2977             :           {
    2978             :                   { "properties", "a{sv}", ARG_OUT },
    2979             :                   END_ARGS
    2980             :           }
    2981             :         },
    2982             : #ifdef CONFIG_WPS
    2983             :         { "Event", WPAS_DBUS_NEW_IFACE_WPS,
    2984             :           {
    2985             :                   { "name", "s", ARG_OUT },
    2986             :                   { "args", "a{sv}", ARG_OUT },
    2987             :                   END_ARGS
    2988             :           }
    2989             :         },
    2990             :         { "Credentials", WPAS_DBUS_NEW_IFACE_WPS,
    2991             :           {
    2992             :                   { "credentials", "a{sv}", ARG_OUT },
    2993             :                   END_ARGS
    2994             :           }
    2995             :         },
    2996             :         /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
    2997             :         { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS,
    2998             :           {
    2999             :                   { "properties", "a{sv}", ARG_OUT },
    3000             :                   END_ARGS
    3001             :           }
    3002             :         },
    3003             : #endif /* CONFIG_WPS */
    3004             : #ifdef CONFIG_P2P
    3005             :         { "DeviceFound", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    3006             :           {
    3007             :                   { "path", "o", ARG_OUT },
    3008             :                   END_ARGS
    3009             :           }
    3010             :         },
    3011             :         { "DeviceLost", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    3012             :           {
    3013             :                   { "path", "o", ARG_OUT },
    3014             :                   END_ARGS
    3015             :           }
    3016             :         },
    3017             :         { "ProvisionDiscoveryRequestDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    3018             :           {
    3019             :                   { "peer_object", "o", ARG_OUT },
    3020             :                   { "pin", "s", ARG_OUT },
    3021             :                   END_ARGS
    3022             :           }
    3023             :         },
    3024             :         { "ProvisionDiscoveryResponseDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    3025             :           {
    3026             :                   { "peer_object", "o", ARG_OUT },
    3027             :                   { "pin", "s", ARG_OUT },
    3028             :                   END_ARGS
    3029             :           }
    3030             :         },
    3031             :         { "ProvisionDiscoveryRequestEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    3032             :           {
    3033             :                   { "peer_object", "o", ARG_OUT },
    3034             :                   END_ARGS
    3035             :           }
    3036             :         },
    3037             :         { "ProvisionDiscoveryResponseEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    3038             :           {
    3039             :                   { "peer_object", "o", ARG_OUT },
    3040             :                   END_ARGS
    3041             :           }
    3042             :         },
    3043             :         { "ProvisionDiscoveryPBCRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    3044             :           {
    3045             :                   { "peer_object", "o", ARG_OUT },
    3046             :                   END_ARGS
    3047             :           }
    3048             :         },
    3049             :         { "ProvisionDiscoveryPBCResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    3050             :           {
    3051             :                   { "peer_object", "o", ARG_OUT },
    3052             :                   END_ARGS
    3053             :           }
    3054             :         },
    3055             :         { "ProvisionDiscoveryFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    3056             :           {
    3057             :                   { "peer_object", "o", ARG_OUT },
    3058             :                   { "status", "i", ARG_OUT },
    3059             :                   END_ARGS
    3060             :           }
    3061             :         },
    3062             :         { "GroupStarted", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    3063             :           {
    3064             :                   { "properties", "a{sv}", ARG_OUT },
    3065             :                   END_ARGS
    3066             :           }
    3067             :         },
    3068             :         { "GONegotiationSuccess", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    3069             :           {
    3070             :                   { "properties", "a{sv}", ARG_OUT },
    3071             :                   END_ARGS
    3072             :           }
    3073             :         },
    3074             :         { "GONegotiationFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    3075             :           {
    3076             :                   { "properties", "a{sv}", ARG_OUT },
    3077             :                   END_ARGS
    3078             :           }
    3079             :         },
    3080             :         { "GONegotiationRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    3081             :           {
    3082             :                   { "path", "o", ARG_OUT },
    3083             :                   { "dev_passwd_id", "i", ARG_OUT },
    3084             :                   END_ARGS
    3085             :           }
    3086             :         },
    3087             :         { "InvitationResult", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    3088             :           {
    3089             :                   { "invite_result", "a{sv}", ARG_OUT },
    3090             :                   END_ARGS
    3091             :           }
    3092             :         },
    3093             :         { "GroupFinished", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    3094             :           {
    3095             :                   { "properties", "a{sv}", ARG_OUT },
    3096             :                   END_ARGS
    3097             :           }
    3098             :         },
    3099             :         { "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    3100             :           {
    3101             :                   { "sd_request", "a{sv}", ARG_OUT },
    3102             :                   END_ARGS
    3103             :           }
    3104             :         },
    3105             :         { "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    3106             :           {
    3107             :                   { "sd_response", "a{sv}", ARG_OUT },
    3108             :                   END_ARGS
    3109             :           }
    3110             :         },
    3111             :         { "PersistentGroupAdded", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    3112             :           {
    3113             :                   { "path", "o", ARG_OUT },
    3114             :                   { "properties", "a{sv}", ARG_OUT },
    3115             :                   END_ARGS
    3116             :           }
    3117             :         },
    3118             :         { "PersistentGroupRemoved", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    3119             :           {
    3120             :                   { "path", "o", ARG_OUT },
    3121             :                   END_ARGS
    3122             :           }
    3123             :         },
    3124             :         { "WpsFailed", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    3125             :           {
    3126             :                   { "name", "s", ARG_OUT },
    3127             :                   { "args", "a{sv}", ARG_OUT },
    3128             :                   END_ARGS
    3129             :           }
    3130             :         },
    3131             : #endif /* CONFIG_P2P */
    3132             : #ifdef CONFIG_AP
    3133             :         { "ProbeRequest", WPAS_DBUS_NEW_IFACE_INTERFACE,
    3134             :           {
    3135             :                   { "args", "a{sv}", ARG_OUT },
    3136             :                   END_ARGS
    3137             :           }
    3138             :         },
    3139             : #endif /* CONFIG_AP */
    3140             :         { "Certification", WPAS_DBUS_NEW_IFACE_INTERFACE,
    3141             :           {
    3142             :                   { "certification", "a{sv}", ARG_OUT },
    3143             :                   END_ARGS
    3144             :           }
    3145             :         },
    3146             :         { "EAP", WPAS_DBUS_NEW_IFACE_INTERFACE,
    3147             :           {
    3148             :                   { "status", "s", ARG_OUT },
    3149             :                   { "parameter", "s", ARG_OUT },
    3150             :                   END_ARGS
    3151             :           }
    3152             :         },
    3153             :         { "StaAuthorized", WPAS_DBUS_NEW_IFACE_INTERFACE,
    3154             :           {
    3155             :                   { "name", "s", ARG_OUT },
    3156             :                   END_ARGS
    3157             :           }
    3158             :         },
    3159             :         { "StaDeauthorized", WPAS_DBUS_NEW_IFACE_INTERFACE,
    3160             :           {
    3161             :                   { "name", "s", ARG_OUT },
    3162             :                   END_ARGS
    3163             :           }
    3164             :         },
    3165             :         { "NetworkRequest", WPAS_DBUS_NEW_IFACE_INTERFACE,
    3166             :           {
    3167             :                   { "path", "o", ARG_OUT },
    3168             :                   { "field", "s", ARG_OUT },
    3169             :                   { "text", "s", ARG_OUT },
    3170             :                   END_ARGS
    3171             :           }
    3172             :         },
    3173             :         { NULL, NULL, { END_ARGS } }
    3174             : };
    3175             : 
    3176             : 
    3177         251 : int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s)
    3178             : {
    3179             : 
    3180         251 :         struct wpa_dbus_object_desc *obj_desc = NULL;
    3181         251 :         struct wpas_dbus_priv *ctrl_iface = wpa_s->global->dbus;
    3182             :         int next;
    3183             : 
    3184             :         /* Do nothing if the control interface is not turned on */
    3185         251 :         if (ctrl_iface == NULL)
    3186         130 :                 return 0;
    3187             : 
    3188             :         /* Create and set the interface's object path */
    3189         121 :         wpa_s->dbus_new_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
    3190         121 :         if (wpa_s->dbus_new_path == NULL)
    3191           1 :                 return -1;
    3192         120 :         next = ctrl_iface->next_objid++;
    3193         120 :         os_snprintf(wpa_s->dbus_new_path, WPAS_DBUS_OBJECT_PATH_MAX,
    3194             :                     WPAS_DBUS_NEW_PATH_INTERFACES "/%u",
    3195             :                     next);
    3196             : 
    3197         120 :         obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
    3198         120 :         if (!obj_desc) {
    3199           1 :                 wpa_printf(MSG_ERROR,
    3200             :                            "Not enough memory to create object description");
    3201           1 :                 goto err;
    3202             :         }
    3203             : 
    3204         119 :         wpas_dbus_register(obj_desc, wpa_s, NULL, wpas_dbus_interface_methods,
    3205             :                            wpas_dbus_interface_properties,
    3206             :                            wpas_dbus_interface_signals);
    3207             : 
    3208         119 :         wpa_printf(MSG_DEBUG, "dbus: Register interface object '%s'",
    3209             :                    wpa_s->dbus_new_path);
    3210         119 :         if (wpa_dbus_register_object_per_iface(ctrl_iface,
    3211         119 :                                                wpa_s->dbus_new_path,
    3212         119 :                                                wpa_s->ifname, obj_desc))
    3213           0 :                 goto err;
    3214             : 
    3215         119 :         wpas_dbus_signal_interface_added(wpa_s);
    3216             : 
    3217         119 :         return 0;
    3218             : 
    3219             : err:
    3220           1 :         os_free(wpa_s->dbus_new_path);
    3221           1 :         wpa_s->dbus_new_path = NULL;
    3222           1 :         free_dbus_object_desc(obj_desc);
    3223           1 :         return -1;
    3224             : }
    3225             : 
    3226             : 
    3227         252 : int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s)
    3228             : {
    3229             :         struct wpas_dbus_priv *ctrl_iface;
    3230             : 
    3231             :         /* Do nothing if the control interface is not turned on */
    3232         252 :         if (wpa_s == NULL || wpa_s->global == NULL)
    3233           0 :                 return 0;
    3234         252 :         ctrl_iface = wpa_s->global->dbus;
    3235         252 :         if (ctrl_iface == NULL || wpa_s->dbus_new_path == NULL)
    3236         133 :                 return 0;
    3237             : 
    3238         119 :         wpa_printf(MSG_DEBUG, "dbus: Unregister interface object '%s'",
    3239             :                    wpa_s->dbus_new_path);
    3240             : 
    3241             : #ifdef CONFIG_AP
    3242         119 :         if (wpa_s->preq_notify_peer) {
    3243           0 :                 wpas_dbus_unsubscribe_noc(ctrl_iface);
    3244           0 :                 os_free(wpa_s->preq_notify_peer);
    3245           0 :                 wpa_s->preq_notify_peer = NULL;
    3246             :         }
    3247             : #endif /* CONFIG_AP */
    3248             : 
    3249         119 :         if (wpa_dbus_unregister_object_per_iface(ctrl_iface,
    3250         119 :                                                  wpa_s->dbus_new_path))
    3251           0 :                 return -1;
    3252             : 
    3253         119 :         wpas_dbus_signal_interface_removed(wpa_s);
    3254             : 
    3255         119 :         os_free(wpa_s->dbus_new_path);
    3256         119 :         wpa_s->dbus_new_path = NULL;
    3257             : 
    3258         119 :         return 0;
    3259             : }
    3260             : 
    3261             : #ifdef CONFIG_P2P
    3262             : 
    3263             : static const struct wpa_dbus_property_desc wpas_dbus_p2p_peer_properties[] = {
    3264             :         { "DeviceName", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
    3265             :           wpas_dbus_getter_p2p_peer_device_name,
    3266             :           NULL
    3267             :         },
    3268             :         { "PrimaryDeviceType", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
    3269             :           wpas_dbus_getter_p2p_peer_primary_device_type,
    3270             :           NULL
    3271             :         },
    3272             :         { "config_method", WPAS_DBUS_NEW_IFACE_P2P_PEER, "q",
    3273             :           wpas_dbus_getter_p2p_peer_config_method,
    3274             :           NULL
    3275             :         },
    3276             :         { "level", WPAS_DBUS_NEW_IFACE_P2P_PEER, "i",
    3277             :           wpas_dbus_getter_p2p_peer_level,
    3278             :           NULL
    3279             :         },
    3280             :         { "devicecapability", WPAS_DBUS_NEW_IFACE_P2P_PEER, "y",
    3281             :           wpas_dbus_getter_p2p_peer_device_capability,
    3282             :           NULL
    3283             :         },
    3284             :         { "groupcapability", WPAS_DBUS_NEW_IFACE_P2P_PEER, "y",
    3285             :           wpas_dbus_getter_p2p_peer_group_capability,
    3286             :           NULL
    3287             :         },
    3288             :         { "SecondaryDeviceTypes", WPAS_DBUS_NEW_IFACE_P2P_PEER, "aay",
    3289             :           wpas_dbus_getter_p2p_peer_secondary_device_types,
    3290             :           NULL
    3291             :         },
    3292             :         { "VendorExtension", WPAS_DBUS_NEW_IFACE_P2P_PEER, "aay",
    3293             :           wpas_dbus_getter_p2p_peer_vendor_extension,
    3294             :           NULL
    3295             :         },
    3296             :         { "IEs", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
    3297             :           wpas_dbus_getter_p2p_peer_ies,
    3298             :           NULL
    3299             :         },
    3300             :         { "DeviceAddress", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
    3301             :           wpas_dbus_getter_p2p_peer_device_address,
    3302             :           NULL
    3303             :         },
    3304             :         { "Groups", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ao",
    3305             :           wpas_dbus_getter_p2p_peer_groups,
    3306             :           NULL
    3307             :         },
    3308             :         { NULL, NULL, NULL, NULL, NULL }
    3309             : };
    3310             : 
    3311             : static const struct wpa_dbus_signal_desc wpas_dbus_p2p_peer_signals[] = {
    3312             :         /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
    3313             :         { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_P2P_PEER,
    3314             :           {
    3315             :                   { "properties", "a{sv}", ARG_OUT },
    3316             :                   END_ARGS
    3317             :           }
    3318             :         },
    3319             :         { NULL, NULL, { END_ARGS } }
    3320             : };
    3321             : 
    3322             : /**
    3323             :  * wpas_dbus_signal_peer - Send a peer related event signal
    3324             :  * @wpa_s: %wpa_supplicant network interface data
    3325             :  * @dev: peer device object
    3326             :  * @interface: name of the interface emitting this signal.
    3327             :  *      In case of peer objects, it would be emitted by either
    3328             :  *      the "interface object" or by "peer objects"
    3329             :  * @sig_name: signal name - DeviceFound
    3330             :  *
    3331             :  * Notify listeners about event related with newly found p2p peer device
    3332             :  */
    3333        1034 : static void wpas_dbus_signal_peer(struct wpa_supplicant *wpa_s,
    3334             :                                   const u8 *dev_addr, const char *interface,
    3335             :                                   const char *sig_name)
    3336             : {
    3337             :         struct wpas_dbus_priv *iface;
    3338             :         DBusMessage *msg;
    3339             :         DBusMessageIter iter;
    3340             :         char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
    3341             : 
    3342        1034 :         if (wpa_s->p2p_mgmt)
    3343          12 :                 wpa_s = wpa_s->parent;
    3344             : 
    3345        1034 :         iface = wpa_s->global->dbus;
    3346             : 
    3347             :         /* Do nothing if the control interface is not turned on */
    3348        1034 :         if (iface == NULL)
    3349        1238 :                 return;
    3350             : 
    3351        2490 :         os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
    3352             :                     "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
    3353        2490 :                     wpa_s->dbus_new_path, MAC2STR(dev_addr));
    3354             : 
    3355         415 :         msg = dbus_message_new_signal(wpa_s->dbus_new_path, interface,
    3356             :                                       sig_name);
    3357         415 :         if (msg == NULL)
    3358           0 :                 return;
    3359             : 
    3360         415 :         dbus_message_iter_init_append(msg, &iter);
    3361         415 :         path = peer_obj_path;
    3362         415 :         if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
    3363             :                                             &path))
    3364           0 :                 wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
    3365             :         else
    3366         415 :                 dbus_connection_send(iface->con, msg, NULL);
    3367             : 
    3368         415 :         dbus_message_unref(msg);
    3369             : }
    3370             : 
    3371             : 
    3372             : /**
    3373             :  * wpas_dbus_signal_peer_found - Send a peer found signal
    3374             :  * @wpa_s: %wpa_supplicant network interface data
    3375             :  * @dev: peer device object
    3376             :  *
    3377             :  * Notify listeners about find a p2p peer device found
    3378             :  */
    3379         528 : void wpas_dbus_signal_peer_device_found(struct wpa_supplicant *wpa_s,
    3380             :                                         const u8 *dev_addr)
    3381             : {
    3382         528 :         wpas_dbus_signal_peer(wpa_s, dev_addr,
    3383             :                               WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    3384             :                               "DeviceFound");
    3385         528 : }
    3386             : 
    3387             : /**
    3388             :  * wpas_dbus_signal_peer_lost - Send a peer lost signal
    3389             :  * @wpa_s: %wpa_supplicant network interface data
    3390             :  * @dev: peer device object
    3391             :  *
    3392             :  * Notify listeners about lost a p2p peer device
    3393             :  */
    3394         506 : void wpas_dbus_signal_peer_device_lost(struct wpa_supplicant *wpa_s,
    3395             :                                        const u8 *dev_addr)
    3396             : {
    3397         506 :         wpas_dbus_signal_peer(wpa_s, dev_addr,
    3398             :                               WPAS_DBUS_NEW_IFACE_P2PDEVICE,
    3399             :                               "DeviceLost");
    3400         506 : }
    3401             : 
    3402             : /**
    3403             :  * wpas_dbus_register_peer - Register a discovered peer object with dbus
    3404             :  * @wpa_s: wpa_supplicant interface structure
    3405             :  * @ssid: network configuration data
    3406             :  * Returns: 0 on success, -1 on failure
    3407             :  *
    3408             :  * Registers network representing object with dbus
    3409             :  */
    3410         506 : int wpas_dbus_register_peer(struct wpa_supplicant *wpa_s, const u8 *dev_addr)
    3411             : {
    3412             :         struct wpas_dbus_priv *ctrl_iface;
    3413             :         struct wpa_dbus_object_desc *obj_desc;
    3414             :         struct peer_handler_args *arg;
    3415             :         char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
    3416             : 
    3417             :         /* Do nothing if the control interface is not turned on */
    3418         506 :         if (wpa_s == NULL || wpa_s->global == NULL)
    3419           0 :                 return 0;
    3420             : 
    3421         506 :         ctrl_iface = wpa_s->global->dbus;
    3422         506 :         if (ctrl_iface == NULL)
    3423         300 :                 return 0;
    3424             : 
    3425         206 :         if (wpa_s->p2p_mgmt)
    3426           0 :                 wpa_s = wpa_s->parent;
    3427             : 
    3428        1236 :         os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
    3429             :                     "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
    3430        1236 :                     wpa_s->dbus_new_path, MAC2STR(dev_addr));
    3431             : 
    3432         206 :         wpa_printf(MSG_INFO, "dbus: Register peer object '%s'",
    3433             :                    peer_obj_path);
    3434         206 :         obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
    3435         206 :         if (!obj_desc) {
    3436           0 :                 wpa_printf(MSG_ERROR,
    3437             :                            "Not enough memory to create object description");
    3438           0 :                 goto err;
    3439             :         }
    3440             : 
    3441             :         /* allocate memory for handlers arguments */
    3442         206 :         arg = os_zalloc(sizeof(struct peer_handler_args));
    3443         206 :         if (!arg) {
    3444           0 :                 wpa_printf(MSG_ERROR,
    3445             :                            "Not enough memory to create arguments for method");
    3446           0 :                 goto err;
    3447             :         }
    3448             : 
    3449         206 :         arg->wpa_s = wpa_s;
    3450         206 :         os_memcpy(arg->p2p_device_addr, dev_addr, ETH_ALEN);
    3451             : 
    3452         206 :         wpas_dbus_register(obj_desc, arg, wpa_dbus_free,
    3453             :                            NULL,
    3454             :                            wpas_dbus_p2p_peer_properties,
    3455             :                            wpas_dbus_p2p_peer_signals);
    3456             : 
    3457         206 :         if (wpa_dbus_register_object_per_iface(ctrl_iface, peer_obj_path,
    3458         206 :                                                wpa_s->ifname, obj_desc))
    3459           0 :                 goto err;
    3460             : 
    3461         206 :         return 0;
    3462             : 
    3463             : err:
    3464           0 :         free_dbus_object_desc(obj_desc);
    3465           0 :         return -1;
    3466             : }
    3467             : 
    3468             : /**
    3469             :  * wpas_dbus_unregister_peer - Unregister a peer object with dbus
    3470             :  * @wpa_s: wpa_supplicant interface structure
    3471             :  * @dev_addr: p2p device addr
    3472             :  * Returns: 0 on success, -1 on failure
    3473             :  *
    3474             :  * Registers network representing object with dbus
    3475             :  */
    3476         506 : int wpas_dbus_unregister_peer(struct wpa_supplicant *wpa_s,
    3477             :                                   const u8 *dev_addr)
    3478             : {
    3479             :         struct wpas_dbus_priv *ctrl_iface;
    3480             :         char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
    3481             :         int ret;
    3482             : 
    3483             :         /* Do nothing if the control interface is not turned on */
    3484        1012 :         if (wpa_s == NULL || wpa_s->global == NULL ||
    3485         506 :             wpa_s->dbus_new_path == NULL)
    3486         300 :                 return 0;
    3487             : 
    3488         206 :         if (wpa_s->p2p_mgmt)
    3489           0 :                 wpa_s = wpa_s->parent;
    3490             : 
    3491         206 :         ctrl_iface = wpa_s->global->dbus;
    3492         206 :         if (ctrl_iface == NULL)
    3493           0 :                 return 0;
    3494             : 
    3495        1236 :         os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
    3496             :                     "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
    3497        1236 :                     wpa_s->dbus_new_path, MAC2STR(dev_addr));
    3498             : 
    3499         206 :         wpa_printf(MSG_INFO, "dbus: Unregister peer object '%s'",
    3500             :                    peer_obj_path);
    3501         206 :         ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, peer_obj_path);
    3502             : 
    3503         206 :         return ret;
    3504             : }
    3505             : 
    3506             : 
    3507         345 : void wpas_dbus_signal_peer_groups_changed(struct wpa_supplicant *wpa_s,
    3508             :                                           const u8 *dev_addr)
    3509             : {
    3510             :         char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
    3511             : 
    3512         345 :         if (wpa_s->p2p_mgmt)
    3513           0 :                 wpa_s = wpa_s->parent;
    3514             : 
    3515        2070 :         os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
    3516             :                     "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
    3517        2070 :                     wpa_s->dbus_new_path, MAC2STR(dev_addr));
    3518             : 
    3519         345 :         wpa_dbus_mark_property_changed(wpa_s->global->dbus, peer_obj_path,
    3520             :                                        WPAS_DBUS_NEW_IFACE_P2P_PEER, "Groups");
    3521         345 : }
    3522             : 
    3523             : 
    3524             : static const struct wpa_dbus_property_desc wpas_dbus_p2p_group_properties[] = {
    3525             :         { "Members", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ao",
    3526             :           wpas_dbus_getter_p2p_group_members,
    3527             :           NULL
    3528             :         },
    3529             :         { "Group", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "o",
    3530             :           wpas_dbus_getter_p2p_group,
    3531             :           NULL
    3532             :         },
    3533             :         { "Role", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "s",
    3534             :           wpas_dbus_getter_p2p_role,
    3535             :           NULL
    3536             :         },
    3537             :         { "SSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
    3538             :           wpas_dbus_getter_p2p_group_ssid,
    3539             :           NULL
    3540             :         },
    3541             :         { "BSSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
    3542             :           wpas_dbus_getter_p2p_group_bssid,
    3543             :           NULL
    3544             :         },
    3545             :         { "Frequency", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "q",
    3546             :           wpas_dbus_getter_p2p_group_frequency,
    3547             :           NULL
    3548             :         },
    3549             :         { "Passphrase", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "s",
    3550             :           wpas_dbus_getter_p2p_group_passphrase,
    3551             :           NULL
    3552             :         },
    3553             :         { "PSK", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
    3554             :           wpas_dbus_getter_p2p_group_psk,
    3555             :           NULL
    3556             :         },
    3557             :         { "WPSVendorExtensions", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "aay",
    3558             :           wpas_dbus_getter_p2p_group_vendor_ext,
    3559             :           wpas_dbus_setter_p2p_group_vendor_ext
    3560             :         },
    3561             :         { NULL, NULL, NULL, NULL, NULL }
    3562             : };
    3563             : 
    3564             : static const struct wpa_dbus_signal_desc wpas_dbus_p2p_group_signals[] = {
    3565             :         { "PeerJoined", WPAS_DBUS_NEW_IFACE_P2P_GROUP,
    3566             :           {
    3567             :                   { "peer", "o", ARG_OUT },
    3568             :                   END_ARGS
    3569             :           }
    3570             :         },
    3571             :         { "PeerDisconnected", WPAS_DBUS_NEW_IFACE_P2P_GROUP,
    3572             :           {
    3573             :                   { "peer", "o", ARG_OUT },
    3574             :                   END_ARGS
    3575             :           }
    3576             :         },
    3577             :         { NULL, NULL, { END_ARGS } }
    3578             : };
    3579             : 
    3580             : /**
    3581             :  * wpas_dbus_register_p2p_group - Register a p2p group object with dbus
    3582             :  * @wpa_s: wpa_supplicant interface structure
    3583             :  * @ssid: SSID struct
    3584             :  * Returns: 0 on success, -1 on failure
    3585             :  *
    3586             :  * Registers p2p group representing object with dbus
    3587             :  */
    3588         483 : void wpas_dbus_register_p2p_group(struct wpa_supplicant *wpa_s,
    3589             :                                   struct wpa_ssid *ssid)
    3590             : {
    3591             :         struct wpas_dbus_priv *ctrl_iface;
    3592             :         struct wpa_dbus_object_desc *obj_desc;
    3593             :         char group_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
    3594             : 
    3595             :         /* Do nothing if the control interface is not turned on */
    3596         483 :         if (wpa_s == NULL || wpa_s->global == NULL)
    3597         483 :                 return;
    3598             : 
    3599         483 :         ctrl_iface = wpa_s->global->dbus;
    3600         483 :         if (ctrl_iface == NULL)
    3601         207 :                 return;
    3602             : 
    3603         276 :         if (wpa_s->dbus_groupobj_path) {
    3604           0 :                 wpa_printf(MSG_INFO, "%s: Group object '%s' already exists",
    3605             :                            __func__, wpa_s->dbus_groupobj_path);
    3606           0 :                 return;
    3607             :         }
    3608             : 
    3609         276 :         if (wpas_dbus_get_group_obj_path(wpa_s, ssid, group_obj_path) < 0)
    3610           0 :                 return;
    3611             : 
    3612         276 :         wpa_s->dbus_groupobj_path = os_strdup(group_obj_path);
    3613         276 :         if (wpa_s->dbus_groupobj_path == NULL)
    3614           0 :                 return;
    3615             : 
    3616         276 :         wpa_printf(MSG_INFO, "dbus: Register group object '%s'",
    3617             :                    group_obj_path);
    3618         276 :         obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
    3619         276 :         if (!obj_desc) {
    3620           0 :                 wpa_printf(MSG_ERROR,
    3621             :                            "Not enough memory to create object description");
    3622           0 :                 goto err;
    3623             :         }
    3624             : 
    3625         276 :         wpas_dbus_register(obj_desc, wpa_s, NULL, NULL,
    3626             :                            wpas_dbus_p2p_group_properties,
    3627             :                            wpas_dbus_p2p_group_signals);
    3628             : 
    3629         276 :         if (wpa_dbus_register_object_per_iface(ctrl_iface, group_obj_path,
    3630         276 :                                                wpa_s->ifname, obj_desc))
    3631           0 :                 goto err;
    3632             : 
    3633         276 :         return;
    3634             : 
    3635             : err:
    3636           0 :         if (wpa_s->dbus_groupobj_path) {
    3637           0 :                 os_free(wpa_s->dbus_groupobj_path);
    3638           0 :                 wpa_s->dbus_groupobj_path = NULL;
    3639             :         }
    3640             : 
    3641           0 :         free_dbus_object_desc(obj_desc);
    3642             : }
    3643             : 
    3644             : /**
    3645             :  * wpas_dbus_unregister_p2p_group - Unregister a p2p group object from dbus
    3646             :  * @wpa_s: wpa_supplicant interface structure
    3647             :  * @ssid: network name of the p2p group started
    3648             :  */
    3649         499 : void wpas_dbus_unregister_p2p_group(struct wpa_supplicant *wpa_s,
    3650             :                                     const struct wpa_ssid *ssid)
    3651             : {
    3652             :         struct wpas_dbus_priv *ctrl_iface;
    3653             : 
    3654             :         /* Do nothing if the control interface is not turned on */
    3655         499 :         if (wpa_s == NULL || wpa_s->global == NULL)
    3656           0 :                 return;
    3657             : 
    3658         499 :         if (wpa_s->p2p_mgmt)
    3659           0 :                 wpa_s = wpa_s->parent;
    3660             : 
    3661         499 :         ctrl_iface = wpa_s->global->dbus;
    3662         499 :         if (ctrl_iface == NULL)
    3663         219 :                 return;
    3664             : 
    3665         280 :         if (!wpa_s->dbus_groupobj_path) {
    3666           4 :                 wpa_printf(MSG_DEBUG,
    3667             :                            "%s: Group object '%s' already unregistered",
    3668             :                            __func__, wpa_s->dbus_groupobj_path);
    3669           4 :                 return;
    3670             :         }
    3671             : 
    3672         276 :         peer_groups_changed(wpa_s);
    3673             : 
    3674         276 :         wpa_printf(MSG_DEBUG, "dbus: Unregister group object '%s'",
    3675             :                    wpa_s->dbus_groupobj_path);
    3676             : 
    3677         276 :         wpa_dbus_unregister_object_per_iface(ctrl_iface,
    3678         276 :                                              wpa_s->dbus_groupobj_path);
    3679             : 
    3680         276 :         os_free(wpa_s->dbus_groupobj_path);
    3681         276 :         wpa_s->dbus_groupobj_path = NULL;
    3682             : }
    3683             : 
    3684             : static const struct wpa_dbus_property_desc
    3685             :         wpas_dbus_persistent_group_properties[] = {
    3686             :         { "Properties", WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, "a{sv}",
    3687             :           wpas_dbus_getter_persistent_group_properties,
    3688             :           wpas_dbus_setter_persistent_group_properties
    3689             :         },
    3690             :         { NULL, NULL, NULL, NULL, NULL }
    3691             : };
    3692             : 
    3693             : /* No signals intended for persistent group objects */
    3694             : 
    3695             : /**
    3696             :  * wpas_dbus_register_persistent_group - Register a configured(saved)
    3697             :  *      persistent group with dbus
    3698             :  * @wpa_s: wpa_supplicant interface structure
    3699             :  * @ssid: persistent group (still represented as a network within wpa)
    3700             :  *        configuration data
    3701             :  * Returns: 0 on success, -1 on failure
    3702             :  *
    3703             :  * Registers a persistent group representing object with dbus.
    3704             :  */
    3705          82 : int wpas_dbus_register_persistent_group(struct wpa_supplicant *wpa_s,
    3706             :                                         struct wpa_ssid *ssid)
    3707             : {
    3708             :         struct wpas_dbus_priv *ctrl_iface;
    3709             :         struct wpa_dbus_object_desc *obj_desc;
    3710             :         struct network_handler_args *arg;
    3711             :         char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
    3712             : 
    3713             :         /* Do nothing if the control interface is not turned on */
    3714          82 :         if (wpa_s == NULL || wpa_s->global == NULL)
    3715           0 :                 return 0;
    3716             : 
    3717             :         /* Make sure ssid is a persistent group */
    3718          82 :         if (ssid->disabled != 2 && !ssid->p2p_persistent_group)
    3719           0 :                 return -1; /* should we return w/o complaining? */
    3720             : 
    3721          82 :         if (wpa_s->p2p_mgmt)
    3722           0 :                 wpa_s = wpa_s->parent;
    3723             : 
    3724          82 :         ctrl_iface = wpa_s->global->dbus;
    3725          82 :         if (ctrl_iface == NULL)
    3726          41 :                 return 0;
    3727             : 
    3728             :         /*
    3729             :          * Intentionally not coming up with different numbering scheme
    3730             :          * for persistent groups.
    3731             :          */
    3732          41 :         os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
    3733             :                     "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
    3734             :                     wpa_s->dbus_new_path, ssid->id);
    3735             : 
    3736          41 :         wpa_printf(MSG_DEBUG, "dbus: Register persistent group object '%s'",
    3737             :                    pgrp_obj_path);
    3738          41 :         obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
    3739          41 :         if (!obj_desc) {
    3740           0 :                 wpa_printf(MSG_ERROR,
    3741             :                            "dbus: Not enough memory to create object description");
    3742           0 :                 goto err;
    3743             :         }
    3744             : 
    3745             :         /*
    3746             :          * Reusing the same context structure as that for networks
    3747             :          * since these are represented using same data structure.
    3748             :          */
    3749             :         /* allocate memory for handlers arguments */
    3750          41 :         arg = os_zalloc(sizeof(struct network_handler_args));
    3751          41 :         if (!arg) {
    3752           0 :                 wpa_printf(MSG_ERROR,
    3753             :                            "dbus: Not enough memory to create arguments for method");
    3754           0 :                 goto err;
    3755             :         }
    3756             : 
    3757          41 :         arg->wpa_s = wpa_s;
    3758          41 :         arg->ssid = ssid;
    3759             : 
    3760          41 :         wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
    3761             :                            wpas_dbus_persistent_group_properties,
    3762             :                            NULL);
    3763             : 
    3764          41 :         if (wpa_dbus_register_object_per_iface(ctrl_iface, pgrp_obj_path,
    3765          41 :                                                wpa_s->ifname, obj_desc))
    3766           0 :                 goto err;
    3767             : 
    3768          41 :         wpas_dbus_signal_persistent_group_added(wpa_s, ssid->id);
    3769             : 
    3770          41 :         return 0;
    3771             : 
    3772             : err:
    3773           0 :         free_dbus_object_desc(obj_desc);
    3774           0 :         return -1;
    3775             : }
    3776             : 
    3777             : 
    3778             : /**
    3779             :  * wpas_dbus_unregister_persistent_group - Unregister a persistent_group
    3780             :  *      from dbus
    3781             :  * @wpa_s: wpa_supplicant interface structure
    3782             :  * @nid: network id
    3783             :  * Returns: 0 on success, -1 on failure
    3784             :  *
    3785             :  * Unregisters persistent group representing object from dbus
    3786             :  *
    3787             :  * NOTE: There is a slight issue with the semantics here. While the
    3788             :  * implementation simply means the persistent group is unloaded from memory,
    3789             :  * it should not get interpreted as the group is actually being erased/removed
    3790             :  * from persistent storage as well.
    3791             :  */
    3792          88 : int wpas_dbus_unregister_persistent_group(struct wpa_supplicant *wpa_s,
    3793             :                                           int nid)
    3794             : {
    3795             :         struct wpas_dbus_priv *ctrl_iface;
    3796             :         char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
    3797             :         int ret;
    3798             : 
    3799             :         /* Do nothing if the control interface is not turned on */
    3800         176 :         if (wpa_s == NULL || wpa_s->global == NULL ||
    3801          88 :             wpa_s->dbus_new_path == NULL)
    3802          43 :                 return 0;
    3803             : 
    3804          45 :         if (wpa_s->p2p_mgmt)
    3805           0 :                 wpa_s = wpa_s->parent;
    3806             : 
    3807          45 :         ctrl_iface = wpa_s->global->dbus;
    3808          45 :         if (ctrl_iface == NULL)
    3809           0 :                 return 0;
    3810             : 
    3811          45 :         os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
    3812             :                     "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
    3813             :                     wpa_s->dbus_new_path, nid);
    3814             : 
    3815          45 :         wpa_printf(MSG_DEBUG, "dbus: Unregister persistent group object '%s'",
    3816             :                    pgrp_obj_path);
    3817          45 :         ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, pgrp_obj_path);
    3818             : 
    3819          45 :         if (!ret)
    3820          45 :                 wpas_dbus_signal_persistent_group_removed(wpa_s, nid);
    3821             : 
    3822          45 :         return ret;
    3823             : }
    3824             : 
    3825             : #endif /* CONFIG_P2P */

Generated by: LCOV version 1.10