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

Generated by: LCOV version 1.10