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

Generated by: LCOV version 1.10