LCOV - code coverage report
Current view: top level - wpa_supplicant - p2p_supplicant.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1393793999 Lines: 2739 3976 68.9 %
Date: 2014-03-02 Functions: 171 200 85.5 %
Branches: 1300 2438 53.3 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * wpa_supplicant - P2P
       3                 :            :  * Copyright (c) 2009-2010, Atheros Communications
       4                 :            :  * Copyright (c) 2010-2014, Jouni Malinen <j@w1.fi>
       5                 :            :  *
       6                 :            :  * This software may be distributed under the terms of the BSD license.
       7                 :            :  * See README for more details.
       8                 :            :  */
       9                 :            : 
      10                 :            : #include "includes.h"
      11                 :            : 
      12                 :            : #include "common.h"
      13                 :            : #include "eloop.h"
      14                 :            : #include "common/ieee802_11_common.h"
      15                 :            : #include "common/ieee802_11_defs.h"
      16                 :            : #include "common/wpa_ctrl.h"
      17                 :            : #include "wps/wps_i.h"
      18                 :            : #include "p2p/p2p.h"
      19                 :            : #include "ap/hostapd.h"
      20                 :            : #include "ap/ap_config.h"
      21                 :            : #include "ap/sta_info.h"
      22                 :            : #include "ap/ap_drv_ops.h"
      23                 :            : #include "ap/wps_hostapd.h"
      24                 :            : #include "ap/p2p_hostapd.h"
      25                 :            : #include "eapol_supp/eapol_supp_sm.h"
      26                 :            : #include "rsn_supp/wpa.h"
      27                 :            : #include "wpa_supplicant_i.h"
      28                 :            : #include "driver_i.h"
      29                 :            : #include "ap.h"
      30                 :            : #include "config_ssid.h"
      31                 :            : #include "config.h"
      32                 :            : #include "notify.h"
      33                 :            : #include "scan.h"
      34                 :            : #include "bss.h"
      35                 :            : #include "offchannel.h"
      36                 :            : #include "wps_supplicant.h"
      37                 :            : #include "p2p_supplicant.h"
      38                 :            : #include "wifi_display.h"
      39                 :            : 
      40                 :            : 
      41                 :            : /*
      42                 :            :  * How many times to try to scan to find the GO before giving up on join
      43                 :            :  * request.
      44                 :            :  */
      45                 :            : #define P2P_MAX_JOIN_SCAN_ATTEMPTS 10
      46                 :            : 
      47                 :            : #define P2P_AUTO_PD_SCAN_ATTEMPTS 5
      48                 :            : 
      49                 :            : #ifndef P2P_MAX_CLIENT_IDLE
      50                 :            : /*
      51                 :            :  * How many seconds to try to reconnect to the GO when connection in P2P client
      52                 :            :  * role has been lost.
      53                 :            :  */
      54                 :            : #define P2P_MAX_CLIENT_IDLE 10
      55                 :            : #endif /* P2P_MAX_CLIENT_IDLE */
      56                 :            : 
      57                 :            : #ifndef P2P_MAX_INITIAL_CONN_WAIT
      58                 :            : /*
      59                 :            :  * How many seconds to wait for initial 4-way handshake to get completed after
      60                 :            :  * WPS provisioning step.
      61                 :            :  */
      62                 :            : #define P2P_MAX_INITIAL_CONN_WAIT 10
      63                 :            : #endif /* P2P_MAX_INITIAL_CONN_WAIT */
      64                 :            : 
      65                 :            : #ifndef P2P_MAX_INITIAL_CONN_WAIT_GO
      66                 :            : /*
      67                 :            :  * How many seconds to wait for initial 4-way handshake to get completed after
      68                 :            :  * WPS provisioning step on the GO. This controls the extra time the P2P
      69                 :            :  * operation is considered to be in progress (e.g., to delay other scans) after
      70                 :            :  * WPS provisioning has been completed on the GO during group formation.
      71                 :            :  */
      72                 :            : #define P2P_MAX_INITIAL_CONN_WAIT_GO 10
      73                 :            : #endif /* P2P_MAX_INITIAL_CONN_WAIT_GO */
      74                 :            : 
      75                 :            : #ifndef P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE
      76                 :            : /*
      77                 :            :  * How many seconds to wait for initial 4-way handshake to get completed after
      78                 :            :  * re-invocation of a persistent group on the GO when the client is expected
      79                 :            :  * to connect automatically (no user interaction).
      80                 :            :  */
      81                 :            : #define P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE 15
      82                 :            : #endif /* P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE */
      83                 :            : 
      84                 :            : #ifndef P2P_CONCURRENT_SEARCH_DELAY
      85                 :            : #define P2P_CONCURRENT_SEARCH_DELAY 500
      86                 :            : #endif /* P2P_CONCURRENT_SEARCH_DELAY */
      87                 :            : 
      88                 :            : #define P2P_MGMT_DEVICE_PREFIX          "p2p-dev-"
      89                 :            : 
      90                 :            : enum p2p_group_removal_reason {
      91                 :            :         P2P_GROUP_REMOVAL_UNKNOWN,
      92                 :            :         P2P_GROUP_REMOVAL_SILENT,
      93                 :            :         P2P_GROUP_REMOVAL_FORMATION_FAILED,
      94                 :            :         P2P_GROUP_REMOVAL_REQUESTED,
      95                 :            :         P2P_GROUP_REMOVAL_IDLE_TIMEOUT,
      96                 :            :         P2P_GROUP_REMOVAL_UNAVAILABLE,
      97                 :            :         P2P_GROUP_REMOVAL_GO_ENDING_SESSION,
      98                 :            :         P2P_GROUP_REMOVAL_PSK_FAILURE,
      99                 :            :         P2P_GROUP_REMOVAL_FREQ_CONFLICT
     100                 :            : };
     101                 :            : 
     102                 :            : 
     103                 :            : static void wpas_p2p_long_listen_timeout(void *eloop_ctx, void *timeout_ctx);
     104                 :            : static struct wpa_supplicant *
     105                 :            : wpas_p2p_get_group_iface(struct wpa_supplicant *wpa_s, int addr_allocated,
     106                 :            :                          int go);
     107                 :            : static int wpas_p2p_join_start(struct wpa_supplicant *wpa_s, int freq,
     108                 :            :                                const u8 *ssid, size_t ssid_len);
     109                 :            : static void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq,
     110                 :            :                                    const u8 *ssid, size_t ssid_len);
     111                 :            : static void wpas_p2p_join_scan(void *eloop_ctx, void *timeout_ctx);
     112                 :            : static int wpas_p2p_join(struct wpa_supplicant *wpa_s, const u8 *iface_addr,
     113                 :            :                          const u8 *dev_addr, enum p2p_wps_method wps_method,
     114                 :            :                          int auto_join, int freq,
     115                 :            :                          const u8 *ssid, size_t ssid_len);
     116                 :            : static int wpas_p2p_create_iface(struct wpa_supplicant *wpa_s);
     117                 :            : static void wpas_p2p_cross_connect_setup(struct wpa_supplicant *wpa_s);
     118                 :            : static void wpas_p2p_group_idle_timeout(void *eloop_ctx, void *timeout_ctx);
     119                 :            : static void wpas_p2p_set_group_idle_timeout(struct wpa_supplicant *wpa_s);
     120                 :            : static void wpas_p2p_group_formation_timeout(void *eloop_ctx,
     121                 :            :                                              void *timeout_ctx);
     122                 :            : static void wpas_p2p_group_freq_conflict(void *eloop_ctx, void *timeout_ctx);
     123                 :            : static void wpas_p2p_fallback_to_go_neg(struct wpa_supplicant *wpa_s,
     124                 :            :                                         int group_added);
     125                 :            : static int wpas_p2p_stop_find_oper(struct wpa_supplicant *wpa_s);
     126                 :            : static void wpas_stop_listen(void *ctx);
     127                 :            : 
     128                 :            : 
     129                 :            : /*
     130                 :            :  * Get the number of concurrent channels that the HW can operate, but that are
     131                 :            :  * currently not in use by any of the wpa_supplicant interfaces.
     132                 :            :  */
     133                 :         62 : static int wpas_p2p_num_unused_channels(struct wpa_supplicant *wpa_s)
     134                 :            : {
     135                 :            :         int *freqs;
     136                 :            :         int num, unused;
     137                 :            : 
     138                 :         62 :         freqs = os_calloc(wpa_s->num_multichan_concurrent, sizeof(int));
     139         [ -  + ]:         62 :         if (!freqs)
     140                 :          0 :                 return -1;
     141                 :            : 
     142                 :         62 :         num = get_shared_radio_freqs(wpa_s, freqs,
     143                 :            :                                      wpa_s->num_multichan_concurrent);
     144                 :         62 :         os_free(freqs);
     145                 :            : 
     146                 :         62 :         unused = wpa_s->num_multichan_concurrent - num;
     147                 :         62 :         wpa_dbg(wpa_s, MSG_DEBUG, "P2P: num_unused_channels: %d", unused);
     148                 :         62 :         return unused;
     149                 :            : }
     150                 :            : 
     151                 :            : 
     152                 :            : /*
     153                 :            :  * Get the frequencies that are currently in use by one or more of the virtual
     154                 :            :  * interfaces, and that are also valid for P2P operation.
     155                 :            :  */
     156                 :         46 : static int wpas_p2p_valid_oper_freqs(struct wpa_supplicant *wpa_s,
     157                 :            :                                      int *p2p_freqs, unsigned int len)
     158                 :            : {
     159                 :            :         int *freqs;
     160                 :            :         unsigned int num, i, j;
     161                 :            : 
     162                 :         46 :         freqs = os_calloc(wpa_s->num_multichan_concurrent, sizeof(int));
     163         [ -  + ]:         46 :         if (!freqs)
     164                 :          0 :                 return -1;
     165                 :            : 
     166                 :         46 :         num = get_shared_radio_freqs(wpa_s, freqs,
     167                 :            :                                      wpa_s->num_multichan_concurrent);
     168                 :            : 
     169                 :         46 :         os_memset(p2p_freqs, 0, sizeof(int) * len);
     170                 :            : 
     171 [ +  + ][ +  - ]:         48 :         for (i = 0, j = 0; i < num && j < len; i++) {
     172         [ +  - ]:          2 :                 if (p2p_supported_freq(wpa_s->global->p2p, freqs[i]))
     173                 :          2 :                         p2p_freqs[j++] = freqs[i];
     174                 :            :         }
     175                 :            : 
     176                 :         46 :         os_free(freqs);
     177                 :            : 
     178                 :         46 :         dump_freq_array(wpa_s, "valid for P2P", p2p_freqs, j);
     179                 :            : 
     180                 :         46 :         return j;
     181                 :            : }
     182                 :            : 
     183                 :            : 
     184                 :        116 : static void wpas_p2p_set_own_freq_preference(struct wpa_supplicant *wpa_s,
     185                 :            :                                              int freq)
     186                 :            : {
     187 [ +  - ][ -  + ]:        116 :         if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
     188                 :        116 :                 return;
     189 [ -  + ][ #  # ]:        116 :         if (wpa_s->parent->conf->p2p_ignore_shared_freq &&
     190   [ #  #  #  # ]:          0 :             freq > 0 && wpa_s->num_multichan_concurrent > 1 &&
     191                 :          0 :             wpas_p2p_num_unused_channels(wpa_s) > 0) {
     192                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Ignore own channel preference %d MHz due to p2p_ignore_shared_freq=1 configuration",
     193                 :            :                            freq);
     194                 :          0 :                 freq = 0;
     195                 :            :         }
     196                 :        116 :         p2p_set_own_freq_preference(wpa_s->global->p2p, freq);
     197                 :            : }
     198                 :            : 
     199                 :            : 
     200                 :        658 : static void wpas_p2p_scan_res_handler(struct wpa_supplicant *wpa_s,
     201                 :            :                                       struct wpa_scan_results *scan_res)
     202                 :            : {
     203                 :            :         size_t i;
     204                 :            : 
     205         [ +  + ]:        658 :         if (wpa_s->p2p_scan_work) {
     206                 :        620 :                 struct wpa_radio_work *work = wpa_s->p2p_scan_work;
     207                 :        620 :                 wpa_s->p2p_scan_work = NULL;
     208                 :        620 :                 radio_work_done(work);
     209                 :            :         }
     210                 :            : 
     211 [ +  - ][ -  + ]:        658 :         if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
     212                 :        658 :                 return;
     213                 :            : 
     214                 :        658 :         wpa_printf(MSG_DEBUG, "P2P: Scan results received (%d BSS)",
     215                 :        658 :                    (int) scan_res->num);
     216                 :            : 
     217         [ +  + ]:       2086 :         for (i = 0; i < scan_res->num; i++) {
     218                 :       1428 :                 struct wpa_scan_res *bss = scan_res->res[i];
     219                 :            :                 struct os_reltime time_tmp_age, entry_ts;
     220                 :            :                 const u8 *ies;
     221                 :            :                 size_t ies_len;
     222                 :            : 
     223                 :       1428 :                 time_tmp_age.sec = bss->age / 1000;
     224                 :       1428 :                 time_tmp_age.usec = (bss->age % 1000) * 1000;
     225                 :       1428 :                 os_reltime_sub(&scan_res->fetch_time, &time_tmp_age, &entry_ts);
     226                 :            : 
     227                 :       1428 :                 ies = (const u8 *) (bss + 1);
     228                 :       1428 :                 ies_len = bss->ie_len;
     229   [ +  +  +  + ]:       2234 :                 if (bss->beacon_ie_len > 0 &&
     230         [ +  + ]:       1065 :                     !wpa_scan_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE) &&
     231                 :        259 :                     wpa_scan_get_vendor_ie_beacon(bss, P2P_IE_VENDOR_TYPE)) {
     232                 :          2 :                         wpa_printf(MSG_DEBUG, "P2P: Use P2P IE(s) from Beacon frame since no P2P IE(s) in Probe Response frames received for "
     233                 :         12 :                                    MACSTR, MAC2STR(bss->bssid));
     234                 :          2 :                         ies = ies + ies_len;
     235                 :          2 :                         ies_len = bss->beacon_ie_len;
     236                 :            :                 }
     237                 :            : 
     238                 :            : 
     239         [ -  + ]:       1428 :                 if (p2p_scan_res_handler(wpa_s->global->p2p, bss->bssid,
     240                 :            :                                          bss->freq, &entry_ts, bss->level,
     241                 :            :                                          ies, ies_len) > 0)
     242                 :          0 :                         break;
     243                 :            :         }
     244                 :            : 
     245                 :        658 :         p2p_scan_res_handled(wpa_s->global->p2p);
     246                 :            : }
     247                 :            : 
     248                 :            : 
     249                 :        642 : static void wpas_p2p_trigger_scan_cb(struct wpa_radio_work *work, int deinit)
     250                 :            : {
     251                 :        642 :         struct wpa_supplicant *wpa_s = work->wpa_s;
     252                 :        642 :         struct wpa_driver_scan_params *params = work->ctx;
     253                 :            :         int ret;
     254                 :            : 
     255         [ +  + ]:        642 :         if (deinit) {
     256         [ +  + ]:         12 :                 if (!work->started) {
     257                 :          2 :                         wpa_scan_free_params(params);
     258                 :          2 :                         return;
     259                 :            :                 }
     260                 :            : 
     261                 :         10 :                 wpa_s->p2p_scan_work = NULL;
     262                 :         10 :                 return;
     263                 :            :         }
     264                 :            : 
     265                 :        630 :         ret = wpa_drv_scan(wpa_s, params);
     266                 :        630 :         wpa_scan_free_params(params);
     267                 :        630 :         work->ctx = NULL;
     268         [ -  + ]:        630 :         if (ret) {
     269                 :          0 :                 radio_work_done(work);
     270                 :          0 :                 return;
     271                 :            :         }
     272                 :            : 
     273                 :        630 :         os_get_reltime(&wpa_s->scan_trigger_time);
     274                 :        630 :         wpa_s->scan_res_handler = wpas_p2p_scan_res_handler;
     275                 :        630 :         wpa_s->own_scan_requested = 1;
     276                 :        642 :         wpa_s->p2p_scan_work = work;
     277                 :            : }
     278                 :            : 
     279                 :            : 
     280                 :        638 : static int wpas_p2p_scan(void *ctx, enum p2p_scan_type type, int freq,
     281                 :            :                          unsigned int num_req_dev_types,
     282                 :            :                          const u8 *req_dev_types, const u8 *dev_id, u16 pw_id)
     283                 :            : {
     284                 :        638 :         struct wpa_supplicant *wpa_s = ctx;
     285                 :        638 :         struct wpa_driver_scan_params *params = NULL;
     286                 :            :         struct wpabuf *wps_ie, *ies;
     287                 :            :         size_t ielen;
     288                 :            :         u8 *n;
     289                 :            : 
     290 [ +  - ][ -  + ]:        638 :         if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
     291                 :          0 :                 return -1;
     292                 :            : 
     293         [ +  + ]:        638 :         if (wpa_s->p2p_scan_work) {
     294                 :          6 :                 wpa_dbg(wpa_s, MSG_INFO, "P2P: Reject scan trigger since one is already pending");
     295                 :          6 :                 return -1;
     296                 :            :         }
     297                 :            : 
     298                 :        632 :         params = os_zalloc(sizeof(*params));
     299         [ -  + ]:        632 :         if (params == NULL)
     300                 :          0 :                 return -1;
     301                 :            : 
     302                 :            :         /* P2P Wildcard SSID */
     303                 :        632 :         params->num_ssids = 1;
     304                 :        632 :         n = os_malloc(P2P_WILDCARD_SSID_LEN);
     305         [ -  + ]:        632 :         if (n == NULL)
     306                 :          0 :                 goto fail;
     307                 :        632 :         os_memcpy(n, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN);
     308                 :        632 :         params->ssids[0].ssid = n;
     309                 :        632 :         params->ssids[0].ssid_len = P2P_WILDCARD_SSID_LEN;
     310                 :            : 
     311                 :        632 :         wpa_s->wps->dev.p2p = 1;
     312                 :        632 :         wps_ie = wps_build_probe_req_ie(pw_id, &wpa_s->wps->dev,
     313                 :        632 :                                         wpa_s->wps->uuid, WPS_REQ_ENROLLEE,
     314                 :            :                                         num_req_dev_types, req_dev_types);
     315         [ -  + ]:        632 :         if (wps_ie == NULL)
     316                 :          0 :                 goto fail;
     317                 :            : 
     318                 :        632 :         ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p);
     319                 :        632 :         ies = wpabuf_alloc(wpabuf_len(wps_ie) + ielen);
     320         [ -  + ]:        632 :         if (ies == NULL) {
     321                 :          0 :                 wpabuf_free(wps_ie);
     322                 :          0 :                 goto fail;
     323                 :            :         }
     324                 :        632 :         wpabuf_put_buf(ies, wps_ie);
     325                 :        632 :         wpabuf_free(wps_ie);
     326                 :            : 
     327                 :        632 :         p2p_scan_ie(wpa_s->global->p2p, ies, dev_id);
     328                 :            : 
     329                 :        632 :         params->p2p_probe = 1;
     330                 :        632 :         n = os_malloc(wpabuf_len(ies));
     331         [ -  + ]:        632 :         if (n == NULL) {
     332                 :          0 :                 wpabuf_free(ies);
     333                 :          0 :                 goto fail;
     334                 :            :         }
     335                 :        632 :         os_memcpy(n, wpabuf_head(ies), wpabuf_len(ies));
     336                 :        632 :         params->extra_ies = n;
     337                 :        632 :         params->extra_ies_len = wpabuf_len(ies);
     338                 :        632 :         wpabuf_free(ies);
     339                 :            : 
     340   [ +  +  -  - ]:        632 :         switch (type) {
     341                 :            :         case P2P_SCAN_SOCIAL:
     342                 :        610 :                 params->freqs = os_malloc(4 * sizeof(int));
     343         [ -  + ]:        610 :                 if (params->freqs == NULL)
     344                 :          0 :                         goto fail;
     345                 :        610 :                 params->freqs[0] = 2412;
     346                 :        610 :                 params->freqs[1] = 2437;
     347                 :        610 :                 params->freqs[2] = 2462;
     348                 :        610 :                 params->freqs[3] = 0;
     349                 :        610 :                 break;
     350                 :            :         case P2P_SCAN_FULL:
     351                 :         22 :                 break;
     352                 :            :         case P2P_SCAN_SOCIAL_PLUS_ONE:
     353                 :          0 :                 params->freqs = os_malloc(5 * sizeof(int));
     354         [ #  # ]:          0 :                 if (params->freqs == NULL)
     355                 :          0 :                         goto fail;
     356                 :          0 :                 params->freqs[0] = 2412;
     357                 :          0 :                 params->freqs[1] = 2437;
     358                 :          0 :                 params->freqs[2] = 2462;
     359                 :          0 :                 params->freqs[3] = freq;
     360                 :          0 :                 params->freqs[4] = 0;
     361                 :          0 :                 break;
     362                 :            :         }
     363                 :            : 
     364                 :        632 :         radio_remove_works(wpa_s, "p2p-scan", 0);
     365         [ -  + ]:        632 :         if (radio_add_work(wpa_s, 0, "p2p-scan", 0, wpas_p2p_trigger_scan_cb,
     366                 :            :                            params) < 0)
     367                 :          0 :                 goto fail;
     368                 :        632 :         return 0;
     369                 :            : 
     370                 :            : fail:
     371                 :          0 :         wpa_scan_free_params(params);
     372                 :        638 :         return -1;
     373                 :            : }
     374                 :            : 
     375                 :            : 
     376                 :         24 : static enum wpa_driver_if_type wpas_p2p_if_type(int p2p_group_interface)
     377                 :            : {
     378   [ -  +  +  - ]:         24 :         switch (p2p_group_interface) {
     379                 :            :         case P2P_GROUP_INTERFACE_PENDING:
     380                 :          0 :                 return WPA_IF_P2P_GROUP;
     381                 :            :         case P2P_GROUP_INTERFACE_GO:
     382                 :         13 :                 return WPA_IF_P2P_GO;
     383                 :            :         case P2P_GROUP_INTERFACE_CLIENT:
     384                 :         11 :                 return WPA_IF_P2P_CLIENT;
     385                 :            :         }
     386                 :            : 
     387                 :         24 :         return WPA_IF_P2P_GROUP;
     388                 :            : }
     389                 :            : 
     390                 :            : 
     391                 :         27 : static struct wpa_supplicant * wpas_get_p2p_group(struct wpa_supplicant *wpa_s,
     392                 :            :                                                   const u8 *ssid,
     393                 :            :                                                   size_t ssid_len, int *go)
     394                 :            : {
     395                 :            :         struct wpa_ssid *s;
     396                 :            : 
     397         [ +  + ]:         54 :         for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
     398         [ +  + ]:         53 :                 for (s = wpa_s->conf->ssid; s; s = s->next) {
     399 [ -  + ][ #  # ]:         26 :                         if (s->disabled != 0 || !s->p2p_group ||
                 [ #  # ]
     400         [ #  # ]:          0 :                             s->ssid_len != ssid_len ||
     401                 :          0 :                             os_memcmp(ssid, s->ssid, ssid_len) != 0)
     402                 :         26 :                                 continue;
     403 [ #  # ][ #  # ]:          0 :                         if (s->mode == WPAS_MODE_P2P_GO &&
     404                 :          0 :                             s != wpa_s->current_ssid)
     405                 :          0 :                                 continue;
     406         [ #  # ]:          0 :                         if (go)
     407                 :          0 :                                 *go = s->mode == WPAS_MODE_P2P_GO;
     408                 :          0 :                         return wpa_s;
     409                 :            :                 }
     410                 :            :         }
     411                 :            : 
     412                 :         27 :         return NULL;
     413                 :            : }
     414                 :            : 
     415                 :            : 
     416                 :        177 : static int wpas_p2p_group_delete(struct wpa_supplicant *wpa_s,
     417                 :            :                                  enum p2p_group_removal_reason removal_reason)
     418                 :            : {
     419                 :            :         struct wpa_ssid *ssid;
     420                 :            :         char *gtype;
     421                 :            :         const char *reason;
     422                 :            : 
     423                 :        177 :         ssid = wpa_s->current_ssid;
     424         [ +  + ]:        177 :         if (ssid == NULL) {
     425                 :            :                 /*
     426                 :            :                  * The current SSID was not known, but there may still be a
     427                 :            :                  * pending P2P group interface waiting for provisioning or a
     428                 :            :                  * P2P group that is trying to reconnect.
     429                 :            :                  */
     430                 :         10 :                 ssid = wpa_s->conf->ssid;
     431         [ -  + ]:         10 :                 while (ssid) {
     432 [ #  # ][ #  # ]:          0 :                         if (ssid->p2p_group && ssid->disabled != 2)
     433                 :          0 :                                 break;
     434                 :          0 :                         ssid = ssid->next;
     435                 :            :                 }
     436 [ +  - ][ +  - ]:         10 :                 if (ssid == NULL &&
     437                 :         10 :                         wpa_s->p2p_group_interface == NOT_P2P_GROUP_INTERFACE)
     438                 :            :                 {
     439                 :         10 :                         wpa_printf(MSG_ERROR, "P2P: P2P group interface "
     440                 :            :                                    "not found");
     441                 :         10 :                         return -1;
     442                 :            :                 }
     443                 :            :         }
     444         [ +  + ]:        167 :         if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_GO)
     445                 :         13 :                 gtype = "GO";
     446 [ +  + ][ +  - ]:        154 :         else if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT ||
     447         [ +  + ]:        143 :                  (ssid && ssid->mode == WPAS_MODE_INFRA)) {
     448                 :         87 :                 wpa_s->reassociate = 0;
     449                 :         87 :                 wpa_s->disconnected = 1;
     450                 :         87 :                 wpa_supplicant_deauthenticate(wpa_s,
     451                 :            :                                               WLAN_REASON_DEAUTH_LEAVING);
     452                 :         87 :                 gtype = "client";
     453                 :            :         } else
     454                 :         67 :                 gtype = "GO";
     455         [ -  + ]:        167 :         if (wpa_s->cross_connect_in_use) {
     456                 :          0 :                 wpa_s->cross_connect_in_use = 0;
     457                 :          0 :                 wpa_msg_global(wpa_s->parent, MSG_INFO,
     458                 :            :                                P2P_EVENT_CROSS_CONNECT_DISABLE "%s %s",
     459                 :          0 :                                wpa_s->ifname, wpa_s->cross_connect_uplink);
     460                 :            :         }
     461   [ +  +  -  -  :        167 :         switch (removal_reason) {
             +  +  -  - ]
     462                 :            :         case P2P_GROUP_REMOVAL_REQUESTED:
     463                 :        113 :                 reason = " reason=REQUESTED";
     464                 :        113 :                 break;
     465                 :            :         case P2P_GROUP_REMOVAL_FORMATION_FAILED:
     466                 :          2 :                 reason = " reason=FORMATION_FAILED";
     467                 :          2 :                 break;
     468                 :            :         case P2P_GROUP_REMOVAL_IDLE_TIMEOUT:
     469                 :          0 :                 reason = " reason=IDLE";
     470                 :          0 :                 break;
     471                 :            :         case P2P_GROUP_REMOVAL_UNAVAILABLE:
     472                 :          0 :                 reason = " reason=UNAVAILABLE";
     473                 :          0 :                 break;
     474                 :            :         case P2P_GROUP_REMOVAL_GO_ENDING_SESSION:
     475                 :         50 :                 reason = " reason=GO_ENDING_SESSION";
     476                 :         50 :                 break;
     477                 :            :         case P2P_GROUP_REMOVAL_PSK_FAILURE:
     478                 :          2 :                 reason = " reason=PSK_FAILURE";
     479                 :          2 :                 break;
     480                 :            :         case P2P_GROUP_REMOVAL_FREQ_CONFLICT:
     481                 :          0 :                 reason = " reason=FREQ_CONFLICT";
     482                 :          0 :                 break;
     483                 :            :         default:
     484                 :          0 :                 reason = "";
     485                 :          0 :                 break;
     486                 :            :         }
     487         [ +  - ]:        167 :         if (removal_reason != P2P_GROUP_REMOVAL_SILENT) {
     488                 :        167 :                 wpa_msg_global(wpa_s->parent, MSG_INFO,
     489                 :            :                                P2P_EVENT_GROUP_REMOVED "%s %s%s",
     490                 :        167 :                                wpa_s->ifname, gtype, reason);
     491                 :            :         }
     492                 :            : 
     493         [ -  + ]:        167 :         if (eloop_cancel_timeout(wpas_p2p_group_freq_conflict, wpa_s, NULL) > 0)
     494                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group freq_conflict timeout");
     495         [ +  + ]:        167 :         if (eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL) > 0)
     496                 :         85 :                 wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group idle timeout");
     497         [ +  + ]:        167 :         if (eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
     498                 :        167 :                                  wpa_s->parent, NULL) > 0) {
     499                 :          1 :                 wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group formation "
     500                 :            :                            "timeout");
     501                 :          1 :                 wpa_s->p2p_in_provisioning = 0;
     502                 :            :         }
     503                 :            : 
     504                 :            :         /*
     505                 :            :          * Make sure wait for the first client does not remain active after the
     506                 :            :          * group has been removed.
     507                 :            :          */
     508                 :        167 :         wpa_s->global->p2p_go_wait_client.sec = 0;
     509                 :            : 
     510 [ +  - ][ +  - ]:        167 :         if (removal_reason != P2P_GROUP_REMOVAL_SILENT && ssid)
     511                 :        167 :                 wpas_notify_p2p_group_removed(wpa_s, ssid, gtype);
     512                 :            : 
     513         [ +  + ]:        167 :         if (wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE) {
     514                 :            :                 struct wpa_global *global;
     515                 :            :                 char *ifname;
     516                 :            :                 enum wpa_driver_if_type type;
     517                 :         24 :                 wpa_printf(MSG_DEBUG, "P2P: Remove group interface %s",
     518                 :         24 :                         wpa_s->ifname);
     519                 :         24 :                 global = wpa_s->global;
     520                 :         24 :                 ifname = os_strdup(wpa_s->ifname);
     521                 :         24 :                 type = wpas_p2p_if_type(wpa_s->p2p_group_interface);
     522                 :         24 :                 wpa_supplicant_remove_iface(wpa_s->global, wpa_s, 0);
     523                 :         24 :                 wpa_s = global->ifaces;
     524 [ +  - ][ +  - ]:         24 :                 if (wpa_s && ifname)
     525                 :         24 :                         wpa_drv_if_remove(wpa_s, type, ifname);
     526                 :         24 :                 os_free(ifname);
     527                 :         24 :                 return 1;
     528                 :            :         }
     529                 :            : 
     530         [ +  + ]:        143 :         if (!wpa_s->p2p_go_group_formation_completed) {
     531                 :          1 :                 wpa_s->global->p2p_group_formation = NULL;
     532                 :          1 :                 wpa_s->p2p_in_provisioning = 0;
     533                 :            :         }
     534                 :            : 
     535                 :        143 :         wpa_s->show_group_started = 0;
     536                 :        143 :         os_free(wpa_s->go_params);
     537                 :        143 :         wpa_s->go_params = NULL;
     538                 :            : 
     539                 :        143 :         wpa_s->waiting_presence_resp = 0;
     540                 :            : 
     541                 :        143 :         wpa_printf(MSG_DEBUG, "P2P: Remove temporary group network");
     542 [ +  - ][ -  + ]:        143 :         if (ssid && (ssid->p2p_group ||
                 [ #  # ]
     543         [ #  # ]:          0 :                      ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION ||
     544                 :        143 :                      (ssid->key_mgmt & WPA_KEY_MGMT_WPS))) {
     545                 :        143 :                 int id = ssid->id;
     546         [ +  + ]:        143 :                 if (ssid == wpa_s->current_ssid) {
     547                 :         67 :                         wpa_sm_set_config(wpa_s->wpa, NULL);
     548                 :         67 :                         eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
     549                 :         67 :                         wpa_s->current_ssid = NULL;
     550                 :            :                 }
     551                 :            :                 /*
     552                 :            :                  * Networks objects created during any P2P activities are not
     553                 :            :                  * exposed out as they might/will confuse certain non-P2P aware
     554                 :            :                  * applications since these network objects won't behave like
     555                 :            :                  * regular ones.
     556                 :            :                  *
     557                 :            :                  * Likewise, we don't send out network removed signals for such
     558                 :            :                  * network objects.
     559                 :            :                  */
     560                 :        143 :                 wpa_config_remove_network(wpa_s->conf, id);
     561                 :        143 :                 wpa_supplicant_clear_status(wpa_s);
     562                 :        143 :                 wpa_supplicant_cancel_sched_scan(wpa_s);
     563                 :            :         } else {
     564                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Temporary group network not "
     565                 :            :                            "found");
     566                 :            :         }
     567         [ +  + ]:        143 :         if (wpa_s->ap_iface)
     568                 :         67 :                 wpa_supplicant_ap_deinit(wpa_s);
     569                 :            :         else
     570                 :         76 :                 wpa_drv_deinit_p2p_cli(wpa_s);
     571                 :            : 
     572                 :        177 :         return 0;
     573                 :            : }
     574                 :            : 
     575                 :            : 
     576                 :        239 : static int wpas_p2p_persistent_group(struct wpa_supplicant *wpa_s,
     577                 :            :                                      u8 *go_dev_addr,
     578                 :            :                                      const u8 *ssid, size_t ssid_len)
     579                 :            : {
     580                 :            :         struct wpa_bss *bss;
     581                 :            :         const u8 *bssid;
     582                 :            :         struct wpabuf *p2p;
     583                 :            :         u8 group_capab;
     584                 :            :         const u8 *addr;
     585                 :            : 
     586         [ +  + ]:        239 :         if (wpa_s->go_params)
     587                 :        228 :                 bssid = wpa_s->go_params->peer_interface_addr;
     588                 :            :         else
     589                 :         11 :                 bssid = wpa_s->bssid;
     590                 :            : 
     591                 :        239 :         bss = wpa_bss_get(wpa_s, bssid, ssid, ssid_len);
     592         [ +  + ]:        251 :         if (bss == NULL && wpa_s->go_params &&
           [ +  -  +  - ]
     593                 :         12 :             !is_zero_ether_addr(wpa_s->go_params->peer_device_addr))
     594                 :         12 :                 bss = wpa_bss_get_p2p_dev_addr(
     595                 :         12 :                         wpa_s, wpa_s->go_params->peer_device_addr);
     596         [ -  + ]:        239 :         if (bss == NULL) {
     597                 :            :                 u8 iface_addr[ETH_ALEN];
     598         [ #  # ]:          0 :                 if (p2p_get_interface_addr(wpa_s->global->p2p, bssid,
     599                 :            :                                            iface_addr) == 0)
     600                 :          0 :                         bss = wpa_bss_get(wpa_s, iface_addr, ssid, ssid_len);
     601                 :            :         }
     602         [ -  + ]:        239 :         if (bss == NULL) {
     603                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Could not figure out whether "
     604                 :            :                            "group is persistent - BSS " MACSTR " not found",
     605                 :          0 :                            MAC2STR(bssid));
     606                 :          0 :                 return 0;
     607                 :            :         }
     608                 :            : 
     609                 :        239 :         p2p = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
     610         [ +  + ]:        239 :         if (p2p == NULL)
     611                 :          1 :                 p2p = wpa_bss_get_vendor_ie_multi_beacon(bss,
     612                 :            :                                                          P2P_IE_VENDOR_TYPE);
     613         [ +  + ]:        239 :         if (p2p == NULL) {
     614                 :          1 :                 wpa_printf(MSG_DEBUG, "P2P: Could not figure out whether "
     615                 :            :                            "group is persistent - BSS " MACSTR
     616                 :          6 :                            " did not include P2P IE", MAC2STR(bssid));
     617                 :          1 :                 wpa_hexdump(MSG_DEBUG, "P2P: Probe Response IEs",
     618                 :            :                             (u8 *) (bss + 1), bss->ie_len);
     619                 :          1 :                 wpa_hexdump(MSG_DEBUG, "P2P: Beacon IEs",
     620                 :          1 :                             ((u8 *) bss + 1) + bss->ie_len,
     621                 :            :                             bss->beacon_ie_len);
     622                 :          1 :                 return 0;
     623                 :            :         }
     624                 :            : 
     625                 :        238 :         group_capab = p2p_get_group_capab(p2p);
     626                 :        238 :         addr = p2p_get_go_dev_addr(p2p);
     627                 :        238 :         wpa_printf(MSG_DEBUG, "P2P: Checking whether group is persistent: "
     628                 :            :                    "group_capab=0x%x", group_capab);
     629         [ +  - ]:        238 :         if (addr) {
     630                 :        238 :                 os_memcpy(go_dev_addr, addr, ETH_ALEN);
     631                 :        238 :                 wpa_printf(MSG_DEBUG, "P2P: GO Device Address " MACSTR,
     632                 :       1428 :                            MAC2STR(addr));
     633                 :            :         } else
     634                 :          0 :                 os_memset(go_dev_addr, 0, ETH_ALEN);
     635                 :        238 :         wpabuf_free(p2p);
     636                 :            : 
     637                 :        238 :         wpa_printf(MSG_DEBUG, "P2P: BSS " MACSTR " group_capab=0x%x "
     638                 :            :                    "go_dev_addr=" MACSTR,
     639                 :       2856 :                    MAC2STR(bssid), group_capab, MAC2STR(go_dev_addr));
     640                 :            : 
     641                 :        239 :         return group_capab & P2P_GROUP_CAPAB_PERSISTENT_GROUP;
     642                 :            : }
     643                 :            : 
     644                 :            : 
     645                 :         44 : static int wpas_p2p_store_persistent_group(struct wpa_supplicant *wpa_s,
     646                 :            :                                            struct wpa_ssid *ssid,
     647                 :            :                                            const u8 *go_dev_addr)
     648                 :            : {
     649                 :            :         struct wpa_ssid *s;
     650                 :         44 :         int changed = 0;
     651                 :            : 
     652                 :         44 :         wpa_printf(MSG_DEBUG, "P2P: Storing credentials for a persistent "
     653                 :        264 :                    "group (GO Dev Addr " MACSTR ")", MAC2STR(go_dev_addr));
     654         [ +  + ]:         74 :         for (s = wpa_s->conf->ssid; s; s = s->next) {
     655 [ +  + ][ +  + ]:         56 :                 if (s->disabled == 2 &&
     656         [ +  - ]:         26 :                     os_memcmp(go_dev_addr, s->bssid, ETH_ALEN) == 0 &&
     657         [ +  - ]:         26 :                     s->ssid_len == ssid->ssid_len &&
     658                 :         26 :                     os_memcmp(ssid->ssid, s->ssid, ssid->ssid_len) == 0)
     659                 :         26 :                         break;
     660                 :            :         }
     661                 :            : 
     662         [ +  + ]:         44 :         if (s) {
     663                 :         26 :                 wpa_printf(MSG_DEBUG, "P2P: Update existing persistent group "
     664                 :            :                            "entry");
     665 [ +  + ][ -  + ]:         26 :                 if (ssid->passphrase && !s->passphrase)
     666                 :          0 :                         changed = 1;
     667 [ +  + ][ +  - ]:         26 :                 else if (ssid->passphrase && s->passphrase &&
                 [ -  + ]
     668                 :          7 :                          os_strcmp(ssid->passphrase, s->passphrase) != 0)
     669                 :         26 :                         changed = 1;
     670                 :            :         } else {
     671                 :         18 :                 wpa_printf(MSG_DEBUG, "P2P: Create a new persistent group "
     672                 :            :                            "entry");
     673                 :         18 :                 changed = 1;
     674                 :         18 :                 s = wpa_config_add_network(wpa_s->conf);
     675         [ -  + ]:         18 :                 if (s == NULL)
     676                 :          0 :                         return -1;
     677                 :            : 
     678                 :            :                 /*
     679                 :            :                  * Instead of network_added we emit persistent_group_added
     680                 :            :                  * notification. Also to keep the defense checks in
     681                 :            :                  * persistent_group obj registration method, we set the
     682                 :            :                  * relevant flags in s to designate it as a persistent group.
     683                 :            :                  */
     684                 :         18 :                 s->p2p_group = 1;
     685                 :         18 :                 s->p2p_persistent_group = 1;
     686                 :         18 :                 wpas_notify_persistent_group_added(wpa_s, s);
     687                 :         18 :                 wpa_config_set_network_defaults(s);
     688                 :            :         }
     689                 :            : 
     690                 :         44 :         s->p2p_group = 1;
     691                 :         44 :         s->p2p_persistent_group = 1;
     692                 :         44 :         s->disabled = 2;
     693                 :         44 :         s->bssid_set = 1;
     694                 :         44 :         os_memcpy(s->bssid, go_dev_addr, ETH_ALEN);
     695                 :         44 :         s->mode = ssid->mode;
     696                 :         44 :         s->auth_alg = WPA_AUTH_ALG_OPEN;
     697                 :         44 :         s->key_mgmt = WPA_KEY_MGMT_PSK;
     698                 :         44 :         s->proto = WPA_PROTO_RSN;
     699                 :         44 :         s->pairwise_cipher = WPA_CIPHER_CCMP;
     700                 :         44 :         s->export_keys = 1;
     701         [ +  + ]:         44 :         if (ssid->passphrase) {
     702                 :         14 :                 os_free(s->passphrase);
     703                 :         14 :                 s->passphrase = os_strdup(ssid->passphrase);
     704                 :            :         }
     705         [ +  - ]:         44 :         if (ssid->psk_set) {
     706                 :         44 :                 s->psk_set = 1;
     707                 :         44 :                 os_memcpy(s->psk, ssid->psk, 32);
     708                 :            :         }
     709 [ +  + ][ -  + ]:         44 :         if (s->passphrase && !s->psk_set)
     710                 :          0 :                 wpa_config_update_psk(s);
     711 [ +  + ][ -  + ]:         44 :         if (s->ssid == NULL || s->ssid_len < ssid->ssid_len) {
     712                 :         18 :                 os_free(s->ssid);
     713                 :         18 :                 s->ssid = os_malloc(ssid->ssid_len);
     714                 :            :         }
     715         [ +  - ]:         44 :         if (s->ssid) {
     716                 :         44 :                 s->ssid_len = ssid->ssid_len;
     717                 :         44 :                 os_memcpy(s->ssid, ssid->ssid, s->ssid_len);
     718                 :            :         }
     719 [ +  + ][ +  + ]:         44 :         if (ssid->mode == WPAS_MODE_P2P_GO && wpa_s->global->add_psk) {
     720                 :          2 :                 dl_list_add(&s->psk_list, &wpa_s->global->add_psk->list);
     721                 :          2 :                 wpa_s->global->add_psk = NULL;
     722                 :          2 :                 changed = 1;
     723                 :            :         }
     724                 :            : 
     725         [ +  + ]:         44 :         if (changed && wpa_s->conf->update_config &&
           [ -  +  #  # ]
     726                 :          0 :             wpa_config_write(wpa_s->confname, wpa_s->conf)) {
     727                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration");
     728                 :            :         }
     729                 :            : 
     730                 :         44 :         return s->id;
     731                 :            : }
     732                 :            : 
     733                 :            : 
     734                 :         85 : static void wpas_p2p_add_persistent_group_client(struct wpa_supplicant *wpa_s,
     735                 :            :                                                  const u8 *addr)
     736                 :            : {
     737                 :            :         struct wpa_ssid *ssid, *s;
     738                 :            :         u8 *n;
     739                 :            :         size_t i;
     740                 :         85 :         int found = 0;
     741                 :            : 
     742                 :         85 :         ssid = wpa_s->current_ssid;
     743 [ +  - ][ +  - ]:         85 :         if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO ||
                 [ +  + ]
     744                 :         85 :             !ssid->p2p_persistent_group)
     745                 :         66 :                 return;
     746                 :            : 
     747         [ +  - ]:         30 :         for (s = wpa_s->parent->conf->ssid; s; s = s->next) {
     748 [ +  + ][ -  + ]:         30 :                 if (s->disabled != 2 || s->mode != WPAS_MODE_P2P_GO)
     749                 :         11 :                         continue;
     750                 :            : 
     751 [ +  - ][ +  - ]:         19 :                 if (s->ssid_len == ssid->ssid_len &&
     752                 :         19 :                     os_memcmp(s->ssid, ssid->ssid, s->ssid_len) == 0)
     753                 :         19 :                         break;
     754                 :            :         }
     755                 :            : 
     756         [ -  + ]:         19 :         if (s == NULL)
     757                 :          0 :                 return;
     758                 :            : 
     759 [ +  + ][ +  + ]:         23 :         for (i = 0; s->p2p_client_list && i < s->num_p2p_clients; i++) {
     760         [ +  + ]:         12 :                 if (os_memcmp(s->p2p_client_list + i * ETH_ALEN, addr,
     761                 :            :                               ETH_ALEN) != 0)
     762                 :          4 :                         continue;
     763                 :            : 
     764         [ +  + ]:          8 :                 if (i == s->num_p2p_clients - 1)
     765                 :          7 :                         return; /* already the most recent entry */
     766                 :            : 
     767                 :            :                 /* move the entry to mark it most recent */
     768                 :          1 :                 os_memmove(s->p2p_client_list + i * ETH_ALEN,
     769                 :            :                            s->p2p_client_list + (i + 1) * ETH_ALEN,
     770                 :            :                            (s->num_p2p_clients - i - 1) * ETH_ALEN);
     771                 :          1 :                 os_memcpy(s->p2p_client_list +
     772                 :            :                           (s->num_p2p_clients - 1) * ETH_ALEN, addr, ETH_ALEN);
     773                 :          1 :                 found = 1;
     774                 :          1 :                 break;
     775                 :            :         }
     776                 :            : 
     777 [ +  + ][ +  - ]:         12 :         if (!found && s->num_p2p_clients < P2P_MAX_STORED_CLIENTS) {
     778                 :         11 :                 n = os_realloc_array(s->p2p_client_list,
     779                 :         11 :                                      s->num_p2p_clients + 1, ETH_ALEN);
     780         [ -  + ]:         11 :                 if (n == NULL)
     781                 :          0 :                         return;
     782                 :         11 :                 os_memcpy(n + s->num_p2p_clients * ETH_ALEN, addr, ETH_ALEN);
     783                 :         11 :                 s->p2p_client_list = n;
     784                 :         11 :                 s->num_p2p_clients++;
     785         [ -  + ]:          1 :         } else if (!found) {
     786                 :            :                 /* Not enough room for an additional entry - drop the oldest
     787                 :            :                  * entry */
     788                 :          0 :                 os_memmove(s->p2p_client_list,
     789                 :            :                            s->p2p_client_list + ETH_ALEN,
     790                 :            :                            (s->num_p2p_clients - 1) * ETH_ALEN);
     791                 :          0 :                 os_memcpy(s->p2p_client_list +
     792                 :            :                           (s->num_p2p_clients - 1) * ETH_ALEN,
     793                 :            :                           addr, ETH_ALEN);
     794                 :            :         }
     795                 :            : 
     796   [ -  +  #  # ]:         12 :         if (wpa_s->parent->conf->update_config &&
     797                 :          0 :             wpa_config_write(wpa_s->parent->confname, wpa_s->parent->conf))
     798                 :         85 :                 wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration");
     799                 :            : }
     800                 :            : 
     801                 :            : 
     802                 :        122 : static void wpas_group_formation_completed(struct wpa_supplicant *wpa_s,
     803                 :            :                                            int success)
     804                 :            : {
     805                 :            :         struct wpa_ssid *ssid;
     806                 :            :         const char *ssid_txt;
     807                 :            :         int client;
     808                 :            :         int persistent;
     809                 :            :         u8 go_dev_addr[ETH_ALEN];
     810                 :        122 :         int network_id = -1;
     811                 :            : 
     812                 :            :         /*
     813                 :            :          * This callback is likely called for the main interface. Update wpa_s
     814                 :            :          * to use the group interface if a new interface was created for the
     815                 :            :          * group.
     816                 :            :          */
     817         [ +  - ]:        122 :         if (wpa_s->global->p2p_group_formation)
     818                 :        122 :                 wpa_s = wpa_s->global->p2p_group_formation;
     819         [ +  + ]:        122 :         if (wpa_s->p2p_go_group_formation_completed) {
     820                 :         78 :                 wpa_s->global->p2p_group_formation = NULL;
     821                 :         78 :                 wpa_s->p2p_in_provisioning = 0;
     822                 :            :         }
     823                 :            : 
     824         [ +  + ]:        122 :         if (!success) {
     825                 :          2 :                 wpa_msg_global(wpa_s->parent, MSG_INFO,
     826                 :            :                                P2P_EVENT_GROUP_FORMATION_FAILURE);
     827                 :          2 :                 wpas_p2p_group_delete(wpa_s,
     828                 :            :                                       P2P_GROUP_REMOVAL_FORMATION_FAILED);
     829                 :        122 :                 return;
     830                 :            :         }
     831                 :            : 
     832                 :        120 :         wpa_msg_global(wpa_s->parent, MSG_INFO,
     833                 :            :                        P2P_EVENT_GROUP_FORMATION_SUCCESS);
     834                 :            : 
     835                 :        120 :         ssid = wpa_s->current_ssid;
     836 [ +  - ][ +  + ]:        120 :         if (ssid && ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
     837                 :         44 :                 ssid->mode = WPAS_MODE_P2P_GO;
     838                 :         44 :                 p2p_group_notif_formation_done(wpa_s->p2p_group);
     839                 :         44 :                 wpa_supplicant_ap_mac_addr_filter(wpa_s, NULL);
     840                 :            :         }
     841                 :            : 
     842                 :        120 :         persistent = 0;
     843         [ +  - ]:        120 :         if (ssid) {
     844                 :        120 :                 ssid_txt = wpa_ssid_txt(ssid->ssid, ssid->ssid_len);
     845                 :        120 :                 client = ssid->mode == WPAS_MODE_INFRA;
     846         [ +  + ]:        120 :                 if (ssid->mode == WPAS_MODE_P2P_GO) {
     847                 :         44 :                         persistent = ssid->p2p_persistent_group;
     848                 :         44 :                         os_memcpy(go_dev_addr, wpa_s->global->p2p_dev_addr,
     849                 :            :                                   ETH_ALEN);
     850                 :            :                 } else
     851                 :         76 :                         persistent = wpas_p2p_persistent_group(wpa_s,
     852                 :            :                                                                go_dev_addr,
     853                 :         76 :                                                                ssid->ssid,
     854                 :            :                                                                ssid->ssid_len);
     855                 :            :         } else {
     856                 :          0 :                 ssid_txt = "";
     857                 :          0 :                 client = wpa_s->p2p_group_interface ==
     858                 :            :                         P2P_GROUP_INTERFACE_CLIENT;
     859                 :          0 :                 os_memset(go_dev_addr, 0, ETH_ALEN);
     860                 :            :         }
     861                 :            : 
     862                 :        120 :         wpa_s->show_group_started = 0;
     863         [ +  + ]:        120 :         if (client) {
     864                 :            :                 /*
     865                 :            :                  * Indicate event only after successfully completed 4-way
     866                 :            :                  * handshake, i.e., when the interface is ready for data
     867                 :            :                  * packets.
     868                 :            :                  */
     869                 :         76 :                 wpa_s->show_group_started = 1;
     870 [ +  - ][ -  + ]:         44 :         } else if (ssid && ssid->passphrase == NULL && ssid->psk_set) {
                 [ #  # ]
     871                 :            :                 char psk[65];
     872                 :          0 :                 wpa_snprintf_hex(psk, sizeof(psk), ssid->psk, 32);
     873         [ #  # ]:          0 :                 wpa_msg_global(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_STARTED
     874                 :            :                                "%s GO ssid=\"%s\" freq=%d psk=%s go_dev_addr="
     875                 :            :                                MACSTR "%s",
     876                 :          0 :                                wpa_s->ifname, ssid_txt, ssid->frequency, psk,
     877                 :          0 :                                MAC2STR(go_dev_addr),
     878                 :            :                                persistent ? " [PERSISTENT]" : "");
     879                 :          0 :                 wpas_p2p_cross_connect_setup(wpa_s);
     880                 :          0 :                 wpas_p2p_set_group_idle_timeout(wpa_s);
     881                 :            :         } else {
     882 [ +  + ][ +  - ]:         88 :                 wpa_msg_global(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_STARTED
                 [ +  - ]
     883                 :            :                                "%s GO ssid=\"%s\" freq=%d passphrase=\"%s\" "
     884                 :            :                                "go_dev_addr=" MACSTR "%s",
     885                 :         44 :                                wpa_s->ifname, ssid_txt,
     886                 :            :                                ssid ? ssid->frequency : 0,
     887         [ +  - ]:         44 :                                ssid && ssid->passphrase ? ssid->passphrase : "",
     888                 :        264 :                                MAC2STR(go_dev_addr),
     889                 :            :                                persistent ? " [PERSISTENT]" : "");
     890                 :         44 :                 wpas_p2p_cross_connect_setup(wpa_s);
     891                 :         44 :                 wpas_p2p_set_group_idle_timeout(wpa_s);
     892                 :            :         }
     893                 :            : 
     894         [ +  + ]:        120 :         if (persistent)
     895                 :         16 :                 network_id = wpas_p2p_store_persistent_group(wpa_s->parent,
     896                 :            :                                                              ssid, go_dev_addr);
     897                 :            :         else {
     898                 :        104 :                 os_free(wpa_s->global->add_psk);
     899                 :        104 :                 wpa_s->global->add_psk = NULL;
     900                 :            :         }
     901 [ +  + ][ +  - ]:        120 :         if (network_id < 0 && ssid)
     902                 :        104 :                 network_id = ssid->id;
     903         [ +  + ]:        120 :         if (!client) {
     904                 :         44 :                 wpas_notify_p2p_group_started(wpa_s, ssid, network_id, 0);
     905                 :         44 :                 os_get_reltime(&wpa_s->global->p2p_go_wait_client);
     906                 :            :         }
     907                 :            : }
     908                 :            : 
     909                 :            : 
     910                 :            : struct send_action_work {
     911                 :            :         unsigned int freq;
     912                 :            :         u8 dst[ETH_ALEN];
     913                 :            :         u8 src[ETH_ALEN];
     914                 :            :         u8 bssid[ETH_ALEN];
     915                 :            :         size_t len;
     916                 :            :         unsigned int wait_time;
     917                 :            :         u8 buf[0];
     918                 :            : };
     919                 :            : 
     920                 :            : 
     921                 :        130 : static void wpas_p2p_send_action_work_timeout(void *eloop_ctx,
     922                 :            :                                               void *timeout_ctx)
     923                 :            : {
     924                 :        130 :         struct wpa_supplicant *wpa_s = eloop_ctx;
     925                 :            : 
     926         [ -  + ]:        130 :         if (!wpa_s->p2p_send_action_work)
     927                 :        130 :                 return;
     928                 :            : 
     929                 :        130 :         wpa_printf(MSG_DEBUG, "P2P: Send Action frame radio work timed out");
     930                 :        130 :         os_free(wpa_s->p2p_send_action_work->ctx);
     931                 :        130 :         radio_work_done(wpa_s->p2p_send_action_work);
     932                 :        130 :         wpa_s->p2p_send_action_work = NULL;
     933                 :            : }
     934                 :            : 
     935                 :            : 
     936                 :        525 : static void wpas_p2p_send_action_tx_status(struct wpa_supplicant *wpa_s,
     937                 :            :                                            unsigned int freq,
     938                 :            :                                            const u8 *dst, const u8 *src,
     939                 :            :                                            const u8 *bssid,
     940                 :            :                                            const u8 *data, size_t data_len,
     941                 :            :                                            enum offchannel_send_action_result
     942                 :            :                                            result)
     943                 :            : {
     944                 :        525 :         enum p2p_send_action_result res = P2P_SEND_ACTION_SUCCESS;
     945                 :            : 
     946         [ +  + ]:        525 :         if (wpa_s->p2p_send_action_work) {
     947                 :            :                 struct send_action_work *awork;
     948                 :        405 :                 awork = wpa_s->p2p_send_action_work->ctx;
     949         [ -  + ]:        405 :                 if (awork->wait_time == 0) {
     950                 :          0 :                         os_free(awork);
     951                 :          0 :                         radio_work_done(wpa_s->p2p_send_action_work);
     952                 :          0 :                         wpa_s->p2p_send_action_work = NULL;
     953                 :            :                 } else {
     954                 :            :                         /*
     955                 :            :                          * In theory, this should not be needed, but number of
     956                 :            :                          * places in the P2P code is still using non-zero wait
     957                 :            :                          * time for the last Action frame in the sequence and
     958                 :            :                          * some of these do not call send_action_done().
     959                 :            :                          */
     960                 :        405 :                         eloop_cancel_timeout(wpas_p2p_send_action_work_timeout,
     961                 :            :                                              wpa_s, NULL);
     962                 :        405 :                         eloop_register_timeout(
     963                 :        405 :                                 0, awork->wait_time * 1000,
     964                 :            :                                 wpas_p2p_send_action_work_timeout,
     965                 :            :                                 wpa_s, NULL);
     966                 :            :                 }
     967                 :            :         }
     968                 :            : 
     969 [ +  - ][ -  + ]:        525 :         if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled)
     970                 :          0 :                 return;
     971                 :            : 
     972   [ +  +  -  - ]:        525 :         switch (result) {
     973                 :            :         case OFFCHANNEL_SEND_ACTION_SUCCESS:
     974                 :        356 :                 res = P2P_SEND_ACTION_SUCCESS;
     975                 :        356 :                 break;
     976                 :            :         case OFFCHANNEL_SEND_ACTION_NO_ACK:
     977                 :        169 :                 res = P2P_SEND_ACTION_NO_ACK;
     978                 :        169 :                 break;
     979                 :            :         case OFFCHANNEL_SEND_ACTION_FAILED:
     980                 :          0 :                 res = P2P_SEND_ACTION_FAILED;
     981                 :          0 :                 break;
     982                 :            :         }
     983                 :            : 
     984                 :        525 :         p2p_send_action_cb(wpa_s->global->p2p, freq, dst, src, bssid, res);
     985                 :            : 
     986 [ +  + ][ -  + ]:        525 :         if (result != OFFCHANNEL_SEND_ACTION_SUCCESS &&
     987         [ #  # ]:          0 :             wpa_s->pending_pd_before_join &&
     988         [ #  # ]:          0 :             (os_memcmp(dst, wpa_s->pending_join_dev_addr, ETH_ALEN) == 0 ||
     989         [ #  # ]:          0 :              os_memcmp(dst, wpa_s->pending_join_iface_addr, ETH_ALEN) == 0) &&
     990                 :            :             wpa_s->p2p_fallback_to_go_neg) {
     991                 :          0 :                 wpa_s->pending_pd_before_join = 0;
     992                 :          0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: No ACK for PD Req "
     993                 :            :                         "during p2p_connect-auto");
     994                 :          0 :                 wpas_p2p_fallback_to_go_neg(wpa_s, 0);
     995                 :        525 :                 return;
     996                 :            :         }
     997                 :            : }
     998                 :            : 
     999                 :            : 
    1000                 :        356 : static void wpas_send_action_cb(struct wpa_radio_work *work, int deinit)
    1001                 :            : {
    1002                 :        356 :         struct wpa_supplicant *wpa_s = work->wpa_s;
    1003                 :        356 :         struct send_action_work *awork = work->ctx;
    1004                 :            : 
    1005         [ +  + ]:        356 :         if (deinit) {
    1006         [ +  - ]:          2 :                 if (work->started) {
    1007                 :          2 :                         eloop_cancel_timeout(wpas_p2p_send_action_work_timeout,
    1008                 :            :                                              wpa_s, NULL);
    1009                 :          2 :                         wpa_s->p2p_send_action_work = NULL;
    1010                 :          2 :                         offchannel_send_action_done(wpa_s);
    1011                 :            :                 }
    1012                 :          2 :                 os_free(awork);
    1013                 :          2 :                 return;
    1014                 :            :         }
    1015                 :            : 
    1016         [ -  + ]:        354 :         if (offchannel_send_action(wpa_s, awork->freq, awork->dst, awork->src,
    1017                 :        354 :                                    awork->bssid, awork->buf, awork->len,
    1018                 :            :                                    awork->wait_time,
    1019                 :            :                                    wpas_p2p_send_action_tx_status, 1) < 0) {
    1020                 :          0 :                 os_free(awork);
    1021                 :          0 :                 radio_work_done(work);
    1022                 :          0 :                 return;
    1023                 :            :         }
    1024                 :        356 :         wpa_s->p2p_send_action_work = work;
    1025                 :            : }
    1026                 :            : 
    1027                 :            : 
    1028                 :        354 : static int wpas_send_action_work(struct wpa_supplicant *wpa_s,
    1029                 :            :                                  unsigned int freq, const u8 *dst,
    1030                 :            :                                  const u8 *src, const u8 *bssid, const u8 *buf,
    1031                 :            :                                  size_t len, unsigned int wait_time)
    1032                 :            : {
    1033                 :            :         struct send_action_work *awork;
    1034                 :            : 
    1035         [ -  + ]:        354 :         if (wpa_s->p2p_send_action_work) {
    1036                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Cannot schedule new p2p-send-action work since one is already pending");
    1037                 :          0 :                 return -1;
    1038                 :            :         }
    1039                 :            : 
    1040                 :        354 :         awork = os_zalloc(sizeof(*awork) + len);
    1041         [ -  + ]:        354 :         if (awork == NULL)
    1042                 :          0 :                 return -1;
    1043                 :            : 
    1044                 :        354 :         awork->freq = freq;
    1045                 :        354 :         os_memcpy(awork->dst, dst, ETH_ALEN);
    1046                 :        354 :         os_memcpy(awork->src, src, ETH_ALEN);
    1047                 :        354 :         os_memcpy(awork->bssid, bssid, ETH_ALEN);
    1048                 :        354 :         awork->len = len;
    1049                 :        354 :         awork->wait_time = wait_time;
    1050                 :        354 :         os_memcpy(awork->buf, buf, len);
    1051                 :            : 
    1052         [ -  + ]:        354 :         if (radio_add_work(wpa_s, freq, "p2p-send-action", 0,
    1053                 :            :                            wpas_send_action_cb, awork) < 0) {
    1054                 :          0 :                 os_free(awork);
    1055                 :          0 :                 return -1;
    1056                 :            :         }
    1057                 :            : 
    1058                 :        354 :         return 0;
    1059                 :            : }
    1060                 :            : 
    1061                 :            : 
    1062                 :        526 : static int wpas_send_action(void *ctx, unsigned int freq, const u8 *dst,
    1063                 :            :                             const u8 *src, const u8 *bssid, const u8 *buf,
    1064                 :            :                             size_t len, unsigned int wait_time)
    1065                 :            : {
    1066                 :        526 :         struct wpa_supplicant *wpa_s = ctx;
    1067                 :        526 :         int listen_freq = -1, send_freq = -1;
    1068                 :            : 
    1069         [ +  + ]:        526 :         if (wpa_s->p2p_listen_work)
    1070                 :        121 :                 listen_freq = wpa_s->p2p_listen_work->freq;
    1071         [ +  + ]:        526 :         if (wpa_s->p2p_send_action_work)
    1072                 :         52 :                 send_freq = wpa_s->p2p_send_action_work->freq;
    1073 [ +  + ][ +  + ]:        526 :         if (listen_freq != (int) freq && send_freq != (int) freq) {
    1074                 :        354 :                 wpa_printf(MSG_DEBUG, "P2P: Schedule new radio work for Action frame TX (listen_freq=%d send_freq=%d)",
    1075                 :            :                            listen_freq, send_freq);
    1076                 :        354 :                 return wpas_send_action_work(wpa_s, freq, dst, src, bssid, buf,
    1077                 :            :                                              len, wait_time);
    1078                 :            :         }
    1079                 :            : 
    1080                 :        172 :         wpa_printf(MSG_DEBUG, "P2P: Use ongoing radio work for Action frame TX");
    1081                 :        526 :         return offchannel_send_action(wpa_s, freq, dst, src, bssid, buf, len,
    1082                 :            :                                       wait_time,
    1083                 :            :                                       wpas_p2p_send_action_tx_status, 1);
    1084                 :            : }
    1085                 :            : 
    1086                 :            : 
    1087                 :        289 : static void wpas_send_action_done(void *ctx)
    1088                 :            : {
    1089                 :        289 :         struct wpa_supplicant *wpa_s = ctx;
    1090                 :            : 
    1091         [ +  + ]:        289 :         if (wpa_s->p2p_send_action_work) {
    1092                 :        222 :                 eloop_cancel_timeout(wpas_p2p_send_action_work_timeout,
    1093                 :            :                                      wpa_s, NULL);
    1094                 :        222 :                 os_free(wpa_s->p2p_send_action_work->ctx);
    1095                 :        222 :                 radio_work_done(wpa_s->p2p_send_action_work);
    1096                 :        222 :                 wpa_s->p2p_send_action_work = NULL;
    1097                 :            :         }
    1098                 :            : 
    1099                 :        289 :         offchannel_send_action_done(wpa_s);
    1100                 :        289 : }
    1101                 :            : 
    1102                 :            : 
    1103                 :        157 : static int wpas_copy_go_neg_results(struct wpa_supplicant *wpa_s,
    1104                 :            :                                     struct p2p_go_neg_results *params)
    1105                 :            : {
    1106         [ +  - ]:        157 :         if (wpa_s->go_params == NULL) {
    1107                 :        157 :                 wpa_s->go_params = os_malloc(sizeof(*params));
    1108         [ -  + ]:        157 :                 if (wpa_s->go_params == NULL)
    1109                 :          0 :                         return -1;
    1110                 :            :         }
    1111                 :        157 :         os_memcpy(wpa_s->go_params, params, sizeof(*params));
    1112                 :        157 :         return 0;
    1113                 :            : }
    1114                 :            : 
    1115                 :            : 
    1116                 :         77 : static void wpas_start_wps_enrollee(struct wpa_supplicant *wpa_s,
    1117                 :            :                                     struct p2p_go_neg_results *res)
    1118                 :            : {
    1119                 :         77 :         wpa_printf(MSG_DEBUG, "P2P: Start WPS Enrollee for peer " MACSTR
    1120                 :            :                    " dev_addr " MACSTR " wps_method %d",
    1121                 :        462 :                    MAC2STR(res->peer_interface_addr),
    1122                 :        462 :                    MAC2STR(res->peer_device_addr), res->wps_method);
    1123                 :         77 :         wpa_hexdump_ascii(MSG_DEBUG, "P2P: Start WPS Enrollee for SSID",
    1124                 :         77 :                           res->ssid, res->ssid_len);
    1125                 :         77 :         wpa_supplicant_ap_deinit(wpa_s);
    1126                 :         77 :         wpas_copy_go_neg_results(wpa_s, res);
    1127         [ +  + ]:         77 :         if (res->wps_method == WPS_PBC) {
    1128                 :          3 :                 wpas_wps_start_pbc(wpa_s, res->peer_interface_addr, 1);
    1129                 :            : #ifdef CONFIG_WPS_NFC
    1130         [ +  + ]:         74 :         } else if (res->wps_method == WPS_NFC) {
    1131         [ +  + ]:         12 :                 wpas_wps_start_nfc(wpa_s, res->peer_device_addr,
    1132                 :         12 :                                    res->peer_interface_addr,
    1133                 :         12 :                                    wpa_s->parent->p2p_oob_dev_pw,
    1134                 :         12 :                                    wpa_s->parent->p2p_oob_dev_pw_id, 1,
    1135                 :         12 :                                    wpa_s->parent->p2p_oob_dev_pw_id ==
    1136                 :            :                                    DEV_PW_NFC_CONNECTION_HANDOVER ?
    1137                 :          6 :                                    wpa_s->parent->p2p_peer_oob_pubkey_hash :
    1138                 :            :                                    NULL,
    1139                 :            :                                    NULL, 0, 0);
    1140                 :            : #endif /* CONFIG_WPS_NFC */
    1141                 :            :         } else {
    1142                 :         62 :                 u16 dev_pw_id = DEV_PW_DEFAULT;
    1143         [ +  + ]:         62 :                 if (wpa_s->p2p_wps_method == WPS_PIN_KEYPAD)
    1144                 :         36 :                         dev_pw_id = DEV_PW_REGISTRAR_SPECIFIED;
    1145                 :         62 :                 wpas_wps_start_pin(wpa_s, res->peer_interface_addr,
    1146                 :         62 :                                    wpa_s->p2p_pin, 1, dev_pw_id);
    1147                 :            :         }
    1148                 :         77 : }
    1149                 :            : 
    1150                 :            : 
    1151                 :          9 : static void wpas_p2p_add_psk_list(struct wpa_supplicant *wpa_s,
    1152                 :            :                                   struct wpa_ssid *ssid)
    1153                 :            : {
    1154                 :            :         struct wpa_ssid *persistent;
    1155                 :            :         struct psk_list_entry *psk;
    1156                 :            :         struct hostapd_data *hapd;
    1157                 :            : 
    1158         [ -  + ]:          9 :         if (!wpa_s->ap_iface)
    1159                 :          0 :                 return;
    1160                 :            : 
    1161                 :          9 :         persistent = wpas_p2p_get_persistent(wpa_s->parent, NULL, ssid->ssid,
    1162                 :            :                                              ssid->ssid_len);
    1163         [ -  + ]:          9 :         if (persistent == NULL)
    1164                 :          0 :                 return;
    1165                 :            : 
    1166                 :          9 :         hapd = wpa_s->ap_iface->bss[0];
    1167                 :            : 
    1168         [ -  + ]:          9 :         dl_list_for_each(psk, &persistent->psk_list, struct psk_list_entry,
    1169                 :            :                          list) {
    1170                 :            :                 struct hostapd_wpa_psk *hpsk;
    1171                 :            : 
    1172                 :          0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Add persistent group PSK entry for "
    1173                 :            :                         MACSTR " psk=%d",
    1174                 :            :                         MAC2STR(psk->addr), psk->p2p);
    1175                 :          0 :                 hpsk = os_zalloc(sizeof(*hpsk));
    1176         [ #  # ]:          0 :                 if (hpsk == NULL)
    1177                 :          0 :                         break;
    1178                 :          0 :                 os_memcpy(hpsk->psk, psk->psk, PMK_LEN);
    1179         [ #  # ]:          0 :                 if (psk->p2p)
    1180                 :          0 :                         os_memcpy(hpsk->p2p_dev_addr, psk->addr, ETH_ALEN);
    1181                 :            :                 else
    1182                 :          0 :                         os_memcpy(hpsk->addr, psk->addr, ETH_ALEN);
    1183                 :          0 :                 hpsk->next = hapd->conf->ssid.wpa_psk;
    1184                 :          0 :                 hapd->conf->ssid.wpa_psk = hpsk;
    1185                 :            :         }
    1186                 :            : }
    1187                 :            : 
    1188                 :            : 
    1189                 :         80 : static void p2p_go_configured(void *ctx, void *data)
    1190                 :            : {
    1191                 :         80 :         struct wpa_supplicant *wpa_s = ctx;
    1192                 :         80 :         struct p2p_go_neg_results *params = data;
    1193                 :            :         struct wpa_ssid *ssid;
    1194                 :         80 :         int network_id = -1;
    1195                 :            : 
    1196                 :         80 :         ssid = wpa_s->current_ssid;
    1197 [ +  - ][ +  + ]:         80 :         if (ssid && ssid->mode == WPAS_MODE_P2P_GO) {
    1198                 :         35 :                 wpa_printf(MSG_DEBUG, "P2P: Group setup without provisioning");
    1199         [ +  + ]:         35 :                 if (wpa_s->global->p2p_group_formation == wpa_s)
    1200                 :          3 :                         wpa_s->global->p2p_group_formation = NULL;
    1201         [ +  - ]:         35 :                 if (os_strlen(params->passphrase) > 0) {
    1202         [ +  + ]:         35 :                         wpa_msg_global(wpa_s->parent, MSG_INFO,
    1203                 :            :                                        P2P_EVENT_GROUP_STARTED
    1204                 :            :                                        "%s GO ssid=\"%s\" freq=%d "
    1205                 :            :                                        "passphrase=\"%s\" go_dev_addr=" MACSTR
    1206                 :         35 :                                        "%s", wpa_s->ifname,
    1207                 :         35 :                                        wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
    1208                 :         35 :                                        ssid->frequency, params->passphrase,
    1209                 :        210 :                                        MAC2STR(wpa_s->global->p2p_dev_addr),
    1210                 :         35 :                                        params->persistent_group ?
    1211                 :            :                                        " [PERSISTENT]" : "");
    1212                 :            :                 } else {
    1213                 :            :                         char psk[65];
    1214                 :          0 :                         wpa_snprintf_hex(psk, sizeof(psk), params->psk,
    1215                 :            :                                          sizeof(params->psk));
    1216         [ #  # ]:          0 :                         wpa_msg_global(wpa_s->parent, MSG_INFO,
    1217                 :            :                                        P2P_EVENT_GROUP_STARTED
    1218                 :            :                                        "%s GO ssid=\"%s\" freq=%d psk=%s "
    1219                 :            :                                        "go_dev_addr=" MACSTR "%s",
    1220                 :          0 :                                        wpa_s->ifname,
    1221                 :          0 :                                        wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
    1222                 :            :                                        ssid->frequency, psk,
    1223                 :          0 :                                        MAC2STR(wpa_s->global->p2p_dev_addr),
    1224                 :          0 :                                        params->persistent_group ?
    1225                 :            :                                        " [PERSISTENT]" : "");
    1226                 :            :                 }
    1227                 :            : 
    1228                 :         35 :                 os_get_reltime(&wpa_s->global->p2p_go_wait_client);
    1229         [ +  + ]:         35 :                 if (params->persistent_group) {
    1230                 :          9 :                         network_id = wpas_p2p_store_persistent_group(
    1231                 :            :                                 wpa_s->parent, ssid,
    1232                 :          9 :                                 wpa_s->global->p2p_dev_addr);
    1233                 :          9 :                         wpas_p2p_add_psk_list(wpa_s, ssid);
    1234                 :            :                 }
    1235         [ +  + ]:         35 :                 if (network_id < 0)
    1236                 :         26 :                         network_id = ssid->id;
    1237                 :         35 :                 wpas_notify_p2p_group_started(wpa_s, ssid, network_id, 0);
    1238                 :         35 :                 wpas_p2p_cross_connect_setup(wpa_s);
    1239                 :         35 :                 wpas_p2p_set_group_idle_timeout(wpa_s);
    1240                 :            : 
    1241         [ +  + ]:         35 :                 if (wpa_s->p2p_first_connection_timeout) {
    1242                 :          7 :                         wpa_dbg(wpa_s, MSG_DEBUG,
    1243                 :            :                                 "P2P: Start group formation timeout of %d seconds until first data connection on GO",
    1244                 :            :                                 wpa_s->p2p_first_connection_timeout);
    1245                 :          7 :                         wpa_s->p2p_go_group_formation_completed = 0;
    1246                 :          7 :                         wpa_s->global->p2p_group_formation = wpa_s;
    1247                 :          7 :                         eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
    1248                 :          7 :                                              wpa_s->parent, NULL);
    1249                 :          7 :                         eloop_register_timeout(
    1250                 :          7 :                                 wpa_s->p2p_first_connection_timeout, 0,
    1251                 :            :                                 wpas_p2p_group_formation_timeout,
    1252                 :          7 :                                 wpa_s->parent, NULL);
    1253                 :            :                 }
    1254                 :            : 
    1255                 :         35 :                 return;
    1256                 :            :         }
    1257                 :            : 
    1258                 :         45 :         wpa_printf(MSG_DEBUG, "P2P: Setting up WPS for GO provisioning");
    1259         [ -  + ]:         45 :         if (wpa_supplicant_ap_mac_addr_filter(wpa_s,
    1260                 :         45 :                                               params->peer_interface_addr)) {
    1261                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Failed to setup MAC address "
    1262                 :            :                            "filtering");
    1263                 :          0 :                 return;
    1264                 :            :         }
    1265         [ +  + ]:         45 :         if (params->wps_method == WPS_PBC) {
    1266                 :          3 :                 wpa_supplicant_ap_wps_pbc(wpa_s, params->peer_interface_addr,
    1267                 :          3 :                                           params->peer_device_addr);
    1268                 :            : #ifdef CONFIG_WPS_NFC
    1269         [ +  + ]:         42 :         } else if (params->wps_method == WPS_NFC) {
    1270         [ +  + ]:          6 :                 if (wpa_s->parent->p2p_oob_dev_pw_id !=
    1271         [ -  + ]:          2 :                     DEV_PW_NFC_CONNECTION_HANDOVER &&
    1272                 :          2 :                     !wpa_s->parent->p2p_oob_dev_pw) {
    1273                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: No NFC Dev Pw known");
    1274                 :          0 :                         return;
    1275                 :            :                 }
    1276         [ +  + ]:          6 :                 wpas_ap_wps_add_nfc_pw(
    1277                 :          6 :                         wpa_s, wpa_s->parent->p2p_oob_dev_pw_id,
    1278                 :          6 :                         wpa_s->parent->p2p_oob_dev_pw,
    1279                 :          6 :                         wpa_s->parent->p2p_peer_oob_pk_hash_known ?
    1280                 :          5 :                         wpa_s->parent->p2p_peer_oob_pubkey_hash : NULL);
    1281                 :            : #endif /* CONFIG_WPS_NFC */
    1282         [ +  - ]:         36 :         } else if (wpa_s->p2p_pin[0])
    1283                 :         36 :                 wpa_supplicant_ap_wps_pin(wpa_s, params->peer_interface_addr,
    1284                 :         36 :                                           wpa_s->p2p_pin, NULL, 0, 0);
    1285                 :         45 :         os_free(wpa_s->go_params);
    1286                 :         80 :         wpa_s->go_params = NULL;
    1287                 :            : }
    1288                 :            : 
    1289                 :            : 
    1290                 :         80 : static void wpas_start_wps_go(struct wpa_supplicant *wpa_s,
    1291                 :            :                               struct p2p_go_neg_results *params,
    1292                 :            :                               int group_formation)
    1293                 :            : {
    1294                 :            :         struct wpa_ssid *ssid;
    1295                 :            : 
    1296                 :         80 :         wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Starting GO");
    1297         [ -  + ]:         80 :         if (wpas_copy_go_neg_results(wpa_s, params) < 0) {
    1298                 :          0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Could not copy GO Negotiation "
    1299                 :            :                         "results");
    1300                 :          0 :                 return;
    1301                 :            :         }
    1302                 :            : 
    1303                 :         80 :         ssid = wpa_config_add_network(wpa_s->conf);
    1304         [ -  + ]:         80 :         if (ssid == NULL) {
    1305                 :          0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Could not add network for GO");
    1306                 :          0 :                 return;
    1307                 :            :         }
    1308                 :            : 
    1309                 :         80 :         wpa_s->show_group_started = 0;
    1310                 :            : 
    1311                 :         80 :         wpa_config_set_network_defaults(ssid);
    1312                 :         80 :         ssid->temporary = 1;
    1313                 :         80 :         ssid->p2p_group = 1;
    1314                 :         80 :         ssid->p2p_persistent_group = params->persistent_group;
    1315         [ +  + ]:         80 :         ssid->mode = group_formation ? WPAS_MODE_P2P_GROUP_FORMATION :
    1316                 :            :                 WPAS_MODE_P2P_GO;
    1317                 :         80 :         ssid->frequency = params->freq;
    1318                 :         80 :         ssid->ht40 = params->ht40;
    1319                 :         80 :         ssid->vht = params->vht;
    1320                 :         80 :         ssid->ssid = os_zalloc(params->ssid_len + 1);
    1321         [ +  - ]:         80 :         if (ssid->ssid) {
    1322                 :         80 :                 os_memcpy(ssid->ssid, params->ssid, params->ssid_len);
    1323                 :         80 :                 ssid->ssid_len = params->ssid_len;
    1324                 :            :         }
    1325                 :         80 :         ssid->auth_alg = WPA_AUTH_ALG_OPEN;
    1326                 :         80 :         ssid->key_mgmt = WPA_KEY_MGMT_PSK;
    1327                 :         80 :         ssid->proto = WPA_PROTO_RSN;
    1328                 :         80 :         ssid->pairwise_cipher = WPA_CIPHER_CCMP;
    1329         [ +  - ]:         80 :         if (os_strlen(params->passphrase) > 0) {
    1330                 :         80 :                 ssid->passphrase = os_strdup(params->passphrase);
    1331         [ -  + ]:         80 :                 if (ssid->passphrase == NULL) {
    1332                 :          0 :                         wpa_msg_global(wpa_s, MSG_ERROR,
    1333                 :            :                                        "P2P: Failed to copy passphrase for GO");
    1334                 :          0 :                         wpa_config_remove_network(wpa_s->conf, ssid->id);
    1335                 :          0 :                         return;
    1336                 :            :                 }
    1337                 :            :         } else
    1338                 :          0 :                 ssid->passphrase = NULL;
    1339                 :         80 :         ssid->psk_set = params->psk_set;
    1340         [ +  + ]:         80 :         if (ssid->psk_set)
    1341                 :          8 :                 os_memcpy(ssid->psk, params->psk, sizeof(ssid->psk));
    1342         [ +  - ]:         72 :         else if (ssid->passphrase)
    1343                 :         72 :                 wpa_config_update_psk(ssid);
    1344                 :         80 :         ssid->ap_max_inactivity = wpa_s->parent->conf->p2p_go_max_inactivity;
    1345                 :            : 
    1346                 :         80 :         wpa_s->ap_configured_cb = p2p_go_configured;
    1347                 :         80 :         wpa_s->ap_configured_cb_ctx = wpa_s;
    1348                 :         80 :         wpa_s->ap_configured_cb_data = wpa_s->go_params;
    1349                 :         80 :         wpa_s->connect_without_scan = ssid;
    1350                 :         80 :         wpa_s->reassociate = 1;
    1351                 :         80 :         wpa_s->disconnected = 0;
    1352                 :         80 :         wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Request scan (that will be skipped) to "
    1353                 :            :                 "start GO)");
    1354                 :         80 :         wpa_supplicant_req_scan(wpa_s, 0, 0);
    1355                 :            : }
    1356                 :            : 
    1357                 :            : 
    1358                 :         24 : static void wpas_p2p_clone_config(struct wpa_supplicant *dst,
    1359                 :            :                                   const struct wpa_supplicant *src)
    1360                 :            : {
    1361                 :            :         struct wpa_config *d;
    1362                 :            :         const struct wpa_config *s;
    1363                 :            : 
    1364                 :         24 :         d = dst->conf;
    1365                 :         24 :         s = src->conf;
    1366                 :            : 
    1367                 :            : #define C(n) if (s->n) d->n = os_strdup(s->n)
    1368         [ +  + ]:         24 :         C(device_name);
    1369         [ -  + ]:         24 :         C(manufacturer);
    1370         [ -  + ]:         24 :         C(model_name);
    1371         [ -  + ]:         24 :         C(model_number);
    1372         [ -  + ]:         24 :         C(serial_number);
    1373         [ -  + ]:         24 :         C(config_methods);
    1374                 :            : #undef C
    1375                 :            : 
    1376                 :         24 :         os_memcpy(d->device_type, s->device_type, WPS_DEV_TYPE_LEN);
    1377                 :         24 :         os_memcpy(d->sec_device_type, s->sec_device_type,
    1378                 :            :                   sizeof(d->sec_device_type));
    1379                 :         24 :         d->num_sec_device_types = s->num_sec_device_types;
    1380                 :            : 
    1381                 :         24 :         d->p2p_group_idle = s->p2p_group_idle;
    1382                 :         24 :         d->p2p_intra_bss = s->p2p_intra_bss;
    1383                 :         24 :         d->persistent_reconnect = s->persistent_reconnect;
    1384                 :         24 :         d->max_num_sta = s->max_num_sta;
    1385                 :         24 :         d->pbc_in_m1 = s->pbc_in_m1;
    1386                 :         24 :         d->ignore_old_scan_res = s->ignore_old_scan_res;
    1387                 :         24 :         d->beacon_int = s->beacon_int;
    1388                 :         24 :         d->dtim_period = s->dtim_period;
    1389                 :         24 :         d->disassoc_low_ack = s->disassoc_low_ack;
    1390                 :         24 :         d->disable_scan_offload = s->disable_scan_offload;
    1391                 :            : 
    1392 [ +  + ][ +  - ]:         24 :         if (s->wps_nfc_dh_privkey && s->wps_nfc_dh_pubkey) {
    1393                 :          4 :                 d->wps_nfc_dh_privkey = wpabuf_dup(s->wps_nfc_dh_privkey);
    1394                 :          4 :                 d->wps_nfc_dh_pubkey = wpabuf_dup(s->wps_nfc_dh_pubkey);
    1395                 :            :         }
    1396                 :         24 : }
    1397                 :            : 
    1398                 :            : 
    1399                 :         24 : static void wpas_p2p_get_group_ifname(struct wpa_supplicant *wpa_s,
    1400                 :            :                                       char *ifname, size_t len)
    1401                 :            : {
    1402                 :         24 :         char *ifname_ptr = wpa_s->ifname;
    1403                 :            : 
    1404         [ -  + ]:         24 :         if (os_strncmp(wpa_s->ifname, P2P_MGMT_DEVICE_PREFIX,
    1405                 :            :                        os_strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) {
    1406                 :          0 :                 ifname_ptr = os_strrchr(wpa_s->ifname, '-') + 1;
    1407                 :            :         }
    1408                 :            : 
    1409                 :         24 :         os_snprintf(ifname, len, "p2p-%s-%d", ifname_ptr, wpa_s->p2p_group_idx);
    1410 [ -  + ][ #  # ]:         24 :         if (os_strlen(ifname) >= IFNAMSIZ &&
    1411                 :          0 :             os_strlen(wpa_s->ifname) < IFNAMSIZ) {
    1412                 :            :                 /* Try to avoid going over the IFNAMSIZ length limit */
    1413                 :          0 :                 os_snprintf(ifname, len, "p2p-%d", wpa_s->p2p_group_idx);
    1414                 :            :         }
    1415                 :         24 : }
    1416                 :            : 
    1417                 :            : 
    1418                 :         24 : static int wpas_p2p_add_group_interface(struct wpa_supplicant *wpa_s,
    1419                 :            :                                         enum wpa_driver_if_type type)
    1420                 :            : {
    1421                 :            :         char ifname[120], force_ifname[120];
    1422                 :            : 
    1423         [ -  + ]:         24 :         if (wpa_s->pending_interface_name[0]) {
    1424                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Pending virtual interface exists "
    1425                 :            :                            "- skip creation of a new one");
    1426         [ #  # ]:          0 :                 if (is_zero_ether_addr(wpa_s->pending_interface_addr)) {
    1427                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: Pending virtual address "
    1428                 :            :                                    "unknown?! ifname='%s'",
    1429                 :          0 :                                    wpa_s->pending_interface_name);
    1430                 :          0 :                         return -1;
    1431                 :            :                 }
    1432                 :          0 :                 return 0;
    1433                 :            :         }
    1434                 :            : 
    1435                 :         24 :         wpas_p2p_get_group_ifname(wpa_s, ifname, sizeof(ifname));
    1436                 :         24 :         force_ifname[0] = '\0';
    1437                 :            : 
    1438                 :         24 :         wpa_printf(MSG_DEBUG, "P2P: Create a new interface %s for the group",
    1439                 :            :                    ifname);
    1440                 :         24 :         wpa_s->p2p_group_idx++;
    1441                 :            : 
    1442                 :         24 :         wpa_s->pending_interface_type = type;
    1443         [ -  + ]:         24 :         if (wpa_drv_if_add(wpa_s, type, ifname, NULL, NULL, force_ifname,
    1444                 :         24 :                            wpa_s->pending_interface_addr, NULL) < 0) {
    1445                 :          0 :                 wpa_printf(MSG_ERROR, "P2P: Failed to create new group "
    1446                 :            :                            "interface");
    1447                 :          0 :                 return -1;
    1448                 :            :         }
    1449                 :            : 
    1450         [ -  + ]:         24 :         if (force_ifname[0]) {
    1451                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Driver forced interface name %s",
    1452                 :            :                            force_ifname);
    1453                 :          0 :                 os_strlcpy(wpa_s->pending_interface_name, force_ifname,
    1454                 :            :                            sizeof(wpa_s->pending_interface_name));
    1455                 :            :         } else
    1456                 :         24 :                 os_strlcpy(wpa_s->pending_interface_name, ifname,
    1457                 :            :                            sizeof(wpa_s->pending_interface_name));
    1458                 :         24 :         wpa_printf(MSG_DEBUG, "P2P: Created pending virtual interface %s addr "
    1459                 :         24 :                    MACSTR, wpa_s->pending_interface_name,
    1460                 :        144 :                    MAC2STR(wpa_s->pending_interface_addr));
    1461                 :            : 
    1462                 :         24 :         return 0;
    1463                 :            : }
    1464                 :            : 
    1465                 :            : 
    1466                 :       1271 : static void wpas_p2p_remove_pending_group_interface(
    1467                 :            :         struct wpa_supplicant *wpa_s)
    1468                 :            : {
    1469   [ -  +  #  # ]:       1271 :         if (!wpa_s->pending_interface_name[0] ||
    1470                 :          0 :             is_zero_ether_addr(wpa_s->pending_interface_addr))
    1471                 :       1271 :                 return; /* No pending virtual interface */
    1472                 :            : 
    1473                 :          0 :         wpa_printf(MSG_DEBUG, "P2P: Removing pending group interface %s",
    1474                 :          0 :                    wpa_s->pending_interface_name);
    1475                 :          0 :         wpa_drv_if_remove(wpa_s, wpa_s->pending_interface_type,
    1476                 :          0 :                           wpa_s->pending_interface_name);
    1477                 :          0 :         os_memset(wpa_s->pending_interface_addr, 0, ETH_ALEN);
    1478                 :          0 :         wpa_s->pending_interface_name[0] = '\0';
    1479                 :            : }
    1480                 :            : 
    1481                 :            : 
    1482                 :            : static struct wpa_supplicant *
    1483                 :         24 : wpas_p2p_init_group_interface(struct wpa_supplicant *wpa_s, int go)
    1484                 :            : {
    1485                 :            :         struct wpa_interface iface;
    1486                 :            :         struct wpa_supplicant *group_wpa_s;
    1487                 :            : 
    1488         [ -  + ]:         24 :         if (!wpa_s->pending_interface_name[0]) {
    1489                 :          0 :                 wpa_printf(MSG_ERROR, "P2P: No pending group interface");
    1490         [ #  # ]:          0 :                 if (!wpas_p2p_create_iface(wpa_s))
    1491                 :          0 :                         return NULL;
    1492                 :            :                 /*
    1493                 :            :                  * Something has forced us to remove the pending interface; try
    1494                 :            :                  * to create a new one and hope for the best that we will get
    1495                 :            :                  * the same local address.
    1496                 :            :                  */
    1497 [ #  # ][ #  # ]:          0 :                 if (wpas_p2p_add_group_interface(wpa_s, go ? WPA_IF_P2P_GO :
    1498                 :            :                                                  WPA_IF_P2P_CLIENT) < 0)
    1499                 :          0 :                         return NULL;
    1500                 :            :         }
    1501                 :            : 
    1502                 :         24 :         os_memset(&iface, 0, sizeof(iface));
    1503                 :         24 :         iface.ifname = wpa_s->pending_interface_name;
    1504                 :         24 :         iface.driver = wpa_s->driver->name;
    1505 [ -  + ][ #  # ]:         24 :         if (wpa_s->conf->ctrl_interface == NULL &&
    1506         [ #  # ]:          0 :             wpa_s->parent != wpa_s &&
    1507         [ #  # ]:          0 :             wpa_s->p2p_mgmt &&
    1508                 :          0 :             (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE))
    1509                 :          0 :                 iface.ctrl_interface = wpa_s->parent->conf->ctrl_interface;
    1510                 :            :         else
    1511                 :         24 :                 iface.ctrl_interface = wpa_s->conf->ctrl_interface;
    1512                 :         24 :         iface.driver_param = wpa_s->conf->driver_param;
    1513                 :         24 :         group_wpa_s = wpa_supplicant_add_iface(wpa_s->global, &iface);
    1514         [ -  + ]:         24 :         if (group_wpa_s == NULL) {
    1515                 :          0 :                 wpa_printf(MSG_ERROR, "P2P: Failed to create new "
    1516                 :            :                            "wpa_supplicant interface");
    1517                 :          0 :                 return NULL;
    1518                 :            :         }
    1519                 :         24 :         wpa_s->pending_interface_name[0] = '\0';
    1520                 :         24 :         group_wpa_s->parent = wpa_s;
    1521         [ +  + ]:         24 :         group_wpa_s->p2p_group_interface = go ? P2P_GROUP_INTERFACE_GO :
    1522                 :            :                 P2P_GROUP_INTERFACE_CLIENT;
    1523                 :         24 :         wpa_s->global->p2p_group_formation = group_wpa_s;
    1524                 :            : 
    1525                 :         24 :         wpas_p2p_clone_config(group_wpa_s, wpa_s);
    1526                 :            : 
    1527                 :         24 :         return group_wpa_s;
    1528                 :            : }
    1529                 :            : 
    1530                 :            : 
    1531                 :          2 : static void wpas_p2p_group_formation_timeout(void *eloop_ctx,
    1532                 :            :                                              void *timeout_ctx)
    1533                 :            : {
    1534                 :          2 :         struct wpa_supplicant *wpa_s = eloop_ctx;
    1535                 :          2 :         wpa_printf(MSG_DEBUG, "P2P: Group Formation timed out");
    1536                 :          2 :         wpas_p2p_group_formation_failed(wpa_s);
    1537                 :          2 : }
    1538                 :            : 
    1539                 :            : 
    1540                 :          2 : void wpas_p2p_group_formation_failed(struct wpa_supplicant *wpa_s)
    1541                 :            : {
    1542                 :          2 :         eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
    1543                 :          2 :                              wpa_s->parent, NULL);
    1544         [ +  - ]:          2 :         if (wpa_s->global->p2p)
    1545                 :          2 :                 p2p_group_formation_failed(wpa_s->global->p2p);
    1546                 :          2 :         wpas_group_formation_completed(wpa_s, 0);
    1547                 :          2 : }
    1548                 :            : 
    1549                 :            : 
    1550                 :          2 : static void wpas_p2p_grpform_fail_after_wps(struct wpa_supplicant *wpa_s)
    1551                 :            : {
    1552                 :          2 :         wpa_printf(MSG_DEBUG, "P2P: Reject group formation due to WPS provisioning failure");
    1553                 :          2 :         eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
    1554                 :          2 :                              wpa_s->parent, NULL);
    1555                 :          2 :         eloop_register_timeout(0, 0, wpas_p2p_group_formation_timeout,
    1556                 :          2 :                                wpa_s->parent, NULL);
    1557                 :          2 :         wpa_s->global->p2p_fail_on_wps_complete = 0;
    1558                 :          2 : }
    1559                 :            : 
    1560                 :            : 
    1561                 :          0 : void wpas_p2p_ap_setup_failed(struct wpa_supplicant *wpa_s)
    1562                 :            : {
    1563         [ #  # ]:          0 :         if (wpa_s->global->p2p_group_formation != wpa_s)
    1564                 :          0 :                 return;
    1565                 :            :         /* Speed up group formation timeout since this cannot succeed */
    1566                 :          0 :         eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
    1567                 :          0 :                              wpa_s->parent, NULL);
    1568                 :          0 :         eloop_register_timeout(0, 0, wpas_p2p_group_formation_timeout,
    1569                 :          0 :                                wpa_s->parent, NULL);
    1570                 :            : }
    1571                 :            : 
    1572                 :            : 
    1573                 :         96 : static void wpas_go_neg_completed(void *ctx, struct p2p_go_neg_results *res)
    1574                 :            : {
    1575                 :         96 :         struct wpa_supplicant *wpa_s = ctx;
    1576                 :            : 
    1577 [ +  - ][ -  + ]:         96 :         if (wpa_s->off_channel_freq || wpa_s->roc_waiting_drv_freq) {
    1578                 :          0 :                 wpa_drv_cancel_remain_on_channel(wpa_s);
    1579                 :          0 :                 wpa_s->off_channel_freq = 0;
    1580                 :          0 :                 wpa_s->roc_waiting_drv_freq = 0;
    1581                 :            :         }
    1582                 :            : 
    1583         [ +  + ]:         96 :         if (res->status) {
    1584                 :          6 :                 wpa_msg_global(wpa_s, MSG_INFO,
    1585                 :            :                                P2P_EVENT_GO_NEG_FAILURE "status=%d",
    1586                 :            :                                res->status);
    1587                 :          6 :                 wpas_notify_p2p_go_neg_completed(wpa_s, res);
    1588                 :          6 :                 wpas_p2p_remove_pending_group_interface(wpa_s);
    1589                 :          6 :                 return;
    1590                 :            :         }
    1591                 :            : 
    1592         [ +  + ]:         90 :         if (wpa_s->p2p_go_ht40)
    1593                 :         12 :                 res->ht40 = 1;
    1594         [ +  + ]:         90 :         if (wpa_s->p2p_go_vht)
    1595                 :         12 :                 res->vht = 1;
    1596                 :            : 
    1597         [ +  + ]:         90 :         wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_GO_NEG_SUCCESS "role=%s "
    1598                 :            :                        "freq=%d ht40=%d peer_dev=" MACSTR " peer_iface=" MACSTR
    1599                 :            :                        " wps_method=%s",
    1600                 :         90 :                        res->role_go ? "GO" : "client", res->freq, res->ht40,
    1601                 :        540 :                        MAC2STR(res->peer_device_addr),
    1602                 :        540 :                        MAC2STR(res->peer_interface_addr),
    1603                 :            :                        p2p_wps_method_text(res->wps_method));
    1604                 :         90 :         wpas_notify_p2p_go_neg_completed(wpa_s, res);
    1605                 :            : 
    1606 [ +  + ][ -  + ]:         90 :         if (res->role_go && wpa_s->p2p_persistent_id >= 0) {
    1607                 :            :                 struct wpa_ssid *ssid;
    1608                 :          0 :                 ssid = wpa_config_get_network(wpa_s->conf,
    1609                 :            :                                               wpa_s->p2p_persistent_id);
    1610 [ #  # ][ #  # ]:          0 :                 if (ssid && ssid->disabled == 2 &&
                 [ #  # ]
    1611         [ #  # ]:          0 :                     ssid->mode == WPAS_MODE_P2P_GO && ssid->passphrase) {
    1612                 :          0 :                         size_t len = os_strlen(ssid->passphrase);
    1613                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: Override passphrase based "
    1614                 :            :                                    "on requested persistent group");
    1615                 :          0 :                         os_memcpy(res->passphrase, ssid->passphrase, len);
    1616                 :          0 :                         res->passphrase[len] = '\0';
    1617                 :            :                 }
    1618                 :            :         }
    1619                 :            : 
    1620         [ +  + ]:         90 :         if (wpa_s->create_p2p_iface) {
    1621                 :         18 :                 struct wpa_supplicant *group_wpa_s =
    1622                 :         18 :                         wpas_p2p_init_group_interface(wpa_s, res->role_go);
    1623         [ -  + ]:         18 :                 if (group_wpa_s == NULL) {
    1624                 :          0 :                         wpas_p2p_remove_pending_group_interface(wpa_s);
    1625                 :          0 :                         return;
    1626                 :            :                 }
    1627         [ +  - ]:         18 :                 if (group_wpa_s != wpa_s) {
    1628                 :         18 :                         os_memcpy(group_wpa_s->p2p_pin, wpa_s->p2p_pin,
    1629                 :            :                                   sizeof(group_wpa_s->p2p_pin));
    1630                 :         18 :                         group_wpa_s->p2p_wps_method = wpa_s->p2p_wps_method;
    1631                 :            :                 }
    1632                 :         18 :                 os_memset(wpa_s->pending_interface_addr, 0, ETH_ALEN);
    1633                 :         18 :                 wpa_s->pending_interface_name[0] = '\0';
    1634                 :         18 :                 group_wpa_s->p2p_in_provisioning = 1;
    1635                 :            : 
    1636         [ +  + ]:         18 :                 if (res->role_go)
    1637                 :         10 :                         wpas_start_wps_go(group_wpa_s, res, 1);
    1638                 :            :                 else
    1639                 :          8 :                         wpas_start_wps_enrollee(group_wpa_s, res);
    1640                 :            :         } else {
    1641                 :         72 :                 wpa_s->p2p_in_provisioning = 1;
    1642                 :         72 :                 wpa_s->global->p2p_group_formation = wpa_s;
    1643                 :            : 
    1644         [ +  + ]:         72 :                 if (res->role_go)
    1645                 :         35 :                         wpas_start_wps_go(wpa_s, res, 1);
    1646                 :            :                 else
    1647                 :         37 :                         wpas_start_wps_enrollee(ctx, res);
    1648                 :            :         }
    1649                 :            : 
    1650                 :         90 :         wpa_s->p2p_long_listen = 0;
    1651                 :         90 :         eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL);
    1652                 :            : 
    1653                 :         90 :         eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s, NULL);
    1654                 :         96 :         eloop_register_timeout(15 + res->peer_config_timeout / 100,
    1655                 :         90 :                                (res->peer_config_timeout % 100) * 10000,
    1656                 :            :                                wpas_p2p_group_formation_timeout, wpa_s, NULL);
    1657                 :            : }
    1658                 :            : 
    1659                 :            : 
    1660                 :          9 : static void wpas_go_neg_req_rx(void *ctx, const u8 *src, u16 dev_passwd_id)
    1661                 :            : {
    1662                 :          9 :         struct wpa_supplicant *wpa_s = ctx;
    1663                 :          9 :         wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_GO_NEG_REQUEST MACSTR
    1664                 :         54 :                        " dev_passwd_id=%u", MAC2STR(src), dev_passwd_id);
    1665                 :            : 
    1666                 :          9 :         wpas_notify_p2p_go_neg_req(wpa_s, src, dev_passwd_id);
    1667                 :          9 : }
    1668                 :            : 
    1669                 :            : 
    1670                 :        241 : static void wpas_dev_found(void *ctx, const u8 *addr,
    1671                 :            :                            const struct p2p_peer_info *info,
    1672                 :            :                            int new_device)
    1673                 :            : {
    1674                 :            : #ifndef CONFIG_NO_STDOUT_DEBUG
    1675                 :        241 :         struct wpa_supplicant *wpa_s = ctx;
    1676                 :            :         char devtype[WPS_DEV_TYPE_BUFSIZE];
    1677                 :        241 :         char *wfd_dev_info_hex = NULL;
    1678                 :            : 
    1679                 :            : #ifdef CONFIG_WIFI_DISPLAY
    1680                 :        241 :         wfd_dev_info_hex = wifi_display_subelem_hex(info->wfd_subelems,
    1681                 :            :                                                     WFD_SUBELEM_DEVICE_INFO);
    1682                 :            : #endif /* CONFIG_WIFI_DISPLAY */
    1683                 :            : 
    1684 [ +  + ][ +  + ]:        241 :         wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_DEVICE_FOUND MACSTR
    1685                 :            :                        " p2p_dev_addr=" MACSTR
    1686                 :            :                        " pri_dev_type=%s name='%s' config_methods=0x%x "
    1687                 :            :                        "dev_capab=0x%x group_capab=0x%x%s%s",
    1688                 :       2892 :                        MAC2STR(addr), MAC2STR(info->p2p_device_addr),
    1689                 :        241 :                        wps_dev_type_bin2str(info->pri_dev_type, devtype,
    1690                 :            :                                             sizeof(devtype)),
    1691                 :        482 :                        info->device_name, info->config_methods,
    1692                 :        482 :                        info->dev_capab, info->group_capab,
    1693                 :            :                        wfd_dev_info_hex ? " wfd_dev_info=0x" : "",
    1694                 :            :                        wfd_dev_info_hex ? wfd_dev_info_hex : "");
    1695                 :            : 
    1696                 :        241 :         os_free(wfd_dev_info_hex);
    1697                 :            : #endif /* CONFIG_NO_STDOUT_DEBUG */
    1698                 :            : 
    1699                 :        241 :         wpas_notify_p2p_device_found(ctx, info->p2p_device_addr, new_device);
    1700                 :        241 : }
    1701                 :            : 
    1702                 :            : 
    1703                 :        236 : static void wpas_dev_lost(void *ctx, const u8 *dev_addr)
    1704                 :            : {
    1705                 :        236 :         struct wpa_supplicant *wpa_s = ctx;
    1706                 :            : 
    1707                 :        236 :         wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_DEVICE_LOST
    1708                 :       1416 :                        "p2p_dev_addr=" MACSTR, MAC2STR(dev_addr));
    1709                 :            : 
    1710                 :        236 :         wpas_notify_p2p_device_lost(wpa_s, dev_addr);
    1711                 :        236 : }
    1712                 :            : 
    1713                 :            : 
    1714                 :        144 : static void wpas_find_stopped(void *ctx)
    1715                 :            : {
    1716                 :        144 :         struct wpa_supplicant *wpa_s = ctx;
    1717                 :        144 :         wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_FIND_STOPPED);
    1718                 :        144 : }
    1719                 :            : 
    1720                 :            : 
    1721                 :            : struct wpas_p2p_listen_work {
    1722                 :            :         unsigned int freq;
    1723                 :            :         unsigned int duration;
    1724                 :            :         struct wpabuf *probe_resp_ie;
    1725                 :            : };
    1726                 :            : 
    1727                 :            : 
    1728                 :        773 : static void wpas_p2p_listen_work_free(struct wpas_p2p_listen_work *lwork)
    1729                 :            : {
    1730         [ -  + ]:        773 :         if (lwork == NULL)
    1731                 :        773 :                 return;
    1732                 :        773 :         wpabuf_free(lwork->probe_resp_ie);
    1733                 :        773 :         os_free(lwork);
    1734                 :            : }
    1735                 :            : 
    1736                 :            : 
    1737                 :       4157 : static void wpas_p2p_listen_work_done(struct wpa_supplicant *wpa_s)
    1738                 :            : {
    1739                 :            :         struct wpas_p2p_listen_work *lwork;
    1740                 :            : 
    1741         [ +  + ]:       4157 :         if (!wpa_s->p2p_listen_work)
    1742                 :       4157 :                 return;
    1743                 :            : 
    1744                 :        773 :         lwork = wpa_s->p2p_listen_work->ctx;
    1745                 :        773 :         wpas_p2p_listen_work_free(lwork);
    1746                 :        773 :         radio_work_done(wpa_s->p2p_listen_work);
    1747                 :        773 :         wpa_s->p2p_listen_work = NULL;
    1748                 :            : }
    1749                 :            : 
    1750                 :            : 
    1751                 :        773 : static void wpas_start_listen_cb(struct wpa_radio_work *work, int deinit)
    1752                 :            : {
    1753                 :        773 :         struct wpa_supplicant *wpa_s = work->wpa_s;
    1754                 :        773 :         struct wpas_p2p_listen_work *lwork = work->ctx;
    1755                 :            : 
    1756         [ -  + ]:        773 :         if (deinit) {
    1757         [ #  # ]:          0 :                 if (work->started) {
    1758                 :          0 :                         wpa_s->p2p_listen_work = NULL;
    1759                 :          0 :                         wpas_stop_listen(wpa_s);
    1760                 :            :                 }
    1761                 :          0 :                 wpas_p2p_listen_work_free(lwork);
    1762                 :          0 :                 return;
    1763                 :            :         }
    1764                 :            : 
    1765                 :        773 :         wpa_s->p2p_listen_work = work;
    1766                 :            : 
    1767                 :        773 :         wpa_drv_set_ap_wps_ie(wpa_s, NULL, lwork->probe_resp_ie, NULL);
    1768                 :            : 
    1769         [ -  + ]:        773 :         if (wpa_drv_probe_req_report(wpa_s, 1) < 0) {
    1770                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Failed to request the driver to "
    1771                 :            :                            "report received Probe Request frames");
    1772                 :          0 :                 wpas_p2p_listen_work_done(wpa_s);
    1773                 :          0 :                 return;
    1774                 :            :         }
    1775                 :            : 
    1776                 :        773 :         wpa_s->pending_listen_freq = lwork->freq;
    1777                 :        773 :         wpa_s->pending_listen_duration = lwork->duration;
    1778                 :            : 
    1779         [ -  + ]:        773 :         if (wpa_drv_remain_on_channel(wpa_s, lwork->freq, lwork->duration) < 0)
    1780                 :            :         {
    1781                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Failed to request the driver "
    1782                 :            :                            "to remain on channel (%u MHz) for Listen "
    1783                 :            :                            "state", lwork->freq);
    1784                 :          0 :                 wpas_p2p_listen_work_done(wpa_s);
    1785                 :          0 :                 wpa_s->pending_listen_freq = 0;
    1786                 :          0 :                 return;
    1787                 :            :         }
    1788                 :        773 :         wpa_s->off_channel_freq = 0;
    1789                 :        773 :         wpa_s->roc_waiting_drv_freq = lwork->freq;
    1790                 :            : }
    1791                 :            : 
    1792                 :            : 
    1793                 :        773 : static int wpas_start_listen(void *ctx, unsigned int freq,
    1794                 :            :                              unsigned int duration,
    1795                 :            :                              const struct wpabuf *probe_resp_ie)
    1796                 :            : {
    1797                 :        773 :         struct wpa_supplicant *wpa_s = ctx;
    1798                 :            :         struct wpas_p2p_listen_work *lwork;
    1799                 :            : 
    1800         [ -  + ]:        773 :         if (wpa_s->p2p_listen_work) {
    1801                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Reject start_listen since p2p_listen_work already exists");
    1802                 :          0 :                 return -1;
    1803                 :            :         }
    1804                 :            : 
    1805                 :        773 :         lwork = os_zalloc(sizeof(*lwork));
    1806         [ -  + ]:        773 :         if (lwork == NULL)
    1807                 :          0 :                 return -1;
    1808                 :        773 :         lwork->freq = freq;
    1809                 :        773 :         lwork->duration = duration;
    1810         [ +  - ]:        773 :         if (probe_resp_ie) {
    1811                 :        773 :                 lwork->probe_resp_ie = wpabuf_dup(probe_resp_ie);
    1812         [ -  + ]:        773 :                 if (lwork->probe_resp_ie == NULL) {
    1813                 :          0 :                         wpas_p2p_listen_work_free(lwork);
    1814                 :          0 :                         return -1;
    1815                 :            :                 }
    1816                 :            :         }
    1817                 :            : 
    1818         [ -  + ]:        773 :         if (radio_add_work(wpa_s, freq, "p2p-listen", 0, wpas_start_listen_cb,
    1819                 :            :                            lwork) < 0) {
    1820                 :          0 :                 wpas_p2p_listen_work_free(lwork);
    1821                 :          0 :                 return -1;
    1822                 :            :         }
    1823                 :            : 
    1824                 :        773 :         return 0;
    1825                 :            : }
    1826                 :            : 
    1827                 :            : 
    1828                 :       3348 : static void wpas_stop_listen(void *ctx)
    1829                 :            : {
    1830                 :       3348 :         struct wpa_supplicant *wpa_s = ctx;
    1831 [ +  + ][ +  + ]:       3348 :         if (wpa_s->off_channel_freq || wpa_s->roc_waiting_drv_freq) {
    1832                 :        184 :                 wpa_drv_cancel_remain_on_channel(wpa_s);
    1833                 :        184 :                 wpa_s->off_channel_freq = 0;
    1834                 :        184 :                 wpa_s->roc_waiting_drv_freq = 0;
    1835                 :            :         }
    1836                 :       3348 :         wpa_drv_set_ap_wps_ie(wpa_s, NULL, NULL, NULL);
    1837                 :       3348 :         wpa_drv_probe_req_report(wpa_s, 0);
    1838                 :       3348 :         wpas_p2p_listen_work_done(wpa_s);
    1839                 :       3348 : }
    1840                 :            : 
    1841                 :            : 
    1842                 :        335 : static int wpas_send_probe_resp(void *ctx, const struct wpabuf *buf)
    1843                 :            : {
    1844                 :        335 :         struct wpa_supplicant *wpa_s = ctx;
    1845                 :        335 :         return wpa_drv_send_mlme(wpa_s, wpabuf_head(buf), wpabuf_len(buf), 1);
    1846                 :            : }
    1847                 :            : 
    1848                 :            : 
    1849                 :            : /*
    1850                 :            :  * DNS Header section is used only to calculate compression pointers, so the
    1851                 :            :  * contents of this data does not matter, but the length needs to be reserved
    1852                 :            :  * in the virtual packet.
    1853                 :            :  */
    1854                 :            : #define DNS_HEADER_LEN 12
    1855                 :            : 
    1856                 :            : /*
    1857                 :            :  * 27-octet in-memory packet from P2P specification containing two implied
    1858                 :            :  * queries for _tcp.lcoal. PTR IN and _udp.local. PTR IN
    1859                 :            :  */
    1860                 :            : #define P2P_SD_IN_MEMORY_LEN 27
    1861                 :            : 
    1862                 :          4 : static int p2p_sd_dns_uncompress_label(char **upos, char *uend, u8 *start,
    1863                 :            :                                        u8 **spos, const u8 *end)
    1864                 :            : {
    1865         [ +  - ]:         10 :         while (*spos < end) {
    1866                 :         10 :                 u8 val = ((*spos)[0] & 0xc0) >> 6;
    1867                 :            :                 int len;
    1868                 :            : 
    1869 [ +  - ][ -  + ]:         10 :                 if (val == 1 || val == 2) {
    1870                 :            :                         /* These are reserved values in RFC 1035 */
    1871                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: Invalid domain name "
    1872                 :            :                                    "sequence starting with 0x%x", val);
    1873                 :          0 :                         return -1;
    1874                 :            :                 }
    1875                 :            : 
    1876         [ +  + ]:         10 :                 if (val == 3) {
    1877                 :            :                         u16 offset;
    1878                 :            :                         u8 *spos_tmp;
    1879                 :            : 
    1880                 :            :                         /* Offset */
    1881         [ -  + ]:          2 :                         if (*spos + 2 > end) {
    1882                 :          0 :                                 wpa_printf(MSG_DEBUG, "P2P: No room for full "
    1883                 :            :                                            "DNS offset field");
    1884                 :          0 :                                 return -1;
    1885                 :            :                         }
    1886                 :            : 
    1887                 :          2 :                         offset = (((*spos)[0] & 0x3f) << 8) | (*spos)[1];
    1888         [ -  + ]:          2 :                         if (offset >= *spos - start) {
    1889                 :          0 :                                 wpa_printf(MSG_DEBUG, "P2P: Invalid DNS "
    1890                 :            :                                            "pointer offset %u", offset);
    1891                 :          0 :                                 return -1;
    1892                 :            :                         }
    1893                 :            : 
    1894                 :          2 :                         (*spos) += 2;
    1895                 :          2 :                         spos_tmp = start + offset;
    1896                 :          2 :                         return p2p_sd_dns_uncompress_label(upos, uend, start,
    1897                 :            :                                                            &spos_tmp,
    1898                 :          2 :                                                            *spos - 2);
    1899                 :            :                 }
    1900                 :            : 
    1901                 :            :                 /* Label */
    1902                 :          8 :                 len = (*spos)[0] & 0x3f;
    1903         [ +  + ]:          8 :                 if (len == 0)
    1904                 :          2 :                         return 0;
    1905                 :            : 
    1906                 :          6 :                 (*spos)++;
    1907         [ -  + ]:          6 :                 if (*spos + len > end) {
    1908                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: Invalid domain name "
    1909                 :            :                                    "sequence - no room for label with length "
    1910                 :            :                                    "%u", len);
    1911                 :          0 :                         return -1;
    1912                 :            :                 }
    1913                 :            : 
    1914         [ -  + ]:          6 :                 if (*upos + len + 2 > uend)
    1915                 :          0 :                         return -2;
    1916                 :            : 
    1917                 :          6 :                 os_memcpy(*upos, *spos, len);
    1918                 :          6 :                 *spos += len;
    1919                 :          6 :                 *upos += len;
    1920                 :          6 :                 (*upos)[0] = '.';
    1921                 :          6 :                 (*upos)++;
    1922                 :          6 :                 (*upos)[0] = '\0';
    1923                 :            :         }
    1924                 :            : 
    1925                 :          4 :         return 0;
    1926                 :            : }
    1927                 :            : 
    1928                 :            : 
    1929                 :            : /* Uncompress domain names per RFC 1035 using the P2P SD in-memory packet.
    1930                 :            :  * Returns -1 on parsing error (invalid input sequence), -2 if output buffer is
    1931                 :            :  * not large enough */
    1932                 :          2 : static int p2p_sd_dns_uncompress(char *buf, size_t buf_len, const u8 *msg,
    1933                 :            :                                  size_t msg_len, size_t offset)
    1934                 :            : {
    1935                 :            :         /* 27-octet in-memory packet from P2P specification */
    1936                 :          2 :         const char *prefix = "\x04_tcp\x05local\x00\x00\x0C\x00\x01"
    1937                 :            :                 "\x04_udp\xC0\x11\x00\x0C\x00\x01";
    1938                 :            :         u8 *tmp, *end, *spos;
    1939                 :            :         char *upos, *uend;
    1940                 :          2 :         int ret = 0;
    1941                 :            : 
    1942         [ -  + ]:          2 :         if (buf_len < 2)
    1943                 :          0 :                 return -1;
    1944         [ -  + ]:          2 :         if (offset > msg_len)
    1945                 :          0 :                 return -1;
    1946                 :            : 
    1947                 :          2 :         tmp = os_malloc(DNS_HEADER_LEN + P2P_SD_IN_MEMORY_LEN + msg_len);
    1948         [ -  + ]:          2 :         if (tmp == NULL)
    1949                 :          0 :                 return -1;
    1950                 :          2 :         spos = tmp + DNS_HEADER_LEN + P2P_SD_IN_MEMORY_LEN;
    1951                 :          2 :         end = spos + msg_len;
    1952                 :          2 :         spos += offset;
    1953                 :            : 
    1954                 :          2 :         os_memset(tmp, 0, DNS_HEADER_LEN);
    1955                 :          2 :         os_memcpy(tmp + DNS_HEADER_LEN, prefix, P2P_SD_IN_MEMORY_LEN);
    1956                 :          2 :         os_memcpy(tmp + DNS_HEADER_LEN + P2P_SD_IN_MEMORY_LEN, msg, msg_len);
    1957                 :            : 
    1958                 :          2 :         upos = buf;
    1959                 :          2 :         uend = buf + buf_len;
    1960                 :            : 
    1961                 :          2 :         ret = p2p_sd_dns_uncompress_label(&upos, uend, tmp, &spos, end);
    1962         [ -  + ]:          2 :         if (ret) {
    1963                 :          0 :                 os_free(tmp);
    1964                 :          0 :                 return ret;
    1965                 :            :         }
    1966                 :            : 
    1967         [ -  + ]:          2 :         if (upos == buf) {
    1968                 :          0 :                 upos[0] = '.';
    1969                 :          0 :                 upos[1] = '\0';
    1970         [ +  - ]:          2 :         } else if (upos[-1] == '.')
    1971                 :          2 :                 upos[-1] = '\0';
    1972                 :            : 
    1973                 :          2 :         os_free(tmp);
    1974                 :          2 :         return 0;
    1975                 :            : }
    1976                 :            : 
    1977                 :            : 
    1978                 :            : static struct p2p_srv_bonjour *
    1979                 :          0 : wpas_p2p_service_get_bonjour(struct wpa_supplicant *wpa_s,
    1980                 :            :                              const struct wpabuf *query)
    1981                 :            : {
    1982                 :            :         struct p2p_srv_bonjour *bsrv;
    1983                 :            :         size_t len;
    1984                 :            : 
    1985                 :          0 :         len = wpabuf_len(query);
    1986         [ #  # ]:          0 :         dl_list_for_each(bsrv, &wpa_s->global->p2p_srv_bonjour,
    1987                 :            :                          struct p2p_srv_bonjour, list) {
    1988   [ #  #  #  # ]:          0 :                 if (len == wpabuf_len(bsrv->query) &&
    1989                 :          0 :                     os_memcmp(wpabuf_head(query), wpabuf_head(bsrv->query),
    1990                 :            :                               len) == 0)
    1991                 :          0 :                         return bsrv;
    1992                 :            :         }
    1993                 :          0 :         return NULL;
    1994                 :            : }
    1995                 :            : 
    1996                 :            : 
    1997                 :            : static struct p2p_srv_upnp *
    1998                 :        275 : wpas_p2p_service_get_upnp(struct wpa_supplicant *wpa_s, u8 version,
    1999                 :            :                           const char *service)
    2000                 :            : {
    2001                 :            :         struct p2p_srv_upnp *usrv;
    2002                 :            : 
    2003         [ +  + ]:      21825 :         dl_list_for_each(usrv, &wpa_s->global->p2p_srv_upnp,
    2004                 :            :                          struct p2p_srv_upnp, list) {
    2005 [ +  - ][ +  + ]:      21575 :                 if (version == usrv->version &&
    2006                 :      21575 :                     os_strcmp(service, usrv->service) == 0)
    2007                 :         25 :                         return usrv;
    2008                 :            :         }
    2009                 :        275 :         return NULL;
    2010                 :            : }
    2011                 :            : 
    2012                 :            : 
    2013                 :          4 : static void wpas_sd_add_proto_not_avail(struct wpabuf *resp, u8 srv_proto,
    2014                 :            :                                         u8 srv_trans_id)
    2015                 :            : {
    2016                 :            :         u8 *len_pos;
    2017                 :            : 
    2018         [ -  + ]:          4 :         if (wpabuf_tailroom(resp) < 5)
    2019                 :          4 :                 return;
    2020                 :            : 
    2021                 :            :         /* Length (to be filled) */
    2022                 :          4 :         len_pos = wpabuf_put(resp, 2);
    2023                 :          4 :         wpabuf_put_u8(resp, srv_proto);
    2024                 :          4 :         wpabuf_put_u8(resp, srv_trans_id);
    2025                 :            :         /* Status Code */
    2026                 :          4 :         wpabuf_put_u8(resp, P2P_SD_PROTO_NOT_AVAILABLE);
    2027                 :            :         /* Response Data: empty */
    2028                 :          4 :         WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos - 2);
    2029                 :            : }
    2030                 :            : 
    2031                 :            : 
    2032                 :         11 : static void wpas_sd_all_bonjour(struct wpa_supplicant *wpa_s,
    2033                 :            :                                 struct wpabuf *resp, u8 srv_trans_id)
    2034                 :            : {
    2035                 :            :         struct p2p_srv_bonjour *bsrv;
    2036                 :            :         u8 *len_pos;
    2037                 :            : 
    2038                 :         11 :         wpa_printf(MSG_DEBUG, "P2P: SD Request for all Bonjour services");
    2039                 :            : 
    2040         [ -  + ]:         11 :         if (dl_list_empty(&wpa_s->global->p2p_srv_bonjour)) {
    2041                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Bonjour protocol not available");
    2042                 :          0 :                 return;
    2043                 :            :         }
    2044                 :            : 
    2045         [ +  + ]:         75 :         dl_list_for_each(bsrv, &wpa_s->global->p2p_srv_bonjour,
    2046                 :            :                          struct p2p_srv_bonjour, list) {
    2047         [ -  + ]:        128 :                 if (wpabuf_tailroom(resp) <
    2048                 :         64 :                     5 + wpabuf_len(bsrv->query) + wpabuf_len(bsrv->resp))
    2049                 :          0 :                         return;
    2050                 :            :                 /* Length (to be filled) */
    2051                 :         64 :                 len_pos = wpabuf_put(resp, 2);
    2052                 :         64 :                 wpabuf_put_u8(resp, P2P_SERV_BONJOUR);
    2053                 :         64 :                 wpabuf_put_u8(resp, srv_trans_id);
    2054                 :            :                 /* Status Code */
    2055                 :         64 :                 wpabuf_put_u8(resp, P2P_SD_SUCCESS);
    2056                 :         64 :                 wpa_hexdump_ascii(MSG_DEBUG, "P2P: Matching Bonjour service",
    2057                 :         64 :                                   wpabuf_head(bsrv->resp),
    2058                 :         64 :                                   wpabuf_len(bsrv->resp));
    2059                 :            :                 /* Response Data */
    2060                 :         64 :                 wpabuf_put_buf(resp, bsrv->query); /* Key */
    2061                 :         64 :                 wpabuf_put_buf(resp, bsrv->resp); /* Value */
    2062                 :         64 :                 WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos -
    2063                 :            :                              2);
    2064                 :            :         }
    2065                 :            : }
    2066                 :            : 
    2067                 :            : 
    2068                 :          4 : static int match_bonjour_query(struct p2p_srv_bonjour *bsrv, const u8 *query,
    2069                 :            :                                size_t query_len)
    2070                 :            : {
    2071                 :            :         char str_rx[256], str_srv[256];
    2072                 :            : 
    2073 [ +  - ][ -  + ]:          4 :         if (query_len < 3 || wpabuf_len(bsrv->query) < 3)
    2074                 :          0 :                 return 0; /* Too short to include DNS Type and Version */
    2075         [ +  + ]:          4 :         if (os_memcmp(query + query_len - 3,
    2076                 :            :                       wpabuf_head_u8(bsrv->query) + wpabuf_len(bsrv->query) - 3,
    2077                 :            :                       3) != 0)
    2078                 :          2 :                 return 0; /* Mismatch in DNS Type or Version */
    2079   [ +  +  +  - ]:          3 :         if (query_len == wpabuf_len(bsrv->query) &&
    2080                 :          1 :             os_memcmp(query, wpabuf_head(bsrv->query), query_len - 3) == 0)
    2081                 :          1 :                 return 1; /* Binary match */
    2082                 :            : 
    2083         [ -  + ]:          1 :         if (p2p_sd_dns_uncompress(str_rx, sizeof(str_rx), query, query_len - 3,
    2084                 :            :                                   0))
    2085                 :          0 :                 return 0; /* Failed to uncompress query */
    2086         [ -  + ]:          1 :         if (p2p_sd_dns_uncompress(str_srv, sizeof(str_srv),
    2087                 :          1 :                                   wpabuf_head(bsrv->query),
    2088                 :          1 :                                   wpabuf_len(bsrv->query) - 3, 0))
    2089                 :          0 :                 return 0; /* Failed to uncompress service */
    2090                 :            : 
    2091                 :          4 :         return os_strcmp(str_rx, str_srv) == 0;
    2092                 :            : }
    2093                 :            : 
    2094                 :            : 
    2095                 :          7 : static void wpas_sd_req_bonjour(struct wpa_supplicant *wpa_s,
    2096                 :            :                                 struct wpabuf *resp, u8 srv_trans_id,
    2097                 :            :                                 const u8 *query, size_t query_len)
    2098                 :            : {
    2099                 :            :         struct p2p_srv_bonjour *bsrv;
    2100                 :            :         u8 *len_pos;
    2101                 :          7 :         int matches = 0;
    2102                 :            : 
    2103                 :          7 :         wpa_hexdump_ascii(MSG_DEBUG, "P2P: SD Request for Bonjour",
    2104                 :            :                           query, query_len);
    2105         [ +  + ]:          7 :         if (dl_list_empty(&wpa_s->global->p2p_srv_bonjour)) {
    2106                 :          1 :                 wpa_printf(MSG_DEBUG, "P2P: Bonjour protocol not available");
    2107                 :          1 :                 wpas_sd_add_proto_not_avail(resp, P2P_SERV_BONJOUR,
    2108                 :            :                                             srv_trans_id);
    2109                 :          1 :                 return;
    2110                 :            :         }
    2111                 :            : 
    2112         [ +  + ]:          6 :         if (query_len == 0) {
    2113                 :          5 :                 wpas_sd_all_bonjour(wpa_s, resp, srv_trans_id);
    2114                 :          5 :                 return;
    2115                 :            :         }
    2116                 :            : 
    2117         [ +  + ]:          5 :         dl_list_for_each(bsrv, &wpa_s->global->p2p_srv_bonjour,
    2118                 :            :                          struct p2p_srv_bonjour, list) {
    2119         [ +  + ]:          4 :                 if (!match_bonjour_query(bsrv, query, query_len))
    2120                 :          3 :                         continue;
    2121                 :            : 
    2122         [ -  + ]:          2 :                 if (wpabuf_tailroom(resp) <
    2123                 :          1 :                     5 + query_len + wpabuf_len(bsrv->resp))
    2124                 :          0 :                         return;
    2125                 :            : 
    2126                 :          1 :                 matches++;
    2127                 :            : 
    2128                 :            :                 /* Length (to be filled) */
    2129                 :          1 :                 len_pos = wpabuf_put(resp, 2);
    2130                 :          1 :                 wpabuf_put_u8(resp, P2P_SERV_BONJOUR);
    2131                 :          1 :                 wpabuf_put_u8(resp, srv_trans_id);
    2132                 :            : 
    2133                 :            :                 /* Status Code */
    2134                 :          1 :                 wpabuf_put_u8(resp, P2P_SD_SUCCESS);
    2135                 :          1 :                 wpa_hexdump_ascii(MSG_DEBUG, "P2P: Matching Bonjour service",
    2136                 :          1 :                                   wpabuf_head(bsrv->resp),
    2137                 :          1 :                                   wpabuf_len(bsrv->resp));
    2138                 :            : 
    2139                 :            :                 /* Response Data */
    2140                 :          1 :                 wpabuf_put_data(resp, query, query_len); /* Key */
    2141                 :          1 :                 wpabuf_put_buf(resp, bsrv->resp); /* Value */
    2142                 :            : 
    2143                 :          1 :                 WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos - 2);
    2144                 :            :         }
    2145                 :            : 
    2146         [ -  + ]:          1 :         if (matches == 0) {
    2147                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Requested Bonjour service not "
    2148                 :            :                            "available");
    2149         [ #  # ]:          0 :                 if (wpabuf_tailroom(resp) < 5)
    2150                 :          0 :                         return;
    2151                 :            : 
    2152                 :            :                 /* Length (to be filled) */
    2153                 :          0 :                 len_pos = wpabuf_put(resp, 2);
    2154                 :          0 :                 wpabuf_put_u8(resp, P2P_SERV_BONJOUR);
    2155                 :          0 :                 wpabuf_put_u8(resp, srv_trans_id);
    2156                 :            : 
    2157                 :            :                 /* Status Code */
    2158                 :          0 :                 wpabuf_put_u8(resp, P2P_SD_REQUESTED_INFO_NOT_AVAILABLE);
    2159                 :            :                 /* Response Data: empty */
    2160                 :          7 :                 WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos -
    2161                 :            :                              2);
    2162                 :            :         }
    2163                 :            : }
    2164                 :            : 
    2165                 :            : 
    2166                 :         11 : static void wpas_sd_all_upnp(struct wpa_supplicant *wpa_s,
    2167                 :            :                              struct wpabuf *resp, u8 srv_trans_id)
    2168                 :            : {
    2169                 :            :         struct p2p_srv_upnp *usrv;
    2170                 :            :         u8 *len_pos;
    2171                 :            : 
    2172                 :         11 :         wpa_printf(MSG_DEBUG, "P2P: SD Request for all UPnP services");
    2173                 :            : 
    2174         [ -  + ]:         11 :         if (dl_list_empty(&wpa_s->global->p2p_srv_upnp)) {
    2175                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: UPnP protocol not available");
    2176                 :          0 :                 return;
    2177                 :            :         }
    2178                 :            : 
    2179         [ +  + ]:        313 :         dl_list_for_each(usrv, &wpa_s->global->p2p_srv_upnp,
    2180                 :            :                          struct p2p_srv_upnp, list) {
    2181         [ +  + ]:        302 :                 if (wpabuf_tailroom(resp) < 5 + 1 + os_strlen(usrv->service))
    2182                 :          1 :                         return;
    2183                 :            : 
    2184                 :            :                 /* Length (to be filled) */
    2185                 :        301 :                 len_pos = wpabuf_put(resp, 2);
    2186                 :        301 :                 wpabuf_put_u8(resp, P2P_SERV_UPNP);
    2187                 :        301 :                 wpabuf_put_u8(resp, srv_trans_id);
    2188                 :            : 
    2189                 :            :                 /* Status Code */
    2190                 :        301 :                 wpabuf_put_u8(resp, P2P_SD_SUCCESS);
    2191                 :            :                 /* Response Data */
    2192                 :        301 :                 wpabuf_put_u8(resp, usrv->version);
    2193                 :        301 :                 wpa_printf(MSG_DEBUG, "P2P: Matching UPnP Service: %s",
    2194                 :            :                            usrv->service);
    2195                 :        301 :                 wpabuf_put_str(resp, usrv->service);
    2196                 :        301 :                 WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos -
    2197                 :            :                              2);
    2198                 :            :         }
    2199                 :            : }
    2200                 :            : 
    2201                 :            : 
    2202                 :          7 : static void wpas_sd_req_upnp(struct wpa_supplicant *wpa_s,
    2203                 :            :                              struct wpabuf *resp, u8 srv_trans_id,
    2204                 :            :                              const u8 *query, size_t query_len)
    2205                 :            : {
    2206                 :            :         struct p2p_srv_upnp *usrv;
    2207                 :            :         u8 *len_pos;
    2208                 :            :         u8 version;
    2209                 :            :         char *str;
    2210                 :          7 :         int count = 0;
    2211                 :            : 
    2212                 :          7 :         wpa_hexdump_ascii(MSG_DEBUG, "P2P: SD Request for UPnP",
    2213                 :            :                           query, query_len);
    2214                 :            : 
    2215         [ +  + ]:          7 :         if (dl_list_empty(&wpa_s->global->p2p_srv_upnp)) {
    2216                 :          1 :                 wpa_printf(MSG_DEBUG, "P2P: UPnP protocol not available");
    2217                 :          1 :                 wpas_sd_add_proto_not_avail(resp, P2P_SERV_UPNP,
    2218                 :            :                                             srv_trans_id);
    2219                 :          1 :                 return;
    2220                 :            :         }
    2221                 :            : 
    2222         [ +  + ]:          6 :         if (query_len == 0) {
    2223                 :          5 :                 wpas_sd_all_upnp(wpa_s, resp, srv_trans_id);
    2224                 :          5 :                 return;
    2225                 :            :         }
    2226                 :            : 
    2227         [ -  + ]:          1 :         if (wpabuf_tailroom(resp) < 5)
    2228                 :          0 :                 return;
    2229                 :            : 
    2230                 :            :         /* Length (to be filled) */
    2231                 :          1 :         len_pos = wpabuf_put(resp, 2);
    2232                 :          1 :         wpabuf_put_u8(resp, P2P_SERV_UPNP);
    2233                 :          1 :         wpabuf_put_u8(resp, srv_trans_id);
    2234                 :            : 
    2235                 :          1 :         version = query[0];
    2236                 :          1 :         str = os_malloc(query_len);
    2237         [ -  + ]:          1 :         if (str == NULL)
    2238                 :          0 :                 return;
    2239                 :          1 :         os_memcpy(str, query + 1, query_len - 1);
    2240                 :          1 :         str[query_len - 1] = '\0';
    2241                 :            : 
    2242         [ +  + ]:          6 :         dl_list_for_each(usrv, &wpa_s->global->p2p_srv_upnp,
    2243                 :            :                          struct p2p_srv_upnp, list) {
    2244         [ -  + ]:          5 :                 if (version != usrv->version)
    2245                 :          0 :                         continue;
    2246                 :            : 
    2247 [ -  + ][ #  # ]:          5 :                 if (os_strcmp(str, "ssdp:all") != 0 &&
    2248                 :          0 :                     os_strstr(usrv->service, str) == NULL)
    2249                 :          0 :                         continue;
    2250                 :            : 
    2251         [ -  + ]:          5 :                 if (wpabuf_tailroom(resp) < 2)
    2252                 :          0 :                         break;
    2253         [ +  + ]:          5 :                 if (count == 0) {
    2254                 :            :                         /* Status Code */
    2255                 :          1 :                         wpabuf_put_u8(resp, P2P_SD_SUCCESS);
    2256                 :            :                         /* Response Data */
    2257                 :          1 :                         wpabuf_put_u8(resp, version);
    2258                 :            :                 } else
    2259                 :          4 :                         wpabuf_put_u8(resp, ',');
    2260                 :            : 
    2261                 :          5 :                 count++;
    2262                 :            : 
    2263                 :          5 :                 wpa_printf(MSG_DEBUG, "P2P: Matching UPnP Service: %s",
    2264                 :            :                            usrv->service);
    2265         [ -  + ]:          5 :                 if (wpabuf_tailroom(resp) < os_strlen(usrv->service))
    2266                 :          0 :                         break;
    2267                 :          5 :                 wpabuf_put_str(resp, usrv->service);
    2268                 :            :         }
    2269                 :          1 :         os_free(str);
    2270                 :            : 
    2271         [ -  + ]:          1 :         if (count == 0) {
    2272                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Requested UPnP service not "
    2273                 :            :                            "available");
    2274                 :            :                 /* Status Code */
    2275                 :          0 :                 wpabuf_put_u8(resp, P2P_SD_REQUESTED_INFO_NOT_AVAILABLE);
    2276                 :            :                 /* Response Data: empty */
    2277                 :            :         }
    2278                 :            : 
    2279                 :          7 :         WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos - 2);
    2280                 :            : }
    2281                 :            : 
    2282                 :            : 
    2283                 :            : #ifdef CONFIG_WIFI_DISPLAY
    2284                 :          0 : static void wpas_sd_req_wfd(struct wpa_supplicant *wpa_s,
    2285                 :            :                             struct wpabuf *resp, u8 srv_trans_id,
    2286                 :            :                             const u8 *query, size_t query_len)
    2287                 :            : {
    2288                 :            :         const u8 *pos;
    2289                 :            :         u8 role;
    2290                 :            :         u8 *len_pos;
    2291                 :            : 
    2292                 :          0 :         wpa_hexdump(MSG_DEBUG, "P2P: SD Request for WFD", query, query_len);
    2293                 :            : 
    2294         [ #  # ]:          0 :         if (!wpa_s->global->wifi_display) {
    2295                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: WFD protocol not available");
    2296                 :          0 :                 wpas_sd_add_proto_not_avail(resp, P2P_SERV_WIFI_DISPLAY,
    2297                 :            :                                             srv_trans_id);
    2298                 :          0 :                 return;
    2299                 :            :         }
    2300                 :            : 
    2301         [ #  # ]:          0 :         if (query_len < 1) {
    2302                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Missing WFD Requested Device "
    2303                 :            :                            "Role");
    2304                 :          0 :                 return;
    2305                 :            :         }
    2306                 :            : 
    2307         [ #  # ]:          0 :         if (wpabuf_tailroom(resp) < 5)
    2308                 :          0 :                 return;
    2309                 :            : 
    2310                 :          0 :         pos = query;
    2311                 :          0 :         role = *pos++;
    2312                 :          0 :         wpa_printf(MSG_DEBUG, "P2P: WSD for device role 0x%x", role);
    2313                 :            : 
    2314                 :            :         /* TODO: role specific handling */
    2315                 :            : 
    2316                 :            :         /* Length (to be filled) */
    2317                 :          0 :         len_pos = wpabuf_put(resp, 2);
    2318                 :          0 :         wpabuf_put_u8(resp, P2P_SERV_WIFI_DISPLAY);
    2319                 :          0 :         wpabuf_put_u8(resp, srv_trans_id);
    2320                 :          0 :         wpabuf_put_u8(resp, P2P_SD_SUCCESS); /* Status Code */
    2321                 :            : 
    2322         [ #  # ]:          0 :         while (pos < query + query_len) {
    2323 [ #  # ][ #  # ]:          0 :                 if (*pos < MAX_WFD_SUBELEMS &&
    2324         [ #  # ]:          0 :                     wpa_s->global->wfd_subelem[*pos] &&
    2325                 :          0 :                     wpabuf_tailroom(resp) >=
    2326                 :          0 :                     wpabuf_len(wpa_s->global->wfd_subelem[*pos])) {
    2327                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: Add WSD response "
    2328                 :          0 :                                    "subelement %u", *pos);
    2329                 :          0 :                         wpabuf_put_buf(resp, wpa_s->global->wfd_subelem[*pos]);
    2330                 :            :                 }
    2331                 :          0 :                 pos++;
    2332                 :            :         }
    2333                 :            : 
    2334                 :          0 :         WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(resp, 0) - len_pos - 2);
    2335                 :            : }
    2336                 :            : #endif /* CONFIG_WIFI_DISPLAY */
    2337                 :            : 
    2338                 :            : 
    2339                 :         22 : static void wpas_sd_request(void *ctx, int freq, const u8 *sa, u8 dialog_token,
    2340                 :            :                             u16 update_indic, const u8 *tlvs, size_t tlvs_len)
    2341                 :            : {
    2342                 :         22 :         struct wpa_supplicant *wpa_s = ctx;
    2343                 :         22 :         const u8 *pos = tlvs;
    2344                 :         22 :         const u8 *end = tlvs + tlvs_len;
    2345                 :            :         const u8 *tlv_end;
    2346                 :            :         u16 slen;
    2347                 :            :         struct wpabuf *resp;
    2348                 :            :         u8 srv_proto, srv_trans_id;
    2349                 :            :         size_t buf_len;
    2350                 :            :         char *buf;
    2351                 :            : 
    2352                 :         22 :         wpa_hexdump(MSG_MSGDUMP, "P2P: Service Discovery Request TLVs",
    2353                 :            :                     tlvs, tlvs_len);
    2354                 :         22 :         buf_len = 2 * tlvs_len + 1;
    2355                 :         22 :         buf = os_malloc(buf_len);
    2356         [ +  - ]:         22 :         if (buf) {
    2357                 :         22 :                 wpa_snprintf_hex(buf, buf_len, tlvs, tlvs_len);
    2358                 :         22 :                 wpa_msg_ctrl(wpa_s, MSG_INFO, P2P_EVENT_SERV_DISC_REQ "%d "
    2359                 :            :                              MACSTR " %u %u %s",
    2360                 :        132 :                              freq, MAC2STR(sa), dialog_token, update_indic,
    2361                 :            :                              buf);
    2362                 :         22 :                 os_free(buf);
    2363                 :            :         }
    2364                 :            : 
    2365         [ -  + ]:         22 :         if (wpa_s->p2p_sd_over_ctrl_iface) {
    2366                 :          0 :                 wpas_notify_p2p_sd_request(wpa_s, freq, sa, dialog_token,
    2367                 :            :                                            update_indic, tlvs, tlvs_len);
    2368                 :          0 :                 return; /* to be processed by an external program */
    2369                 :            :         }
    2370                 :            : 
    2371                 :         22 :         resp = wpabuf_alloc(10000);
    2372         [ -  + ]:         22 :         if (resp == NULL)
    2373                 :          0 :                 return;
    2374                 :            : 
    2375         [ +  + ]:         44 :         while (pos + 1 < end) {
    2376                 :         22 :                 wpa_printf(MSG_DEBUG, "P2P: Service Request TLV");
    2377                 :         22 :                 slen = WPA_GET_LE16(pos);
    2378                 :         22 :                 pos += 2;
    2379 [ +  - ][ -  + ]:         22 :                 if (pos + slen > end || slen < 2) {
    2380                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: Unexpected Query Data "
    2381                 :            :                                    "length");
    2382                 :          0 :                         wpabuf_free(resp);
    2383                 :          0 :                         return;
    2384                 :            :                 }
    2385                 :         22 :                 tlv_end = pos + slen;
    2386                 :            : 
    2387                 :         22 :                 srv_proto = *pos++;
    2388                 :         22 :                 wpa_printf(MSG_DEBUG, "P2P: Service Protocol Type %u",
    2389                 :            :                            srv_proto);
    2390                 :         22 :                 srv_trans_id = *pos++;
    2391                 :         22 :                 wpa_printf(MSG_DEBUG, "P2P: Service Transaction ID %u",
    2392                 :            :                            srv_trans_id);
    2393                 :            : 
    2394                 :         22 :                 wpa_hexdump(MSG_MSGDUMP, "P2P: Query Data",
    2395                 :         22 :                             pos, tlv_end - pos);
    2396                 :            : 
    2397                 :            : 
    2398         [ -  + ]:         22 :                 if (wpa_s->force_long_sd) {
    2399                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: SD test - force long "
    2400                 :            :                                    "response");
    2401                 :          0 :                         wpas_sd_all_bonjour(wpa_s, resp, srv_trans_id);
    2402                 :          0 :                         wpas_sd_all_upnp(wpa_s, resp, srv_trans_id);
    2403                 :          0 :                         goto done;
    2404                 :            :                 }
    2405                 :            : 
    2406   [ +  +  +  -  :         22 :                 switch (srv_proto) {
                      + ]
    2407                 :            :                 case P2P_SERV_ALL_SERVICES:
    2408                 :          7 :                         wpa_printf(MSG_DEBUG, "P2P: Service Discovery Request "
    2409                 :            :                                    "for all services");
    2410   [ +  +  +  - ]:          8 :                         if (dl_list_empty(&wpa_s->global->p2p_srv_upnp) &&
    2411                 :          1 :                             dl_list_empty(&wpa_s->global->p2p_srv_bonjour)) {
    2412                 :          1 :                                 wpa_printf(MSG_DEBUG, "P2P: No service "
    2413                 :            :                                            "discovery protocols available");
    2414                 :          1 :                                 wpas_sd_add_proto_not_avail(
    2415                 :            :                                         resp, P2P_SERV_ALL_SERVICES,
    2416                 :            :                                         srv_trans_id);
    2417                 :          1 :                                 break;
    2418                 :            :                         }
    2419                 :          6 :                         wpas_sd_all_bonjour(wpa_s, resp, srv_trans_id);
    2420                 :          6 :                         wpas_sd_all_upnp(wpa_s, resp, srv_trans_id);
    2421                 :          6 :                         break;
    2422                 :            :                 case P2P_SERV_BONJOUR:
    2423                 :          7 :                         wpas_sd_req_bonjour(wpa_s, resp, srv_trans_id,
    2424                 :          7 :                                             pos, tlv_end - pos);
    2425                 :          7 :                         break;
    2426                 :            :                 case P2P_SERV_UPNP:
    2427                 :          7 :                         wpas_sd_req_upnp(wpa_s, resp, srv_trans_id,
    2428                 :          7 :                                          pos, tlv_end - pos);
    2429                 :          7 :                         break;
    2430                 :            : #ifdef CONFIG_WIFI_DISPLAY
    2431                 :            :                 case P2P_SERV_WIFI_DISPLAY:
    2432                 :          0 :                         wpas_sd_req_wfd(wpa_s, resp, srv_trans_id,
    2433                 :          0 :                                         pos, tlv_end - pos);
    2434                 :          0 :                         break;
    2435                 :            : #endif /* CONFIG_WIFI_DISPLAY */
    2436                 :            :                 default:
    2437                 :          1 :                         wpa_printf(MSG_DEBUG, "P2P: Unavailable service "
    2438                 :            :                                    "protocol %u", srv_proto);
    2439                 :          1 :                         wpas_sd_add_proto_not_avail(resp, srv_proto,
    2440                 :            :                                                     srv_trans_id);
    2441                 :          1 :                         break;
    2442                 :            :                 }
    2443                 :            : 
    2444                 :         22 :                 pos = tlv_end;
    2445                 :            :         }
    2446                 :            : 
    2447                 :            : done:
    2448                 :         22 :         wpas_notify_p2p_sd_request(wpa_s, freq, sa, dialog_token,
    2449                 :            :                                    update_indic, tlvs, tlvs_len);
    2450                 :            : 
    2451                 :         22 :         wpas_p2p_sd_response(wpa_s, freq, sa, dialog_token, resp);
    2452                 :            : 
    2453                 :         22 :         wpabuf_free(resp);
    2454                 :            : }
    2455                 :            : 
    2456                 :            : 
    2457                 :         22 : static void wpas_sd_response(void *ctx, const u8 *sa, u16 update_indic,
    2458                 :            :                              const u8 *tlvs, size_t tlvs_len)
    2459                 :            : {
    2460                 :         22 :         struct wpa_supplicant *wpa_s = ctx;
    2461                 :         22 :         const u8 *pos = tlvs;
    2462                 :         22 :         const u8 *end = tlvs + tlvs_len;
    2463                 :            :         const u8 *tlv_end;
    2464                 :            :         u16 slen;
    2465                 :            :         size_t buf_len;
    2466                 :            :         char *buf;
    2467                 :            : 
    2468                 :         22 :         wpa_hexdump(MSG_MSGDUMP, "P2P: Service Discovery Response TLVs",
    2469                 :            :                     tlvs, tlvs_len);
    2470         [ +  + ]:         22 :         if (tlvs_len > 1500) {
    2471                 :            :                 /* TODO: better way for handling this */
    2472                 :          2 :                 wpa_msg_ctrl(wpa_s, MSG_INFO,
    2473                 :            :                              P2P_EVENT_SERV_DISC_RESP MACSTR
    2474                 :            :                              " %u <long response: %u bytes>",
    2475                 :         12 :                              MAC2STR(sa), update_indic,
    2476                 :            :                              (unsigned int) tlvs_len);
    2477                 :            :         } else {
    2478                 :         20 :                 buf_len = 2 * tlvs_len + 1;
    2479                 :         20 :                 buf = os_malloc(buf_len);
    2480         [ +  - ]:         20 :                 if (buf) {
    2481                 :         20 :                         wpa_snprintf_hex(buf, buf_len, tlvs, tlvs_len);
    2482                 :         20 :                         wpa_msg_ctrl(wpa_s, MSG_INFO,
    2483                 :            :                                      P2P_EVENT_SERV_DISC_RESP MACSTR " %u %s",
    2484                 :        120 :                                      MAC2STR(sa), update_indic, buf);
    2485                 :         20 :                         os_free(buf);
    2486                 :            :                 }
    2487                 :            :         }
    2488                 :            : 
    2489         [ +  + ]:        393 :         while (pos < end) {
    2490                 :            :                 u8 srv_proto, srv_trans_id, status;
    2491                 :            : 
    2492                 :        371 :                 wpa_printf(MSG_DEBUG, "P2P: Service Response TLV");
    2493                 :        371 :                 slen = WPA_GET_LE16(pos);
    2494                 :        371 :                 pos += 2;
    2495 [ +  - ][ -  + ]:        371 :                 if (pos + slen > end || slen < 3) {
    2496                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: Unexpected Response Data "
    2497                 :            :                                    "length");
    2498                 :         22 :                         return;
    2499                 :            :                 }
    2500                 :        371 :                 tlv_end = pos + slen;
    2501                 :            : 
    2502                 :        371 :                 srv_proto = *pos++;
    2503                 :        371 :                 wpa_printf(MSG_DEBUG, "P2P: Service Protocol Type %u",
    2504                 :            :                            srv_proto);
    2505                 :        371 :                 srv_trans_id = *pos++;
    2506                 :        371 :                 wpa_printf(MSG_DEBUG, "P2P: Service Transaction ID %u",
    2507                 :            :                            srv_trans_id);
    2508                 :        371 :                 status = *pos++;
    2509                 :        371 :                 wpa_printf(MSG_DEBUG, "P2P: Status Code ID %u",
    2510                 :            :                            status);
    2511                 :            : 
    2512                 :        371 :                 wpa_hexdump(MSG_MSGDUMP, "P2P: Response Data",
    2513                 :        371 :                             pos, tlv_end - pos);
    2514                 :            : 
    2515                 :        371 :                 pos = tlv_end;
    2516                 :            :         }
    2517                 :            : 
    2518                 :         22 :         wpas_notify_p2p_sd_response(wpa_s, sa, update_indic, tlvs, tlvs_len);
    2519                 :            : }
    2520                 :            : 
    2521                 :            : 
    2522                 :         23 : u64 wpas_p2p_sd_request(struct wpa_supplicant *wpa_s, const u8 *dst,
    2523                 :            :                         const struct wpabuf *tlvs)
    2524                 :            : {
    2525 [ +  - ][ -  + ]:         23 :         if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
    2526                 :          0 :                 return 0;
    2527                 :         23 :         return (uintptr_t) p2p_sd_request(wpa_s->global->p2p, dst, tlvs);
    2528                 :            : }
    2529                 :            : 
    2530                 :            : 
    2531                 :          1 : u64 wpas_p2p_sd_request_upnp(struct wpa_supplicant *wpa_s, const u8 *dst,
    2532                 :            :                              u8 version, const char *query)
    2533                 :            : {
    2534                 :            :         struct wpabuf *tlvs;
    2535                 :            :         u64 ret;
    2536                 :            : 
    2537                 :          1 :         tlvs = wpabuf_alloc(2 + 1 + 1 + 1 + os_strlen(query));
    2538         [ -  + ]:          1 :         if (tlvs == NULL)
    2539                 :          0 :                 return 0;
    2540                 :          1 :         wpabuf_put_le16(tlvs, 1 + 1 + 1 + os_strlen(query));
    2541                 :          1 :         wpabuf_put_u8(tlvs, P2P_SERV_UPNP); /* Service Protocol Type */
    2542                 :          1 :         wpabuf_put_u8(tlvs, 1); /* Service Transaction ID */
    2543                 :          1 :         wpabuf_put_u8(tlvs, version);
    2544                 :          1 :         wpabuf_put_str(tlvs, query);
    2545                 :          1 :         ret = wpas_p2p_sd_request(wpa_s, dst, tlvs);
    2546                 :          1 :         wpabuf_free(tlvs);
    2547                 :          1 :         return ret;
    2548                 :            : }
    2549                 :            : 
    2550                 :            : 
    2551                 :            : #ifdef CONFIG_WIFI_DISPLAY
    2552                 :            : 
    2553                 :          0 : static u64 wpas_p2p_sd_request_wfd(struct wpa_supplicant *wpa_s, const u8 *dst,
    2554                 :            :                                    const struct wpabuf *tlvs)
    2555                 :            : {
    2556 [ #  # ][ #  # ]:          0 :         if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
    2557                 :          0 :                 return 0;
    2558                 :          0 :         return (uintptr_t) p2p_sd_request_wfd(wpa_s->global->p2p, dst, tlvs);
    2559                 :            : }
    2560                 :            : 
    2561                 :            : 
    2562                 :            : #define MAX_WFD_SD_SUBELEMS 20
    2563                 :            : 
    2564                 :          0 : static void wfd_add_sd_req_role(struct wpabuf *tlvs, u8 id, u8 role,
    2565                 :            :                                 const char *subelems)
    2566                 :            : {
    2567                 :            :         u8 *len;
    2568                 :            :         const char *pos;
    2569                 :            :         int val;
    2570                 :          0 :         int count = 0;
    2571                 :            : 
    2572                 :          0 :         len = wpabuf_put(tlvs, 2);
    2573                 :          0 :         wpabuf_put_u8(tlvs, P2P_SERV_WIFI_DISPLAY); /* Service Protocol Type */
    2574                 :          0 :         wpabuf_put_u8(tlvs, id); /* Service Transaction ID */
    2575                 :            : 
    2576                 :          0 :         wpabuf_put_u8(tlvs, role);
    2577                 :            : 
    2578                 :          0 :         pos = subelems;
    2579         [ #  # ]:          0 :         while (*pos) {
    2580                 :          0 :                 val = atoi(pos);
    2581 [ #  # ][ #  # ]:          0 :                 if (val >= 0 && val < 256) {
    2582                 :          0 :                         wpabuf_put_u8(tlvs, val);
    2583                 :          0 :                         count++;
    2584         [ #  # ]:          0 :                         if (count == MAX_WFD_SD_SUBELEMS)
    2585                 :          0 :                                 break;
    2586                 :            :                 }
    2587                 :          0 :                 pos = os_strchr(pos + 1, ',');
    2588         [ #  # ]:          0 :                 if (pos == NULL)
    2589                 :          0 :                         break;
    2590                 :          0 :                 pos++;
    2591                 :            :         }
    2592                 :            : 
    2593                 :          0 :         WPA_PUT_LE16(len, (u8 *) wpabuf_put(tlvs, 0) - len - 2);
    2594                 :          0 : }
    2595                 :            : 
    2596                 :            : 
    2597                 :          0 : u64 wpas_p2p_sd_request_wifi_display(struct wpa_supplicant *wpa_s,
    2598                 :            :                                      const u8 *dst, const char *role)
    2599                 :            : {
    2600                 :            :         struct wpabuf *tlvs;
    2601                 :            :         u64 ret;
    2602                 :            :         const char *subelems;
    2603                 :          0 :         u8 id = 1;
    2604                 :            : 
    2605                 :          0 :         subelems = os_strchr(role, ' ');
    2606         [ #  # ]:          0 :         if (subelems == NULL)
    2607                 :          0 :                 return 0;
    2608                 :          0 :         subelems++;
    2609                 :            : 
    2610                 :          0 :         tlvs = wpabuf_alloc(4 * (2 + 1 + 1 + 1 + MAX_WFD_SD_SUBELEMS));
    2611         [ #  # ]:          0 :         if (tlvs == NULL)
    2612                 :          0 :                 return 0;
    2613                 :            : 
    2614         [ #  # ]:          0 :         if (os_strstr(role, "[source]"))
    2615                 :          0 :                 wfd_add_sd_req_role(tlvs, id++, 0x00, subelems);
    2616         [ #  # ]:          0 :         if (os_strstr(role, "[pri-sink]"))
    2617                 :          0 :                 wfd_add_sd_req_role(tlvs, id++, 0x01, subelems);
    2618         [ #  # ]:          0 :         if (os_strstr(role, "[sec-sink]"))
    2619                 :          0 :                 wfd_add_sd_req_role(tlvs, id++, 0x02, subelems);
    2620         [ #  # ]:          0 :         if (os_strstr(role, "[source+sink]"))
    2621                 :          0 :                 wfd_add_sd_req_role(tlvs, id++, 0x03, subelems);
    2622                 :            : 
    2623                 :          0 :         ret = wpas_p2p_sd_request_wfd(wpa_s, dst, tlvs);
    2624                 :          0 :         wpabuf_free(tlvs);
    2625                 :          0 :         return ret;
    2626                 :            : }
    2627                 :            : 
    2628                 :            : #endif /* CONFIG_WIFI_DISPLAY */
    2629                 :            : 
    2630                 :            : 
    2631                 :          5 : int wpas_p2p_sd_cancel_request(struct wpa_supplicant *wpa_s, u64 req)
    2632                 :            : {
    2633 [ +  - ][ -  + ]:          5 :         if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
    2634                 :          0 :                 return -1;
    2635                 :          5 :         return p2p_sd_cancel_request(wpa_s->global->p2p,
    2636                 :            :                                      (void *) (uintptr_t) req);
    2637                 :            : }
    2638                 :            : 
    2639                 :            : 
    2640                 :         22 : void wpas_p2p_sd_response(struct wpa_supplicant *wpa_s, int freq,
    2641                 :            :                           const u8 *dst, u8 dialog_token,
    2642                 :            :                           const struct wpabuf *resp_tlvs)
    2643                 :            : {
    2644 [ +  - ][ -  + ]:         22 :         if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
    2645                 :         22 :                 return;
    2646                 :         22 :         p2p_sd_response(wpa_s->global->p2p, freq, dst, dialog_token,
    2647                 :            :                         resp_tlvs);
    2648                 :            : }
    2649                 :            : 
    2650                 :            : 
    2651                 :       1493 : void wpas_p2p_sd_service_update(struct wpa_supplicant *wpa_s)
    2652                 :            : {
    2653         [ +  - ]:       1493 :         if (wpa_s->global->p2p)
    2654                 :       1493 :                 p2p_sd_service_update(wpa_s->global->p2p);
    2655                 :       1493 : }
    2656                 :            : 
    2657                 :            : 
    2658                 :         60 : static void wpas_p2p_srv_bonjour_free(struct p2p_srv_bonjour *bsrv)
    2659                 :            : {
    2660                 :         60 :         dl_list_del(&bsrv->list);
    2661                 :         60 :         wpabuf_free(bsrv->query);
    2662                 :         60 :         wpabuf_free(bsrv->resp);
    2663                 :         60 :         os_free(bsrv);
    2664                 :         60 : }
    2665                 :            : 
    2666                 :            : 
    2667                 :        250 : static void wpas_p2p_srv_upnp_free(struct p2p_srv_upnp *usrv)
    2668                 :            : {
    2669                 :        250 :         dl_list_del(&usrv->list);
    2670                 :        250 :         os_free(usrv->service);
    2671                 :        250 :         os_free(usrv);
    2672                 :        250 : }
    2673                 :            : 
    2674                 :            : 
    2675                 :       1183 : void wpas_p2p_service_flush(struct wpa_supplicant *wpa_s)
    2676                 :            : {
    2677                 :            :         struct p2p_srv_bonjour *bsrv, *bn;
    2678                 :            :         struct p2p_srv_upnp *usrv, *un;
    2679                 :            : 
    2680         [ +  + ]:       1243 :         dl_list_for_each_safe(bsrv, bn, &wpa_s->global->p2p_srv_bonjour,
    2681                 :            :                               struct p2p_srv_bonjour, list)
    2682                 :         60 :                 wpas_p2p_srv_bonjour_free(bsrv);
    2683                 :            : 
    2684         [ +  + ]:       1433 :         dl_list_for_each_safe(usrv, un, &wpa_s->global->p2p_srv_upnp,
    2685                 :            :                               struct p2p_srv_upnp, list)
    2686                 :        250 :                 wpas_p2p_srv_upnp_free(usrv);
    2687                 :            : 
    2688                 :       1183 :         wpas_p2p_sd_service_update(wpa_s);
    2689                 :       1183 : }
    2690                 :            : 
    2691                 :            : 
    2692                 :         60 : int wpas_p2p_service_add_bonjour(struct wpa_supplicant *wpa_s,
    2693                 :            :                                  struct wpabuf *query, struct wpabuf *resp)
    2694                 :            : {
    2695                 :            :         struct p2p_srv_bonjour *bsrv;
    2696                 :            : 
    2697                 :         60 :         bsrv = os_zalloc(sizeof(*bsrv));
    2698         [ -  + ]:         60 :         if (bsrv == NULL)
    2699                 :          0 :                 return -1;
    2700                 :         60 :         bsrv->query = query;
    2701                 :         60 :         bsrv->resp = resp;
    2702                 :         60 :         dl_list_add(&wpa_s->global->p2p_srv_bonjour, &bsrv->list);
    2703                 :            : 
    2704                 :         60 :         wpas_p2p_sd_service_update(wpa_s);
    2705                 :         60 :         return 0;
    2706                 :            : }
    2707                 :            : 
    2708                 :            : 
    2709                 :          0 : int wpas_p2p_service_del_bonjour(struct wpa_supplicant *wpa_s,
    2710                 :            :                                  const struct wpabuf *query)
    2711                 :            : {
    2712                 :            :         struct p2p_srv_bonjour *bsrv;
    2713                 :            : 
    2714                 :          0 :         bsrv = wpas_p2p_service_get_bonjour(wpa_s, query);
    2715         [ #  # ]:          0 :         if (bsrv == NULL)
    2716                 :          0 :                 return -1;
    2717                 :          0 :         wpas_p2p_srv_bonjour_free(bsrv);
    2718                 :          0 :         wpas_p2p_sd_service_update(wpa_s);
    2719                 :          0 :         return 0;
    2720                 :            : }
    2721                 :            : 
    2722                 :            : 
    2723                 :        275 : int wpas_p2p_service_add_upnp(struct wpa_supplicant *wpa_s, u8 version,
    2724                 :            :                               const char *service)
    2725                 :            : {
    2726                 :            :         struct p2p_srv_upnp *usrv;
    2727                 :            : 
    2728         [ +  + ]:        275 :         if (wpas_p2p_service_get_upnp(wpa_s, version, service))
    2729                 :         25 :                 return 0; /* Already listed */
    2730                 :        250 :         usrv = os_zalloc(sizeof(*usrv));
    2731         [ -  + ]:        250 :         if (usrv == NULL)
    2732                 :          0 :                 return -1;
    2733                 :        250 :         usrv->version = version;
    2734                 :        250 :         usrv->service = os_strdup(service);
    2735         [ -  + ]:        250 :         if (usrv->service == NULL) {
    2736                 :          0 :                 os_free(usrv);
    2737                 :          0 :                 return -1;
    2738                 :            :         }
    2739                 :        250 :         dl_list_add(&wpa_s->global->p2p_srv_upnp, &usrv->list);
    2740                 :            : 
    2741                 :        250 :         wpas_p2p_sd_service_update(wpa_s);
    2742                 :        275 :         return 0;
    2743                 :            : }
    2744                 :            : 
    2745                 :            : 
    2746                 :          0 : int wpas_p2p_service_del_upnp(struct wpa_supplicant *wpa_s, u8 version,
    2747                 :            :                               const char *service)
    2748                 :            : {
    2749                 :            :         struct p2p_srv_upnp *usrv;
    2750                 :            : 
    2751                 :          0 :         usrv = wpas_p2p_service_get_upnp(wpa_s, version, service);
    2752         [ #  # ]:          0 :         if (usrv == NULL)
    2753                 :          0 :                 return -1;
    2754                 :          0 :         wpas_p2p_srv_upnp_free(usrv);
    2755                 :          0 :         wpas_p2p_sd_service_update(wpa_s);
    2756                 :          0 :         return 0;
    2757                 :            : }
    2758                 :            : 
    2759                 :            : 
    2760                 :         31 : static void wpas_prov_disc_local_display(struct wpa_supplicant *wpa_s,
    2761                 :            :                                          const u8 *peer, const char *params,
    2762                 :            :                                          unsigned int generated_pin)
    2763                 :            : {
    2764                 :         31 :         wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_SHOW_PIN MACSTR
    2765                 :        186 :                        " %08d%s", MAC2STR(peer), generated_pin, params);
    2766                 :         31 : }
    2767                 :            : 
    2768                 :            : 
    2769                 :          3 : static void wpas_prov_disc_local_keypad(struct wpa_supplicant *wpa_s,
    2770                 :            :                                         const u8 *peer, const char *params)
    2771                 :            : {
    2772                 :          3 :         wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_ENTER_PIN MACSTR
    2773                 :         18 :                        "%s", MAC2STR(peer), params);
    2774                 :          3 : }
    2775                 :            : 
    2776                 :            : 
    2777                 :         32 : static void wpas_prov_disc_req(void *ctx, const u8 *peer, u16 config_methods,
    2778                 :            :                                const u8 *dev_addr, const u8 *pri_dev_type,
    2779                 :            :                                const char *dev_name, u16 supp_config_methods,
    2780                 :            :                                u8 dev_capab, u8 group_capab, const u8 *group_id,
    2781                 :            :                                size_t group_id_len)
    2782                 :            : {
    2783                 :         32 :         struct wpa_supplicant *wpa_s = ctx;
    2784                 :            :         char devtype[WPS_DEV_TYPE_BUFSIZE];
    2785                 :            :         char params[300];
    2786                 :            :         u8 empty_dev_type[8];
    2787                 :         32 :         unsigned int generated_pin = 0;
    2788                 :         32 :         struct wpa_supplicant *group = NULL;
    2789                 :            : 
    2790         [ +  + ]:         32 :         if (group_id) {
    2791         [ +  - ]:         26 :                 for (group = wpa_s->global->ifaces; group; group = group->next)
    2792                 :            :                 {
    2793                 :         26 :                         struct wpa_ssid *s = group->current_ssid;
    2794 [ +  - ][ +  - ]:         26 :                         if (s != NULL &&
    2795         [ +  - ]:         26 :                             s->mode == WPAS_MODE_P2P_GO &&
    2796         [ +  - ]:         26 :                             group_id_len - ETH_ALEN == s->ssid_len &&
    2797                 :         26 :                             os_memcmp(group_id + ETH_ALEN, s->ssid,
    2798                 :            :                                       s->ssid_len) == 0)
    2799                 :         26 :                                 break;
    2800                 :            :                 }
    2801                 :            :         }
    2802                 :            : 
    2803         [ -  + ]:         32 :         if (pri_dev_type == NULL) {
    2804                 :          0 :                 os_memset(empty_dev_type, 0, sizeof(empty_dev_type));
    2805                 :          0 :                 pri_dev_type = empty_dev_type;
    2806                 :            :         }
    2807 [ +  + ][ +  + ]:         32 :         os_snprintf(params, sizeof(params), " p2p_dev_addr=" MACSTR
    2808                 :            :                     " pri_dev_type=%s name='%s' config_methods=0x%x "
    2809                 :            :                     "dev_capab=0x%x group_capab=0x%x%s%s",
    2810                 :        192 :                     MAC2STR(dev_addr),
    2811                 :            :                     wps_dev_type_bin2str(pri_dev_type, devtype,
    2812                 :            :                                          sizeof(devtype)),
    2813                 :            :                     dev_name, supp_config_methods, dev_capab, group_capab,
    2814                 :            :                     group ? " group=" : "",
    2815                 :            :                     group ? group->ifname : "");
    2816                 :         32 :         params[sizeof(params) - 1] = '\0';
    2817                 :            : 
    2818         [ +  + ]:         32 :         if (config_methods & WPS_CONFIG_DISPLAY) {
    2819                 :         30 :                 generated_pin = wps_generate_pin();
    2820                 :         30 :                 wpas_prov_disc_local_display(wpa_s, peer, params,
    2821                 :            :                                              generated_pin);
    2822         [ +  + ]:          2 :         } else if (config_methods & WPS_CONFIG_KEYPAD)
    2823                 :          1 :                 wpas_prov_disc_local_keypad(wpa_s, peer, params);
    2824         [ +  - ]:          1 :         else if (config_methods & WPS_CONFIG_PUSHBUTTON)
    2825                 :          1 :                 wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_PBC_REQ
    2826                 :          6 :                                MACSTR "%s", MAC2STR(peer), params);
    2827                 :            : 
    2828                 :         32 :         wpas_notify_p2p_provision_discovery(wpa_s, peer, 1 /* request */,
    2829                 :            :                                             P2P_PROV_DISC_SUCCESS,
    2830                 :            :                                             config_methods, generated_pin);
    2831                 :         32 : }
    2832                 :            : 
    2833                 :            : 
    2834                 :         30 : static void wpas_prov_disc_resp(void *ctx, const u8 *peer, u16 config_methods)
    2835                 :            : {
    2836                 :         30 :         struct wpa_supplicant *wpa_s = ctx;
    2837                 :         30 :         unsigned int generated_pin = 0;
    2838                 :            :         char params[20];
    2839                 :            : 
    2840 [ +  + ][ -  + ]:         30 :         if (wpa_s->pending_pd_before_join &&
    2841         [ #  # ]:          0 :             (os_memcmp(peer, wpa_s->pending_join_dev_addr, ETH_ALEN) == 0 ||
    2842                 :          0 :              os_memcmp(peer, wpa_s->pending_join_iface_addr, ETH_ALEN) == 0)) {
    2843                 :         26 :                 wpa_s->pending_pd_before_join = 0;
    2844                 :         26 :                 wpa_printf(MSG_DEBUG, "P2P: Starting pending "
    2845                 :            :                            "join-existing-group operation");
    2846                 :         26 :                 wpas_p2p_join_start(wpa_s, 0, NULL, 0);
    2847                 :         30 :                 return;
    2848                 :            :         }
    2849                 :            : 
    2850 [ +  - ][ -  + ]:          4 :         if (wpa_s->pending_pd_use == AUTO_PD_JOIN ||
    2851                 :          4 :             wpa_s->pending_pd_use == AUTO_PD_GO_NEG)
    2852                 :          0 :                 os_snprintf(params, sizeof(params), " peer_go=%d",
    2853                 :          0 :                             wpa_s->pending_pd_use == AUTO_PD_JOIN);
    2854                 :            :         else
    2855                 :          4 :                 params[0] = '\0';
    2856                 :            : 
    2857         [ +  + ]:          4 :         if (config_methods & WPS_CONFIG_DISPLAY)
    2858                 :          2 :                 wpas_prov_disc_local_keypad(wpa_s, peer, params);
    2859         [ +  + ]:          2 :         else if (config_methods & WPS_CONFIG_KEYPAD) {
    2860                 :          1 :                 generated_pin = wps_generate_pin();
    2861                 :          1 :                 wpas_prov_disc_local_display(wpa_s, peer, params,
    2862                 :            :                                              generated_pin);
    2863         [ +  - ]:          1 :         } else if (config_methods & WPS_CONFIG_PUSHBUTTON)
    2864                 :          1 :                 wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_PBC_RESP
    2865                 :          6 :                                MACSTR "%s", MAC2STR(peer), params);
    2866                 :            : 
    2867                 :          4 :         wpas_notify_p2p_provision_discovery(wpa_s, peer, 0 /* response */,
    2868                 :            :                                             P2P_PROV_DISC_SUCCESS,
    2869                 :            :                                             config_methods, generated_pin);
    2870                 :            : }
    2871                 :            : 
    2872                 :            : 
    2873                 :          2 : static void wpas_prov_disc_fail(void *ctx, const u8 *peer,
    2874                 :            :                                 enum p2p_prov_disc_status status)
    2875                 :            : {
    2876                 :          2 :         struct wpa_supplicant *wpa_s = ctx;
    2877                 :            : 
    2878         [ -  + ]:          2 :         if (wpa_s->p2p_fallback_to_go_neg) {
    2879                 :          0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: PD for p2p_connect-auto "
    2880                 :            :                         "failed - fall back to GO Negotiation");
    2881                 :          0 :                 wpas_p2p_fallback_to_go_neg(wpa_s, 0);
    2882                 :          0 :                 return;
    2883                 :            :         }
    2884                 :            : 
    2885         [ -  + ]:          2 :         if (status == P2P_PROV_DISC_TIMEOUT_JOIN) {
    2886                 :          0 :                 wpa_s->pending_pd_before_join = 0;
    2887                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Starting pending "
    2888                 :            :                            "join-existing-group operation (no ACK for PD "
    2889                 :            :                            "Req attempts)");
    2890                 :          0 :                 wpas_p2p_join_start(wpa_s, 0, NULL, 0);
    2891                 :          0 :                 return;
    2892                 :            :         }
    2893                 :            : 
    2894                 :          2 :         wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_FAILURE
    2895                 :            :                        " p2p_dev_addr=" MACSTR " status=%d",
    2896                 :         12 :                        MAC2STR(peer), status);
    2897                 :            : 
    2898                 :          2 :         wpas_notify_p2p_provision_discovery(wpa_s, peer, 0 /* response */,
    2899                 :            :                                             status, 0, 0);
    2900                 :            : }
    2901                 :            : 
    2902                 :            : 
    2903                 :         42 : static int freq_included(const struct p2p_channels *channels, unsigned int freq)
    2904                 :            : {
    2905         [ +  + ]:         42 :         if (channels == NULL)
    2906                 :         37 :                 return 1; /* Assume no restrictions */
    2907                 :         42 :         return p2p_channels_includes_freq(channels, freq);
    2908                 :            : 
    2909                 :            : }
    2910                 :            : 
    2911                 :            : 
    2912                 :         20 : static u8 wpas_invitation_process(void *ctx, const u8 *sa, const u8 *bssid,
    2913                 :            :                                   const u8 *go_dev_addr, const u8 *ssid,
    2914                 :            :                                   size_t ssid_len, int *go, u8 *group_bssid,
    2915                 :            :                                   int *force_freq, int persistent_group,
    2916                 :            :                                   const struct p2p_channels *channels,
    2917                 :            :                                   int dev_pw_id)
    2918                 :            : {
    2919                 :         20 :         struct wpa_supplicant *wpa_s = ctx;
    2920                 :            :         struct wpa_ssid *s;
    2921                 :            :         int res;
    2922                 :            :         struct wpa_supplicant *grp;
    2923                 :            : 
    2924         [ +  + ]:         20 :         if (!persistent_group) {
    2925                 :         12 :                 wpa_printf(MSG_DEBUG, "P2P: Invitation from " MACSTR
    2926                 :            :                            " to join an active group (SSID: %s)",
    2927                 :         72 :                            MAC2STR(sa), wpa_ssid_txt(ssid, ssid_len));
    2928 [ +  + ][ -  + ]:         12 :                 if (!is_zero_ether_addr(wpa_s->p2p_auth_invite) &&
    2929                 :          1 :                     (os_memcmp(go_dev_addr, wpa_s->p2p_auth_invite, ETH_ALEN)
    2930         [ #  # ]:          0 :                      == 0 ||
    2931                 :          0 :                      os_memcmp(sa, wpa_s->p2p_auth_invite, ETH_ALEN) == 0)) {
    2932                 :          1 :                         wpa_printf(MSG_DEBUG, "P2P: Accept previously "
    2933                 :            :                                    "authorized invitation");
    2934                 :          1 :                         goto accept_inv;
    2935                 :            :                 }
    2936                 :            : 
    2937                 :            : #ifdef CONFIG_WPS_NFC
    2938 [ +  + ][ +  - ]:         11 :                 if (dev_pw_id >= 0 && wpa_s->parent->p2p_nfc_tag_enabled &&
                 [ +  - ]
    2939                 :          2 :                     dev_pw_id == wpa_s->parent->p2p_oob_dev_pw_id) {
    2940                 :          2 :                         wpa_printf(MSG_DEBUG, "P2P: Accept invitation based on local enabled NFC Tag");
    2941                 :          2 :                         wpa_s->parent->p2p_wps_method = WPS_NFC;
    2942                 :          2 :                         wpa_s->parent->pending_join_wps_method = WPS_NFC;
    2943                 :          2 :                         os_memcpy(wpa_s->parent->pending_join_dev_addr,
    2944                 :            :                                   go_dev_addr, ETH_ALEN);
    2945                 :          2 :                         os_memcpy(wpa_s->parent->pending_join_iface_addr,
    2946                 :            :                                   bssid, ETH_ALEN);
    2947                 :          2 :                         goto accept_inv;
    2948                 :            :                 }
    2949                 :            : #endif /* CONFIG_WPS_NFC */
    2950                 :            : 
    2951                 :            :                 /*
    2952                 :            :                  * Do not accept the invitation automatically; notify user and
    2953                 :            :                  * request approval.
    2954                 :            :                  */
    2955                 :          9 :                 return P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE;
    2956                 :            :         }
    2957                 :            : 
    2958                 :          8 :         grp = wpas_get_p2p_group(wpa_s, ssid, ssid_len, go);
    2959         [ -  + ]:          8 :         if (grp) {
    2960                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Accept invitation to already "
    2961                 :            :                            "running persistent group");
    2962         [ #  # ]:          0 :                 if (*go)
    2963                 :          0 :                         os_memcpy(group_bssid, grp->own_addr, ETH_ALEN);
    2964                 :          0 :                 goto accept_inv;
    2965                 :            :         }
    2966                 :            : 
    2967 [ +  + ][ +  - ]:          8 :         if (!is_zero_ether_addr(wpa_s->p2p_auth_invite) &&
    2968                 :          3 :             os_memcmp(sa, wpa_s->p2p_auth_invite, ETH_ALEN) == 0) {
    2969                 :          3 :                 wpa_printf(MSG_DEBUG, "P2P: Accept previously initiated "
    2970                 :            :                            "invitation to re-invoke a persistent group");
    2971         [ +  + ]:          5 :         } else if (!wpa_s->conf->persistent_reconnect)
    2972                 :          1 :                 return P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE;
    2973                 :            : 
    2974         [ +  - ]:          7 :         for (s = wpa_s->conf->ssid; s; s = s->next) {
    2975 [ +  - ][ +  - ]:          7 :                 if (s->disabled == 2 &&
    2976         [ +  - ]:          7 :                     os_memcmp(s->bssid, go_dev_addr, ETH_ALEN) == 0 &&
    2977         [ +  - ]:          7 :                     s->ssid_len == ssid_len &&
    2978                 :          7 :                     os_memcmp(ssid, s->ssid, ssid_len) == 0)
    2979                 :          7 :                         break;
    2980                 :            :         }
    2981                 :            : 
    2982         [ -  + ]:          7 :         if (!s) {
    2983                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Invitation from " MACSTR
    2984                 :            :                            " requested reinvocation of an unknown group",
    2985                 :          0 :                            MAC2STR(sa));
    2986                 :          0 :                 return P2P_SC_FAIL_UNKNOWN_GROUP;
    2987                 :            :         }
    2988                 :            : 
    2989 [ +  + ][ +  - ]:          7 :         if (s->mode == WPAS_MODE_P2P_GO && !wpas_p2p_create_iface(wpa_s)) {
    2990                 :          4 :                 *go = 1;
    2991         [ -  + ]:          4 :                 if (wpa_s->wpa_state >= WPA_AUTHENTICATING) {
    2992                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: The only available "
    2993                 :            :                                    "interface is already in use - reject "
    2994                 :            :                                    "invitation");
    2995                 :          0 :                         return P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE;
    2996                 :            :                 }
    2997                 :          4 :                 os_memcpy(group_bssid, wpa_s->own_addr, ETH_ALEN);
    2998         [ -  + ]:          3 :         } else if (s->mode == WPAS_MODE_P2P_GO) {
    2999                 :          0 :                 *go = 1;
    3000         [ #  # ]:          0 :                 if (wpas_p2p_add_group_interface(wpa_s, WPA_IF_P2P_GO) < 0)
    3001                 :            :                 {
    3002                 :          0 :                         wpa_printf(MSG_ERROR, "P2P: Failed to allocate a new "
    3003                 :            :                                    "interface address for the group");
    3004                 :          0 :                         return P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE;
    3005                 :            :                 }
    3006                 :          0 :                 os_memcpy(group_bssid, wpa_s->pending_interface_addr,
    3007                 :            :                           ETH_ALEN);
    3008                 :            :         }
    3009                 :            : 
    3010                 :            : accept_inv:
    3011                 :         10 :         wpas_p2p_set_own_freq_preference(wpa_s, 0);
    3012                 :            : 
    3013                 :            :         /* Get one of the frequencies currently in use */
    3014         [ -  + ]:         10 :         if (wpas_p2p_valid_oper_freqs(wpa_s, &res, 1) > 0) {
    3015                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Trying to prefer a channel already used by one of the interfaces");
    3016                 :          0 :                 wpas_p2p_set_own_freq_preference(wpa_s, res);
    3017                 :            : 
    3018   [ #  #  #  # ]:          0 :                 if (wpa_s->num_multichan_concurrent < 2 ||
    3019                 :          0 :                     wpas_p2p_num_unused_channels(wpa_s) < 1) {
    3020                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: No extra channels available - trying to force channel to match a channel already used by one of the interfaces");
    3021                 :          0 :                         *force_freq = res;
    3022                 :            :                 }
    3023                 :            :         }
    3024                 :            : 
    3025         [ -  + ]:         10 :         if (*force_freq > 0 && wpa_s->num_multichan_concurrent > 1 &&
           [ #  #  #  # ]
    3026                 :          0 :             wpas_p2p_num_unused_channels(wpa_s) > 0) {
    3027         [ #  # ]:          0 :                 if (*go == 0) {
    3028                 :            :                         /* We are the client */
    3029                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: Peer was found to be "
    3030                 :            :                                    "running a GO but we are capable of MCC, "
    3031                 :            :                                    "figure out the best channel to use");
    3032                 :          0 :                         *force_freq = 0;
    3033         [ #  # ]:          0 :                 } else if (!freq_included(channels, *force_freq)) {
    3034                 :            :                         /* We are the GO, and *force_freq is not in the
    3035                 :            :                          * intersection */
    3036                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: Forced GO freq %d MHz not "
    3037                 :            :                                    "in intersection but we are capable of MCC, "
    3038                 :            :                                    "figure out the best channel to use",
    3039                 :            :                                    *force_freq);
    3040                 :          0 :                         *force_freq = 0;
    3041                 :            :                 }
    3042                 :            :         }
    3043                 :            : 
    3044                 :         20 :         return P2P_SC_SUCCESS;
    3045                 :            : }
    3046                 :            : 
    3047                 :            : 
    3048                 :         25 : static void wpas_invitation_received(void *ctx, const u8 *sa, const u8 *bssid,
    3049                 :            :                                      const u8 *ssid, size_t ssid_len,
    3050                 :            :                                      const u8 *go_dev_addr, u8 status,
    3051                 :            :                                      int op_freq)
    3052                 :            : {
    3053                 :         25 :         struct wpa_supplicant *wpa_s = ctx;
    3054                 :            :         struct wpa_ssid *s;
    3055                 :            : 
    3056         [ +  + ]:         25 :         for (s = wpa_s->conf->ssid; s; s = s->next) {
    3057 [ +  - ][ +  - ]:          8 :                 if (s->disabled == 2 &&
    3058         [ +  - ]:          8 :                     s->ssid_len == ssid_len &&
    3059                 :          8 :                     os_memcmp(ssid, s->ssid, ssid_len) == 0)
    3060                 :          8 :                         break;
    3061                 :            :         }
    3062                 :            : 
    3063         [ +  + ]:         25 :         if (status == P2P_SC_SUCCESS) {
    3064                 :         10 :                 wpa_printf(MSG_DEBUG, "P2P: Invitation from peer " MACSTR
    3065                 :            :                            " was accepted; op_freq=%d MHz, SSID=%s",
    3066                 :         60 :                            MAC2STR(sa), op_freq, wpa_ssid_txt(ssid, ssid_len));
    3067         [ +  + ]:         10 :                 if (s) {
    3068                 :          7 :                         int go = s->mode == WPAS_MODE_P2P_GO;
    3069 [ +  + ][ +  + ]:          7 :                         wpas_p2p_group_add_persistent(
    3070                 :            :                                 wpa_s, s, go, 0, go ? op_freq : 0, 0, 0, NULL,
    3071                 :            :                                 go ? P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0);
    3072         [ +  - ]:          3 :                 } else if (bssid) {
    3073                 :          3 :                         wpa_s->user_initiated_pd = 0;
    3074                 :          3 :                         wpas_p2p_join(wpa_s, bssid, go_dev_addr,
    3075                 :          3 :                                       wpa_s->p2p_wps_method, 0, op_freq,
    3076                 :            :                                       ssid, ssid_len);
    3077                 :            :                 }
    3078                 :         10 :                 return;
    3079                 :            :         }
    3080                 :            : 
    3081         [ +  + ]:         15 :         if (status != P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) {
    3082                 :          4 :                 wpa_printf(MSG_DEBUG, "P2P: Invitation from peer " MACSTR
    3083                 :         24 :                            " was rejected (status %u)", MAC2STR(sa), status);
    3084                 :          4 :                 return;
    3085                 :            :         }
    3086                 :            : 
    3087         [ +  + ]:         11 :         if (!s) {
    3088         [ +  + ]:         10 :                 if (bssid) {
    3089                 :          9 :                         wpa_msg_global(wpa_s, MSG_INFO,
    3090                 :            :                                        P2P_EVENT_INVITATION_RECEIVED
    3091                 :            :                                        "sa=" MACSTR " go_dev_addr=" MACSTR
    3092                 :            :                                        " bssid=" MACSTR " unknown-network",
    3093                 :        108 :                                        MAC2STR(sa), MAC2STR(go_dev_addr),
    3094                 :         54 :                                        MAC2STR(bssid));
    3095                 :            :                 } else {
    3096                 :          1 :                         wpa_msg_global(wpa_s, MSG_INFO,
    3097                 :            :                                        P2P_EVENT_INVITATION_RECEIVED
    3098                 :            :                                        "sa=" MACSTR " go_dev_addr=" MACSTR
    3099                 :            :                                        " unknown-network",
    3100                 :         12 :                                        MAC2STR(sa), MAC2STR(go_dev_addr));
    3101                 :            :                 }
    3102                 :         10 :                 return;
    3103                 :            :         }
    3104                 :            : 
    3105 [ -  + ][ #  # ]:          1 :         if (s->mode == WPAS_MODE_P2P_GO && op_freq) {
    3106                 :          0 :                 wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RECEIVED
    3107                 :            :                                "sa=" MACSTR " persistent=%d freq=%d",
    3108                 :          0 :                                MAC2STR(sa), s->id, op_freq);
    3109                 :            :         } else {
    3110                 :         25 :                 wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RECEIVED
    3111                 :            :                                "sa=" MACSTR " persistent=%d",
    3112                 :          6 :                                MAC2STR(sa), s->id);
    3113                 :            :         }
    3114                 :            : }
    3115                 :            : 
    3116                 :            : 
    3117                 :          3 : static void wpas_remove_persistent_peer(struct wpa_supplicant *wpa_s,
    3118                 :            :                                         struct wpa_ssid *ssid,
    3119                 :            :                                         const u8 *peer, int inv)
    3120                 :            : {
    3121                 :            :         size_t i;
    3122                 :            : 
    3123         [ -  + ]:          3 :         if (ssid == NULL)
    3124                 :          0 :                 return;
    3125                 :            : 
    3126 [ +  - ][ +  - ]:          4 :         for (i = 0; ssid->p2p_client_list && i < ssid->num_p2p_clients; i++) {
    3127         [ +  + ]:          4 :                 if (os_memcmp(ssid->p2p_client_list + i * ETH_ALEN, peer,
    3128                 :            :                               ETH_ALEN) == 0)
    3129                 :          3 :                         break;
    3130                 :            :         }
    3131         [ -  + ]:          3 :         if (i >= ssid->num_p2p_clients) {
    3132 [ #  # ][ #  # ]:          0 :                 if (ssid->mode != WPAS_MODE_P2P_GO &&
    3133                 :          0 :                     os_memcmp(ssid->bssid, peer, ETH_ALEN) == 0) {
    3134                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: Remove persistent group %d "
    3135                 :            :                                    "due to invitation result", ssid->id);
    3136                 :          0 :                         wpas_notify_network_removed(wpa_s, ssid);
    3137                 :          0 :                         wpa_config_remove_network(wpa_s->conf, ssid->id);
    3138                 :          0 :                         return;
    3139                 :            :                 }
    3140                 :          0 :                 return; /* Peer not found in client list */
    3141                 :            :         }
    3142                 :            : 
    3143         [ -  + ]:          3 :         wpa_printf(MSG_DEBUG, "P2P: Remove peer " MACSTR " from persistent "
    3144                 :            :                    "group %d client list%s",
    3145                 :         18 :                    MAC2STR(peer), ssid->id,
    3146                 :            :                    inv ? " due to invitation result" : "");
    3147                 :          3 :         os_memmove(ssid->p2p_client_list + i * ETH_ALEN,
    3148                 :            :                    ssid->p2p_client_list + (i + 1) * ETH_ALEN,
    3149                 :            :                    (ssid->num_p2p_clients - i - 1) * ETH_ALEN);
    3150                 :          3 :         ssid->num_p2p_clients--;
    3151   [ -  +  #  # ]:          3 :         if (wpa_s->parent->conf->update_config &&
    3152                 :          0 :             wpa_config_write(wpa_s->parent->confname, wpa_s->parent->conf))
    3153                 :          3 :                 wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration");
    3154                 :            : }
    3155                 :            : 
    3156                 :            : 
    3157                 :          0 : static void wpas_remove_persistent_client(struct wpa_supplicant *wpa_s,
    3158                 :            :                                           const u8 *peer)
    3159                 :            : {
    3160                 :            :         struct wpa_ssid *ssid;
    3161                 :            : 
    3162                 :          0 :         wpa_s = wpa_s->global->p2p_invite_group;
    3163         [ #  # ]:          0 :         if (wpa_s == NULL)
    3164                 :          0 :                 return; /* No known invitation group */
    3165                 :          0 :         ssid = wpa_s->current_ssid;
    3166 [ #  # ][ #  # ]:          0 :         if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO ||
                 [ #  # ]
    3167                 :          0 :             !ssid->p2p_persistent_group)
    3168                 :          0 :                 return; /* Not operating as a GO in persistent group */
    3169                 :          0 :         ssid = wpas_p2p_get_persistent(wpa_s->parent, peer,
    3170                 :          0 :                                        ssid->ssid, ssid->ssid_len);
    3171                 :          0 :         wpas_remove_persistent_peer(wpa_s, ssid, peer, 1);
    3172                 :            : }
    3173                 :            : 
    3174                 :            : 
    3175                 :         13 : static void wpas_invitation_result(void *ctx, int status, const u8 *bssid,
    3176                 :            :                                    const struct p2p_channels *channels,
    3177                 :            :                                    const u8 *peer, int neg_freq)
    3178                 :            : {
    3179                 :         13 :         struct wpa_supplicant *wpa_s = ctx;
    3180                 :            :         struct wpa_ssid *ssid;
    3181                 :            : 
    3182         [ +  + ]:         13 :         if (bssid) {
    3183                 :          4 :                 wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RESULT
    3184                 :            :                                "status=%d " MACSTR,
    3185                 :         24 :                                status, MAC2STR(bssid));
    3186                 :            :         } else {
    3187                 :          9 :                 wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RESULT
    3188                 :            :                                "status=%d ", status);
    3189                 :            :         }
    3190                 :         13 :         wpas_notify_p2p_invitation_result(wpa_s, status, bssid);
    3191                 :            : 
    3192                 :         13 :         wpa_printf(MSG_DEBUG, "P2P: Invitation result - status=%d peer=" MACSTR,
    3193                 :         78 :                    status, MAC2STR(peer));
    3194         [ +  + ]:         13 :         if (wpa_s->pending_invite_ssid_id == -1) {
    3195         [ -  + ]:          6 :                 if (status == P2P_SC_FAIL_UNKNOWN_GROUP)
    3196                 :          0 :                         wpas_remove_persistent_client(wpa_s, peer);
    3197                 :          6 :                 return; /* Invitation to active group */
    3198                 :            :         }
    3199                 :            : 
    3200         [ -  + ]:          7 :         if (status == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) {
    3201                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Waiting for peer to start another "
    3202                 :            :                            "invitation exchange to indicate readiness for "
    3203                 :            :                            "re-invocation");
    3204                 :            :         }
    3205                 :            : 
    3206         [ -  + ]:          7 :         if (status != P2P_SC_SUCCESS) {
    3207         [ #  # ]:          0 :                 if (status == P2P_SC_FAIL_UNKNOWN_GROUP) {
    3208                 :          0 :                         ssid = wpa_config_get_network(
    3209                 :            :                                 wpa_s->conf, wpa_s->pending_invite_ssid_id);
    3210                 :          0 :                         wpas_remove_persistent_peer(wpa_s, ssid, peer, 1);
    3211                 :            :                 }
    3212                 :          0 :                 wpas_p2p_remove_pending_group_interface(wpa_s);
    3213                 :          0 :                 return;
    3214                 :            :         }
    3215                 :            : 
    3216                 :          7 :         ssid = wpa_config_get_network(wpa_s->conf,
    3217                 :            :                                       wpa_s->pending_invite_ssid_id);
    3218         [ -  + ]:          7 :         if (ssid == NULL) {
    3219                 :          0 :                 wpa_printf(MSG_ERROR, "P2P: Could not find persistent group "
    3220                 :            :                            "data matching with invitation");
    3221                 :          0 :                 return;
    3222                 :            :         }
    3223                 :            : 
    3224                 :            :         /*
    3225                 :            :          * The peer could have missed our ctrl::ack frame for Invitation
    3226                 :            :          * Response and continue retransmitting the frame. To reduce the
    3227                 :            :          * likelihood of the peer not getting successful TX status for the
    3228                 :            :          * Invitation Response frame, wait a short time here before starting
    3229                 :            :          * the persistent group so that we will remain on the current channel to
    3230                 :            :          * acknowledge any possible retransmission from the peer.
    3231                 :            :          */
    3232                 :          7 :         wpa_dbg(wpa_s, MSG_DEBUG, "P2P: 50 ms wait on current channel before "
    3233                 :            :                 "starting persistent group");
    3234                 :          7 :         os_sleep(0, 50000);
    3235                 :            : 
    3236         [ +  + ]:         13 :         wpas_p2p_group_add_persistent(wpa_s, ssid,
    3237                 :          7 :                                       ssid->mode == WPAS_MODE_P2P_GO,
    3238                 :            :                                       wpa_s->p2p_persistent_go_freq,
    3239                 :            :                                       neg_freq,
    3240                 :         14 :                                       wpa_s->p2p_go_ht40, wpa_s->p2p_go_vht,
    3241                 :            :                                       channels,
    3242                 :          7 :                                       ssid->mode == WPAS_MODE_P2P_GO ?
    3243                 :            :                                       P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE :
    3244                 :            :                                       0);
    3245                 :            : }
    3246                 :            : 
    3247                 :            : 
    3248                 :     127547 : static int wpas_p2p_disallowed_freq(struct wpa_global *global,
    3249                 :            :                                     unsigned int freq)
    3250                 :            : {
    3251         [ -  + ]:     127547 :         if (freq_range_list_includes(&global->p2p_go_avoid_freq, freq))
    3252                 :          0 :                 return 1;
    3253                 :     127547 :         return freq_range_list_includes(&global->p2p_disallow_freq, freq);
    3254                 :            : }
    3255                 :            : 
    3256                 :            : 
    3257                 :          0 : static void wpas_p2p_add_chan(struct p2p_reg_class *reg, u8 chan)
    3258                 :            : {
    3259                 :          0 :         reg->channel[reg->channels] = chan;
    3260                 :          0 :         reg->channels++;
    3261                 :          0 : }
    3262                 :            : 
    3263                 :            : 
    3264                 :          0 : static int wpas_p2p_default_channels(struct wpa_supplicant *wpa_s,
    3265                 :            :                                      struct p2p_channels *chan,
    3266                 :            :                                      struct p2p_channels *cli_chan)
    3267                 :            : {
    3268                 :          0 :         int i, cla = 0;
    3269                 :            : 
    3270                 :          0 :         os_memset(cli_chan, 0, sizeof(*cli_chan));
    3271                 :            : 
    3272                 :          0 :         wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for 2.4 GHz "
    3273                 :            :                    "band");
    3274                 :            : 
    3275                 :            :         /* Operating class 81 - 2.4 GHz band channels 1..13 */
    3276                 :          0 :         chan->reg_class[cla].reg_class = 81;
    3277                 :          0 :         chan->reg_class[cla].channels = 0;
    3278         [ #  # ]:          0 :         for (i = 0; i < 11; i++) {
    3279         [ #  # ]:          0 :                 if (!wpas_p2p_disallowed_freq(wpa_s->global, 2412 + i * 5))
    3280                 :          0 :                         wpas_p2p_add_chan(&chan->reg_class[cla], i + 1);
    3281                 :            :         }
    3282         [ #  # ]:          0 :         if (chan->reg_class[cla].channels)
    3283                 :          0 :                 cla++;
    3284                 :            : 
    3285                 :          0 :         wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for lower 5 GHz "
    3286                 :            :                    "band");
    3287                 :            : 
    3288                 :            :         /* Operating class 115 - 5 GHz, channels 36-48 */
    3289                 :          0 :         chan->reg_class[cla].reg_class = 115;
    3290                 :          0 :         chan->reg_class[cla].channels = 0;
    3291         [ #  # ]:          0 :         if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 36 * 5))
    3292                 :          0 :                 wpas_p2p_add_chan(&chan->reg_class[cla], 36);
    3293         [ #  # ]:          0 :         if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 40 * 5))
    3294                 :          0 :                 wpas_p2p_add_chan(&chan->reg_class[cla], 40);
    3295         [ #  # ]:          0 :         if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 44 * 5))
    3296                 :          0 :                 wpas_p2p_add_chan(&chan->reg_class[cla], 44);
    3297         [ #  # ]:          0 :         if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 48 * 5))
    3298                 :          0 :                 wpas_p2p_add_chan(&chan->reg_class[cla], 48);
    3299         [ #  # ]:          0 :         if (chan->reg_class[cla].channels)
    3300                 :          0 :                 cla++;
    3301                 :            : 
    3302                 :          0 :         wpa_printf(MSG_DEBUG, "P2P: Enable operating classes for higher 5 GHz "
    3303                 :            :                    "band");
    3304                 :            : 
    3305                 :            :         /* Operating class 124 - 5 GHz, channels 149,153,157,161 */
    3306                 :          0 :         chan->reg_class[cla].reg_class = 124;
    3307                 :          0 :         chan->reg_class[cla].channels = 0;
    3308         [ #  # ]:          0 :         if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 149 * 5))
    3309                 :          0 :                 wpas_p2p_add_chan(&chan->reg_class[cla], 149);
    3310         [ #  # ]:          0 :         if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 153 * 5))
    3311                 :          0 :                 wpas_p2p_add_chan(&chan->reg_class[cla], 153);
    3312         [ #  # ]:          0 :         if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 156 * 5))
    3313                 :          0 :                 wpas_p2p_add_chan(&chan->reg_class[cla], 157);
    3314         [ #  # ]:          0 :         if (!wpas_p2p_disallowed_freq(wpa_s->global, 5000 + 161 * 5))
    3315                 :          0 :                 wpas_p2p_add_chan(&chan->reg_class[cla], 161);
    3316         [ #  # ]:          0 :         if (chan->reg_class[cla].channels)
    3317                 :          0 :                 cla++;
    3318                 :            : 
    3319                 :          0 :         chan->reg_classes = cla;
    3320                 :          0 :         return 0;
    3321                 :            : }
    3322                 :            : 
    3323                 :            : 
    3324                 :      13424 : static struct hostapd_hw_modes * get_mode(struct hostapd_hw_modes *modes,
    3325                 :            :                                           u16 num_modes,
    3326                 :            :                                           enum hostapd_hw_mode mode)
    3327                 :            : {
    3328                 :            :         u16 i;
    3329                 :            : 
    3330         [ +  - ]:      25170 :         for (i = 0; i < num_modes; i++) {
    3331         [ +  + ]:      25170 :                 if (modes[i].mode == mode)
    3332                 :      13424 :                         return &modes[i];
    3333                 :            :         }
    3334                 :            : 
    3335                 :      13424 :         return NULL;
    3336                 :            : }
    3337                 :            : 
    3338                 :            : 
    3339                 :            : enum chan_allowed {
    3340                 :            :         NOT_ALLOWED, PASSIVE_ONLY, ALLOWED
    3341                 :            : };
    3342                 :            : 
    3343                 :     127528 : static int has_channel(struct wpa_global *global,
    3344                 :            :                        struct hostapd_hw_modes *mode, u8 chan, int *flags)
    3345                 :            : {
    3346                 :            :         int i;
    3347                 :            :         unsigned int freq;
    3348                 :            : 
    3349         [ +  + ]:     127528 :         freq = (mode->mode == HOSTAPD_MODE_IEEE80211A ? 5000 : 2407) +
    3350                 :     127528 :                 chan * 5;
    3351         [ -  + ]:     127528 :         if (wpas_p2p_disallowed_freq(global, freq))
    3352                 :          0 :                 return NOT_ALLOWED;
    3353                 :            : 
    3354         [ +  + ]:    1607524 :         for (i = 0; i < mode->num_channels; i++) {
    3355         [ +  + ]:    1585710 :                 if (mode->channels[i].chan == chan) {
    3356         [ +  + ]:     105714 :                         if (flags)
    3357                 :      92290 :                                 *flags = mode->channels[i].flag;
    3358         [ +  + ]:     105714 :                         if (mode->channels[i].flag &
    3359                 :            :                             (HOSTAPD_CHAN_DISABLED |
    3360                 :            :                              HOSTAPD_CHAN_RADAR))
    3361                 :      25170 :                                 return NOT_ALLOWED;
    3362         [ +  + ]:      80544 :                         if (mode->channels[i].flag &
    3363                 :            :                             (HOSTAPD_CHAN_PASSIVE_SCAN |
    3364                 :            :                              HOSTAPD_CHAN_NO_IBSS))
    3365                 :      62086 :                                 return PASSIVE_ONLY;
    3366                 :      18458 :                         return ALLOWED;
    3367                 :            :                 }
    3368                 :            :         }
    3369                 :            : 
    3370                 :     127528 :         return NOT_ALLOWED;
    3371                 :            : }
    3372                 :            : 
    3373                 :            : 
    3374                 :            : struct p2p_oper_class_map {
    3375                 :            :         enum hostapd_hw_mode mode;
    3376                 :            :         u8 op_class;
    3377                 :            :         u8 min_chan;
    3378                 :            :         u8 max_chan;
    3379                 :            :         u8 inc;
    3380                 :            :         enum { BW20, BW40PLUS, BW40MINUS, BW80 } bw;
    3381                 :            : };
    3382                 :            : 
    3383                 :            : static struct p2p_oper_class_map op_class[] = {
    3384                 :            :         { HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1, BW20 },
    3385                 :            : #if 0 /* Do not enable HT40 on 2 GHz for now */
    3386                 :            :         { HOSTAPD_MODE_IEEE80211G, 83, 1, 9, 1, BW40PLUS },
    3387                 :            :         { HOSTAPD_MODE_IEEE80211G, 84, 5, 13, 1, BW40MINUS },
    3388                 :            : #endif
    3389                 :            :         { HOSTAPD_MODE_IEEE80211A, 115, 36, 48, 4, BW20 },
    3390                 :            :         { HOSTAPD_MODE_IEEE80211A, 124, 149, 161, 4, BW20 },
    3391                 :            :         { HOSTAPD_MODE_IEEE80211A, 116, 36, 44, 8, BW40PLUS },
    3392                 :            :         { HOSTAPD_MODE_IEEE80211A, 117, 40, 48, 8, BW40MINUS },
    3393                 :            :         { HOSTAPD_MODE_IEEE80211A, 126, 149, 157, 8, BW40PLUS },
    3394                 :            :         { HOSTAPD_MODE_IEEE80211A, 127, 153, 161, 8, BW40MINUS },
    3395                 :            : 
    3396                 :            :         /*
    3397                 :            :          * IEEE P802.11ac/D7.0 Table E-4 actually talks about channel center
    3398                 :            :          * frequency index 42, 58, 106, 122, 138, 155 with channel spacing of
    3399                 :            :          * 80 MHz, but currently use the following definition for simplicity
    3400                 :            :          * (these center frequencies are not actual channels, which makes
    3401                 :            :          * has_channel() fail). wpas_p2p_verify_80mhz() should take care of
    3402                 :            :          * removing invalid channels.
    3403                 :            :          */
    3404                 :            :         { HOSTAPD_MODE_IEEE80211A, 128, 36, 161, 4, BW80 },
    3405                 :            :         { -1, 0, 0, 0, 0, BW20 }
    3406                 :            : };
    3407                 :            : 
    3408                 :            : 
    3409                 :      53696 : static int wpas_p2p_get_center_80mhz(struct wpa_supplicant *wpa_s,
    3410                 :            :                                      struct hostapd_hw_modes *mode,
    3411                 :            :                                      u8 channel)
    3412                 :            : {
    3413                 :      53696 :         u8 center_channels[] = { 42, 58, 106, 122, 138, 155 };
    3414                 :            :         unsigned int i;
    3415                 :            : 
    3416         [ -  + ]:      53696 :         if (mode->mode != HOSTAPD_MODE_IEEE80211A)
    3417                 :          0 :                 return 0;
    3418                 :            : 
    3419         [ +  + ]:     236598 :         for (i = 0; i < ARRAY_SIZE(center_channels); i++)
    3420                 :            :                 /*
    3421                 :            :                  * In 80 MHz, the bandwidth "spans" 12 channels (e.g., 36-48),
    3422                 :            :                  * so the center channel is 6 channels away from the start/end.
    3423                 :            :                  */
    3424 [ +  + ][ +  + ]:     221496 :                 if (channel >= center_channels[i] - 6 &&
    3425                 :     166122 :                     channel <= center_channels[i] + 6)
    3426                 :      38594 :                         return center_channels[i];
    3427                 :            : 
    3428                 :      53696 :         return 0;
    3429                 :            : }
    3430                 :            : 
    3431                 :            : 
    3432                 :      53696 : static enum chan_allowed wpas_p2p_verify_80mhz(struct wpa_supplicant *wpa_s,
    3433                 :            :                                                struct hostapd_hw_modes *mode,
    3434                 :            :                                                u8 channel, u8 bw)
    3435                 :            : {
    3436                 :            :         u8 center_chan;
    3437                 :            :         int i, flags;
    3438                 :      53696 :         enum chan_allowed res, ret = ALLOWED;
    3439                 :            : 
    3440                 :      53696 :         center_chan = wpas_p2p_get_center_80mhz(wpa_s, mode, channel);
    3441         [ +  + ]:      53696 :         if (!center_chan)
    3442                 :      15102 :                 return NOT_ALLOWED;
    3443 [ +  + ][ +  + ]:      38594 :         if (center_chan >= 58 && center_chan <= 138)
    3444                 :      26848 :                 return NOT_ALLOWED; /* Do not allow DFS channels for P2P */
    3445                 :            : 
    3446                 :            :         /* check all the channels are available */
    3447         [ +  - ]:      11746 :         for (i = 0; i < 4; i++) {
    3448                 :      11746 :                 int adj_chan = center_chan - 6 + i * 4;
    3449                 :            : 
    3450                 :      11746 :                 res = has_channel(wpa_s->global, mode, adj_chan, &flags);
    3451         [ -  + ]:      11746 :                 if (res == NOT_ALLOWED)
    3452                 :          0 :                         return NOT_ALLOWED;
    3453         [ +  - ]:      11746 :                 if (res == PASSIVE_ONLY)
    3454                 :      11746 :                         ret = PASSIVE_ONLY;
    3455                 :            : 
    3456 [ +  - ][ +  - ]:      11746 :                 if (i == 0 && !(flags & HOSTAPD_CHAN_VHT_10_70))
    3457                 :      11746 :                         return NOT_ALLOWED;
    3458 [ #  # ][ #  # ]:          0 :                 if (i == 1 && !(flags & HOSTAPD_CHAN_VHT_30_50))
    3459                 :          0 :                         return NOT_ALLOWED;
    3460 [ #  # ][ #  # ]:          0 :                 if (i == 2 && !(flags & HOSTAPD_CHAN_VHT_50_30))
    3461                 :          0 :                         return NOT_ALLOWED;
    3462 [ #  # ][ #  # ]:          0 :                 if (i == 3 && !(flags & HOSTAPD_CHAN_VHT_70_10))
    3463                 :          0 :                         return NOT_ALLOWED;
    3464                 :            :         }
    3465                 :            : 
    3466                 :      53696 :         return ret;
    3467                 :            : }
    3468                 :            : 
    3469                 :            : 
    3470                 :     102358 : static enum chan_allowed wpas_p2p_verify_channel(struct wpa_supplicant *wpa_s,
    3471                 :            :                                                  struct hostapd_hw_modes *mode,
    3472                 :            :                                                  u8 channel, u8 bw)
    3473                 :            : {
    3474                 :     102358 :         int flag = 0;
    3475                 :            :         enum chan_allowed res, res2;
    3476                 :            : 
    3477                 :     102358 :         res2 = res = has_channel(wpa_s->global, mode, channel, &flag);
    3478         [ +  + ]:     102358 :         if (bw == BW40MINUS) {
    3479         [ -  + ]:       6712 :                 if (!(flag & HOSTAPD_CHAN_HT40MINUS))
    3480                 :          0 :                         return NOT_ALLOWED;
    3481                 :       6712 :                 res2 = has_channel(wpa_s->global, mode, channel - 4, NULL);
    3482         [ +  + ]:      95646 :         } else if (bw == BW40PLUS) {
    3483         [ -  + ]:       6712 :                 if (!(flag & HOSTAPD_CHAN_HT40PLUS))
    3484                 :          0 :                         return NOT_ALLOWED;
    3485                 :       6712 :                 res2 = has_channel(wpa_s->global, mode, channel + 4, NULL);
    3486         [ +  + ]:      88934 :         } else if (bw == BW80) {
    3487                 :      53696 :                 res2 = wpas_p2p_verify_80mhz(wpa_s, mode, channel, bw);
    3488                 :            :         }
    3489                 :            : 
    3490 [ +  + ][ +  + ]:     102358 :         if (res == NOT_ALLOWED || res2 == NOT_ALLOWED)
    3491                 :      53696 :                 return NOT_ALLOWED;
    3492 [ +  + ][ -  + ]:      48662 :         if (res == PASSIVE_ONLY || res2 == PASSIVE_ONLY)
    3493                 :      30204 :                 return PASSIVE_ONLY;
    3494                 :     102358 :         return res;
    3495                 :            : }
    3496                 :            : 
    3497                 :            : 
    3498                 :       1678 : static int wpas_p2p_setup_channels(struct wpa_supplicant *wpa_s,
    3499                 :            :                                    struct p2p_channels *chan,
    3500                 :            :                                    struct p2p_channels *cli_chan)
    3501                 :            : {
    3502                 :            :         struct hostapd_hw_modes *mode;
    3503                 :            :         int cla, op, cli_cla;
    3504                 :            : 
    3505         [ -  + ]:       1678 :         if (wpa_s->hw.modes == NULL) {
    3506                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Driver did not support fetching "
    3507                 :            :                            "of all supported channels; assume dualband "
    3508                 :            :                            "support");
    3509                 :          0 :                 return wpas_p2p_default_channels(wpa_s, chan, cli_chan);
    3510                 :            :         }
    3511                 :            : 
    3512                 :       1678 :         cla = cli_cla = 0;
    3513                 :            : 
    3514         [ +  + ]:      15102 :         for (op = 0; op_class[op].op_class; op++) {
    3515                 :      13424 :                 struct p2p_oper_class_map *o = &op_class[op];
    3516                 :            :                 u8 ch;
    3517                 :      13424 :                 struct p2p_reg_class *reg = NULL, *cli_reg = NULL;
    3518                 :            : 
    3519                 :      13424 :                 mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, o->mode);
    3520         [ -  + ]:      13424 :                 if (mode == NULL)
    3521                 :          0 :                         continue;
    3522         [ +  + ]:     115782 :                 for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
    3523                 :            :                         enum chan_allowed res;
    3524                 :     102358 :                         res = wpas_p2p_verify_channel(wpa_s, mode, ch, o->bw);
    3525         [ +  + ]:     102358 :                         if (res == ALLOWED) {
    3526         [ +  + ]:      18458 :                                 if (reg == NULL) {
    3527                 :       1678 :                                         wpa_printf(MSG_DEBUG, "P2P: Add operating class %u",
    3528                 :       1678 :                                                    o->op_class);
    3529                 :       1678 :                                         reg = &chan->reg_class[cla];
    3530                 :       1678 :                                         cla++;
    3531                 :       1678 :                                         reg->reg_class = o->op_class;
    3532                 :            :                                 }
    3533                 :      18458 :                                 reg->channel[reg->channels] = ch;
    3534                 :      18458 :                                 reg->channels++;
    3535 [ +  + ][ +  + ]:      83900 :                         } else if (res == PASSIVE_ONLY &&
    3536                 :      30204 :                                    wpa_s->conf->p2p_add_cli_chan) {
    3537         [ +  + ]:        252 :                                 if (cli_reg == NULL) {
    3538                 :         98 :                                         wpa_printf(MSG_DEBUG, "P2P: Add operating class %u (client only)",
    3539                 :         98 :                                                    o->op_class);
    3540                 :         98 :                                         cli_reg = &cli_chan->reg_class[cli_cla];
    3541                 :         98 :                                         cli_cla++;
    3542                 :         98 :                                         cli_reg->reg_class = o->op_class;
    3543                 :            :                                 }
    3544                 :        252 :                                 cli_reg->channel[cli_reg->channels] = ch;
    3545                 :        252 :                                 cli_reg->channels++;
    3546                 :            :                         }
    3547                 :            :                 }
    3548         [ +  + ]:      13424 :                 if (reg) {
    3549                 :       1678 :                         wpa_hexdump(MSG_DEBUG, "P2P: Channels",
    3550                 :       1678 :                                     reg->channel, reg->channels);
    3551                 :            :                 }
    3552         [ +  + ]:      13424 :                 if (cli_reg) {
    3553                 :         98 :                         wpa_hexdump(MSG_DEBUG, "P2P: Channels (client only)",
    3554                 :         98 :                                     cli_reg->channel, cli_reg->channels);
    3555                 :            :                 }
    3556                 :            :         }
    3557                 :            : 
    3558                 :       1678 :         chan->reg_classes = cla;
    3559                 :       1678 :         cli_chan->reg_classes = cli_cla;
    3560                 :            : 
    3561                 :       1678 :         return 0;
    3562                 :            : }
    3563                 :            : 
    3564                 :            : 
    3565                 :          0 : int wpas_p2p_get_ht40_mode(struct wpa_supplicant *wpa_s,
    3566                 :            :                            struct hostapd_hw_modes *mode, u8 channel)
    3567                 :            : {
    3568                 :            :         int op;
    3569                 :            :         enum chan_allowed ret;
    3570                 :            : 
    3571         [ #  # ]:          0 :         for (op = 0; op_class[op].op_class; op++) {
    3572                 :          0 :                 struct p2p_oper_class_map *o = &op_class[op];
    3573                 :            :                 u8 ch;
    3574                 :            : 
    3575         [ #  # ]:          0 :                 for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
    3576 [ #  # ][ #  # ]:          0 :                         if (o->mode != HOSTAPD_MODE_IEEE80211A ||
    3577         [ #  # ]:          0 :                             o->bw == BW20 || ch != channel)
    3578                 :          0 :                                 continue;
    3579                 :          0 :                         ret = wpas_p2p_verify_channel(wpa_s, mode, ch, o->bw);
    3580         [ #  # ]:          0 :                         if (ret == ALLOWED)
    3581         [ #  # ]:          0 :                                 return (o->bw == BW40MINUS) ? -1 : 1;
    3582                 :            :                 }
    3583                 :            :         }
    3584                 :          0 :         return 0;
    3585                 :            : }
    3586                 :            : 
    3587                 :            : 
    3588                 :          0 : int wpas_p2p_get_vht80_center(struct wpa_supplicant *wpa_s,
    3589                 :            :                               struct hostapd_hw_modes *mode, u8 channel)
    3590                 :            : {
    3591         [ #  # ]:          0 :         if (!wpas_p2p_verify_channel(wpa_s, mode, channel, BW80))
    3592                 :          0 :                 return 0;
    3593                 :            : 
    3594                 :          0 :         return wpas_p2p_get_center_80mhz(wpa_s, mode, channel);
    3595                 :            : }
    3596                 :            : 
    3597                 :            : 
    3598                 :          2 : static int wpas_get_noa(void *ctx, const u8 *interface_addr, u8 *buf,
    3599                 :            :                         size_t buf_len)
    3600                 :            : {
    3601                 :          2 :         struct wpa_supplicant *wpa_s = ctx;
    3602                 :            : 
    3603         [ +  - ]:          2 :         for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
    3604         [ +  - ]:          2 :                 if (os_memcmp(wpa_s->own_addr, interface_addr, ETH_ALEN) == 0)
    3605                 :          2 :                         break;
    3606                 :            :         }
    3607         [ -  + ]:          2 :         if (wpa_s == NULL)
    3608                 :          0 :                 return -1;
    3609                 :            : 
    3610                 :          2 :         return wpa_drv_get_noa(wpa_s, buf, buf_len);
    3611                 :            : }
    3612                 :            : 
    3613                 :            : 
    3614                 :          0 : static int wpas_go_connected(void *ctx, const u8 *dev_addr)
    3615                 :            : {
    3616                 :          0 :         struct wpa_supplicant *wpa_s = ctx;
    3617                 :            : 
    3618         [ #  # ]:          0 :         for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
    3619                 :          0 :                 struct wpa_ssid *ssid = wpa_s->current_ssid;
    3620         [ #  # ]:          0 :                 if (ssid == NULL)
    3621                 :          0 :                         continue;
    3622         [ #  # ]:          0 :                 if (ssid->mode != WPAS_MODE_INFRA)
    3623                 :          0 :                         continue;
    3624 [ #  # ][ #  # ]:          0 :                 if (wpa_s->wpa_state != WPA_COMPLETED &&
    3625                 :          0 :                     wpa_s->wpa_state != WPA_GROUP_HANDSHAKE)
    3626                 :          0 :                         continue;
    3627         [ #  # ]:          0 :                 if (os_memcmp(wpa_s->go_dev_addr, dev_addr, ETH_ALEN) == 0)
    3628                 :          0 :                         return 1;
    3629                 :            :         }
    3630                 :            : 
    3631                 :          0 :         return 0;
    3632                 :            : }
    3633                 :            : 
    3634                 :            : 
    3635                 :          5 : static int wpas_is_concurrent_session_active(void *ctx)
    3636                 :            : {
    3637                 :          5 :         struct wpa_supplicant *wpa_s = ctx;
    3638                 :            :         struct wpa_supplicant *ifs;
    3639                 :            : 
    3640         [ +  + ]:         10 :         for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) {
    3641         [ +  - ]:          5 :                 if (ifs == wpa_s)
    3642                 :          5 :                         continue;
    3643         [ #  # ]:          0 :                 if (ifs->wpa_state > WPA_ASSOCIATED)
    3644                 :          0 :                         return 1;
    3645                 :            :         }
    3646                 :          5 :         return 0;
    3647                 :            : }
    3648                 :            : 
    3649                 :            : 
    3650                 :      29929 : static void wpas_p2p_debug_print(void *ctx, int level, const char *msg)
    3651                 :            : {
    3652                 :      29929 :         struct wpa_supplicant *wpa_s = ctx;
    3653                 :      29929 :         wpa_msg_global(wpa_s, level, "P2P: %s", msg);
    3654                 :      29929 : }
    3655                 :            : 
    3656                 :            : 
    3657                 :          0 : int wpas_p2p_add_p2pdev_interface(struct wpa_supplicant *wpa_s)
    3658                 :            : {
    3659                 :            :         struct wpa_interface iface;
    3660                 :            :         struct wpa_supplicant *p2pdev_wpa_s;
    3661                 :            :         char ifname[100];
    3662                 :            :         char force_name[100];
    3663                 :            :         int ret;
    3664                 :            : 
    3665                 :          0 :         os_snprintf(ifname, sizeof(ifname), P2P_MGMT_DEVICE_PREFIX "%s",
    3666                 :          0 :                     wpa_s->ifname);
    3667                 :          0 :         force_name[0] = '\0';
    3668                 :          0 :         wpa_s->pending_interface_type = WPA_IF_P2P_DEVICE;
    3669                 :          0 :         ret = wpa_drv_if_add(wpa_s, WPA_IF_P2P_DEVICE, ifname, NULL, NULL,
    3670                 :          0 :                              force_name, wpa_s->pending_interface_addr, NULL);
    3671         [ #  # ]:          0 :         if (ret < 0) {
    3672                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Failed to create P2P Device interface");
    3673                 :          0 :                 return ret;
    3674                 :            :         }
    3675                 :          0 :         os_strlcpy(wpa_s->pending_interface_name, ifname,
    3676                 :            :                    sizeof(wpa_s->pending_interface_name));
    3677                 :            : 
    3678                 :          0 :         os_memset(&iface, 0, sizeof(iface));
    3679                 :          0 :         iface.p2p_mgmt = 1;
    3680                 :          0 :         iface.ifname = wpa_s->pending_interface_name;
    3681                 :          0 :         iface.driver = wpa_s->driver->name;
    3682                 :          0 :         iface.driver_param = wpa_s->conf->driver_param;
    3683                 :          0 :         iface.confname = wpa_s->confname;
    3684                 :          0 :         p2pdev_wpa_s = wpa_supplicant_add_iface(wpa_s->global, &iface);
    3685         [ #  # ]:          0 :         if (!p2pdev_wpa_s) {
    3686                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Failed to add P2P Device interface");
    3687                 :          0 :                 return -1;
    3688                 :            :         }
    3689                 :          0 :         p2pdev_wpa_s->parent = wpa_s;
    3690                 :            : 
    3691                 :          0 :         wpa_s->pending_interface_name[0] = '\0';
    3692                 :          0 :         return 0;
    3693                 :            : }
    3694                 :            : 
    3695                 :            : 
    3696                 :          1 : static void wpas_presence_resp(void *ctx, const u8 *src, u8 status,
    3697                 :            :                                const u8 *noa, size_t noa_len)
    3698                 :            : {
    3699                 :          1 :         struct wpa_supplicant *wpa_s, *intf = ctx;
    3700                 :            :         char hex[100];
    3701                 :            : 
    3702         [ +  - ]:          1 :         for (wpa_s = intf->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
    3703         [ +  - ]:          1 :                 if (wpa_s->waiting_presence_resp)
    3704                 :          1 :                         break;
    3705                 :            :         }
    3706         [ -  + ]:          1 :         if (!wpa_s) {
    3707                 :          0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: No group interface was waiting for presence response");
    3708                 :          1 :                 return;
    3709                 :            :         }
    3710                 :          1 :         wpa_s->waiting_presence_resp = 0;
    3711                 :            : 
    3712                 :          1 :         wpa_snprintf_hex(hex, sizeof(hex), noa, noa_len);
    3713                 :          1 :         wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_PRESENCE_RESPONSE "src=" MACSTR
    3714                 :          6 :                 " status=%u noa=%s", MAC2STR(src), status, hex);
    3715                 :            : }
    3716                 :            : 
    3717                 :            : 
    3718                 :            : /**
    3719                 :            :  * wpas_p2p_init - Initialize P2P module for %wpa_supplicant
    3720                 :            :  * @global: Pointer to global data from wpa_supplicant_init()
    3721                 :            :  * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
    3722                 :            :  * Returns: 0 on success, -1 on failure
    3723                 :            :  */
    3724                 :         39 : int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
    3725                 :            : {
    3726                 :            :         struct p2p_config p2p;
    3727                 :            :         unsigned int r;
    3728                 :            :         int i;
    3729                 :            : 
    3730         [ -  + ]:         39 :         if (wpa_s->conf->p2p_disabled)
    3731                 :          0 :                 return 0;
    3732                 :            : 
    3733         [ -  + ]:         39 :         if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE))
    3734                 :          0 :                 return 0;
    3735                 :            : 
    3736         [ +  + ]:         39 :         if (global->p2p)
    3737                 :         24 :                 return 0;
    3738                 :            : 
    3739                 :         15 :         os_memset(&p2p, 0, sizeof(p2p));
    3740                 :         15 :         p2p.cb_ctx = wpa_s;
    3741                 :         15 :         p2p.debug_print = wpas_p2p_debug_print;
    3742                 :         15 :         p2p.p2p_scan = wpas_p2p_scan;
    3743                 :         15 :         p2p.send_action = wpas_send_action;
    3744                 :         15 :         p2p.send_action_done = wpas_send_action_done;
    3745                 :         15 :         p2p.go_neg_completed = wpas_go_neg_completed;
    3746                 :         15 :         p2p.go_neg_req_rx = wpas_go_neg_req_rx;
    3747                 :         15 :         p2p.dev_found = wpas_dev_found;
    3748                 :         15 :         p2p.dev_lost = wpas_dev_lost;
    3749                 :         15 :         p2p.find_stopped = wpas_find_stopped;
    3750                 :         15 :         p2p.start_listen = wpas_start_listen;
    3751                 :         15 :         p2p.stop_listen = wpas_stop_listen;
    3752                 :         15 :         p2p.send_probe_resp = wpas_send_probe_resp;
    3753                 :         15 :         p2p.sd_request = wpas_sd_request;
    3754                 :         15 :         p2p.sd_response = wpas_sd_response;
    3755                 :         15 :         p2p.prov_disc_req = wpas_prov_disc_req;
    3756                 :         15 :         p2p.prov_disc_resp = wpas_prov_disc_resp;
    3757                 :         15 :         p2p.prov_disc_fail = wpas_prov_disc_fail;
    3758                 :         15 :         p2p.invitation_process = wpas_invitation_process;
    3759                 :         15 :         p2p.invitation_received = wpas_invitation_received;
    3760                 :         15 :         p2p.invitation_result = wpas_invitation_result;
    3761                 :         15 :         p2p.get_noa = wpas_get_noa;
    3762                 :         15 :         p2p.go_connected = wpas_go_connected;
    3763                 :         15 :         p2p.presence_resp = wpas_presence_resp;
    3764                 :         15 :         p2p.is_concurrent_session_active = wpas_is_concurrent_session_active;
    3765                 :            : 
    3766                 :         15 :         os_memcpy(wpa_s->global->p2p_dev_addr, wpa_s->own_addr, ETH_ALEN);
    3767                 :         15 :         os_memcpy(p2p.dev_addr, wpa_s->global->p2p_dev_addr, ETH_ALEN);
    3768                 :         15 :         p2p.dev_name = wpa_s->conf->device_name;
    3769                 :         15 :         p2p.manufacturer = wpa_s->conf->manufacturer;
    3770                 :         15 :         p2p.model_name = wpa_s->conf->model_name;
    3771                 :         15 :         p2p.model_number = wpa_s->conf->model_number;
    3772                 :         15 :         p2p.serial_number = wpa_s->conf->serial_number;
    3773         [ +  - ]:         15 :         if (wpa_s->wps) {
    3774                 :         15 :                 os_memcpy(p2p.uuid, wpa_s->wps->uuid, 16);
    3775                 :         15 :                 p2p.config_methods = wpa_s->wps->config_methods;
    3776                 :            :         }
    3777                 :            : 
    3778 [ -  + ][ #  # ]:         15 :         if (wpa_s->conf->p2p_listen_reg_class &&
    3779                 :          0 :             wpa_s->conf->p2p_listen_channel) {
    3780                 :          0 :                 p2p.reg_class = wpa_s->conf->p2p_listen_reg_class;
    3781                 :          0 :                 p2p.channel = wpa_s->conf->p2p_listen_channel;
    3782                 :            :         } else {
    3783                 :         15 :                 p2p.reg_class = 81;
    3784                 :            :                 /*
    3785                 :            :                  * Pick one of the social channels randomly as the listen
    3786                 :            :                  * channel.
    3787                 :            :                  */
    3788                 :         15 :                 os_get_random((u8 *) &r, sizeof(r));
    3789                 :         15 :                 p2p.channel = 1 + (r % 3) * 5;
    3790                 :            :         }
    3791                 :         15 :         wpa_printf(MSG_DEBUG, "P2P: Own listen channel: %d", p2p.channel);
    3792                 :            : 
    3793 [ -  + ][ #  # ]:         15 :         if (wpa_s->conf->p2p_oper_reg_class &&
    3794                 :          0 :             wpa_s->conf->p2p_oper_channel) {
    3795                 :          0 :                 p2p.op_reg_class = wpa_s->conf->p2p_oper_reg_class;
    3796                 :          0 :                 p2p.op_channel = wpa_s->conf->p2p_oper_channel;
    3797                 :          0 :                 p2p.cfg_op_channel = 1;
    3798                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Configured operating channel: "
    3799                 :          0 :                            "%d:%d", p2p.op_reg_class, p2p.op_channel);
    3800                 :            : 
    3801                 :            :         } else {
    3802                 :         15 :                 p2p.op_reg_class = 81;
    3803                 :            :                 /*
    3804                 :            :                  * Use random operation channel from (1, 6, 11) if no other
    3805                 :            :                  * preference is indicated.
    3806                 :            :                  */
    3807                 :         15 :                 os_get_random((u8 *) &r, sizeof(r));
    3808                 :         15 :                 p2p.op_channel = 1 + (r % 3) * 5;
    3809                 :         15 :                 p2p.cfg_op_channel = 0;
    3810                 :         15 :                 wpa_printf(MSG_DEBUG, "P2P: Random operating channel: "
    3811                 :         30 :                            "%d:%d", p2p.op_reg_class, p2p.op_channel);
    3812                 :            :         }
    3813                 :            : 
    3814 [ -  + ][ #  # ]:         15 :         if (wpa_s->conf->p2p_pref_chan && wpa_s->conf->num_p2p_pref_chan) {
    3815                 :          0 :                 p2p.pref_chan = wpa_s->conf->p2p_pref_chan;
    3816                 :          0 :                 p2p.num_pref_chan = wpa_s->conf->num_p2p_pref_chan;
    3817                 :            :         }
    3818                 :            : 
    3819 [ -  + ][ #  # ]:         15 :         if (wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
    3820                 :          0 :                 os_memcpy(p2p.country, wpa_s->conf->country, 2);
    3821                 :          0 :                 p2p.country[2] = 0x04;
    3822                 :            :         } else
    3823                 :         15 :                 os_memcpy(p2p.country, "XX\x04", 3);
    3824                 :            : 
    3825         [ -  + ]:         15 :         if (wpas_p2p_setup_channels(wpa_s, &p2p.channels, &p2p.cli_channels)) {
    3826                 :          0 :                 wpa_printf(MSG_ERROR, "P2P: Failed to configure supported "
    3827                 :            :                            "channel list");
    3828                 :          0 :                 return -1;
    3829                 :            :         }
    3830                 :            : 
    3831                 :         15 :         os_memcpy(p2p.pri_dev_type, wpa_s->conf->device_type,
    3832                 :            :                   WPS_DEV_TYPE_LEN);
    3833                 :            : 
    3834                 :         15 :         p2p.num_sec_dev_types = wpa_s->conf->num_sec_device_types;
    3835                 :         15 :         os_memcpy(p2p.sec_dev_type, wpa_s->conf->sec_device_type,
    3836                 :            :                   p2p.num_sec_dev_types * WPS_DEV_TYPE_LEN);
    3837                 :            : 
    3838                 :         15 :         p2p.concurrent_operations = !!(wpa_s->drv_flags &
    3839                 :            :                                        WPA_DRIVER_FLAGS_P2P_CONCURRENT);
    3840                 :            : 
    3841                 :         15 :         p2p.max_peers = 100;
    3842                 :            : 
    3843         [ -  + ]:         15 :         if (wpa_s->conf->p2p_ssid_postfix) {
    3844                 :          0 :                 p2p.ssid_postfix_len =
    3845                 :          0 :                         os_strlen(wpa_s->conf->p2p_ssid_postfix);
    3846         [ #  # ]:          0 :                 if (p2p.ssid_postfix_len > sizeof(p2p.ssid_postfix))
    3847                 :          0 :                         p2p.ssid_postfix_len = sizeof(p2p.ssid_postfix);
    3848                 :          0 :                 os_memcpy(p2p.ssid_postfix, wpa_s->conf->p2p_ssid_postfix,
    3849                 :            :                           p2p.ssid_postfix_len);
    3850                 :            :         }
    3851                 :            : 
    3852                 :         15 :         p2p.p2p_intra_bss = wpa_s->conf->p2p_intra_bss;
    3853                 :            : 
    3854                 :         15 :         p2p.max_listen = wpa_s->max_remain_on_chan;
    3855                 :            : 
    3856                 :         15 :         global->p2p = p2p_init(&p2p);
    3857         [ -  + ]:         15 :         if (global->p2p == NULL)
    3858                 :          0 :                 return -1;
    3859                 :         15 :         global->p2p_init_wpa_s = wpa_s;
    3860                 :            : 
    3861         [ +  + ]:        165 :         for (i = 0; i < MAX_WPS_VENDOR_EXT; i++) {
    3862         [ +  - ]:        150 :                 if (wpa_s->conf->wps_vendor_ext[i] == NULL)
    3863                 :        150 :                         continue;
    3864                 :          0 :                 p2p_add_wps_vendor_extension(
    3865                 :          0 :                         global->p2p, wpa_s->conf->wps_vendor_ext[i]);
    3866                 :            :         }
    3867                 :            : 
    3868                 :         15 :         p2p_set_no_go_freq(global->p2p, &wpa_s->conf->p2p_no_go_freq);
    3869                 :            : 
    3870                 :         39 :         return 0;
    3871                 :            : }
    3872                 :            : 
    3873                 :            : 
    3874                 :            : /**
    3875                 :            :  * wpas_p2p_deinit - Deinitialize per-interface P2P data
    3876                 :            :  * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
    3877                 :            :  *
    3878                 :            :  * This function deinitialize per-interface P2P data.
    3879                 :            :  */
    3880                 :         40 : void wpas_p2p_deinit(struct wpa_supplicant *wpa_s)
    3881                 :            : {
    3882 [ +  + ][ +  - ]:         40 :         if (wpa_s->driver && wpa_s->drv_priv)
    3883                 :         39 :                 wpa_drv_probe_req_report(wpa_s, 0);
    3884                 :            : 
    3885         [ +  + ]:         40 :         if (wpa_s->go_params) {
    3886                 :            :                 /* Clear any stored provisioning info */
    3887                 :         14 :                 p2p_clear_provisioning_info(
    3888                 :         14 :                         wpa_s->global->p2p,
    3889                 :         14 :                         wpa_s->go_params->peer_device_addr);
    3890                 :            :         }
    3891                 :            : 
    3892                 :         40 :         os_free(wpa_s->go_params);
    3893                 :         40 :         wpa_s->go_params = NULL;
    3894                 :         40 :         eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s, NULL);
    3895                 :         40 :         eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
    3896                 :         40 :         wpa_s->p2p_long_listen = 0;
    3897                 :         40 :         eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL);
    3898                 :         40 :         eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL);
    3899                 :         40 :         wpas_p2p_remove_pending_group_interface(wpa_s);
    3900                 :         40 :         eloop_cancel_timeout(wpas_p2p_group_freq_conflict, wpa_s, NULL);
    3901                 :         40 :         wpas_p2p_listen_work_done(wpa_s);
    3902         [ -  + ]:         40 :         if (wpa_s->p2p_send_action_work) {
    3903                 :          0 :                 os_free(wpa_s->p2p_send_action_work->ctx);
    3904                 :          0 :                 radio_work_done(wpa_s->p2p_send_action_work);
    3905                 :          0 :                 wpa_s->p2p_send_action_work = NULL;
    3906                 :            :         }
    3907                 :         40 :         eloop_cancel_timeout(wpas_p2p_send_action_work_timeout, wpa_s, NULL);
    3908                 :            : 
    3909                 :         40 :         wpabuf_free(wpa_s->p2p_oob_dev_pw);
    3910                 :         40 :         wpa_s->p2p_oob_dev_pw = NULL;
    3911                 :            : 
    3912                 :            :         /* TODO: remove group interface from the driver if this wpa_s instance
    3913                 :            :          * is on top of a P2P group interface */
    3914                 :         40 : }
    3915                 :            : 
    3916                 :            : 
    3917                 :            : /**
    3918                 :            :  * wpas_p2p_deinit_global - Deinitialize global P2P module
    3919                 :            :  * @global: Pointer to global data from wpa_supplicant_init()
    3920                 :            :  *
    3921                 :            :  * This function deinitializes the global (per device) P2P module.
    3922                 :            :  */
    3923                 :         15 : void wpas_p2p_deinit_global(struct wpa_global *global)
    3924                 :            : {
    3925                 :            :         struct wpa_supplicant *wpa_s, *tmp;
    3926                 :            : 
    3927                 :         15 :         wpa_s = global->ifaces;
    3928         [ -  + ]:         15 :         if (wpa_s)
    3929                 :          0 :                 wpas_p2p_service_flush(wpa_s);
    3930                 :            : 
    3931         [ -  + ]:         15 :         if (global->p2p == NULL)
    3932                 :         15 :                 return;
    3933                 :            : 
    3934                 :            :         /* Remove remaining P2P group interfaces */
    3935 [ -  + ][ #  # ]:         15 :         while (wpa_s && wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE)
    3936                 :          0 :                 wpa_s = wpa_s->next;
    3937         [ -  + ]:         15 :         while (wpa_s) {
    3938                 :          0 :                 tmp = global->ifaces;
    3939 [ #  # ][ #  # ]:          0 :                 while (tmp &&
    3940         [ #  # ]:          0 :                        (tmp == wpa_s ||
    3941                 :          0 :                         tmp->p2p_group_interface == NOT_P2P_GROUP_INTERFACE)) {
    3942                 :          0 :                         tmp = tmp->next;
    3943                 :            :                 }
    3944         [ #  # ]:          0 :                 if (tmp == NULL)
    3945                 :          0 :                         break;
    3946                 :            :                 /* Disconnect from the P2P group and deinit the interface */
    3947                 :          0 :                 wpas_p2p_disconnect(tmp);
    3948                 :            :         }
    3949                 :            : 
    3950                 :            :         /*
    3951                 :            :          * Deinit GO data on any possibly remaining interface (if main
    3952                 :            :          * interface is used as GO).
    3953                 :            :          */
    3954         [ -  + ]:         15 :         for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
    3955         [ #  # ]:          0 :                 if (wpa_s->ap_iface)
    3956                 :          0 :                         wpas_p2p_group_deinit(wpa_s);
    3957                 :            :         }
    3958                 :            : 
    3959                 :         15 :         p2p_deinit(global->p2p);
    3960                 :         15 :         global->p2p = NULL;
    3961                 :         15 :         global->p2p_init_wpa_s = NULL;
    3962                 :            : }
    3963                 :            : 
    3964                 :            : 
    3965                 :        192 : static int wpas_p2p_create_iface(struct wpa_supplicant *wpa_s)
    3966                 :            : {
    3967 [ +  - ][ +  + ]:        192 :         if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&
    3968                 :        192 :             wpa_s->conf->p2p_no_group_iface)
    3969                 :        168 :                 return 0; /* separate interface disabled per configuration */
    3970         [ +  - ]:         24 :         if (wpa_s->drv_flags &
    3971                 :            :             (WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE |
    3972                 :            :              WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P))
    3973                 :         24 :                 return 1; /* P2P group requires a new interface in every case
    3974                 :            :                            */
    3975         [ #  # ]:          0 :         if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CONCURRENT))
    3976                 :          0 :                 return 0; /* driver does not support concurrent operations */
    3977         [ #  # ]:          0 :         if (wpa_s->global->ifaces->next)
    3978                 :          0 :                 return 1; /* more that one interface already in use */
    3979         [ #  # ]:          0 :         if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
    3980                 :          0 :                 return 1; /* this interface is already in use */
    3981                 :        192 :         return 0;
    3982                 :            : }
    3983                 :            : 
    3984                 :            : 
    3985                 :         59 : static int wpas_p2p_start_go_neg(struct wpa_supplicant *wpa_s,
    3986                 :            :                                  const u8 *peer_addr,
    3987                 :            :                                  enum p2p_wps_method wps_method,
    3988                 :            :                                  int go_intent, const u8 *own_interface_addr,
    3989                 :            :                                  unsigned int force_freq, int persistent_group,
    3990                 :            :                                  struct wpa_ssid *ssid, unsigned int pref_freq)
    3991                 :            : {
    3992 [ +  + ][ +  + ]:         59 :         if (persistent_group && wpa_s->conf->persistent_reconnect)
    3993                 :          4 :                 persistent_group = 2;
    3994                 :            : 
    3995                 :            :         /*
    3996                 :            :          * Increase GO config timeout if HT40 is used since it takes some time
    3997                 :            :          * to scan channels for coex purposes before the BSS can be started.
    3998                 :            :          */
    3999         [ +  + ]:         59 :         p2p_set_config_timeout(wpa_s->global->p2p,
    4000                 :         59 :                                wpa_s->p2p_go_ht40 ? 255 : 100, 20);
    4001                 :            : 
    4002 [ +  + ][ -  + ]:         59 :         return p2p_connect(wpa_s->global->p2p, peer_addr, wps_method,
                 [ -  + ]
    4003                 :            :                            go_intent, own_interface_addr, force_freq,
    4004                 :            :                            persistent_group, ssid ? ssid->ssid : NULL,
    4005                 :            :                            ssid ? ssid->ssid_len : 0,
    4006                 :         59 :                            wpa_s->p2p_pd_before_go_neg, pref_freq,
    4007                 :          6 :                            wps_method == WPS_NFC ? wpa_s->p2p_oob_dev_pw_id :
    4008                 :            :                            0);
    4009                 :            : }
    4010                 :            : 
    4011                 :            : 
    4012                 :         43 : static int wpas_p2p_auth_go_neg(struct wpa_supplicant *wpa_s,
    4013                 :            :                                 const u8 *peer_addr,
    4014                 :            :                                 enum p2p_wps_method wps_method,
    4015                 :            :                                 int go_intent, const u8 *own_interface_addr,
    4016                 :            :                                 unsigned int force_freq, int persistent_group,
    4017                 :            :                                 struct wpa_ssid *ssid, unsigned int pref_freq)
    4018                 :            : {
    4019 [ +  + ][ +  + ]:         43 :         if (persistent_group && wpa_s->conf->persistent_reconnect)
    4020                 :          4 :                 persistent_group = 2;
    4021                 :            : 
    4022 [ +  + ][ -  + ]:         43 :         return p2p_authorize(wpa_s->global->p2p, peer_addr, wps_method,
                 [ -  + ]
    4023                 :            :                              go_intent, own_interface_addr, force_freq,
    4024                 :            :                              persistent_group, ssid ? ssid->ssid : NULL,
    4025                 :            :                              ssid ? ssid->ssid_len : 0, pref_freq,
    4026                 :          4 :                              wps_method == WPS_NFC ? wpa_s->p2p_oob_dev_pw_id :
    4027                 :            :                              0);
    4028                 :            : }
    4029                 :            : 
    4030                 :            : 
    4031                 :          1 : static void wpas_p2p_check_join_scan_limit(struct wpa_supplicant *wpa_s)
    4032                 :            : {
    4033                 :          1 :         wpa_s->p2p_join_scan_count++;
    4034                 :          1 :         wpa_printf(MSG_DEBUG, "P2P: Join scan attempt %d",
    4035                 :            :                    wpa_s->p2p_join_scan_count);
    4036         [ -  + ]:          1 :         if (wpa_s->p2p_join_scan_count > P2P_MAX_JOIN_SCAN_ATTEMPTS) {
    4037                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Failed to find GO " MACSTR
    4038                 :            :                            " for join operationg - stop join attempt",
    4039                 :          0 :                            MAC2STR(wpa_s->pending_join_iface_addr));
    4040                 :          0 :                 eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
    4041         [ #  # ]:          0 :                 if (wpa_s->p2p_auto_pd) {
    4042                 :          0 :                         wpa_s->p2p_auto_pd = 0;
    4043                 :          0 :                         wpa_msg_global(wpa_s, MSG_INFO,
    4044                 :            :                                        P2P_EVENT_PROV_DISC_FAILURE
    4045                 :            :                                        " p2p_dev_addr=" MACSTR " status=N/A",
    4046                 :          0 :                                        MAC2STR(wpa_s->pending_join_dev_addr));
    4047                 :          1 :                         return;
    4048                 :            :                 }
    4049                 :          0 :                 wpa_msg_global(wpa_s->parent, MSG_INFO,
    4050                 :            :                                P2P_EVENT_GROUP_FORMATION_FAILURE);
    4051                 :            :         }
    4052                 :            : }
    4053                 :            : 
    4054                 :            : 
    4055                 :         28 : static int wpas_check_freq_conflict(struct wpa_supplicant *wpa_s, int freq)
    4056                 :            : {
    4057                 :            :         int *freqs, res, num, i;
    4058                 :            : 
    4059         [ +  + ]:         28 :         if (wpas_p2p_num_unused_channels(wpa_s) > 0) {
    4060                 :            :                 /* Multiple channels are supported and not all are in use */
    4061                 :         27 :                 return 0;
    4062                 :            :         }
    4063                 :            : 
    4064                 :          1 :         freqs = os_calloc(wpa_s->num_multichan_concurrent, sizeof(int));
    4065         [ -  + ]:          1 :         if (!freqs)
    4066                 :          0 :                 return 1;
    4067                 :            : 
    4068                 :          1 :         num = wpas_p2p_valid_oper_freqs(wpa_s, freqs,
    4069                 :            :                                         wpa_s->num_multichan_concurrent);
    4070         [ -  + ]:          1 :         if (num < 0) {
    4071                 :          0 :                 res = 1;
    4072                 :          0 :                 goto exit_free;
    4073                 :            :         }
    4074                 :            : 
    4075         [ +  - ]:          1 :         for (i = 0; i < num; i++) {
    4076         [ +  - ]:          1 :                 if (freqs[i] == freq) {
    4077                 :          1 :                         wpa_printf(MSG_DEBUG, "P2P: Frequency %d MHz in use by another virtual interface and can be used",
    4078                 :            :                                    freq);
    4079                 :          1 :                         res = 0;
    4080                 :          1 :                         goto exit_free;
    4081                 :            :                 }
    4082                 :            :         }
    4083                 :            : 
    4084                 :          0 :         res = 1;
    4085                 :            : 
    4086                 :            : exit_free:
    4087                 :          1 :         os_free(freqs);
    4088                 :         28 :         return res;
    4089                 :            : }
    4090                 :            : 
    4091                 :            : 
    4092                 :          0 : static int wpas_p2p_peer_go(struct wpa_supplicant *wpa_s,
    4093                 :            :                             const u8 *peer_dev_addr)
    4094                 :            : {
    4095                 :            :         struct wpa_bss *bss;
    4096                 :            :         int updated;
    4097                 :            : 
    4098                 :          0 :         bss = wpa_bss_get_p2p_dev_addr(wpa_s, peer_dev_addr);
    4099         [ #  # ]:          0 :         if (bss == NULL)
    4100                 :          0 :                 return -1;
    4101         [ #  # ]:          0 :         if (bss->last_update_idx < wpa_s->bss_update_idx) {
    4102                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Peer BSS entry not updated in the "
    4103                 :            :                            "last scan");
    4104                 :          0 :                 return 0;
    4105                 :            :         }
    4106                 :            : 
    4107                 :          0 :         updated = os_reltime_before(&wpa_s->p2p_auto_started,
    4108                 :            :                                     &bss->last_update);
    4109         [ #  # ]:          0 :         wpa_printf(MSG_DEBUG, "P2P: Current BSS entry for peer updated at "
    4110                 :            :                    "%ld.%06ld (%supdated in last scan)",
    4111                 :            :                    bss->last_update.sec, bss->last_update.usec,
    4112                 :            :                    updated ? "": "not ");
    4113                 :            : 
    4114                 :          0 :         return updated;
    4115                 :            : }
    4116                 :            : 
    4117                 :            : 
    4118                 :         28 : static void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s,
    4119                 :            :                                    struct wpa_scan_results *scan_res)
    4120                 :            : {
    4121                 :         28 :         struct wpa_bss *bss = NULL;
    4122                 :            :         int freq;
    4123                 :            :         u8 iface_addr[ETH_ALEN];
    4124                 :            : 
    4125                 :         28 :         eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
    4126                 :            : 
    4127         [ -  + ]:         28 :         if (wpa_s->global->p2p_disabled)
    4128                 :          0 :                 return;
    4129                 :            : 
    4130 [ -  + ][ +  - ]:         28 :         wpa_printf(MSG_DEBUG, "P2P: Scan results received (%d BSS) for %sjoin",
    4131                 :         28 :                    scan_res ? (int) scan_res->num : -1,
    4132                 :         28 :                    wpa_s->p2p_auto_join ? "auto_" : "");
    4133                 :            : 
    4134         [ +  - ]:         28 :         if (scan_res)
    4135                 :         28 :                 wpas_p2p_scan_res_handler(wpa_s, scan_res);
    4136                 :            : 
    4137         [ -  + ]:         28 :         if (wpa_s->p2p_auto_pd) {
    4138                 :          0 :                 int join = wpas_p2p_peer_go(wpa_s,
    4139                 :          0 :                                             wpa_s->pending_join_dev_addr);
    4140 [ #  # ][ #  # ]:          0 :                 if (join == 0 &&
    4141                 :          0 :                     wpa_s->auto_pd_scan_retry < P2P_AUTO_PD_SCAN_ATTEMPTS) {
    4142                 :          0 :                         wpa_s->auto_pd_scan_retry++;
    4143                 :          0 :                         bss = wpa_bss_get_bssid_latest(
    4144                 :          0 :                                 wpa_s, wpa_s->pending_join_dev_addr);
    4145         [ #  # ]:          0 :                         if (bss) {
    4146                 :          0 :                                 freq = bss->freq;
    4147                 :          0 :                                 wpa_printf(MSG_DEBUG, "P2P: Scan retry %d for "
    4148                 :            :                                            "the peer " MACSTR " at %d MHz",
    4149                 :            :                                            wpa_s->auto_pd_scan_retry,
    4150                 :          0 :                                            MAC2STR(wpa_s->
    4151                 :            :                                                    pending_join_dev_addr),
    4152                 :            :                                            freq);
    4153                 :          0 :                                 wpas_p2p_join_scan_req(wpa_s, freq, NULL, 0);
    4154                 :          0 :                                 return;
    4155                 :            :                         }
    4156                 :            :                 }
    4157                 :            : 
    4158         [ #  # ]:          0 :                 if (join < 0)
    4159                 :          0 :                         join = 0;
    4160                 :            : 
    4161                 :          0 :                 wpa_s->p2p_auto_pd = 0;
    4162         [ #  # ]:          0 :                 wpa_s->pending_pd_use = join ? AUTO_PD_JOIN : AUTO_PD_GO_NEG;
    4163                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Auto PD with " MACSTR " join=%d",
    4164                 :          0 :                            MAC2STR(wpa_s->pending_join_dev_addr), join);
    4165         [ #  # ]:          0 :                 if (p2p_prov_disc_req(wpa_s->global->p2p,
    4166                 :          0 :                                       wpa_s->pending_join_dev_addr,
    4167                 :          0 :                                       wpa_s->pending_pd_config_methods, join,
    4168                 :          0 :                                       0, wpa_s->user_initiated_pd) < 0) {
    4169                 :          0 :                         wpa_s->p2p_auto_pd = 0;
    4170                 :          0 :                         wpa_msg_global(wpa_s, MSG_INFO,
    4171                 :            :                                        P2P_EVENT_PROV_DISC_FAILURE
    4172                 :            :                                        " p2p_dev_addr=" MACSTR " status=N/A",
    4173                 :          0 :                                        MAC2STR(wpa_s->pending_join_dev_addr));
    4174                 :            :                 }
    4175                 :          0 :                 return;
    4176                 :            :         }
    4177                 :            : 
    4178         [ -  + ]:         28 :         if (wpa_s->p2p_auto_join) {
    4179                 :          0 :                 int join = wpas_p2p_peer_go(wpa_s,
    4180                 :          0 :                                             wpa_s->pending_join_dev_addr);
    4181         [ #  # ]:          0 :                 if (join < 0) {
    4182                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: Peer was not found to be "
    4183                 :            :                                    "running a GO -> use GO Negotiation");
    4184                 :          0 :                         wpas_p2p_connect(wpa_s, wpa_s->pending_join_dev_addr,
    4185                 :          0 :                                          wpa_s->p2p_pin, wpa_s->p2p_wps_method,
    4186                 :          0 :                                          wpa_s->p2p_persistent_group, 0, 0, 0,
    4187                 :            :                                          wpa_s->p2p_go_intent,
    4188                 :            :                                          wpa_s->p2p_connect_freq,
    4189                 :            :                                          wpa_s->p2p_persistent_id,
    4190                 :          0 :                                          wpa_s->p2p_pd_before_go_neg,
    4191                 :          0 :                                          wpa_s->p2p_go_ht40,
    4192                 :          0 :                                          wpa_s->p2p_go_vht);
    4193                 :          0 :                         return;
    4194                 :            :                 }
    4195                 :            : 
    4196         [ #  # ]:          0 :                 wpa_printf(MSG_DEBUG, "P2P: Peer was found running GO%s -> "
    4197                 :            :                            "try to join the group", join ? "" :
    4198                 :            :                            " in older scan");
    4199         [ #  # ]:          0 :                 if (!join)
    4200                 :          0 :                         wpa_s->p2p_fallback_to_go_neg = 1;
    4201                 :            :         }
    4202                 :            : 
    4203                 :         28 :         freq = p2p_get_oper_freq(wpa_s->global->p2p,
    4204                 :         28 :                                  wpa_s->pending_join_iface_addr);
    4205   [ +  -  +  + ]:         56 :         if (freq < 0 &&
    4206                 :         28 :             p2p_get_interface_addr(wpa_s->global->p2p,
    4207                 :         28 :                                    wpa_s->pending_join_dev_addr,
    4208         [ +  + ]:          4 :                                    iface_addr) == 0 &&
    4209                 :          4 :             os_memcmp(iface_addr, wpa_s->pending_join_dev_addr, ETH_ALEN) != 0)
    4210                 :            :         {
    4211                 :          3 :                 wpa_printf(MSG_DEBUG, "P2P: Overwrite pending interface "
    4212                 :            :                            "address for join from " MACSTR " to " MACSTR
    4213                 :            :                            " based on newly discovered P2P peer entry",
    4214                 :         18 :                            MAC2STR(wpa_s->pending_join_iface_addr),
    4215                 :         18 :                            MAC2STR(iface_addr));
    4216                 :          3 :                 os_memcpy(wpa_s->pending_join_iface_addr, iface_addr,
    4217                 :            :                           ETH_ALEN);
    4218                 :            : 
    4219                 :          3 :                 freq = p2p_get_oper_freq(wpa_s->global->p2p,
    4220                 :          3 :                                          wpa_s->pending_join_iface_addr);
    4221                 :            :         }
    4222         [ -  + ]:         28 :         if (freq >= 0) {
    4223                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Target GO operating frequency "
    4224                 :            :                            "from P2P peer table: %d MHz", freq);
    4225                 :            :         }
    4226         [ +  + ]:         28 :         if (wpa_s->p2p_join_ssid_len) {
    4227                 :          3 :                 wpa_printf(MSG_DEBUG, "P2P: Trying to find target GO BSS entry based on BSSID "
    4228                 :            :                            MACSTR " and SSID %s",
    4229                 :         18 :                            MAC2STR(wpa_s->pending_join_iface_addr),
    4230                 :          3 :                            wpa_ssid_txt(wpa_s->p2p_join_ssid,
    4231                 :            :                                         wpa_s->p2p_join_ssid_len));
    4232                 :          3 :                 bss = wpa_bss_get(wpa_s, wpa_s->pending_join_iface_addr,
    4233                 :          3 :                                   wpa_s->p2p_join_ssid,
    4234                 :            :                                   wpa_s->p2p_join_ssid_len);
    4235                 :            :         }
    4236         [ +  + ]:         28 :         if (!bss) {
    4237                 :         25 :                 wpa_printf(MSG_DEBUG, "P2P: Trying to find target GO BSS entry based on BSSID "
    4238                 :        150 :                            MACSTR, MAC2STR(wpa_s->pending_join_iface_addr));
    4239                 :         25 :                 bss = wpa_bss_get_bssid_latest(wpa_s,
    4240                 :         25 :                                                wpa_s->pending_join_iface_addr);
    4241                 :            :         }
    4242         [ +  - ]:         28 :         if (bss) {
    4243                 :         28 :                 freq = bss->freq;
    4244                 :         28 :                 wpa_printf(MSG_DEBUG, "P2P: Target GO operating frequency "
    4245                 :            :                            "from BSS table: %d MHz (SSID %s)", freq,
    4246                 :         28 :                            wpa_ssid_txt(bss->ssid, bss->ssid_len));
    4247                 :            :         }
    4248         [ +  - ]:         28 :         if (freq > 0) {
    4249                 :            :                 u16 method;
    4250                 :            : 
    4251         [ -  + ]:         28 :                 if (wpas_check_freq_conflict(wpa_s, freq) > 0) {
    4252                 :          0 :                         wpa_msg_global(wpa_s->parent, MSG_INFO,
    4253                 :            :                                        P2P_EVENT_GROUP_FORMATION_FAILURE
    4254                 :            :                                        "reason=FREQ_CONFLICT");
    4255                 :          0 :                         return;
    4256                 :            :                 }
    4257                 :            : 
    4258                 :         28 :                 wpa_printf(MSG_DEBUG, "P2P: Send Provision Discovery Request "
    4259                 :            :                            "prior to joining an existing group (GO " MACSTR
    4260                 :            :                            " freq=%u MHz)",
    4261                 :        168 :                            MAC2STR(wpa_s->pending_join_dev_addr), freq);
    4262                 :         28 :                 wpa_s->pending_pd_before_join = 1;
    4263                 :            : 
    4264   [ -  +  -  + ]:         28 :                 switch (wpa_s->pending_join_wps_method) {
    4265                 :            :                 case WPS_PIN_DISPLAY:
    4266                 :          0 :                         method = WPS_CONFIG_KEYPAD;
    4267                 :          0 :                         break;
    4268                 :            :                 case WPS_PIN_KEYPAD:
    4269                 :         26 :                         method = WPS_CONFIG_DISPLAY;
    4270                 :         26 :                         break;
    4271                 :            :                 case WPS_PBC:
    4272                 :          0 :                         method = WPS_CONFIG_PUSHBUTTON;
    4273                 :          0 :                         break;
    4274                 :            :                 default:
    4275                 :          2 :                         method = 0;
    4276                 :          2 :                         break;
    4277                 :            :                 }
    4278                 :            : 
    4279         [ +  + ]:         28 :                 if ((p2p_get_provisioning_info(wpa_s->global->p2p,
    4280                 :         28 :                                                wpa_s->pending_join_dev_addr) ==
    4281                 :            :                      method)) {
    4282                 :            :                         /*
    4283                 :            :                          * We have already performed provision discovery for
    4284                 :            :                          * joining the group. Proceed directly to join
    4285                 :            :                          * operation without duplicated provision discovery. */
    4286                 :          2 :                         wpa_printf(MSG_DEBUG, "P2P: Provision discovery "
    4287                 :            :                                    "with " MACSTR " already done - proceed to "
    4288                 :            :                                    "join",
    4289                 :         12 :                                    MAC2STR(wpa_s->pending_join_dev_addr));
    4290                 :          2 :                         wpa_s->pending_pd_before_join = 0;
    4291                 :          2 :                         goto start;
    4292                 :            :                 }
    4293                 :            : 
    4294         [ -  + ]:         26 :                 if (p2p_prov_disc_req(wpa_s->global->p2p,
    4295                 :         26 :                                       wpa_s->pending_join_dev_addr, method, 1,
    4296                 :         26 :                                       freq, wpa_s->user_initiated_pd) < 0) {
    4297                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: Failed to send Provision "
    4298                 :            :                                    "Discovery Request before joining an "
    4299                 :            :                                    "existing group");
    4300                 :          0 :                         wpa_s->pending_pd_before_join = 0;
    4301                 :          0 :                         goto start;
    4302                 :            :                 }
    4303                 :         26 :                 return;
    4304                 :            :         }
    4305                 :            : 
    4306                 :          0 :         wpa_printf(MSG_DEBUG, "P2P: Failed to find BSS/GO - try again later");
    4307                 :          0 :         eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
    4308                 :          0 :         eloop_register_timeout(1, 0, wpas_p2p_join_scan, wpa_s, NULL);
    4309                 :          0 :         wpas_p2p_check_join_scan_limit(wpa_s);
    4310                 :          0 :         return;
    4311                 :            : 
    4312                 :            : start:
    4313                 :            :         /* Start join operation immediately */
    4314                 :         28 :         wpas_p2p_join_start(wpa_s, 0, NULL, 0);
    4315                 :            : }
    4316                 :            : 
    4317                 :            : 
    4318                 :         29 : static void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq,
    4319                 :            :                                    const u8 *ssid, size_t ssid_len)
    4320                 :            : {
    4321                 :            :         int ret;
    4322                 :            :         struct wpa_driver_scan_params params;
    4323                 :            :         struct wpabuf *wps_ie, *ies;
    4324                 :            :         size_t ielen;
    4325                 :         29 :         int freqs[2] = { 0, 0 };
    4326                 :            : 
    4327                 :         29 :         os_memset(&params, 0, sizeof(params));
    4328                 :            : 
    4329                 :            :         /* P2P Wildcard SSID */
    4330                 :         29 :         params.num_ssids = 1;
    4331 [ +  + ][ +  - ]:         29 :         if (ssid && ssid_len) {
    4332                 :          3 :                 params.ssids[0].ssid = ssid;
    4333                 :          3 :                 params.ssids[0].ssid_len = ssid_len;
    4334                 :          3 :                 os_memcpy(wpa_s->p2p_join_ssid, ssid, ssid_len);
    4335                 :          3 :                 wpa_s->p2p_join_ssid_len = ssid_len;
    4336                 :            :         } else {
    4337                 :         26 :                 params.ssids[0].ssid = (u8 *) P2P_WILDCARD_SSID;
    4338                 :         26 :                 params.ssids[0].ssid_len = P2P_WILDCARD_SSID_LEN;
    4339                 :         26 :                 wpa_s->p2p_join_ssid_len = 0;
    4340                 :            :         }
    4341                 :            : 
    4342                 :         29 :         wpa_s->wps->dev.p2p = 1;
    4343                 :         29 :         wps_ie = wps_build_probe_req_ie(DEV_PW_DEFAULT, &wpa_s->wps->dev,
    4344                 :         29 :                                         wpa_s->wps->uuid, WPS_REQ_ENROLLEE, 0,
    4345                 :            :                                         NULL);
    4346         [ -  + ]:         29 :         if (wps_ie == NULL) {
    4347                 :          0 :                 wpas_p2p_scan_res_join(wpa_s, NULL);
    4348                 :          0 :                 return;
    4349                 :            :         }
    4350                 :            : 
    4351                 :         29 :         ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p);
    4352                 :         29 :         ies = wpabuf_alloc(wpabuf_len(wps_ie) + ielen);
    4353         [ -  + ]:         29 :         if (ies == NULL) {
    4354                 :          0 :                 wpabuf_free(wps_ie);
    4355                 :          0 :                 wpas_p2p_scan_res_join(wpa_s, NULL);
    4356                 :          0 :                 return;
    4357                 :            :         }
    4358                 :         29 :         wpabuf_put_buf(ies, wps_ie);
    4359                 :         29 :         wpabuf_free(wps_ie);
    4360                 :            : 
    4361                 :         29 :         p2p_scan_ie(wpa_s->global->p2p, ies, NULL);
    4362                 :            : 
    4363                 :         29 :         params.p2p_probe = 1;
    4364                 :         29 :         params.extra_ies = wpabuf_head(ies);
    4365                 :         29 :         params.extra_ies_len = wpabuf_len(ies);
    4366                 :            : 
    4367         [ +  + ]:         29 :         if (!freq) {
    4368                 :            :                 int oper_freq;
    4369                 :            :                 /*
    4370                 :            :                  * If freq is not provided, check the operating freq of the GO
    4371                 :            :                  * and use a single channel scan on if possible.
    4372                 :            :                  */
    4373                 :         26 :                 oper_freq = p2p_get_oper_freq(wpa_s->global->p2p,
    4374                 :         26 :                                               wpa_s->pending_join_iface_addr);
    4375         [ -  + ]:         26 :                 if (oper_freq > 0)
    4376                 :          0 :                         freq = oper_freq;
    4377                 :            :         }
    4378         [ +  + ]:         29 :         if (freq > 0) {
    4379                 :          3 :                 freqs[0] = freq;
    4380                 :          3 :                 params.freqs = freqs;
    4381                 :            :         }
    4382                 :            : 
    4383                 :            :         /*
    4384                 :            :          * Run a scan to update BSS table and start Provision Discovery once
    4385                 :            :          * the new scan results become available.
    4386                 :            :          */
    4387                 :         29 :         ret = wpa_drv_scan(wpa_s, &params);
    4388         [ +  + ]:         29 :         if (!ret) {
    4389                 :         28 :                 os_get_reltime(&wpa_s->scan_trigger_time);
    4390                 :         28 :                 wpa_s->scan_res_handler = wpas_p2p_scan_res_join;
    4391                 :         28 :                 wpa_s->own_scan_requested = 1;
    4392                 :            :         }
    4393                 :            : 
    4394                 :         29 :         wpabuf_free(ies);
    4395                 :            : 
    4396         [ +  + ]:         29 :         if (ret) {
    4397                 :          1 :                 wpa_printf(MSG_DEBUG, "P2P: Failed to start scan for join - "
    4398                 :            :                            "try again later");
    4399                 :          1 :                 eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
    4400                 :          1 :                 eloop_register_timeout(1, 0, wpas_p2p_join_scan, wpa_s, NULL);
    4401                 :         29 :                 wpas_p2p_check_join_scan_limit(wpa_s);
    4402                 :            :         }
    4403                 :            : }
    4404                 :            : 
    4405                 :            : 
    4406                 :          1 : static void wpas_p2p_join_scan(void *eloop_ctx, void *timeout_ctx)
    4407                 :            : {
    4408                 :          1 :         struct wpa_supplicant *wpa_s = eloop_ctx;
    4409                 :          1 :         wpas_p2p_join_scan_req(wpa_s, 0, NULL, 0);
    4410                 :          1 : }
    4411                 :            : 
    4412                 :            : 
    4413                 :         28 : static int wpas_p2p_join(struct wpa_supplicant *wpa_s, const u8 *iface_addr,
    4414                 :            :                          const u8 *dev_addr, enum p2p_wps_method wps_method,
    4415                 :            :                          int auto_join, int op_freq,
    4416                 :            :                          const u8 *ssid, size_t ssid_len)
    4417                 :            : {
    4418         [ -  + ]:         28 :         wpa_printf(MSG_DEBUG, "P2P: Request to join existing group (iface "
    4419                 :            :                    MACSTR " dev " MACSTR " op_freq=%d)%s",
    4420                 :        336 :                    MAC2STR(iface_addr), MAC2STR(dev_addr), op_freq,
    4421                 :            :                    auto_join ? " (auto_join)" : "");
    4422 [ +  + ][ +  - ]:         28 :         if (ssid && ssid_len) {
    4423                 :          3 :                 wpa_printf(MSG_DEBUG, "P2P: Group SSID specified: %s",
    4424                 :            :                            wpa_ssid_txt(ssid, ssid_len));
    4425                 :            :         }
    4426                 :            : 
    4427                 :         28 :         wpa_s->p2p_auto_pd = 0;
    4428                 :         28 :         wpa_s->p2p_auto_join = !!auto_join;
    4429                 :         28 :         os_memcpy(wpa_s->pending_join_iface_addr, iface_addr, ETH_ALEN);
    4430                 :         28 :         os_memcpy(wpa_s->pending_join_dev_addr, dev_addr, ETH_ALEN);
    4431                 :         28 :         wpa_s->pending_join_wps_method = wps_method;
    4432                 :            : 
    4433                 :            :         /* Make sure we are not running find during connection establishment */
    4434                 :         28 :         wpas_p2p_stop_find(wpa_s);
    4435                 :            : 
    4436                 :         28 :         wpa_s->p2p_join_scan_count = 0;
    4437                 :         28 :         wpas_p2p_join_scan_req(wpa_s, op_freq, ssid, ssid_len);
    4438                 :         28 :         return 0;
    4439                 :            : }
    4440                 :            : 
    4441                 :            : 
    4442                 :         32 : static int wpas_p2p_join_start(struct wpa_supplicant *wpa_s, int freq,
    4443                 :            :                                const u8 *ssid, size_t ssid_len)
    4444                 :            : {
    4445                 :            :         struct wpa_supplicant *group;
    4446                 :            :         struct p2p_go_neg_results res;
    4447                 :            :         struct wpa_bss *bss;
    4448                 :            : 
    4449                 :         32 :         group = wpas_p2p_get_group_iface(wpa_s, 0, 0);
    4450         [ -  + ]:         32 :         if (group == NULL)
    4451                 :          0 :                 return -1;
    4452         [ +  + ]:         32 :         if (group != wpa_s) {
    4453                 :          3 :                 os_memcpy(group->p2p_pin, wpa_s->p2p_pin,
    4454                 :            :                           sizeof(group->p2p_pin));
    4455                 :          3 :                 group->p2p_wps_method = wpa_s->p2p_wps_method;
    4456                 :            :         } else {
    4457                 :            :                 /*
    4458                 :            :                  * Need to mark the current interface for p2p_group_formation
    4459                 :            :                  * when a separate group interface is not used. This is needed
    4460                 :            :                  * to allow p2p_cancel stop a pending p2p_connect-join.
    4461                 :            :                  * wpas_p2p_init_group_interface() addresses this for the case
    4462                 :            :                  * where a separate group interface is used.
    4463                 :            :                  */
    4464                 :         29 :                 wpa_s->global->p2p_group_formation = wpa_s;
    4465                 :            :         }
    4466                 :            : 
    4467                 :         32 :         group->p2p_in_provisioning = 1;
    4468                 :         32 :         group->p2p_fallback_to_go_neg = wpa_s->p2p_fallback_to_go_neg;
    4469                 :            : 
    4470                 :         32 :         os_memset(&res, 0, sizeof(res));
    4471                 :         32 :         os_memcpy(res.peer_device_addr, wpa_s->pending_join_dev_addr, ETH_ALEN);
    4472                 :         32 :         os_memcpy(res.peer_interface_addr, wpa_s->pending_join_iface_addr,
    4473                 :            :                   ETH_ALEN);
    4474                 :         32 :         res.wps_method = wpa_s->pending_join_wps_method;
    4475 [ +  + ][ +  - ]:         32 :         if (freq && ssid && ssid_len) {
                 [ +  - ]
    4476                 :          4 :                 res.freq = freq;
    4477                 :          4 :                 res.ssid_len = ssid_len;
    4478                 :          4 :                 os_memcpy(res.ssid, ssid, ssid_len);
    4479                 :            :         } else {
    4480                 :         28 :                 bss = wpa_bss_get_bssid_latest(wpa_s,
    4481                 :         28 :                                                wpa_s->pending_join_iface_addr);
    4482         [ +  - ]:         28 :                 if (bss) {
    4483                 :         28 :                         res.freq = bss->freq;
    4484                 :         28 :                         res.ssid_len = bss->ssid_len;
    4485                 :         28 :                         os_memcpy(res.ssid, bss->ssid, bss->ssid_len);
    4486                 :         28 :                         wpa_printf(MSG_DEBUG, "P2P: Join target GO operating frequency from BSS table: %d MHz (SSID %s)",
    4487                 :            :                                    bss->freq,
    4488                 :         28 :                                    wpa_ssid_txt(bss->ssid, bss->ssid_len));
    4489                 :            :                 }
    4490                 :            :         }
    4491                 :            : 
    4492 [ +  - ][ -  + ]:         32 :         if (wpa_s->off_channel_freq || wpa_s->roc_waiting_drv_freq) {
    4493                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Cancel remain-on-channel prior to "
    4494                 :            :                            "starting client");
    4495                 :          0 :                 wpa_drv_cancel_remain_on_channel(wpa_s);
    4496                 :          0 :                 wpa_s->off_channel_freq = 0;
    4497                 :          0 :                 wpa_s->roc_waiting_drv_freq = 0;
    4498                 :            :         }
    4499                 :         32 :         wpas_start_wps_enrollee(group, &res);
    4500                 :            : 
    4501                 :            :         /*
    4502                 :            :          * Allow a longer timeout for join-a-running-group than normal 15
    4503                 :            :          * second group formation timeout since the GO may not have authorized
    4504                 :            :          * our connection yet.
    4505                 :            :          */
    4506                 :         32 :         eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s, NULL);
    4507                 :         32 :         eloop_register_timeout(60, 0, wpas_p2p_group_formation_timeout,
    4508                 :            :                                wpa_s, NULL);
    4509                 :            : 
    4510                 :         32 :         return 0;
    4511                 :            : }
    4512                 :            : 
    4513                 :            : 
    4514                 :        113 : static int wpas_p2p_setup_freqs(struct wpa_supplicant *wpa_s, int freq,
    4515                 :            :                                 int *force_freq, int *pref_freq, int go)
    4516                 :            : {
    4517                 :            :         int *freqs, res;
    4518                 :        113 :         unsigned int freq_in_use = 0, num, i;
    4519                 :            : 
    4520                 :        113 :         freqs = os_calloc(wpa_s->num_multichan_concurrent, sizeof(int));
    4521         [ -  + ]:        113 :         if (!freqs)
    4522                 :          0 :                 return -1;
    4523                 :            : 
    4524                 :        113 :         num = get_shared_radio_freqs(wpa_s, freqs,
    4525                 :            :                                      wpa_s->num_multichan_concurrent);
    4526                 :        113 :         wpa_printf(MSG_DEBUG,
    4527                 :            :                    "P2P: Setup freqs: freq=%d num_MCC=%d shared_freqs=%u",
    4528                 :            :                    freq, wpa_s->num_multichan_concurrent, num);
    4529                 :            : 
    4530         [ +  + ]:        113 :         if (freq > 0) {
    4531                 :            :                 int ret;
    4532         [ +  + ]:         24 :                 if (go)
    4533                 :          9 :                         ret = p2p_supported_freq(wpa_s->global->p2p, freq);
    4534                 :            :                 else
    4535                 :         15 :                         ret = p2p_supported_freq_cli(wpa_s->global->p2p, freq);
    4536         [ -  + ]:         24 :                 if (!ret) {
    4537                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: The forced channel "
    4538                 :            :                                    "(%u MHz) is not supported for P2P uses",
    4539                 :            :                                    freq);
    4540                 :          0 :                         res = -3;
    4541                 :          0 :                         goto exit_free;
    4542                 :            :                 }
    4543                 :            : 
    4544         [ +  + ]:         32 :                 for (i = 0; i < num; i++) {
    4545         [ +  - ]:          8 :                         if (freqs[i] == freq)
    4546                 :          8 :                                 freq_in_use = 1;
    4547                 :            :                 }
    4548                 :            : 
    4549 [ +  + ][ -  + ]:         24 :                 if (num == wpa_s->num_multichan_concurrent && !freq_in_use) {
    4550                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: Cannot start P2P group on %u MHz as there are no available channels",
    4551                 :            :                                    freq);
    4552                 :          0 :                         res = -2;
    4553                 :          0 :                         goto exit_free;
    4554                 :            :                 }
    4555                 :         24 :                 wpa_printf(MSG_DEBUG, "P2P: Trying to force us to use the "
    4556                 :            :                            "requested channel (%u MHz)", freq);
    4557                 :         24 :                 *force_freq = freq;
    4558                 :         24 :                 goto exit_ok;
    4559                 :            :         }
    4560                 :            : 
    4561         [ +  + ]:         89 :         for (i = 0; i < num; i++) {
    4562         [ -  + ]:          2 :                 if (!p2p_supported_freq(wpa_s->global->p2p, freqs[i]))
    4563                 :          0 :                         continue;
    4564                 :            : 
    4565 [ +  - ][ -  + ]:          2 :                 if (*pref_freq == 0 && num < wpa_s->num_multichan_concurrent) {
    4566                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: Try to prefer a frequency (%u MHz) we are already using",
    4567                 :          0 :                                    freqs[i]);
    4568                 :          0 :                         *pref_freq = freqs[i];
    4569                 :            :                 } else {
    4570                 :          2 :                         wpa_printf(MSG_DEBUG, "P2P: Try to force us to use frequency (%u MHz) which is already in use",
    4571                 :          2 :                                    freqs[i]);
    4572                 :          2 :                         *force_freq = freqs[i];
    4573                 :            :                 }
    4574                 :          2 :                 break;
    4575                 :            :         }
    4576                 :            : 
    4577         [ +  + ]:         89 :         if (i == num) {
    4578 [ +  - ][ -  + ]:         87 :                 if (num < wpa_s->num_multichan_concurrent && num > 0) {
    4579                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: Current operating channels are not available for P2P. Try to use another channel");
    4580                 :          0 :                         *force_freq = 0;
    4581         [ +  - ]:         87 :                 } else if (num < wpa_s->num_multichan_concurrent) {
    4582                 :         87 :                         wpa_printf(MSG_DEBUG, "P2P: No current operating channels - try to use a new channel");
    4583                 :         87 :                         *force_freq = 0;
    4584                 :            :                 } else {
    4585                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: All channels are in use and none of them are P2P enabled. Cannot start P2P group");
    4586                 :          0 :                         res = -2;
    4587                 :          0 :                         goto exit_free;
    4588                 :            :                 }
    4589                 :            :         }
    4590                 :            : 
    4591                 :            : exit_ok:
    4592                 :        113 :         res = 0;
    4593                 :            : exit_free:
    4594                 :        113 :         os_free(freqs);
    4595                 :        113 :         return res;
    4596                 :            : }
    4597                 :            : 
    4598                 :            : 
    4599                 :            : /**
    4600                 :            :  * wpas_p2p_connect - Request P2P Group Formation to be started
    4601                 :            :  * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
    4602                 :            :  * @peer_addr: Address of the peer P2P Device
    4603                 :            :  * @pin: PIN to use during provisioning or %NULL to indicate PBC mode
    4604                 :            :  * @persistent_group: Whether to create a persistent group
    4605                 :            :  * @auto_join: Whether to select join vs. GO Negotiation automatically
    4606                 :            :  * @join: Whether to join an existing group (as a client) instead of starting
    4607                 :            :  *      Group Owner negotiation; @peer_addr is BSSID in that case
    4608                 :            :  * @auth: Whether to only authorize the connection instead of doing that and
    4609                 :            :  *      initiating Group Owner negotiation
    4610                 :            :  * @go_intent: GO Intent or -1 to use default
    4611                 :            :  * @freq: Frequency for the group or 0 for auto-selection
    4612                 :            :  * @persistent_id: Persistent group credentials to use for forcing GO
    4613                 :            :  *      parameters or -1 to generate new values (SSID/passphrase)
    4614                 :            :  * @pd: Whether to send Provision Discovery prior to GO Negotiation as an
    4615                 :            :  *      interoperability workaround when initiating group formation
    4616                 :            :  * @ht40: Start GO with 40 MHz channel width
    4617                 :            :  * @vht:  Start GO with VHT support
    4618                 :            :  * Returns: 0 or new PIN (if pin was %NULL) on success, -1 on unspecified
    4619                 :            :  *      failure, -2 on failure due to channel not currently available,
    4620                 :            :  *      -3 if forced channel is not supported
    4621                 :            :  */
    4622                 :        128 : int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
    4623                 :            :                      const char *pin, enum p2p_wps_method wps_method,
    4624                 :            :                      int persistent_group, int auto_join, int join, int auth,
    4625                 :            :                      int go_intent, int freq, int persistent_id, int pd,
    4626                 :            :                      int ht40, int vht)
    4627                 :            : {
    4628                 :        128 :         int force_freq = 0, pref_freq = 0;
    4629                 :        128 :         int ret = 0, res;
    4630                 :            :         enum wpa_driver_if_type iftype;
    4631                 :            :         const u8 *if_addr;
    4632                 :        128 :         struct wpa_ssid *ssid = NULL;
    4633                 :            : 
    4634 [ +  - ][ -  + ]:        128 :         if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
    4635                 :          0 :                 return -1;
    4636                 :            : 
    4637         [ -  + ]:        128 :         if (persistent_id >= 0) {
    4638                 :          0 :                 ssid = wpa_config_get_network(wpa_s->conf, persistent_id);
    4639 [ #  # ][ #  # ]:          0 :                 if (ssid == NULL || ssid->disabled != 2 ||
                 [ #  # ]
    4640                 :          0 :                     ssid->mode != WPAS_MODE_P2P_GO)
    4641                 :          0 :                         return -1;
    4642                 :            :         }
    4643                 :            : 
    4644                 :        128 :         os_free(wpa_s->global->add_psk);
    4645                 :        128 :         wpa_s->global->add_psk = NULL;
    4646                 :            : 
    4647                 :        128 :         wpa_s->global->p2p_fail_on_wps_complete = 0;
    4648                 :            : 
    4649         [ +  + ]:        128 :         if (go_intent < 0)
    4650                 :         80 :                 go_intent = wpa_s->conf->p2p_go_intent;
    4651                 :            : 
    4652         [ +  + ]:        128 :         if (!auth)
    4653                 :         84 :                 wpa_s->p2p_long_listen = 0;
    4654                 :            : 
    4655                 :        128 :         wpa_s->p2p_wps_method = wps_method;
    4656                 :        128 :         wpa_s->p2p_persistent_group = !!persistent_group;
    4657                 :        128 :         wpa_s->p2p_persistent_id = persistent_id;
    4658                 :        128 :         wpa_s->p2p_go_intent = go_intent;
    4659                 :        128 :         wpa_s->p2p_connect_freq = freq;
    4660                 :        128 :         wpa_s->p2p_fallback_to_go_neg = 0;
    4661                 :        128 :         wpa_s->p2p_pd_before_go_neg = !!pd;
    4662                 :        128 :         wpa_s->p2p_go_ht40 = !!ht40;
    4663                 :        128 :         wpa_s->p2p_go_vht = !!vht;
    4664                 :            : 
    4665         [ +  + ]:        128 :         if (pin)
    4666                 :        110 :                 os_strlcpy(wpa_s->p2p_pin, pin, sizeof(wpa_s->p2p_pin));
    4667         [ -  + ]:         18 :         else if (wps_method == WPS_PIN_DISPLAY) {
    4668                 :          0 :                 ret = wps_generate_pin();
    4669                 :          0 :                 os_snprintf(wpa_s->p2p_pin, sizeof(wpa_s->p2p_pin), "%08d",
    4670                 :            :                             ret);
    4671                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Randomly generated PIN: %s",
    4672                 :          0 :                            wpa_s->p2p_pin);
    4673                 :            :         } else
    4674                 :         18 :                 wpa_s->p2p_pin[0] = '\0';
    4675                 :            : 
    4676 [ +  + ][ -  + ]:        128 :         if (join || auto_join) {
    4677                 :            :                 u8 iface_addr[ETH_ALEN], dev_addr[ETH_ALEN];
    4678         [ +  + ]:         26 :                 if (auth) {
    4679                 :          1 :                         wpa_printf(MSG_DEBUG, "P2P: Authorize invitation to "
    4680                 :            :                                    "connect a running group from " MACSTR,
    4681                 :          6 :                                    MAC2STR(peer_addr));
    4682                 :          1 :                         os_memcpy(wpa_s->p2p_auth_invite, peer_addr, ETH_ALEN);
    4683                 :          1 :                         return ret;
    4684                 :            :                 }
    4685                 :         25 :                 os_memcpy(dev_addr, peer_addr, ETH_ALEN);
    4686         [ +  + ]:         25 :                 if (p2p_get_interface_addr(wpa_s->global->p2p, peer_addr,
    4687                 :            :                                            iface_addr) < 0) {
    4688                 :         22 :                         os_memcpy(iface_addr, peer_addr, ETH_ALEN);
    4689                 :         22 :                         p2p_get_dev_addr(wpa_s->global->p2p, peer_addr,
    4690                 :            :                                          dev_addr);
    4691                 :            :                 }
    4692         [ -  + ]:         25 :                 if (auto_join) {
    4693                 :          0 :                         os_get_reltime(&wpa_s->p2p_auto_started);
    4694                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: Auto join started at "
    4695                 :            :                                    "%ld.%06ld",
    4696                 :            :                                    wpa_s->p2p_auto_started.sec,
    4697                 :            :                                    wpa_s->p2p_auto_started.usec);
    4698                 :            :                 }
    4699                 :         25 :                 wpa_s->user_initiated_pd = 1;
    4700         [ -  + ]:         25 :                 if (wpas_p2p_join(wpa_s, iface_addr, dev_addr, wps_method,
    4701                 :            :                                   auto_join, freq, NULL, 0) < 0)
    4702                 :          0 :                         return -1;
    4703                 :         25 :                 return ret;
    4704                 :            :         }
    4705                 :            : 
    4706                 :        102 :         res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq,
    4707                 :            :                                    go_intent == 15);
    4708         [ -  + ]:        102 :         if (res)
    4709                 :          0 :                 return res;
    4710         [ +  + ]:        102 :         wpas_p2p_set_own_freq_preference(wpa_s,
    4711                 :        102 :                                          force_freq ? force_freq : pref_freq);
    4712                 :            : 
    4713                 :        102 :         wpa_s->create_p2p_iface = wpas_p2p_create_iface(wpa_s);
    4714                 :            : 
    4715         [ +  + ]:        102 :         if (wpa_s->create_p2p_iface) {
    4716                 :            :                 /* Prepare to add a new interface for the group */
    4717                 :         18 :                 iftype = WPA_IF_P2P_GROUP;
    4718         [ +  + ]:         18 :                 if (go_intent == 15)
    4719                 :          7 :                         iftype = WPA_IF_P2P_GO;
    4720         [ -  + ]:         18 :                 if (wpas_p2p_add_group_interface(wpa_s, iftype) < 0) {
    4721                 :          0 :                         wpa_printf(MSG_ERROR, "P2P: Failed to allocate a new "
    4722                 :            :                                    "interface for the group");
    4723                 :          0 :                         return -1;
    4724                 :            :                 }
    4725                 :            : 
    4726                 :         18 :                 if_addr = wpa_s->pending_interface_addr;
    4727                 :            :         } else
    4728                 :         84 :                 if_addr = wpa_s->own_addr;
    4729                 :            : 
    4730         [ +  + ]:        102 :         if (auth) {
    4731         [ -  + ]:         43 :                 if (wpas_p2p_auth_go_neg(wpa_s, peer_addr, wps_method,
    4732                 :            :                                          go_intent, if_addr,
    4733                 :            :                                          force_freq, persistent_group, ssid,
    4734                 :            :                                          pref_freq) < 0)
    4735                 :          0 :                         return -1;
    4736                 :         43 :                 return ret;
    4737                 :            :         }
    4738                 :            : 
    4739         [ -  + ]:         59 :         if (wpas_p2p_start_go_neg(wpa_s, peer_addr, wps_method,
    4740                 :            :                                   go_intent, if_addr, force_freq,
    4741                 :            :                                   persistent_group, ssid, pref_freq) < 0) {
    4742         [ #  # ]:          0 :                 if (wpa_s->create_p2p_iface)
    4743                 :          0 :                         wpas_p2p_remove_pending_group_interface(wpa_s);
    4744                 :          0 :                 return -1;
    4745                 :            :         }
    4746                 :        128 :         return ret;
    4747                 :            : }
    4748                 :            : 
    4749                 :            : 
    4750                 :            : /**
    4751                 :            :  * wpas_p2p_remain_on_channel_cb - Indication of remain-on-channel start
    4752                 :            :  * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
    4753                 :            :  * @freq: Frequency of the channel in MHz
    4754                 :            :  * @duration: Duration of the stay on the channel in milliseconds
    4755                 :            :  *
    4756                 :            :  * This callback is called when the driver indicates that it has started the
    4757                 :            :  * requested remain-on-channel duration.
    4758                 :            :  */
    4759                 :        775 : void wpas_p2p_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
    4760                 :            :                                    unsigned int freq, unsigned int duration)
    4761                 :            : {
    4762 [ +  - ][ -  + ]:        775 :         if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
    4763                 :        775 :                 return;
    4764         [ +  + ]:        775 :         if (wpa_s->off_channel_freq == wpa_s->pending_listen_freq) {
    4765                 :        773 :                 p2p_listen_cb(wpa_s->global->p2p, wpa_s->pending_listen_freq,
    4766                 :            :                               wpa_s->pending_listen_duration);
    4767                 :        773 :                 wpa_s->pending_listen_freq = 0;
    4768                 :            :         } else {
    4769                 :          2 :                 wpa_printf(MSG_DEBUG, "P2P: Ignore remain-on-channel callback (off_channel_freq=%u pending_listen_freq=%d freq=%u duration=%u)",
    4770                 :            :                            wpa_s->off_channel_freq, wpa_s->pending_listen_freq,
    4771                 :            :                            freq, duration);
    4772                 :            :         }
    4773                 :            : }
    4774                 :            : 
    4775                 :            : 
    4776                 :        151 : static int wpas_p2p_listen_start(struct wpa_supplicant *wpa_s,
    4777                 :            :                                  unsigned int timeout)
    4778                 :            : {
    4779                 :            :         /* Limit maximum Listen state time based on driver limitation. */
    4780         [ +  - ]:        151 :         if (timeout > wpa_s->max_remain_on_chan)
    4781                 :        151 :                 timeout = wpa_s->max_remain_on_chan;
    4782                 :            : 
    4783                 :        151 :         return p2p_listen(wpa_s->global->p2p, timeout);
    4784                 :            : }
    4785                 :            : 
    4786                 :            : 
    4787                 :            : /**
    4788                 :            :  * wpas_p2p_cancel_remain_on_channel_cb - Remain-on-channel timeout
    4789                 :            :  * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
    4790                 :            :  * @freq: Frequency of the channel in MHz
    4791                 :            :  *
    4792                 :            :  * This callback is called when the driver indicates that a remain-on-channel
    4793                 :            :  * operation has been completed, i.e., the duration on the requested channel
    4794                 :            :  * has timed out.
    4795                 :            :  */
    4796                 :        769 : void wpas_p2p_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
    4797                 :            :                                           unsigned int freq)
    4798                 :            : {
    4799                 :        769 :         wpa_printf(MSG_DEBUG, "P2P: Cancel remain-on-channel callback "
    4800                 :            :                    "(p2p_long_listen=%d ms pending_action_tx=%p)",
    4801                 :            :                    wpa_s->p2p_long_listen, offchannel_pending_action_tx(wpa_s));
    4802                 :        769 :         wpas_p2p_listen_work_done(wpa_s);
    4803 [ +  - ][ -  + ]:        769 :         if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
    4804                 :          0 :                 return;
    4805         [ +  + ]:        769 :         if (p2p_listen_end(wpa_s->global->p2p, freq) > 0)
    4806                 :          7 :                 return; /* P2P module started a new operation */
    4807         [ +  + ]:        762 :         if (offchannel_pending_action_tx(wpa_s))
    4808                 :         26 :                 return;
    4809         [ +  + ]:        736 :         if (wpa_s->p2p_long_listen > 0)
    4810                 :         20 :                 wpa_s->p2p_long_listen -= wpa_s->max_remain_on_chan;
    4811         [ +  + ]:        736 :         if (wpa_s->p2p_long_listen > 0) {
    4812                 :         20 :                 wpa_printf(MSG_DEBUG, "P2P: Continuing long Listen state");
    4813                 :         20 :                 wpas_p2p_listen_start(wpa_s, wpa_s->p2p_long_listen);
    4814                 :            :         } else {
    4815                 :            :                 /*
    4816                 :            :                  * When listen duration is over, stop listen & update p2p_state
    4817                 :            :                  * to IDLE.
    4818                 :            :                  */
    4819                 :        769 :                 p2p_stop_listen(wpa_s->global->p2p);
    4820                 :            :         }
    4821                 :            : }
    4822                 :            : 
    4823                 :            : 
    4824                 :            : /**
    4825                 :            :  * wpas_p2p_group_remove - Remove a P2P group
    4826                 :            :  * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
    4827                 :            :  * @ifname: Network interface name of the group interface or "*" to remove all
    4828                 :            :  *      groups
    4829                 :            :  * Returns: 0 on success, -1 on failure
    4830                 :            :  *
    4831                 :            :  * This function is used to remove a P2P group. This can be used to disconnect
    4832                 :            :  * from a group in which the local end is a P2P Client or to end a P2P Group in
    4833                 :            :  * case the local end is the Group Owner. If a virtual network interface was
    4834                 :            :  * created for this group, that interface will be removed. Otherwise, only the
    4835                 :            :  * configured P2P group network will be removed from the interface.
    4836                 :            :  */
    4837                 :       1283 : int wpas_p2p_group_remove(struct wpa_supplicant *wpa_s, const char *ifname)
    4838                 :            : {
    4839                 :       1283 :         struct wpa_global *global = wpa_s->global;
    4840                 :            : 
    4841         [ +  + ]:       1283 :         if (os_strcmp(ifname, "*") == 0) {
    4842                 :            :                 struct wpa_supplicant *prev;
    4843                 :       1183 :                 wpa_s = global->ifaces;
    4844         [ +  + ]:       2366 :                 while (wpa_s) {
    4845                 :       1183 :                         prev = wpa_s;
    4846                 :       1183 :                         wpa_s = wpa_s->next;
    4847         [ +  - ]:       1183 :                         if (prev->p2p_group_interface !=
    4848         [ +  + ]:       1183 :                             NOT_P2P_GROUP_INTERFACE ||
    4849         [ +  + ]:        265 :                             (prev->current_ssid &&
    4850                 :        265 :                              prev->current_ssid->p2p_group))
    4851                 :         26 :                                 wpas_p2p_disconnect(prev);
    4852                 :            :                 }
    4853                 :       1183 :                 return 0;
    4854                 :            :         }
    4855                 :            : 
    4856         [ +  + ]:        103 :         for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
    4857         [ +  + ]:        100 :                 if (os_strcmp(wpa_s->ifname, ifname) == 0)
    4858                 :         97 :                         break;
    4859                 :            :         }
    4860                 :            : 
    4861                 :       1283 :         return wpas_p2p_disconnect(wpa_s);
    4862                 :            : }
    4863                 :            : 
    4864                 :            : 
    4865                 :         35 : static int wpas_p2p_select_go_freq(struct wpa_supplicant *wpa_s, int freq)
    4866                 :            : {
    4867                 :            :         unsigned int r;
    4868                 :            : 
    4869         [ -  + ]:         35 :         if (freq == 2) {
    4870                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Request to start GO on 2.4 GHz "
    4871                 :            :                            "band");
    4872   [ #  #  #  # ]:          0 :                 if (wpa_s->best_24_freq > 0 &&
    4873                 :          0 :                     p2p_supported_freq_go(wpa_s->global->p2p,
    4874                 :          0 :                                           wpa_s->best_24_freq)) {
    4875                 :          0 :                         freq = wpa_s->best_24_freq;
    4876                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: Use best 2.4 GHz band "
    4877                 :            :                                    "channel: %d MHz", freq);
    4878                 :            :                 } else {
    4879                 :          0 :                         os_get_random((u8 *) &r, sizeof(r));
    4880                 :          0 :                         freq = 2412 + (r % 3) * 25;
    4881                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: Use random 2.4 GHz band "
    4882                 :            :                                    "channel: %d MHz", freq);
    4883                 :            :                 }
    4884                 :            :         }
    4885                 :            : 
    4886         [ -  + ]:         35 :         if (freq == 5) {
    4887                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Request to start GO on 5 GHz "
    4888                 :            :                            "band");
    4889   [ #  #  #  # ]:          0 :                 if (wpa_s->best_5_freq > 0 &&
    4890                 :          0 :                     p2p_supported_freq_go(wpa_s->global->p2p,
    4891                 :          0 :                                        wpa_s->best_5_freq)) {
    4892                 :          0 :                         freq = wpa_s->best_5_freq;
    4893                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: Use best 5 GHz band "
    4894                 :            :                                    "channel: %d MHz", freq);
    4895                 :            :                 } else {
    4896                 :          0 :                         os_get_random((u8 *) &r, sizeof(r));
    4897                 :          0 :                         freq = 5180 + (r % 4) * 20;
    4898         [ #  # ]:          0 :                         if (!p2p_supported_freq_go(wpa_s->global->p2p, freq)) {
    4899                 :          0 :                                 wpa_printf(MSG_DEBUG, "P2P: Could not select "
    4900                 :            :                                            "5 GHz channel for P2P group");
    4901                 :          0 :                                 return -1;
    4902                 :            :                         }
    4903                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: Use random 5 GHz band "
    4904                 :            :                                    "channel: %d MHz", freq);
    4905                 :            :                 }
    4906                 :            :         }
    4907                 :            : 
    4908 [ +  + ][ -  + ]:         35 :         if (freq > 0 && !p2p_supported_freq_go(wpa_s->global->p2p, freq)) {
    4909                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: The forced channel for GO "
    4910                 :            :                            "(%u MHz) is not supported for P2P uses",
    4911                 :            :                            freq);
    4912                 :          0 :                 return -1;
    4913                 :            :         }
    4914                 :            : 
    4915                 :         35 :         return freq;
    4916                 :            : }
    4917                 :            : 
    4918                 :            : 
    4919                 :         35 : static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
    4920                 :            :                                    struct p2p_go_neg_results *params,
    4921                 :            :                                    int freq, int ht40, int vht,
    4922                 :            :                                    const struct p2p_channels *channels)
    4923                 :            : {
    4924                 :            :         int res, *freqs;
    4925                 :            :         unsigned int pref_freq;
    4926                 :            :         unsigned int num, i;
    4927                 :            : 
    4928                 :         35 :         os_memset(params, 0, sizeof(*params));
    4929                 :         35 :         params->role_go = 1;
    4930                 :         35 :         params->ht40 = ht40;
    4931                 :         35 :         params->vht = vht;
    4932         [ +  + ]:         35 :         if (freq) {
    4933         [ -  + ]:         16 :                 if (!freq_included(channels, freq)) {
    4934                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: Forced GO freq %d MHz not "
    4935                 :            :                                    "accepted", freq);
    4936                 :          0 :                         return -1;
    4937                 :            :                 }
    4938                 :         16 :                 wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on forced "
    4939                 :            :                            "frequency %d MHz", freq);
    4940                 :         16 :                 params->freq = freq;
    4941 [ -  + ][ #  # ]:         19 :         } else if (wpa_s->conf->p2p_oper_reg_class == 81 &&
    4942         [ #  # ]:          0 :                    wpa_s->conf->p2p_oper_channel >= 1 &&
    4943         [ #  # ]:          0 :                    wpa_s->conf->p2p_oper_channel <= 11 &&
    4944                 :          0 :                    freq_included(channels,
    4945                 :          0 :                                  2407 + 5 * wpa_s->conf->p2p_oper_channel)) {
    4946                 :          0 :                 params->freq = 2407 + 5 * wpa_s->conf->p2p_oper_channel;
    4947                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on configured "
    4948                 :            :                            "frequency %d MHz", params->freq);
    4949 [ +  - ][ +  - ]:         19 :         } else if ((wpa_s->conf->p2p_oper_reg_class == 115 ||
    4950         [ +  - ]:         19 :                     wpa_s->conf->p2p_oper_reg_class == 116 ||
    4951         [ +  - ]:         19 :                     wpa_s->conf->p2p_oper_reg_class == 117 ||
    4952         [ +  - ]:         19 :                     wpa_s->conf->p2p_oper_reg_class == 124 ||
    4953         [ -  + ]:         19 :                     wpa_s->conf->p2p_oper_reg_class == 126 ||
    4954         [ #  # ]:          0 :                     wpa_s->conf->p2p_oper_reg_class == 127) &&
    4955                 :          0 :                    freq_included(channels,
    4956                 :          0 :                                  5000 + 5 * wpa_s->conf->p2p_oper_channel)) {
    4957                 :          0 :                 params->freq = 5000 + 5 * wpa_s->conf->p2p_oper_channel;
    4958                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on configured "
    4959                 :            :                            "frequency %d MHz", params->freq);
    4960 [ +  - ][ -  + ]:         19 :         } else if (wpa_s->conf->p2p_oper_channel == 0 &&
    4961         [ #  # ]:          0 :                    wpa_s->best_overall_freq > 0 &&
    4962                 :          0 :                    p2p_supported_freq_go(wpa_s->global->p2p,
    4963         [ #  # ]:          0 :                                          wpa_s->best_overall_freq) &&
    4964                 :          0 :                    freq_included(channels, wpa_s->best_overall_freq)) {
    4965                 :          0 :                 params->freq = wpa_s->best_overall_freq;
    4966                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on best overall "
    4967                 :            :                            "channel %d MHz", params->freq);
    4968 [ +  - ][ -  + ]:         19 :         } else if (wpa_s->conf->p2p_oper_channel == 0 &&
    4969         [ #  # ]:          0 :                    wpa_s->best_24_freq > 0 &&
    4970                 :          0 :                    p2p_supported_freq_go(wpa_s->global->p2p,
    4971         [ #  # ]:          0 :                                          wpa_s->best_24_freq) &&
    4972                 :          0 :                    freq_included(channels, wpa_s->best_24_freq)) {
    4973                 :          0 :                 params->freq = wpa_s->best_24_freq;
    4974                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on best 2.4 GHz "
    4975                 :            :                            "channel %d MHz", params->freq);
    4976 [ +  - ][ -  + ]:         19 :         } else if (wpa_s->conf->p2p_oper_channel == 0 &&
    4977         [ #  # ]:          0 :                    wpa_s->best_5_freq > 0 &&
    4978                 :          0 :                    p2p_supported_freq_go(wpa_s->global->p2p,
    4979         [ #  # ]:          0 :                                          wpa_s->best_5_freq) &&
    4980                 :          0 :                    freq_included(channels, wpa_s->best_5_freq)) {
    4981                 :          0 :                 params->freq = wpa_s->best_5_freq;
    4982                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on best 5 GHz "
    4983                 :            :                            "channel %d MHz", params->freq);
    4984         [ -  + ]:         19 :         } else if ((pref_freq = p2p_get_pref_freq(wpa_s->global->p2p,
    4985                 :            :                                                   channels))) {
    4986                 :          0 :                 params->freq = pref_freq;
    4987                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Set GO freq %d MHz from preferred "
    4988                 :            :                            "channels", params->freq);
    4989                 :            :         } else {
    4990                 :            :                 int chan;
    4991         [ +  - ]:         19 :                 for (chan = 0; chan < 11; chan++) {
    4992                 :         19 :                         params->freq = 2412 + chan * 5;
    4993         [ +  - ]:         19 :                         if (!wpas_p2p_disallowed_freq(wpa_s->global,
    4994         [ +  - ]:         19 :                                                       params->freq) &&
    4995                 :         19 :                             freq_included(channels, params->freq))
    4996                 :         19 :                                 break;
    4997                 :            :                 }
    4998         [ -  + ]:         19 :                 if (chan == 11) {
    4999                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: No 2.4 GHz channel "
    5000                 :            :                                    "allowed");
    5001                 :          0 :                         return -1;
    5002                 :            :                 }
    5003                 :         19 :                 wpa_printf(MSG_DEBUG, "P2P: Set GO freq %d MHz (no preference "
    5004                 :            :                            "known)", params->freq);
    5005                 :            :         }
    5006                 :            : 
    5007                 :         35 :         freqs = os_calloc(wpa_s->num_multichan_concurrent, sizeof(int));
    5008         [ -  + ]:         35 :         if (!freqs)
    5009                 :          0 :                 return -1;
    5010                 :            : 
    5011                 :         35 :         res = wpas_p2p_valid_oper_freqs(wpa_s, freqs,
    5012                 :            :                                         wpa_s->num_multichan_concurrent);
    5013         [ -  + ]:         35 :         if (res < 0) {
    5014                 :          0 :                 os_free(freqs);
    5015                 :          0 :                 return -1;
    5016                 :            :         }
    5017                 :         35 :         num = res;
    5018                 :            : 
    5019         [ +  + ]:         35 :         for (i = 0; i < num; i++) {
    5020 [ -  + ][ #  # ]:          1 :                 if (freq && freqs[i] == freq)
    5021                 :          0 :                         break;
    5022 [ +  - ][ +  - ]:          1 :                 if (!freq && freq_included(channels, freqs[i])) {
    5023                 :          1 :                         wpa_printf(MSG_DEBUG, "P2P: Force GO on a channel we are already using (%u MHz)",
    5024                 :          1 :                                    freqs[i]);
    5025                 :          1 :                         params->freq = freqs[i];
    5026                 :          1 :                         break;
    5027                 :            :                 }
    5028                 :            :         }
    5029                 :            : 
    5030         [ +  + ]:         35 :         if (i == num) {
    5031         [ -  + ]:         34 :                 if (wpas_p2p_num_unused_channels(wpa_s) <= 0) {
    5032         [ #  # ]:          0 :                         if (freq)
    5033                 :          0 :                                 wpa_printf(MSG_DEBUG, "P2P: Cannot force GO on freq (%u MHz) as all the channels are in use", freq);
    5034                 :            :                         else
    5035                 :          0 :                                 wpa_printf(MSG_DEBUG, "P2P: Cannot force GO on any of the channels we are already using");
    5036                 :          0 :                         os_free(freqs);
    5037                 :          0 :                         return -1;
    5038         [ +  - ]:         34 :                 } else if (num == 0) {
    5039                 :         34 :                         wpa_printf(MSG_DEBUG, "P2P: Use one of the free channels");
    5040                 :            :                 } else {
    5041                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: Cannot force GO on any of the channels we are already using. Use one of the free channels");
    5042                 :            :                 }
    5043                 :            :         }
    5044                 :            : 
    5045                 :         35 :         os_free(freqs);
    5046                 :         35 :         return 0;
    5047                 :            : }
    5048                 :            : 
    5049                 :            : 
    5050                 :            : static struct wpa_supplicant *
    5051                 :         78 : wpas_p2p_get_group_iface(struct wpa_supplicant *wpa_s, int addr_allocated,
    5052                 :            :                          int go)
    5053                 :            : {
    5054                 :            :         struct wpa_supplicant *group_wpa_s;
    5055                 :            : 
    5056         [ +  + ]:         78 :         if (!wpas_p2p_create_iface(wpa_s)) {
    5057                 :         72 :                 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use same interface for group "
    5058                 :            :                         "operations");
    5059                 :         72 :                 wpa_s->p2p_first_connection_timeout = 0;
    5060                 :         72 :                 return wpa_s;
    5061                 :            :         }
    5062                 :            : 
    5063 [ +  + ][ -  + ]:          6 :         if (wpas_p2p_add_group_interface(wpa_s, go ? WPA_IF_P2P_GO :
    5064                 :            :                                          WPA_IF_P2P_CLIENT) < 0) {
    5065                 :          0 :                 wpa_msg_global(wpa_s, MSG_ERROR,
    5066                 :            :                                "P2P: Failed to add group interface");
    5067                 :          0 :                 return NULL;
    5068                 :            :         }
    5069                 :          6 :         group_wpa_s = wpas_p2p_init_group_interface(wpa_s, go);
    5070         [ -  + ]:          6 :         if (group_wpa_s == NULL) {
    5071                 :          0 :                 wpa_msg_global(wpa_s, MSG_ERROR,
    5072                 :            :                                "P2P: Failed to initialize group interface");
    5073                 :          0 :                 wpas_p2p_remove_pending_group_interface(wpa_s);
    5074                 :          0 :                 return NULL;
    5075                 :            :         }
    5076                 :            : 
    5077                 :          6 :         wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use separate group interface %s",
    5078                 :            :                 group_wpa_s->ifname);
    5079                 :          6 :         group_wpa_s->p2p_first_connection_timeout = 0;
    5080                 :         78 :         return group_wpa_s;
    5081                 :            : }
    5082                 :            : 
    5083                 :            : 
    5084                 :            : /**
    5085                 :            :  * wpas_p2p_group_add - Add a new P2P group with local end as Group Owner
    5086                 :            :  * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
    5087                 :            :  * @persistent_group: Whether to create a persistent group
    5088                 :            :  * @freq: Frequency for the group or 0 to indicate no hardcoding
    5089                 :            :  * @ht40: Start GO with 40 MHz channel width
    5090                 :            :  * @vht:  Start GO with VHT support
    5091                 :            :  * Returns: 0 on success, -1 on failure
    5092                 :            :  *
    5093                 :            :  * This function creates a new P2P group with the local end as the Group Owner,
    5094                 :            :  * i.e., without using Group Owner Negotiation.
    5095                 :            :  */
    5096                 :         27 : int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group,
    5097                 :            :                        int freq, int ht40, int vht)
    5098                 :            : {
    5099                 :            :         struct p2p_go_neg_results params;
    5100                 :            : 
    5101 [ +  - ][ -  + ]:         27 :         if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
    5102                 :          0 :                 return -1;
    5103                 :            : 
    5104                 :         27 :         os_free(wpa_s->global->add_psk);
    5105                 :         27 :         wpa_s->global->add_psk = NULL;
    5106                 :            : 
    5107                 :            :         /* Make sure we are not running find during connection establishment */
    5108                 :         27 :         wpa_printf(MSG_DEBUG, "P2P: Stop any on-going P2P FIND");
    5109                 :         27 :         wpas_p2p_stop_find_oper(wpa_s);
    5110                 :            : 
    5111                 :         27 :         freq = wpas_p2p_select_go_freq(wpa_s, freq);
    5112         [ -  + ]:         27 :         if (freq < 0)
    5113                 :          0 :                 return -1;
    5114                 :            : 
    5115         [ -  + ]:         27 :         if (wpas_p2p_init_go_params(wpa_s, &params, freq, ht40, vht, NULL))
    5116                 :          0 :                 return -1;
    5117   [ +  -  -  + ]:         54 :         if (params.freq &&
    5118                 :         27 :             !p2p_supported_freq_go(wpa_s->global->p2p, params.freq)) {
    5119                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: The selected channel for GO "
    5120                 :            :                            "(%u MHz) is not supported for P2P uses",
    5121                 :            :                            params.freq);
    5122                 :          0 :                 return -1;
    5123                 :            :         }
    5124                 :         27 :         p2p_go_params(wpa_s->global->p2p, &params);
    5125                 :         27 :         params.persistent_group = persistent_group;
    5126                 :            : 
    5127                 :         27 :         wpa_s = wpas_p2p_get_group_iface(wpa_s, 0, 1);
    5128         [ -  + ]:         27 :         if (wpa_s == NULL)
    5129                 :          0 :                 return -1;
    5130                 :         27 :         wpas_start_wps_go(wpa_s, &params, 0);
    5131                 :            : 
    5132                 :         27 :         return 0;
    5133                 :            : }
    5134                 :            : 
    5135                 :            : 
    5136                 :         11 : static int wpas_start_p2p_client(struct wpa_supplicant *wpa_s,
    5137                 :            :                                  struct wpa_ssid *params, int addr_allocated)
    5138                 :            : {
    5139                 :            :         struct wpa_ssid *ssid;
    5140                 :            : 
    5141                 :         11 :         wpa_s = wpas_p2p_get_group_iface(wpa_s, addr_allocated, 0);
    5142         [ -  + ]:         11 :         if (wpa_s == NULL)
    5143                 :          0 :                 return -1;
    5144                 :         11 :         wpa_s->p2p_last_4way_hs_fail = NULL;
    5145                 :            : 
    5146                 :         11 :         wpa_supplicant_ap_deinit(wpa_s);
    5147                 :            : 
    5148                 :         11 :         ssid = wpa_config_add_network(wpa_s->conf);
    5149         [ -  + ]:         11 :         if (ssid == NULL)
    5150                 :          0 :                 return -1;
    5151                 :         11 :         wpa_config_set_network_defaults(ssid);
    5152                 :         11 :         ssid->temporary = 1;
    5153                 :         11 :         ssid->proto = WPA_PROTO_RSN;
    5154                 :         11 :         ssid->pairwise_cipher = WPA_CIPHER_CCMP;
    5155                 :         11 :         ssid->group_cipher = WPA_CIPHER_CCMP;
    5156                 :         11 :         ssid->key_mgmt = WPA_KEY_MGMT_PSK;
    5157                 :         11 :         ssid->ssid = os_malloc(params->ssid_len);
    5158         [ -  + ]:         11 :         if (ssid->ssid == NULL) {
    5159                 :          0 :                 wpa_config_remove_network(wpa_s->conf, ssid->id);
    5160                 :          0 :                 return -1;
    5161                 :            :         }
    5162                 :         11 :         os_memcpy(ssid->ssid, params->ssid, params->ssid_len);
    5163                 :         11 :         ssid->ssid_len = params->ssid_len;
    5164                 :         11 :         ssid->p2p_group = 1;
    5165                 :         11 :         ssid->export_keys = 1;
    5166         [ +  - ]:         11 :         if (params->psk_set) {
    5167                 :         11 :                 os_memcpy(ssid->psk, params->psk, 32);
    5168                 :         11 :                 ssid->psk_set = 1;
    5169                 :            :         }
    5170         [ -  + ]:         11 :         if (params->passphrase)
    5171                 :          0 :                 ssid->passphrase = os_strdup(params->passphrase);
    5172                 :            : 
    5173                 :         11 :         wpa_s->show_group_started = 1;
    5174                 :            : 
    5175                 :         11 :         wpa_supplicant_select_network(wpa_s, ssid);
    5176                 :            : 
    5177                 :         11 :         return 0;
    5178                 :            : }
    5179                 :            : 
    5180                 :            : 
    5181                 :         19 : int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
    5182                 :            :                                   struct wpa_ssid *ssid, int addr_allocated,
    5183                 :            :                                   int force_freq, int neg_freq, int ht40,
    5184                 :            :                                   int vht, const struct p2p_channels *channels,
    5185                 :            :                                   int connection_timeout)
    5186                 :            : {
    5187                 :            :         struct p2p_go_neg_results params;
    5188                 :         19 :         int go = 0, freq;
    5189                 :            : 
    5190 [ +  - ][ -  + ]:         19 :         if (ssid->disabled != 2 || ssid->ssid == NULL)
    5191                 :          0 :                 return -1;
    5192                 :            : 
    5193 [ -  + ][ #  # ]:         19 :         if (wpas_get_p2p_group(wpa_s, ssid->ssid, ssid->ssid_len, &go) &&
    5194                 :          0 :             go == (ssid->mode == WPAS_MODE_P2P_GO)) {
    5195                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Requested persistent group is "
    5196                 :            :                            "already running");
    5197                 :          0 :                 return 0;
    5198                 :            :         }
    5199                 :            : 
    5200                 :         19 :         os_free(wpa_s->global->add_psk);
    5201                 :         19 :         wpa_s->global->add_psk = NULL;
    5202                 :            : 
    5203                 :            :         /* Make sure we are not running find during connection establishment */
    5204                 :         19 :         wpas_p2p_stop_find_oper(wpa_s);
    5205                 :            : 
    5206                 :         19 :         wpa_s->p2p_fallback_to_go_neg = 0;
    5207                 :            : 
    5208         [ +  + ]:         19 :         if (ssid->mode == WPAS_MODE_INFRA)
    5209                 :         11 :                 return wpas_start_p2p_client(wpa_s, ssid, addr_allocated);
    5210                 :            : 
    5211         [ -  + ]:          8 :         if (ssid->mode != WPAS_MODE_P2P_GO)
    5212                 :          0 :                 return -1;
    5213                 :            : 
    5214         [ +  + ]:          8 :         if (force_freq > 0) {
    5215                 :          1 :                 freq = wpas_p2p_select_go_freq(wpa_s, force_freq);
    5216         [ -  + ]:          1 :                 if (freq < 0)
    5217                 :          0 :                         return -1;
    5218                 :            :         } else {
    5219                 :          7 :                 freq = wpas_p2p_select_go_freq(wpa_s, neg_freq);
    5220 [ +  - ][ +  + ]:          7 :                 if (freq < 0 || (freq > 0 && !freq_included(channels, freq)))
                 [ -  + ]
    5221                 :          0 :                         freq = 0;
    5222                 :            :         }
    5223                 :            : 
    5224         [ -  + ]:          8 :         if (wpas_p2p_init_go_params(wpa_s, &params, freq, ht40, vht, channels))
    5225                 :          0 :                 return -1;
    5226                 :            : 
    5227                 :          8 :         params.role_go = 1;
    5228                 :          8 :         params.psk_set = ssid->psk_set;
    5229         [ +  - ]:          8 :         if (params.psk_set)
    5230                 :          8 :                 os_memcpy(params.psk, ssid->psk, sizeof(params.psk));
    5231         [ +  - ]:          8 :         if (ssid->passphrase) {
    5232         [ -  + ]:          8 :                 if (os_strlen(ssid->passphrase) >= sizeof(params.passphrase)) {
    5233                 :          0 :                         wpa_printf(MSG_ERROR, "P2P: Invalid passphrase in "
    5234                 :            :                                    "persistent group");
    5235                 :          0 :                         return -1;
    5236                 :            :                 }
    5237                 :          8 :                 os_strlcpy(params.passphrase, ssid->passphrase,
    5238                 :            :                            sizeof(params.passphrase));
    5239                 :            :         }
    5240                 :          8 :         os_memcpy(params.ssid, ssid->ssid, ssid->ssid_len);
    5241                 :          8 :         params.ssid_len = ssid->ssid_len;
    5242                 :          8 :         params.persistent_group = 1;
    5243                 :            : 
    5244                 :          8 :         wpa_s = wpas_p2p_get_group_iface(wpa_s, addr_allocated, 1);
    5245         [ -  + ]:          8 :         if (wpa_s == NULL)
    5246                 :          0 :                 return -1;
    5247                 :            : 
    5248                 :          8 :         wpa_s->p2p_first_connection_timeout = connection_timeout;
    5249                 :          8 :         wpas_start_wps_go(wpa_s, &params, 0);
    5250                 :            : 
    5251                 :         19 :         return 0;
    5252                 :            : }
    5253                 :            : 
    5254                 :            : 
    5255                 :        488 : static void wpas_p2p_ie_update(void *ctx, struct wpabuf *beacon_ies,
    5256                 :            :                                struct wpabuf *proberesp_ies)
    5257                 :            : {
    5258                 :        488 :         struct wpa_supplicant *wpa_s = ctx;
    5259         [ +  - ]:        488 :         if (wpa_s->ap_iface) {
    5260                 :        488 :                 struct hostapd_data *hapd = wpa_s->ap_iface->bss[0];
    5261         [ +  + ]:        488 :                 if (!(hapd->conf->p2p & P2P_GROUP_OWNER)) {
    5262                 :         42 :                         wpabuf_free(beacon_ies);
    5263                 :         42 :                         wpabuf_free(proberesp_ies);
    5264                 :        488 :                         return;
    5265                 :            :                 }
    5266         [ +  + ]:        446 :                 if (beacon_ies) {
    5267                 :        159 :                         wpabuf_free(hapd->p2p_beacon_ie);
    5268                 :        159 :                         hapd->p2p_beacon_ie = beacon_ies;
    5269                 :            :                 }
    5270                 :        446 :                 wpabuf_free(hapd->p2p_probe_resp_ie);
    5271                 :        446 :                 hapd->p2p_probe_resp_ie = proberesp_ies;
    5272                 :            :         } else {
    5273                 :          0 :                 wpabuf_free(beacon_ies);
    5274                 :          0 :                 wpabuf_free(proberesp_ies);
    5275                 :            :         }
    5276                 :        446 :         wpa_supplicant_ap_update_beacon(wpa_s);
    5277                 :            : }
    5278                 :            : 
    5279                 :            : 
    5280                 :        346 : static void wpas_p2p_idle_update(void *ctx, int idle)
    5281                 :            : {
    5282                 :        346 :         struct wpa_supplicant *wpa_s = ctx;
    5283         [ -  + ]:        346 :         if (!wpa_s->ap_iface)
    5284                 :          0 :                 return;
    5285         [ +  + ]:        346 :         wpa_printf(MSG_DEBUG, "P2P: GO - group %sidle", idle ? "" : "not ");
    5286         [ +  + ]:        346 :         if (idle) {
    5287 [ +  + ][ +  - ]:        187 :                 if (wpa_s->global->p2p_fail_on_wps_complete &&
    5288                 :          1 :                     wpa_s->p2p_in_provisioning) {
    5289                 :          1 :                         wpas_p2p_grpform_fail_after_wps(wpa_s);
    5290                 :          1 :                         return;
    5291                 :            :                 }
    5292                 :        186 :                 wpas_p2p_set_group_idle_timeout(wpa_s);
    5293                 :            :         } else
    5294                 :        346 :                 eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL);
    5295                 :            : }
    5296                 :            : 
    5297                 :            : 
    5298                 :         86 : struct p2p_group * wpas_p2p_group_init(struct wpa_supplicant *wpa_s,
    5299                 :            :                                        struct wpa_ssid *ssid)
    5300                 :            : {
    5301                 :            :         struct p2p_group *group;
    5302                 :            :         struct p2p_group_config *cfg;
    5303                 :            : 
    5304 [ +  - ][ -  + ]:         86 :         if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
    5305                 :          0 :                 return NULL;
    5306                 :            : 
    5307                 :         86 :         cfg = os_zalloc(sizeof(*cfg));
    5308         [ -  + ]:         86 :         if (cfg == NULL)
    5309                 :          0 :                 return NULL;
    5310                 :            : 
    5311 [ +  + ][ +  + ]:         86 :         if (ssid->p2p_persistent_group && wpa_s->conf->persistent_reconnect)
    5312                 :         12 :                 cfg->persistent_group = 2;
    5313         [ +  + ]:         74 :         else if (ssid->p2p_persistent_group)
    5314                 :          2 :                 cfg->persistent_group = 1;
    5315                 :         86 :         os_memcpy(cfg->interface_addr, wpa_s->own_addr, ETH_ALEN);
    5316 [ -  + ][ #  # ]:         86 :         if (wpa_s->max_stations &&
    5317                 :          0 :             wpa_s->max_stations < wpa_s->conf->max_num_sta)
    5318                 :          0 :                 cfg->max_clients = wpa_s->max_stations;
    5319                 :            :         else
    5320                 :         86 :                 cfg->max_clients = wpa_s->conf->max_num_sta;
    5321                 :         86 :         os_memcpy(cfg->ssid, ssid->ssid, ssid->ssid_len);
    5322                 :         86 :         cfg->ssid_len = ssid->ssid_len;
    5323                 :         86 :         cfg->freq = ssid->frequency;
    5324                 :         86 :         cfg->cb_ctx = wpa_s;
    5325                 :         86 :         cfg->ie_update = wpas_p2p_ie_update;
    5326                 :         86 :         cfg->idle_update = wpas_p2p_idle_update;
    5327                 :            : 
    5328                 :         86 :         group = p2p_group_init(wpa_s->global->p2p, cfg);
    5329         [ -  + ]:         86 :         if (group == NULL)
    5330                 :          0 :                 os_free(cfg);
    5331         [ +  + ]:         86 :         if (ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION)
    5332                 :         41 :                 p2p_group_notif_formation_done(group);
    5333                 :         86 :         wpa_s->p2p_group = group;
    5334                 :         86 :         return group;
    5335                 :            : }
    5336                 :            : 
    5337                 :            : 
    5338                 :        198 : void wpas_p2p_wps_success(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
    5339                 :            :                           int registrar)
    5340                 :            : {
    5341                 :        198 :         struct wpa_ssid *ssid = wpa_s->current_ssid;
    5342                 :            : 
    5343         [ +  + ]:        198 :         if (!wpa_s->p2p_in_provisioning) {
    5344                 :         78 :                 wpa_printf(MSG_DEBUG, "P2P: Ignore WPS success event - P2P "
    5345                 :            :                            "provisioning not in progress");
    5346                 :        198 :                 return;
    5347                 :            :         }
    5348                 :            : 
    5349 [ +  - ][ +  + ]:        120 :         if (ssid && ssid->mode == WPAS_MODE_INFRA) {
    5350                 :            :                 u8 go_dev_addr[ETH_ALEN];
    5351                 :         76 :                 os_memcpy(go_dev_addr, wpa_s->bssid, ETH_ALEN);
    5352                 :         76 :                 wpas_p2p_persistent_group(wpa_s, go_dev_addr, ssid->ssid,
    5353                 :            :                                           ssid->ssid_len);
    5354                 :            :                 /* Clear any stored provisioning info */
    5355                 :         76 :                 p2p_clear_provisioning_info(wpa_s->global->p2p, go_dev_addr);
    5356                 :            :         }
    5357                 :            : 
    5358                 :        120 :         eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s->parent,
    5359                 :            :                              NULL);
    5360                 :        120 :         wpa_s->p2p_go_group_formation_completed = 1;
    5361 [ +  - ][ +  + ]:        120 :         if (ssid && ssid->mode == WPAS_MODE_INFRA) {
    5362                 :            :                 /*
    5363                 :            :                  * Use a separate timeout for initial data connection to
    5364                 :            :                  * complete to allow the group to be removed automatically if
    5365                 :            :                  * something goes wrong in this step before the P2P group idle
    5366                 :            :                  * timeout mechanism is taken into use.
    5367                 :            :                  */
    5368                 :         76 :                 wpa_dbg(wpa_s, MSG_DEBUG,
    5369                 :            :                         "P2P: Re-start group formation timeout (%d seconds) as client for initial connection",
    5370                 :            :                         P2P_MAX_INITIAL_CONN_WAIT);
    5371                 :         76 :                 eloop_register_timeout(P2P_MAX_INITIAL_CONN_WAIT, 0,
    5372                 :            :                                        wpas_p2p_group_formation_timeout,
    5373                 :         76 :                                        wpa_s->parent, NULL);
    5374         [ +  - ]:         44 :         } else if (ssid) {
    5375                 :            :                 /*
    5376                 :            :                  * Use a separate timeout for initial data connection to
    5377                 :            :                  * complete to allow the group to be removed automatically if
    5378                 :            :                  * the client does not complete data connection successfully.
    5379                 :            :                  */
    5380                 :         44 :                 wpa_dbg(wpa_s, MSG_DEBUG,
    5381                 :            :                         "P2P: Re-start group formation timeout (%d seconds) as GO for initial connection",
    5382                 :            :                         P2P_MAX_INITIAL_CONN_WAIT_GO);
    5383                 :         44 :                 eloop_register_timeout(P2P_MAX_INITIAL_CONN_WAIT_GO, 0,
    5384                 :            :                                        wpas_p2p_group_formation_timeout,
    5385                 :         44 :                                        wpa_s->parent, NULL);
    5386                 :            :                 /*
    5387                 :            :                  * Complete group formation on first successful data connection
    5388                 :            :                  */
    5389                 :         44 :                 wpa_s->p2p_go_group_formation_completed = 0;
    5390                 :            :         }
    5391         [ +  - ]:        120 :         if (wpa_s->global->p2p)
    5392                 :        120 :                 p2p_wps_success_cb(wpa_s->global->p2p, peer_addr);
    5393                 :        120 :         wpas_group_formation_completed(wpa_s, 1);
    5394                 :            : }
    5395                 :            : 
    5396                 :            : 
    5397                 :         34 : void wpas_p2p_wps_failed(struct wpa_supplicant *wpa_s,
    5398                 :            :                          struct wps_event_fail *fail)
    5399                 :            : {
    5400         [ +  + ]:         34 :         if (!wpa_s->p2p_in_provisioning) {
    5401                 :         32 :                 wpa_printf(MSG_DEBUG, "P2P: Ignore WPS fail event - P2P "
    5402                 :            :                            "provisioning not in progress");
    5403                 :         34 :                 return;
    5404                 :            :         }
    5405                 :            : 
    5406         [ +  + ]:          2 :         if (wpa_s->go_params) {
    5407                 :          1 :                 p2p_clear_provisioning_info(
    5408                 :          1 :                         wpa_s->global->p2p,
    5409                 :          1 :                         wpa_s->go_params->peer_device_addr);
    5410                 :            :         }
    5411                 :            : 
    5412                 :          2 :         wpas_notify_p2p_wps_failed(wpa_s, fail);
    5413                 :            : 
    5414         [ +  - ]:          2 :         if (wpa_s == wpa_s->global->p2p_group_formation) {
    5415                 :            :                 /*
    5416                 :            :                  * Allow some time for the failed WPS negotiation exchange to
    5417                 :            :                  * complete, but remove the group since group formation cannot
    5418                 :            :                  * succeed after provisioning failure.
    5419                 :            :                  */
    5420                 :          2 :                 wpa_printf(MSG_DEBUG, "P2P: WPS step failed during group formation - reject connection from timeout");
    5421                 :          2 :                 wpa_s->global->p2p_fail_on_wps_complete = 1;
    5422                 :          2 :                 eloop_deplete_timeout(0, 50000,
    5423                 :            :                                       wpas_p2p_group_formation_timeout,
    5424                 :          2 :                                       wpa_s->parent, NULL);
    5425                 :            :         }
    5426                 :            : }
    5427                 :            : 
    5428                 :            : 
    5429                 :        590 : int wpas_p2p_wps_eapol_cb(struct wpa_supplicant *wpa_s)
    5430                 :            : {
    5431 [ +  + ][ -  + ]:        590 :         if (!wpa_s->global->p2p_fail_on_wps_complete ||
    5432                 :          1 :             !wpa_s->p2p_in_provisioning)
    5433                 :        589 :                 return 0;
    5434                 :            : 
    5435                 :          1 :         wpas_p2p_grpform_fail_after_wps(wpa_s);
    5436                 :            : 
    5437                 :        590 :         return 1;
    5438                 :            : }
    5439                 :            : 
    5440                 :            : 
    5441                 :          8 : int wpas_p2p_prov_disc(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
    5442                 :            :                        const char *config_method,
    5443                 :            :                        enum wpas_p2p_prov_disc_use use)
    5444                 :            : {
    5445                 :            :         u16 config_methods;
    5446                 :            : 
    5447                 :          8 :         wpa_s->p2p_fallback_to_go_neg = 0;
    5448                 :          8 :         wpa_s->pending_pd_use = NORMAL_PD;
    5449         [ +  + ]:          8 :         if (os_strncmp(config_method, "display", 7) == 0)
    5450                 :          6 :                 config_methods = WPS_CONFIG_DISPLAY;
    5451         [ +  + ]:          2 :         else if (os_strncmp(config_method, "keypad", 6) == 0)
    5452                 :          1 :                 config_methods = WPS_CONFIG_KEYPAD;
    5453 [ -  + ][ #  # ]:          1 :         else if (os_strncmp(config_method, "pbc", 3) == 0 ||
    5454                 :          0 :                  os_strncmp(config_method, "pushbutton", 10) == 0)
    5455                 :          1 :                 config_methods = WPS_CONFIG_PUSHBUTTON;
    5456                 :            :         else {
    5457                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Unknown config method");
    5458                 :          0 :                 return -1;
    5459                 :            :         }
    5460                 :            : 
    5461         [ -  + ]:          8 :         if (use == WPAS_P2P_PD_AUTO) {
    5462                 :          0 :                 os_memcpy(wpa_s->pending_join_dev_addr, peer_addr, ETH_ALEN);
    5463                 :          0 :                 wpa_s->pending_pd_config_methods = config_methods;
    5464                 :          0 :                 wpa_s->p2p_auto_pd = 1;
    5465                 :          0 :                 wpa_s->p2p_auto_join = 0;
    5466                 :          0 :                 wpa_s->pending_pd_before_join = 0;
    5467                 :          0 :                 wpa_s->auto_pd_scan_retry = 0;
    5468                 :          0 :                 wpas_p2p_stop_find(wpa_s);
    5469                 :          0 :                 wpa_s->p2p_join_scan_count = 0;
    5470                 :          0 :                 os_get_reltime(&wpa_s->p2p_auto_started);
    5471                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Auto PD started at %ld.%06ld",
    5472                 :            :                            wpa_s->p2p_auto_started.sec,
    5473                 :            :                            wpa_s->p2p_auto_started.usec);
    5474                 :          0 :                 wpas_p2p_join_scan(wpa_s, NULL);
    5475                 :          0 :                 return 0;
    5476                 :            :         }
    5477                 :            : 
    5478 [ +  - ][ -  + ]:          8 :         if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled)
    5479                 :          0 :                 return -1;
    5480                 :            : 
    5481                 :          8 :         return p2p_prov_disc_req(wpa_s->global->p2p, peer_addr,
    5482                 :            :                                  config_methods, use == WPAS_P2P_PD_FOR_JOIN,
    5483                 :            :                                  0, 1);
    5484                 :            : }
    5485                 :            : 
    5486                 :            : 
    5487                 :         34 : int wpas_p2p_scan_result_text(const u8 *ies, size_t ies_len, char *buf,
    5488                 :            :                               char *end)
    5489                 :            : {
    5490                 :         34 :         return p2p_scan_result_text(ies, ies_len, buf, end);
    5491                 :            : }
    5492                 :            : 
    5493                 :            : 
    5494                 :       1553 : static void wpas_p2p_clear_pending_action_tx(struct wpa_supplicant *wpa_s)
    5495                 :            : {
    5496         [ +  - ]:       1553 :         if (!offchannel_pending_action_tx(wpa_s))
    5497                 :       1553 :                 return;
    5498                 :            : 
    5499                 :          0 :         wpa_printf(MSG_DEBUG, "P2P: Drop pending Action TX due to new "
    5500                 :            :                    "operation request");
    5501                 :          0 :         offchannel_clear_pending_action_tx(wpa_s);
    5502                 :            : }
    5503                 :            : 
    5504                 :            : 
    5505                 :        151 : int wpas_p2p_find(struct wpa_supplicant *wpa_s, unsigned int timeout,
    5506                 :            :                   enum p2p_discovery_type type,
    5507                 :            :                   unsigned int num_req_dev_types, const u8 *req_dev_types,
    5508                 :            :                   const u8 *dev_id, unsigned int search_delay)
    5509                 :            : {
    5510                 :        151 :         wpas_p2p_clear_pending_action_tx(wpa_s);
    5511                 :        151 :         wpa_s->p2p_long_listen = 0;
    5512                 :            : 
    5513 [ +  - ][ +  - ]:        151 :         if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL ||
                 [ -  + ]
    5514                 :        151 :             wpa_s->p2p_in_provisioning)
    5515                 :          0 :                 return -1;
    5516                 :            : 
    5517                 :        151 :         wpa_supplicant_cancel_sched_scan(wpa_s);
    5518                 :            : 
    5519                 :        151 :         return p2p_find(wpa_s->global->p2p, timeout, type,
    5520                 :            :                         num_req_dev_types, req_dev_types, dev_id,
    5521                 :            :                         search_delay);
    5522                 :            : }
    5523                 :            : 
    5524                 :            : 
    5525                 :       1271 : static int wpas_p2p_stop_find_oper(struct wpa_supplicant *wpa_s)
    5526                 :            : {
    5527                 :       1271 :         wpas_p2p_clear_pending_action_tx(wpa_s);
    5528                 :       1271 :         wpa_s->p2p_long_listen = 0;
    5529                 :       1271 :         eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL);
    5530                 :       1271 :         eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
    5531                 :            : 
    5532         [ +  - ]:       1271 :         if (wpa_s->global->p2p)
    5533                 :       1271 :                 p2p_stop_find(wpa_s->global->p2p);
    5534                 :            : 
    5535                 :       1271 :         return 0;
    5536                 :            : }
    5537                 :            : 
    5538                 :            : 
    5539                 :       1225 : void wpas_p2p_stop_find(struct wpa_supplicant *wpa_s)
    5540                 :            : {
    5541         [ -  + ]:       1225 :         if (wpas_p2p_stop_find_oper(wpa_s) > 0)
    5542                 :       1225 :                 return;
    5543                 :       1225 :         wpas_p2p_remove_pending_group_interface(wpa_s);
    5544                 :            : }
    5545                 :            : 
    5546                 :            : 
    5547                 :          0 : static void wpas_p2p_long_listen_timeout(void *eloop_ctx, void *timeout_ctx)
    5548                 :            : {
    5549                 :          0 :         struct wpa_supplicant *wpa_s = eloop_ctx;
    5550                 :          0 :         wpa_s->p2p_long_listen = 0;
    5551                 :          0 : }
    5552                 :            : 
    5553                 :            : 
    5554                 :        131 : int wpas_p2p_listen(struct wpa_supplicant *wpa_s, unsigned int timeout)
    5555                 :            : {
    5556                 :            :         int res;
    5557                 :            : 
    5558 [ +  - ][ -  + ]:        131 :         if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
    5559                 :          0 :                 return -1;
    5560                 :            : 
    5561                 :        131 :         wpa_supplicant_cancel_sched_scan(wpa_s);
    5562                 :        131 :         wpas_p2p_clear_pending_action_tx(wpa_s);
    5563                 :            : 
    5564         [ +  + ]:        131 :         if (timeout == 0) {
    5565                 :            :                 /*
    5566                 :            :                  * This is a request for unlimited Listen state. However, at
    5567                 :            :                  * least for now, this is mapped to a Listen state for one
    5568                 :            :                  * hour.
    5569                 :            :                  */
    5570                 :        127 :                 timeout = 3600;
    5571                 :            :         }
    5572                 :        131 :         eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL);
    5573                 :        131 :         wpa_s->p2p_long_listen = 0;
    5574                 :            : 
    5575                 :            :         /*
    5576                 :            :          * Stop previous find/listen operation to avoid trying to request a new
    5577                 :            :          * remain-on-channel operation while the driver is still running the
    5578                 :            :          * previous one.
    5579                 :            :          */
    5580         [ +  - ]:        131 :         if (wpa_s->global->p2p)
    5581                 :        131 :                 p2p_stop_find(wpa_s->global->p2p);
    5582                 :            : 
    5583                 :        131 :         res = wpas_p2p_listen_start(wpa_s, timeout * 1000);
    5584 [ +  - ][ +  - ]:        131 :         if (res == 0 && timeout * 1000 > wpa_s->max_remain_on_chan) {
    5585                 :        131 :                 wpa_s->p2p_long_listen = timeout * 1000;
    5586                 :        131 :                 eloop_register_timeout(timeout, 0,
    5587                 :            :                                        wpas_p2p_long_listen_timeout,
    5588                 :            :                                        wpa_s, NULL);
    5589                 :            :         }
    5590                 :            : 
    5591                 :        131 :         return res;
    5592                 :            : }
    5593                 :            : 
    5594                 :            : 
    5595                 :        701 : int wpas_p2p_assoc_req_ie(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
    5596                 :            :                           u8 *buf, size_t len, int p2p_group)
    5597                 :            : {
    5598                 :            :         struct wpabuf *p2p_ie;
    5599                 :            :         int ret;
    5600                 :            : 
    5601         [ +  + ]:        701 :         if (wpa_s->global->p2p_disabled)
    5602                 :          3 :                 return -1;
    5603         [ -  + ]:        698 :         if (wpa_s->global->p2p == NULL)
    5604                 :          0 :                 return -1;
    5605         [ +  + ]:        698 :         if (bss == NULL)
    5606                 :          5 :                 return -1;
    5607                 :            : 
    5608                 :        693 :         p2p_ie = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
    5609                 :        693 :         ret = p2p_assoc_req_ie(wpa_s->global->p2p, bss->bssid, buf, len,
    5610                 :            :                                p2p_group, p2p_ie);
    5611                 :        693 :         wpabuf_free(p2p_ie);
    5612                 :            : 
    5613                 :        701 :         return ret;
    5614                 :            : }
    5615                 :            : 
    5616                 :            : 
    5617                 :        542 : int wpas_p2p_probe_req_rx(struct wpa_supplicant *wpa_s, const u8 *addr,
    5618                 :            :                           const u8 *dst, const u8 *bssid,
    5619                 :            :                           const u8 *ie, size_t ie_len, int ssi_signal)
    5620                 :            : {
    5621         [ -  + ]:        542 :         if (wpa_s->global->p2p_disabled)
    5622                 :          0 :                 return 0;
    5623         [ -  + ]:        542 :         if (wpa_s->global->p2p == NULL)
    5624                 :          0 :                 return 0;
    5625                 :            : 
    5626      [ -  +  + ]:        542 :         switch (p2p_probe_req_rx(wpa_s->global->p2p, addr, dst, bssid,
    5627                 :            :                                  ie, ie_len)) {
    5628                 :            :         case P2P_PREQ_NOT_P2P:
    5629                 :          0 :                 wpas_notify_preq(wpa_s, addr, dst, bssid, ie, ie_len,
    5630                 :            :                                  ssi_signal);
    5631                 :            :                 /* fall through */
    5632                 :            :         case P2P_PREQ_MALFORMED:
    5633                 :            :         case P2P_PREQ_NOT_LISTEN:
    5634                 :            :         case P2P_PREQ_NOT_PROCESSED:
    5635                 :            :         default: /* make gcc happy */
    5636                 :        526 :                 return 0;
    5637                 :            :         case P2P_PREQ_PROCESSED:
    5638                 :        542 :                 return 1;
    5639                 :            :         }
    5640                 :            : }
    5641                 :            : 
    5642                 :            : 
    5643                 :        389 : void wpas_p2p_rx_action(struct wpa_supplicant *wpa_s, const u8 *da,
    5644                 :            :                         const u8 *sa, const u8 *bssid,
    5645                 :            :                         u8 category, const u8 *data, size_t len, int freq)
    5646                 :            : {
    5647         [ -  + ]:        389 :         if (wpa_s->global->p2p_disabled)
    5648                 :          0 :                 return;
    5649         [ -  + ]:        389 :         if (wpa_s->global->p2p == NULL)
    5650                 :          0 :                 return;
    5651                 :            : 
    5652                 :        389 :         p2p_rx_action(wpa_s->global->p2p, da, sa, bssid, category, data, len,
    5653                 :            :                       freq);
    5654                 :            : }
    5655                 :            : 
    5656                 :            : 
    5657                 :        694 : void wpas_p2p_scan_ie(struct wpa_supplicant *wpa_s, struct wpabuf *ies)
    5658                 :            : {
    5659         [ +  + ]:        694 :         if (wpa_s->global->p2p_disabled)
    5660                 :          1 :                 return;
    5661         [ -  + ]:        693 :         if (wpa_s->global->p2p == NULL)
    5662                 :          0 :                 return;
    5663                 :            : 
    5664                 :        694 :         p2p_scan_ie(wpa_s->global->p2p, ies, NULL);
    5665                 :            : }
    5666                 :            : 
    5667                 :            : 
    5668                 :         86 : void wpas_p2p_group_deinit(struct wpa_supplicant *wpa_s)
    5669                 :            : {
    5670                 :         86 :         p2p_group_deinit(wpa_s->p2p_group);
    5671                 :         86 :         wpa_s->p2p_group = NULL;
    5672                 :            : 
    5673                 :         86 :         wpa_s->ap_configured_cb = NULL;
    5674                 :         86 :         wpa_s->ap_configured_cb_ctx = NULL;
    5675                 :         86 :         wpa_s->ap_configured_cb_data = NULL;
    5676                 :         86 :         wpa_s->connect_without_scan = NULL;
    5677                 :         86 : }
    5678                 :            : 
    5679                 :            : 
    5680                 :          1 : int wpas_p2p_reject(struct wpa_supplicant *wpa_s, const u8 *addr)
    5681                 :            : {
    5682                 :          1 :         wpa_s->p2p_long_listen = 0;
    5683                 :            : 
    5684 [ +  - ][ -  + ]:          1 :         if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
    5685                 :          0 :                 return -1;
    5686                 :            : 
    5687                 :          1 :         return p2p_reject(wpa_s->global->p2p, addr);
    5688                 :            : }
    5689                 :            : 
    5690                 :            : 
    5691                 :            : /* Invite to reinvoke a persistent group */
    5692                 :          7 : int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
    5693                 :            :                     struct wpa_ssid *ssid, const u8 *go_dev_addr, int freq,
    5694                 :            :                     int ht40, int vht, int pref_freq)
    5695                 :            : {
    5696                 :            :         enum p2p_invite_role role;
    5697                 :          7 :         u8 *bssid = NULL;
    5698                 :          7 :         int force_freq = 0;
    5699                 :            :         int res;
    5700                 :          7 :         int no_pref_freq_given = pref_freq == 0;
    5701                 :            : 
    5702                 :          7 :         wpa_s->global->p2p_invite_group = NULL;
    5703         [ +  - ]:          7 :         if (peer_addr)
    5704                 :          7 :                 os_memcpy(wpa_s->p2p_auth_invite, peer_addr, ETH_ALEN);
    5705                 :            :         else
    5706                 :          0 :                 os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
    5707                 :            : 
    5708                 :          7 :         wpa_s->p2p_persistent_go_freq = freq;
    5709                 :          7 :         wpa_s->p2p_go_ht40 = !!ht40;
    5710         [ +  + ]:          7 :         if (ssid->mode == WPAS_MODE_P2P_GO) {
    5711                 :          3 :                 role = P2P_INVITE_ROLE_GO;
    5712         [ -  + ]:          3 :                 if (peer_addr == NULL) {
    5713                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: Missing peer "
    5714                 :            :                                    "address in invitation command");
    5715                 :          0 :                         return -1;
    5716                 :            :                 }
    5717         [ -  + ]:          3 :                 if (wpas_p2p_create_iface(wpa_s)) {
    5718         [ #  # ]:          0 :                         if (wpas_p2p_add_group_interface(wpa_s,
    5719                 :            :                                                          WPA_IF_P2P_GO) < 0) {
    5720                 :          0 :                                 wpa_printf(MSG_ERROR, "P2P: Failed to "
    5721                 :            :                                            "allocate a new interface for the "
    5722                 :            :                                            "group");
    5723                 :          0 :                                 return -1;
    5724                 :            :                         }
    5725                 :          0 :                         bssid = wpa_s->pending_interface_addr;
    5726                 :            :                 } else
    5727                 :          3 :                         bssid = wpa_s->own_addr;
    5728                 :            :         } else {
    5729                 :          4 :                 role = P2P_INVITE_ROLE_CLIENT;
    5730                 :          4 :                 peer_addr = ssid->bssid;
    5731                 :            :         }
    5732                 :          7 :         wpa_s->pending_invite_ssid_id = ssid->id;
    5733                 :            : 
    5734                 :          7 :         res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq,
    5735                 :            :                                    role == P2P_INVITE_ROLE_GO);
    5736         [ -  + ]:          7 :         if (res)
    5737                 :          0 :                 return res;
    5738                 :            : 
    5739 [ +  - ][ -  + ]:          7 :         if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
    5740                 :          0 :                 return -1;
    5741                 :            : 
    5742 [ -  + ][ #  # ]:          7 :         if (wpa_s->parent->conf->p2p_ignore_shared_freq &&
    5743 [ #  # ][ #  # ]:          0 :             no_pref_freq_given && pref_freq > 0 &&
    5744         [ #  # ]:          0 :             wpa_s->num_multichan_concurrent > 1 &&
    5745                 :          0 :             wpas_p2p_num_unused_channels(wpa_s) > 0) {
    5746                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Ignore own channel preference %d MHz for invitation due to p2p_ignore_shared_freq=1 configuration",
    5747                 :            :                            pref_freq);
    5748                 :          0 :                 pref_freq = 0;
    5749                 :            :         }
    5750                 :            : 
    5751                 :          7 :         return p2p_invite(wpa_s->global->p2p, peer_addr, role, bssid,
    5752                 :          7 :                           ssid->ssid, ssid->ssid_len, force_freq, go_dev_addr,
    5753                 :            :                           1, pref_freq, -1);
    5754                 :            : }
    5755                 :            : 
    5756                 :            : 
    5757                 :            : /* Invite to join an active group */
    5758                 :          4 : int wpas_p2p_invite_group(struct wpa_supplicant *wpa_s, const char *ifname,
    5759                 :            :                           const u8 *peer_addr, const u8 *go_dev_addr)
    5760                 :            : {
    5761                 :          4 :         struct wpa_global *global = wpa_s->global;
    5762                 :            :         enum p2p_invite_role role;
    5763                 :          4 :         u8 *bssid = NULL;
    5764                 :            :         struct wpa_ssid *ssid;
    5765                 :            :         int persistent;
    5766                 :          4 :         int freq = 0, force_freq = 0, pref_freq = 0;
    5767                 :            :         int res;
    5768                 :            : 
    5769                 :          4 :         wpa_s->p2p_persistent_go_freq = 0;
    5770                 :          4 :         wpa_s->p2p_go_ht40 = 0;
    5771                 :          4 :         wpa_s->p2p_go_vht = 0;
    5772                 :            : 
    5773         [ +  - ]:          4 :         for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
    5774         [ +  - ]:          4 :                 if (os_strcmp(wpa_s->ifname, ifname) == 0)
    5775                 :          4 :                         break;
    5776                 :            :         }
    5777         [ -  + ]:          4 :         if (wpa_s == NULL) {
    5778                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Interface '%s' not found", ifname);
    5779                 :          0 :                 return -1;
    5780                 :            :         }
    5781                 :            : 
    5782                 :          4 :         ssid = wpa_s->current_ssid;
    5783         [ -  + ]:          4 :         if (ssid == NULL) {
    5784                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: No current SSID to use for "
    5785                 :            :                            "invitation");
    5786                 :          0 :                 return -1;
    5787                 :            :         }
    5788                 :            : 
    5789                 :          4 :         wpa_s->global->p2p_invite_group = wpa_s;
    5790   [ +  +  -  + ]:          6 :         persistent = ssid->p2p_persistent_group &&
    5791                 :          2 :                 wpas_p2p_get_persistent(wpa_s->parent, peer_addr,
    5792                 :          2 :                                         ssid->ssid, ssid->ssid_len);
    5793                 :            : 
    5794         [ +  - ]:          4 :         if (ssid->mode == WPAS_MODE_P2P_GO) {
    5795                 :          4 :                 role = P2P_INVITE_ROLE_ACTIVE_GO;
    5796                 :          4 :                 bssid = wpa_s->own_addr;
    5797         [ +  - ]:          4 :                 if (go_dev_addr == NULL)
    5798                 :          4 :                         go_dev_addr = wpa_s->global->p2p_dev_addr;
    5799                 :          4 :                 freq = ssid->frequency;
    5800                 :            :         } else {
    5801                 :          0 :                 role = P2P_INVITE_ROLE_CLIENT;
    5802         [ #  # ]:          0 :                 if (wpa_s->wpa_state < WPA_ASSOCIATED) {
    5803                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: Not associated - cannot "
    5804                 :            :                                    "invite to current group");
    5805                 :          0 :                         return -1;
    5806                 :            :                 }
    5807                 :          0 :                 bssid = wpa_s->bssid;
    5808   [ #  #  #  # ]:          0 :                 if (go_dev_addr == NULL &&
    5809                 :          0 :                     !is_zero_ether_addr(wpa_s->go_dev_addr))
    5810                 :          0 :                         go_dev_addr = wpa_s->go_dev_addr;
    5811         [ #  # ]:          0 :                 freq = wpa_s->current_bss ? wpa_s->current_bss->freq :
    5812                 :          0 :                         (int) wpa_s->assoc_freq;
    5813                 :            :         }
    5814                 :          4 :         wpa_s->parent->pending_invite_ssid_id = -1;
    5815                 :            : 
    5816 [ +  - ][ -  + ]:          4 :         if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
    5817                 :          0 :                 return -1;
    5818                 :            : 
    5819                 :          4 :         res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq,
    5820                 :            :                                    role == P2P_INVITE_ROLE_ACTIVE_GO);
    5821         [ -  + ]:          4 :         if (res)
    5822                 :          0 :                 return res;
    5823                 :          4 :         wpas_p2p_set_own_freq_preference(wpa_s, force_freq);
    5824                 :            : 
    5825                 :          4 :         return p2p_invite(wpa_s->global->p2p, peer_addr, role, bssid,
    5826                 :          4 :                           ssid->ssid, ssid->ssid_len, force_freq,
    5827                 :            :                           go_dev_addr, persistent, pref_freq, -1);
    5828                 :            : }
    5829                 :            : 
    5830                 :            : 
    5831                 :        592 : void wpas_p2p_completed(struct wpa_supplicant *wpa_s)
    5832                 :            : {
    5833                 :        592 :         struct wpa_ssid *ssid = wpa_s->current_ssid;
    5834                 :            :         const char *ssid_txt;
    5835                 :            :         u8 go_dev_addr[ETH_ALEN];
    5836                 :        592 :         int network_id = -1;
    5837                 :            :         int persistent;
    5838                 :            :         int freq;
    5839                 :            :         u8 ip[3 * 4];
    5840                 :            :         char ip_addr[100];
    5841                 :            : 
    5842 [ +  - ][ +  + ]:        592 :         if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION) {
    5843                 :        547 :                 eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
    5844                 :        547 :                                      wpa_s->parent, NULL);
    5845                 :            :         }
    5846                 :            : 
    5847 [ +  + ][ -  + ]:        592 :         if (!wpa_s->show_group_started || !ssid)
    5848                 :        592 :                 return;
    5849                 :            : 
    5850                 :         85 :         wpa_s->show_group_started = 0;
    5851                 :            : 
    5852                 :         85 :         ssid_txt = wpa_ssid_txt(ssid->ssid, ssid->ssid_len);
    5853                 :         85 :         os_memset(go_dev_addr, 0, ETH_ALEN);
    5854         [ +  + ]:         85 :         if (ssid->bssid_set)
    5855                 :         72 :                 os_memcpy(go_dev_addr, ssid->bssid, ETH_ALEN);
    5856                 :         85 :         persistent = wpas_p2p_persistent_group(wpa_s, go_dev_addr, ssid->ssid,
    5857                 :            :                                                ssid->ssid_len);
    5858                 :         85 :         os_memcpy(wpa_s->go_dev_addr, go_dev_addr, ETH_ALEN);
    5859                 :            : 
    5860         [ -  + ]:         85 :         if (wpa_s->global->p2p_group_formation == wpa_s)
    5861                 :          0 :                 wpa_s->global->p2p_group_formation = NULL;
    5862                 :            : 
    5863         [ +  + ]:         85 :         freq = wpa_s->current_bss ? wpa_s->current_bss->freq :
    5864                 :         76 :                 (int) wpa_s->assoc_freq;
    5865                 :            : 
    5866                 :         85 :         ip_addr[0] = '\0';
    5867         [ +  + ]:         85 :         if (wpa_sm_get_p2p_ip_addr(wpa_s->wpa, ip) == 0) {
    5868                 :         49 :                 os_snprintf(ip_addr, sizeof(ip_addr), " ip_addr=%u.%u.%u.%u "
    5869                 :            :                             "ip_mask=%u.%u.%u.%u go_ip_addr=%u.%u.%u.%u",
    5870                 :        196 :                             ip[0], ip[1], ip[2], ip[3],
    5871                 :        196 :                             ip[4], ip[5], ip[6], ip[7],
    5872                 :        196 :                             ip[8], ip[9], ip[10], ip[11]);
    5873                 :            :         }
    5874                 :            : 
    5875 [ +  - ][ +  + ]:        169 :         if (ssid->passphrase == NULL && ssid->psk_set) {
    5876                 :            :                 char psk[65];
    5877                 :         84 :                 wpa_snprintf_hex(psk, sizeof(psk), ssid->psk, 32);
    5878         [ +  + ]:         84 :                 wpa_msg_global(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_STARTED
    5879                 :            :                                "%s client ssid=\"%s\" freq=%d psk=%s "
    5880                 :            :                                "go_dev_addr=" MACSTR "%s%s",
    5881                 :         84 :                                wpa_s->ifname, ssid_txt, freq, psk,
    5882                 :        504 :                                MAC2STR(go_dev_addr),
    5883                 :            :                                persistent ? " [PERSISTENT]" : "", ip_addr);
    5884                 :            :         } else {
    5885 [ -  + ][ -  + ]:          1 :                 wpa_msg_global(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_STARTED
    5886                 :            :                                "%s client ssid=\"%s\" freq=%d "
    5887                 :            :                                "passphrase=\"%s\" go_dev_addr=" MACSTR "%s%s",
    5888                 :          1 :                                wpa_s->ifname, ssid_txt, freq,
    5889                 :          1 :                                ssid->passphrase ? ssid->passphrase : "",
    5890                 :          6 :                                MAC2STR(go_dev_addr),
    5891                 :            :                                persistent ? " [PERSISTENT]" : "", ip_addr);
    5892                 :            :         }
    5893                 :            : 
    5894         [ +  + ]:         85 :         if (persistent)
    5895                 :         19 :                 network_id = wpas_p2p_store_persistent_group(wpa_s->parent,
    5896                 :            :                                                              ssid, go_dev_addr);
    5897         [ +  + ]:         85 :         if (network_id < 0)
    5898                 :         66 :                 network_id = ssid->id;
    5899                 :         85 :         wpas_notify_p2p_group_started(wpa_s, ssid, network_id, 1);
    5900                 :            : }
    5901                 :            : 
    5902                 :            : 
    5903                 :          1 : int wpas_p2p_presence_req(struct wpa_supplicant *wpa_s, u32 duration1,
    5904                 :            :                           u32 interval1, u32 duration2, u32 interval2)
    5905                 :            : {
    5906                 :            :         int ret;
    5907                 :            : 
    5908 [ +  - ][ -  + ]:          1 :         if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
    5909                 :          0 :                 return -1;
    5910                 :            : 
    5911 [ +  - ][ +  - ]:          1 :         if (wpa_s->wpa_state < WPA_ASSOCIATED ||
    5912         [ -  + ]:          1 :             wpa_s->current_ssid == NULL ||
    5913                 :          1 :             wpa_s->current_ssid->mode != WPAS_MODE_INFRA)
    5914                 :          0 :                 return -1;
    5915                 :            : 
    5916                 :          1 :         ret = p2p_presence_req(wpa_s->global->p2p, wpa_s->bssid,
    5917                 :          1 :                                wpa_s->own_addr, wpa_s->assoc_freq,
    5918                 :            :                                duration1, interval1, duration2, interval2);
    5919         [ +  - ]:          1 :         if (ret == 0)
    5920                 :          1 :                 wpa_s->waiting_presence_resp = 1;
    5921                 :            : 
    5922                 :          1 :         return ret;
    5923                 :            : }
    5924                 :            : 
    5925                 :            : 
    5926                 :          0 : int wpas_p2p_ext_listen(struct wpa_supplicant *wpa_s, unsigned int period,
    5927                 :            :                         unsigned int interval)
    5928                 :            : {
    5929 [ #  # ][ #  # ]:          0 :         if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
    5930                 :          0 :                 return -1;
    5931                 :            : 
    5932                 :          0 :         return p2p_ext_listen(wpa_s->global->p2p, period, interval);
    5933                 :            : }
    5934                 :            : 
    5935                 :            : 
    5936                 :          0 : static int wpas_p2p_is_client(struct wpa_supplicant *wpa_s)
    5937                 :            : {
    5938         [ #  # ]:          0 :         if (wpa_s->current_ssid == NULL) {
    5939                 :            :                 /*
    5940                 :            :                  * current_ssid can be cleared when P2P client interface gets
    5941                 :            :                  * disconnected, so assume this interface was used as P2P
    5942                 :            :                  * client.
    5943                 :            :                  */
    5944                 :          0 :                 return 1;
    5945                 :            :         }
    5946 [ #  # ][ #  # ]:          0 :         return wpa_s->current_ssid->p2p_group &&
    5947                 :          0 :                 wpa_s->current_ssid->mode == WPAS_MODE_INFRA;
    5948                 :            : }
    5949                 :            : 
    5950                 :            : 
    5951                 :          0 : static void wpas_p2p_group_idle_timeout(void *eloop_ctx, void *timeout_ctx)
    5952                 :            : {
    5953                 :          0 :         struct wpa_supplicant *wpa_s = eloop_ctx;
    5954                 :            : 
    5955 [ #  # ][ #  # ]:          0 :         if (wpa_s->conf->p2p_group_idle == 0 && !wpas_p2p_is_client(wpa_s)) {
    5956                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Ignore group idle timeout - "
    5957                 :            :                            "disabled");
    5958                 :          0 :                 return;
    5959                 :            :         }
    5960                 :            : 
    5961                 :          0 :         wpa_printf(MSG_DEBUG, "P2P: Group idle timeout reached - terminate "
    5962                 :            :                    "group");
    5963                 :          0 :         wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_IDLE_TIMEOUT);
    5964                 :            : }
    5965                 :            : 
    5966                 :            : 
    5967                 :        963 : static void wpas_p2p_set_group_idle_timeout(struct wpa_supplicant *wpa_s)
    5968                 :            : {
    5969                 :            :         int timeout;
    5970                 :            : 
    5971         [ -  + ]:        963 :         if (eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL) > 0)
    5972                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group idle timeout");
    5973                 :            : 
    5974 [ +  + ][ +  + ]:        963 :         if (wpa_s->current_ssid == NULL || !wpa_s->current_ssid->p2p_group)
    5975                 :        627 :                 return;
    5976                 :            : 
    5977                 :        336 :         timeout = wpa_s->conf->p2p_group_idle;
    5978 [ +  + ][ -  + ]:        336 :         if (wpa_s->current_ssid->mode == WPAS_MODE_INFRA &&
    5979         [ #  # ]:          0 :             (timeout == 0 || timeout > P2P_MAX_CLIENT_IDLE))
    5980                 :        167 :             timeout = P2P_MAX_CLIENT_IDLE;
    5981                 :            : 
    5982         [ +  + ]:        336 :         if (timeout == 0)
    5983                 :        169 :                 return;
    5984                 :            : 
    5985         [ -  + ]:        167 :         if (timeout < 0) {
    5986         [ #  # ]:          0 :                 if (wpa_s->current_ssid->mode == WPAS_MODE_INFRA)
    5987                 :          0 :                         timeout = 0; /* special client mode no-timeout */
    5988                 :            :                 else
    5989                 :          0 :                         return;
    5990                 :            :         }
    5991                 :            : 
    5992         [ -  + ]:        167 :         if (wpa_s->p2p_in_provisioning) {
    5993                 :            :                 /*
    5994                 :            :                  * Use the normal group formation timeout during the
    5995                 :            :                  * provisioning phase to avoid terminating this process too
    5996                 :            :                  * early due to group idle timeout.
    5997                 :            :                  */
    5998                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Do not use P2P group idle timeout "
    5999                 :            :                            "during provisioning");
    6000                 :          0 :                 return;
    6001                 :            :         }
    6002                 :            : 
    6003         [ +  + ]:        167 :         if (wpa_s->show_group_started) {
    6004                 :            :                 /*
    6005                 :            :                  * Use the normal group formation timeout between the end of
    6006                 :            :                  * the provisioning phase and completion of 4-way handshake to
    6007                 :            :                  * avoid terminating this process too early due to group idle
    6008                 :            :                  * timeout.
    6009                 :            :                  */
    6010                 :         81 :                 wpa_printf(MSG_DEBUG, "P2P: Do not use P2P group idle timeout "
    6011                 :            :                            "while waiting for initial 4-way handshake to "
    6012                 :            :                            "complete");
    6013                 :         81 :                 return;
    6014                 :            :         }
    6015                 :            : 
    6016                 :         86 :         wpa_printf(MSG_DEBUG, "P2P: Set P2P group idle timeout to %u seconds",
    6017                 :            :                    timeout);
    6018                 :        963 :         eloop_register_timeout(timeout, 0, wpas_p2p_group_idle_timeout,
    6019                 :            :                                wpa_s, NULL);
    6020                 :            : }
    6021                 :            : 
    6022                 :            : 
    6023                 :            : /* Returns 1 if the interface was removed */
    6024                 :       1248 : int wpas_p2p_deauth_notif(struct wpa_supplicant *wpa_s, const u8 *bssid,
    6025                 :            :                           u16 reason_code, const u8 *ie, size_t ie_len,
    6026                 :            :                           int locally_generated)
    6027                 :            : {
    6028 [ +  + ][ -  + ]:       1248 :         if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
    6029                 :          6 :                 return 0;
    6030                 :            : 
    6031         [ +  + ]:       1242 :         if (!locally_generated)
    6032                 :         99 :                 p2p_deauth_notif(wpa_s->global->p2p, bssid, reason_code, ie,
    6033                 :            :                                  ie_len);
    6034                 :            : 
    6035 [ +  + ][ +  + ]:       1242 :         if (reason_code == WLAN_REASON_DEAUTH_LEAVING && !locally_generated &&
                 [ +  + ]
    6036         [ +  + ]:         57 :             wpa_s->current_ssid &&
    6037         [ +  - ]:         50 :             wpa_s->current_ssid->p2p_group &&
    6038                 :         50 :             wpa_s->current_ssid->mode == WPAS_MODE_INFRA) {
    6039                 :         50 :                 wpa_printf(MSG_DEBUG, "P2P: GO indicated that the P2P Group "
    6040                 :            :                            "session is ending");
    6041         [ +  + ]:         50 :                 if (wpas_p2p_group_delete(wpa_s,
    6042                 :            :                                           P2P_GROUP_REMOVAL_GO_ENDING_SESSION)
    6043                 :            :                     > 0)
    6044                 :          6 :                         return 1;
    6045                 :            :         }
    6046                 :            : 
    6047                 :       1248 :         return 0;
    6048                 :            : }
    6049                 :            : 
    6050                 :            : 
    6051                 :          1 : void wpas_p2p_disassoc_notif(struct wpa_supplicant *wpa_s, const u8 *bssid,
    6052                 :            :                              u16 reason_code, const u8 *ie, size_t ie_len,
    6053                 :            :                              int locally_generated)
    6054                 :            : {
    6055 [ +  - ][ -  + ]:          1 :         if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
    6056                 :          1 :                 return;
    6057                 :            : 
    6058         [ +  - ]:          1 :         if (!locally_generated)
    6059                 :          1 :                 p2p_disassoc_notif(wpa_s->global->p2p, bssid, reason_code, ie,
    6060                 :            :                                    ie_len);
    6061                 :            : }
    6062                 :            : 
    6063                 :            : 
    6064                 :      10812 : void wpas_p2p_update_config(struct wpa_supplicant *wpa_s)
    6065                 :            : {
    6066                 :      10812 :         struct p2p_data *p2p = wpa_s->global->p2p;
    6067                 :            : 
    6068         [ -  + ]:      10812 :         if (p2p == NULL)
    6069                 :          0 :                 return;
    6070                 :            : 
    6071         [ -  + ]:      10812 :         if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE))
    6072                 :          0 :                 return;
    6073                 :            : 
    6074         [ +  + ]:      10812 :         if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_NAME)
    6075                 :          3 :                 p2p_set_dev_name(p2p, wpa_s->conf->device_name);
    6076                 :            : 
    6077         [ -  + ]:      10812 :         if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_TYPE)
    6078                 :          0 :                 p2p_set_pri_dev_type(p2p, wpa_s->conf->device_type);
    6079                 :            : 
    6080 [ +  - ][ -  + ]:      10812 :         if (wpa_s->wps &&
    6081                 :      10812 :             (wpa_s->conf->changed_parameters & CFG_CHANGED_CONFIG_METHODS))
    6082                 :          0 :                 p2p_set_config_methods(p2p, wpa_s->wps->config_methods);
    6083                 :            : 
    6084 [ +  - ][ -  + ]:      10812 :         if (wpa_s->wps && (wpa_s->conf->changed_parameters & CFG_CHANGED_UUID))
    6085                 :          0 :                 p2p_set_uuid(p2p, wpa_s->wps->uuid);
    6086                 :            : 
    6087         [ +  + ]:      10812 :         if (wpa_s->conf->changed_parameters & CFG_CHANGED_WPS_STRING) {
    6088                 :          1 :                 p2p_set_manufacturer(p2p, wpa_s->conf->manufacturer);
    6089                 :          1 :                 p2p_set_model_name(p2p, wpa_s->conf->model_name);
    6090                 :          1 :                 p2p_set_model_number(p2p, wpa_s->conf->model_number);
    6091                 :          1 :                 p2p_set_serial_number(p2p, wpa_s->conf->serial_number);
    6092                 :            :         }
    6093                 :            : 
    6094         [ +  + ]:      10812 :         if (wpa_s->conf->changed_parameters & CFG_CHANGED_SEC_DEVICE_TYPE)
    6095                 :          2 :                 p2p_set_sec_dev_types(p2p,
    6096                 :          2 :                                       (void *) wpa_s->conf->sec_device_type,
    6097                 :          2 :                                       wpa_s->conf->num_sec_device_types);
    6098                 :            : 
    6099         [ +  + ]:      10812 :         if (wpa_s->conf->changed_parameters & CFG_CHANGED_VENDOR_EXTENSION) {
    6100                 :            :                 int i;
    6101                 :          1 :                 p2p_remove_wps_vendor_extensions(p2p);
    6102         [ +  + ]:         11 :                 for (i = 0; i < MAX_WPS_VENDOR_EXT; i++) {
    6103         [ +  - ]:         10 :                         if (wpa_s->conf->wps_vendor_ext[i] == NULL)
    6104                 :         10 :                                 continue;
    6105                 :          0 :                         p2p_add_wps_vendor_extension(
    6106                 :          0 :                                 p2p, wpa_s->conf->wps_vendor_ext[i]);
    6107                 :            :                 }
    6108                 :            :         }
    6109                 :            : 
    6110 [ -  + ][ #  # ]:      10812 :         if ((wpa_s->conf->changed_parameters & CFG_CHANGED_COUNTRY) &&
    6111         [ #  # ]:          0 :             wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
    6112                 :            :                 char country[3];
    6113                 :          0 :                 country[0] = wpa_s->conf->country[0];
    6114                 :          0 :                 country[1] = wpa_s->conf->country[1];
    6115                 :          0 :                 country[2] = 0x04;
    6116                 :          0 :                 p2p_set_country(p2p, country);
    6117                 :            :         }
    6118                 :            : 
    6119         [ -  + ]:      10812 :         if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_SSID_POSTFIX) {
    6120         [ #  # ]:          0 :                 p2p_set_ssid_postfix(p2p, (u8 *) wpa_s->conf->p2p_ssid_postfix,
    6121                 :          0 :                                      wpa_s->conf->p2p_ssid_postfix ?
    6122                 :          0 :                                      os_strlen(wpa_s->conf->p2p_ssid_postfix) :
    6123                 :            :                                      0);
    6124                 :            :         }
    6125                 :            : 
    6126         [ -  + ]:      10812 :         if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_INTRA_BSS)
    6127                 :          0 :                 p2p_set_intra_bss_dist(p2p, wpa_s->conf->p2p_intra_bss);
    6128                 :            : 
    6129         [ -  + ]:      10812 :         if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_LISTEN_CHANNEL) {
    6130                 :            :                 u8 reg_class, channel;
    6131                 :            :                 int ret;
    6132                 :            :                 unsigned int r;
    6133 [ #  # ][ #  # ]:          0 :                 if (wpa_s->conf->p2p_listen_reg_class &&
    6134                 :          0 :                     wpa_s->conf->p2p_listen_channel) {
    6135                 :          0 :                         reg_class = wpa_s->conf->p2p_listen_reg_class;
    6136                 :          0 :                         channel = wpa_s->conf->p2p_listen_channel;
    6137                 :            :                 } else {
    6138                 :          0 :                         reg_class = 81;
    6139                 :            :                         /*
    6140                 :            :                          * Pick one of the social channels randomly as the
    6141                 :            :                          * listen channel.
    6142                 :            :                          */
    6143                 :          0 :                         os_get_random((u8 *) &r, sizeof(r));
    6144                 :          0 :                         channel = 1 + (r % 3) * 5;
    6145                 :            :                 }
    6146                 :          0 :                 ret = p2p_set_listen_channel(p2p, reg_class, channel);
    6147         [ #  # ]:          0 :                 if (ret)
    6148                 :          0 :                         wpa_printf(MSG_ERROR, "P2P: Own listen channel update "
    6149                 :            :                                    "failed: %d", ret);
    6150                 :            :         }
    6151         [ -  + ]:      10812 :         if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_OPER_CHANNEL) {
    6152                 :            :                 u8 op_reg_class, op_channel, cfg_op_channel;
    6153                 :          0 :                 int ret = 0;
    6154                 :            :                 unsigned int r;
    6155 [ #  # ][ #  # ]:          0 :                 if (wpa_s->conf->p2p_oper_reg_class &&
    6156                 :          0 :                     wpa_s->conf->p2p_oper_channel) {
    6157                 :          0 :                         op_reg_class = wpa_s->conf->p2p_oper_reg_class;
    6158                 :          0 :                         op_channel = wpa_s->conf->p2p_oper_channel;
    6159                 :          0 :                         cfg_op_channel = 1;
    6160                 :            :                 } else {
    6161                 :          0 :                         op_reg_class = 81;
    6162                 :            :                         /*
    6163                 :            :                          * Use random operation channel from (1, 6, 11)
    6164                 :            :                          *if no other preference is indicated.
    6165                 :            :                          */
    6166                 :          0 :                         os_get_random((u8 *) &r, sizeof(r));
    6167                 :          0 :                         op_channel = 1 + (r % 3) * 5;
    6168                 :          0 :                         cfg_op_channel = 0;
    6169                 :            :                 }
    6170                 :          0 :                 ret = p2p_set_oper_channel(p2p, op_reg_class, op_channel,
    6171                 :            :                                            cfg_op_channel);
    6172         [ #  # ]:          0 :                 if (ret)
    6173                 :          0 :                         wpa_printf(MSG_ERROR, "P2P: Own oper channel update "
    6174                 :            :                                    "failed: %d", ret);
    6175                 :            :         }
    6176                 :            : 
    6177         [ +  + ]:      10812 :         if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_PREF_CHAN) {
    6178         [ -  + ]:       2344 :                 if (p2p_set_pref_chan(p2p, wpa_s->conf->num_p2p_pref_chan,
    6179                 :       2344 :                                       wpa_s->conf->p2p_pref_chan) < 0) {
    6180                 :          0 :                         wpa_printf(MSG_ERROR, "P2P: Preferred channel list "
    6181                 :            :                                    "update failed");
    6182                 :            :                 }
    6183                 :            : 
    6184         [ -  + ]:       2344 :                 if (p2p_set_no_go_freq(p2p, &wpa_s->conf->p2p_no_go_freq) < 0) {
    6185                 :      10812 :                         wpa_printf(MSG_ERROR, "P2P: No GO channel list "
    6186                 :            :                                    "update failed");
    6187                 :            :                 }
    6188                 :            :         }
    6189                 :            : }
    6190                 :            : 
    6191                 :            : 
    6192                 :          0 : int wpas_p2p_set_noa(struct wpa_supplicant *wpa_s, u8 count, int start,
    6193                 :            :                      int duration)
    6194                 :            : {
    6195         [ #  # ]:          0 :         if (!wpa_s->ap_iface)
    6196                 :          0 :                 return -1;
    6197                 :          0 :         return hostapd_p2p_set_noa(wpa_s->ap_iface->bss[0], count, start,
    6198                 :            :                                    duration);
    6199                 :            : }
    6200                 :            : 
    6201                 :            : 
    6202                 :          0 : int wpas_p2p_set_cross_connect(struct wpa_supplicant *wpa_s, int enabled)
    6203                 :            : {
    6204 [ #  # ][ #  # ]:          0 :         if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
    6205                 :          0 :                 return -1;
    6206                 :            : 
    6207                 :          0 :         wpa_s->global->cross_connection = enabled;
    6208                 :          0 :         p2p_set_cross_connect(wpa_s->global->p2p, enabled);
    6209                 :            : 
    6210         [ #  # ]:          0 :         if (!enabled) {
    6211                 :            :                 struct wpa_supplicant *iface;
    6212                 :            : 
    6213         [ #  # ]:          0 :                 for (iface = wpa_s->global->ifaces; iface; iface = iface->next)
    6214                 :            :                 {
    6215         [ #  # ]:          0 :                         if (iface->cross_connect_enabled == 0)
    6216                 :          0 :                                 continue;
    6217                 :            : 
    6218                 :          0 :                         iface->cross_connect_enabled = 0;
    6219                 :          0 :                         iface->cross_connect_in_use = 0;
    6220                 :          0 :                         wpa_msg_global(iface->parent, MSG_INFO,
    6221                 :            :                                        P2P_EVENT_CROSS_CONNECT_DISABLE "%s %s",
    6222                 :          0 :                                        iface->ifname,
    6223                 :          0 :                                        iface->cross_connect_uplink);
    6224                 :            :                 }
    6225                 :            :         }
    6226                 :            : 
    6227                 :          0 :         return 0;
    6228                 :            : }
    6229                 :            : 
    6230                 :            : 
    6231                 :        523 : static void wpas_p2p_enable_cross_connect(struct wpa_supplicant *uplink)
    6232                 :            : {
    6233                 :            :         struct wpa_supplicant *iface;
    6234                 :            : 
    6235         [ +  - ]:        523 :         if (!uplink->global->cross_connection)
    6236                 :        523 :                 return;
    6237                 :            : 
    6238         [ #  # ]:          0 :         for (iface = uplink->global->ifaces; iface; iface = iface->next) {
    6239         [ #  # ]:          0 :                 if (!iface->cross_connect_enabled)
    6240                 :          0 :                         continue;
    6241         [ #  # ]:          0 :                 if (os_strcmp(uplink->ifname, iface->cross_connect_uplink) !=
    6242                 :            :                     0)
    6243                 :          0 :                         continue;
    6244         [ #  # ]:          0 :                 if (iface->ap_iface == NULL)
    6245                 :          0 :                         continue;
    6246         [ #  # ]:          0 :                 if (iface->cross_connect_in_use)
    6247                 :          0 :                         continue;
    6248                 :            : 
    6249                 :          0 :                 iface->cross_connect_in_use = 1;
    6250                 :          0 :                 wpa_msg_global(iface->parent, MSG_INFO,
    6251                 :            :                                P2P_EVENT_CROSS_CONNECT_ENABLE "%s %s",
    6252                 :          0 :                                iface->ifname, iface->cross_connect_uplink);
    6253                 :            :         }
    6254                 :            : }
    6255                 :            : 
    6256                 :            : 
    6257                 :        928 : static void wpas_p2p_disable_cross_connect(struct wpa_supplicant *uplink)
    6258                 :            : {
    6259                 :            :         struct wpa_supplicant *iface;
    6260                 :            : 
    6261         [ +  + ]:       1887 :         for (iface = uplink->global->ifaces; iface; iface = iface->next) {
    6262         [ +  - ]:        959 :                 if (!iface->cross_connect_enabled)
    6263                 :        959 :                         continue;
    6264         [ #  # ]:          0 :                 if (os_strcmp(uplink->ifname, iface->cross_connect_uplink) !=
    6265                 :            :                     0)
    6266                 :          0 :                         continue;
    6267         [ #  # ]:          0 :                 if (!iface->cross_connect_in_use)
    6268                 :          0 :                         continue;
    6269                 :            : 
    6270                 :          0 :                 wpa_msg_global(iface->parent, MSG_INFO,
    6271                 :            :                                P2P_EVENT_CROSS_CONNECT_DISABLE "%s %s",
    6272                 :          0 :                                iface->ifname, iface->cross_connect_uplink);
    6273                 :          0 :                 iface->cross_connect_in_use = 0;
    6274                 :            :         }
    6275                 :        928 : }
    6276                 :            : 
    6277                 :            : 
    6278                 :        619 : void wpas_p2p_notif_connected(struct wpa_supplicant *wpa_s)
    6279                 :            : {
    6280 [ +  + ][ +  - ]:        619 :         if (wpa_s->ap_iface || wpa_s->current_ssid == NULL ||
                 [ +  + ]
    6281         [ +  + ]:        525 :             wpa_s->current_ssid->mode != WPAS_MODE_INFRA ||
    6282                 :        525 :             wpa_s->cross_connect_disallowed)
    6283                 :         96 :                 wpas_p2p_disable_cross_connect(wpa_s);
    6284                 :            :         else
    6285                 :        523 :                 wpas_p2p_enable_cross_connect(wpa_s);
    6286   [ +  +  +  + ]:       1152 :         if (!wpa_s->ap_iface &&
    6287                 :        533 :             eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL) > 0)
    6288                 :          1 :                 wpa_printf(MSG_DEBUG, "P2P: Cancelled P2P group idle timeout");
    6289                 :        619 : }
    6290                 :            : 
    6291                 :            : 
    6292                 :        832 : void wpas_p2p_notif_disconnected(struct wpa_supplicant *wpa_s)
    6293                 :            : {
    6294                 :        832 :         wpas_p2p_disable_cross_connect(wpa_s);
    6295   [ +  +  +  - ]:       1530 :         if (!wpa_s->ap_iface &&
    6296                 :        698 :             !eloop_is_timeout_registered(wpas_p2p_group_idle_timeout,
    6297                 :            :                                          wpa_s, NULL))
    6298                 :        698 :                 wpas_p2p_set_group_idle_timeout(wpa_s);
    6299                 :        832 : }
    6300                 :            : 
    6301                 :            : 
    6302                 :         79 : static void wpas_p2p_cross_connect_setup(struct wpa_supplicant *wpa_s)
    6303                 :            : {
    6304                 :            :         struct wpa_supplicant *iface;
    6305                 :            : 
    6306         [ +  - ]:         79 :         if (!wpa_s->global->cross_connection)
    6307                 :         79 :                 return;
    6308                 :            : 
    6309         [ #  # ]:          0 :         for (iface = wpa_s->global->ifaces; iface; iface = iface->next) {
    6310         [ #  # ]:          0 :                 if (iface == wpa_s)
    6311                 :          0 :                         continue;
    6312         [ #  # ]:          0 :                 if (iface->drv_flags &
    6313                 :            :                     WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)
    6314                 :          0 :                         continue;
    6315         [ #  # ]:          0 :                 if (iface->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE)
    6316                 :          0 :                         continue;
    6317                 :            : 
    6318                 :          0 :                 wpa_s->cross_connect_enabled = 1;
    6319                 :          0 :                 os_strlcpy(wpa_s->cross_connect_uplink, iface->ifname,
    6320                 :            :                            sizeof(wpa_s->cross_connect_uplink));
    6321                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Enable cross connection from "
    6322                 :            :                            "%s to %s whenever uplink is available",
    6323                 :          0 :                            wpa_s->ifname, wpa_s->cross_connect_uplink);
    6324                 :            : 
    6325 [ #  # ][ #  # ]:          0 :                 if (iface->ap_iface || iface->current_ssid == NULL ||
                 [ #  # ]
    6326         [ #  # ]:          0 :                     iface->current_ssid->mode != WPAS_MODE_INFRA ||
    6327         [ #  # ]:          0 :                     iface->cross_connect_disallowed ||
    6328                 :          0 :                     iface->wpa_state != WPA_COMPLETED)
    6329                 :            :                         break;
    6330                 :            : 
    6331                 :          0 :                 wpa_s->cross_connect_in_use = 1;
    6332                 :          0 :                 wpa_msg_global(wpa_s->parent, MSG_INFO,
    6333                 :            :                                P2P_EVENT_CROSS_CONNECT_ENABLE "%s %s",
    6334                 :          0 :                                wpa_s->ifname, wpa_s->cross_connect_uplink);
    6335                 :          0 :                 break;
    6336                 :            :         }
    6337                 :            : }
    6338                 :            : 
    6339                 :            : 
    6340                 :          3 : int wpas_p2p_notif_pbc_overlap(struct wpa_supplicant *wpa_s)
    6341                 :            : {
    6342 [ +  - ][ +  - ]:          3 :         if (wpa_s->p2p_group_interface != P2P_GROUP_INTERFACE_CLIENT &&
    6343                 :          3 :             !wpa_s->p2p_in_provisioning)
    6344                 :          3 :                 return 0; /* not P2P client operation */
    6345                 :            : 
    6346                 :          0 :         wpa_printf(MSG_DEBUG, "P2P: Terminate connection due to WPS PBC "
    6347                 :            :                    "session overlap");
    6348         [ #  # ]:          0 :         if (wpa_s != wpa_s->parent)
    6349                 :          0 :                 wpa_msg_ctrl(wpa_s->parent, MSG_INFO, WPS_EVENT_OVERLAP);
    6350                 :          0 :         wpas_p2p_group_formation_failed(wpa_s);
    6351                 :          3 :         return 1;
    6352                 :            : }
    6353                 :            : 
    6354                 :            : 
    6355                 :       1663 : void wpas_p2p_update_channel_list(struct wpa_supplicant *wpa_s)
    6356                 :            : {
    6357                 :            :         struct p2p_channels chan, cli_chan;
    6358                 :            : 
    6359 [ +  - ][ -  + ]:       1663 :         if (wpa_s->global == NULL || wpa_s->global->p2p == NULL)
    6360                 :          0 :                 return;
    6361                 :            : 
    6362                 :       1663 :         os_memset(&chan, 0, sizeof(chan));
    6363                 :       1663 :         os_memset(&cli_chan, 0, sizeof(cli_chan));
    6364         [ -  + ]:       1663 :         if (wpas_p2p_setup_channels(wpa_s, &chan, &cli_chan)) {
    6365                 :          0 :                 wpa_printf(MSG_ERROR, "P2P: Failed to update supported "
    6366                 :            :                            "channel list");
    6367                 :          0 :                 return;
    6368                 :            :         }
    6369                 :            : 
    6370                 :       1663 :         p2p_update_channel_list(wpa_s->global->p2p, &chan, &cli_chan);
    6371                 :            : }
    6372                 :            : 
    6373                 :            : 
    6374                 :          0 : static void wpas_p2p_scan_res_ignore(struct wpa_supplicant *wpa_s,
    6375                 :            :                                      struct wpa_scan_results *scan_res)
    6376                 :            : {
    6377                 :          0 :         wpa_printf(MSG_DEBUG, "P2P: Ignore scan results");
    6378                 :          0 : }
    6379                 :            : 
    6380                 :            : 
    6381                 :          0 : int wpas_p2p_cancel(struct wpa_supplicant *wpa_s)
    6382                 :            : {
    6383                 :          0 :         struct wpa_global *global = wpa_s->global;
    6384                 :          0 :         int found = 0;
    6385                 :            :         const u8 *peer;
    6386                 :            : 
    6387         [ #  # ]:          0 :         if (global->p2p == NULL)
    6388                 :          0 :                 return -1;
    6389                 :            : 
    6390                 :          0 :         wpa_printf(MSG_DEBUG, "P2P: Request to cancel group formation");
    6391                 :            : 
    6392   [ #  #  #  # ]:          0 :         if (wpa_s->pending_interface_name[0] &&
    6393                 :          0 :             !is_zero_ether_addr(wpa_s->pending_interface_addr))
    6394                 :          0 :                 found = 1;
    6395                 :            : 
    6396                 :          0 :         peer = p2p_get_go_neg_peer(global->p2p);
    6397         [ #  # ]:          0 :         if (peer) {
    6398                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Unauthorize pending GO Neg peer "
    6399                 :          0 :                            MACSTR, MAC2STR(peer));
    6400                 :          0 :                 p2p_unauthorize(global->p2p, peer);
    6401                 :          0 :                 found = 1;
    6402                 :            :         }
    6403                 :            : 
    6404         [ #  # ]:          0 :         if (wpa_s->scan_res_handler == wpas_p2p_scan_res_join) {
    6405                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Stop pending scan for join");
    6406                 :          0 :                 wpa_s->scan_res_handler = wpas_p2p_scan_res_ignore;
    6407                 :          0 :                 found = 1;
    6408                 :            :         }
    6409                 :            : 
    6410         [ #  # ]:          0 :         if (wpa_s->pending_pd_before_join) {
    6411                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Stop pending PD before join");
    6412                 :          0 :                 wpa_s->pending_pd_before_join = 0;
    6413                 :          0 :                 found = 1;
    6414                 :            :         }
    6415                 :            : 
    6416                 :          0 :         wpas_p2p_stop_find(wpa_s);
    6417                 :            : 
    6418         [ #  # ]:          0 :         for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
    6419 [ #  # ][ #  # ]:          0 :                 if (wpa_s == global->p2p_group_formation &&
    6420         [ #  # ]:          0 :                     (wpa_s->p2p_in_provisioning ||
    6421                 :          0 :                      wpa_s->parent->pending_interface_type ==
    6422                 :            :                      WPA_IF_P2P_CLIENT)) {
    6423                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: Interface %s in group "
    6424                 :            :                                    "formation found - cancelling",
    6425                 :          0 :                                    wpa_s->ifname);
    6426                 :          0 :                         found = 1;
    6427                 :          0 :                         eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
    6428                 :          0 :                                              wpa_s->parent, NULL);
    6429         [ #  # ]:          0 :                         if (wpa_s->p2p_in_provisioning) {
    6430                 :          0 :                                 wpas_group_formation_completed(wpa_s, 0);
    6431                 :          0 :                                 break;
    6432                 :            :                         }
    6433                 :          0 :                         wpas_p2p_group_delete(wpa_s,
    6434                 :            :                                               P2P_GROUP_REMOVAL_REQUESTED);
    6435                 :          0 :                         break;
    6436                 :            :                 }
    6437                 :            :         }
    6438                 :            : 
    6439         [ #  # ]:          0 :         if (!found) {
    6440                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: No ongoing group formation found");
    6441                 :          0 :                 return -1;
    6442                 :            :         }
    6443                 :            : 
    6444                 :          0 :         return 0;
    6445                 :            : }
    6446                 :            : 
    6447                 :            : 
    6448                 :         71 : void wpas_p2p_interface_unavailable(struct wpa_supplicant *wpa_s)
    6449                 :            : {
    6450 [ -  + ][ #  # ]:         71 :         if (wpa_s->current_ssid == NULL || !wpa_s->current_ssid->p2p_group)
    6451                 :         71 :                 return;
    6452                 :            : 
    6453                 :          0 :         wpa_printf(MSG_DEBUG, "P2P: Remove group due to driver resource not "
    6454                 :            :                    "being available anymore");
    6455                 :          0 :         wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_UNAVAILABLE);
    6456                 :            : }
    6457                 :            : 
    6458                 :            : 
    6459                 :          0 : void wpas_p2p_update_best_channels(struct wpa_supplicant *wpa_s,
    6460                 :            :                                    int freq_24, int freq_5, int freq_overall)
    6461                 :            : {
    6462                 :          0 :         struct p2p_data *p2p = wpa_s->global->p2p;
    6463         [ #  # ]:          0 :         if (p2p == NULL)
    6464                 :          0 :                 return;
    6465                 :          0 :         p2p_set_best_channels(p2p, freq_24, freq_5, freq_overall);
    6466                 :            : }
    6467                 :            : 
    6468                 :            : 
    6469                 :          0 : int wpas_p2p_unauthorize(struct wpa_supplicant *wpa_s, const char *addr)
    6470                 :            : {
    6471                 :            :         u8 peer[ETH_ALEN];
    6472                 :          0 :         struct p2p_data *p2p = wpa_s->global->p2p;
    6473                 :            : 
    6474         [ #  # ]:          0 :         if (p2p == NULL)
    6475                 :          0 :                 return -1;
    6476                 :            : 
    6477         [ #  # ]:          0 :         if (hwaddr_aton(addr, peer))
    6478                 :          0 :                 return -1;
    6479                 :            : 
    6480                 :          0 :         return p2p_unauthorize(p2p, peer);
    6481                 :            : }
    6482                 :            : 
    6483                 :            : 
    6484                 :            : /**
    6485                 :            :  * wpas_p2p_disconnect - Disconnect from a P2P Group
    6486                 :            :  * @wpa_s: Pointer to wpa_supplicant data
    6487                 :            :  * Returns: 0 on success, -1 on failure
    6488                 :            :  *
    6489                 :            :  * This can be used to disconnect from a group in which the local end is a P2P
    6490                 :            :  * Client or to end a P2P Group in case the local end is the Group Owner. If a
    6491                 :            :  * virtual network interface was created for this group, that interface will be
    6492                 :            :  * removed. Otherwise, only the configured P2P group network will be removed
    6493                 :            :  * from the interface.
    6494                 :            :  */
    6495                 :        126 : int wpas_p2p_disconnect(struct wpa_supplicant *wpa_s)
    6496                 :            : {
    6497                 :            : 
    6498         [ +  + ]:        126 :         if (wpa_s == NULL)
    6499                 :          3 :                 return -1;
    6500                 :            : 
    6501                 :        249 :         return wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_REQUESTED) < 0 ?
    6502         [ +  + ]:        123 :                 -1 : 0;
    6503                 :            : }
    6504                 :            : 
    6505                 :            : 
    6506                 :        775 : int wpas_p2p_in_progress(struct wpa_supplicant *wpa_s)
    6507                 :            : {
    6508                 :            :         int ret;
    6509                 :            : 
    6510 [ +  + ][ -  + ]:        775 :         if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
    6511                 :          2 :                 return 0;
    6512                 :            : 
    6513                 :        773 :         ret = p2p_in_progress(wpa_s->global->p2p);
    6514         [ +  - ]:        773 :         if (ret == 0) {
    6515                 :            :                 /*
    6516                 :            :                  * Check whether there is an ongoing WPS provisioning step (or
    6517                 :            :                  * other parts of group formation) on another interface since
    6518                 :            :                  * p2p_in_progress() does not report this to avoid issues for
    6519                 :            :                  * scans during such provisioning step.
    6520                 :            :                  */
    6521 [ +  + ][ -  + ]:        773 :                 if (wpa_s->global->p2p_group_formation &&
    6522                 :        156 :                     wpa_s->global->p2p_group_formation != wpa_s) {
    6523                 :          0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Another interface (%s) "
    6524                 :            :                                 "in group formation",
    6525                 :            :                                 wpa_s->global->p2p_group_formation->ifname);
    6526                 :          0 :                         ret = 1;
    6527                 :            :                 }
    6528                 :            :         }
    6529                 :            : 
    6530 [ +  - ][ -  + ]:        773 :         if (!ret && wpa_s->global->p2p_go_wait_client.sec) {
    6531                 :            :                 struct os_reltime now;
    6532                 :          0 :                 os_get_reltime(&now);
    6533         [ #  # ]:          0 :                 if (os_reltime_expired(&now, &wpa_s->global->p2p_go_wait_client,
    6534                 :            :                                        P2P_MAX_INITIAL_CONN_WAIT_GO)) {
    6535                 :            :                         /* Wait for the first client has expired */
    6536                 :          0 :                         wpa_s->global->p2p_go_wait_client.sec = 0;
    6537                 :            :                 } else {
    6538                 :          0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Waiting for initial client connection during group formation");
    6539                 :          0 :                         ret = 1;
    6540                 :            :                 }
    6541                 :            :         }
    6542                 :            : 
    6543                 :        775 :         return ret;
    6544                 :            : }
    6545                 :            : 
    6546                 :            : 
    6547                 :        515 : void wpas_p2p_network_removed(struct wpa_supplicant *wpa_s,
    6548                 :            :                               struct wpa_ssid *ssid)
    6549                 :            : {
    6550         [ -  + ]:        515 :         if (wpa_s->p2p_in_provisioning && ssid->p2p_group &&
           [ #  #  #  # ]
    6551                 :          0 :             eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
    6552                 :          0 :                                  wpa_s->parent, NULL) > 0) {
    6553                 :            :                 /**
    6554                 :            :                  * Remove the network by scheduling the group formation
    6555                 :            :                  * timeout to happen immediately. The teardown code
    6556                 :            :                  * needs to be scheduled to run asynch later so that we
    6557                 :            :                  * don't delete data from under ourselves unexpectedly.
    6558                 :            :                  * Calling wpas_p2p_group_formation_timeout directly
    6559                 :            :                  * causes a series of crashes in WPS failure scenarios.
    6560                 :            :                  */
    6561                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Canceled group formation due to "
    6562                 :            :                            "P2P group network getting removed");
    6563                 :          0 :                 eloop_register_timeout(0, 0, wpas_p2p_group_formation_timeout,
    6564                 :          0 :                                        wpa_s->parent, NULL);
    6565                 :            :         }
    6566                 :        515 : }
    6567                 :            : 
    6568                 :            : 
    6569                 :        253 : struct wpa_ssid * wpas_p2p_get_persistent(struct wpa_supplicant *wpa_s,
    6570                 :            :                                           const u8 *addr, const u8 *ssid,
    6571                 :            :                                           size_t ssid_len)
    6572                 :            : {
    6573                 :            :         struct wpa_ssid *s;
    6574                 :            :         size_t i;
    6575                 :            : 
    6576         [ +  + ]:        278 :         for (s = wpa_s->conf->ssid; s; s = s->next) {
    6577         [ +  + ]:         61 :                 if (s->disabled != 2)
    6578                 :         21 :                         continue;
    6579 [ +  + ][ +  - ]:         40 :                 if (ssid &&
    6580         [ -  + ]:         15 :                     (ssid_len != s->ssid_len ||
    6581                 :         15 :                      os_memcmp(ssid, s->ssid, ssid_len) != 0))
    6582                 :          0 :                         continue;
    6583         [ +  + ]:         40 :                 if (addr == NULL) {
    6584         [ +  - ]:         11 :                         if (s->mode == WPAS_MODE_P2P_GO)
    6585                 :         11 :                                 return s;
    6586                 :          0 :                         continue;
    6587                 :            :                 }
    6588         [ +  + ]:         29 :                 if (os_memcmp(s->bssid, addr, ETH_ALEN) == 0)
    6589                 :         15 :                         return s; /* peer is GO in the persistent group */
    6590 [ +  - ][ -  + ]:         14 :                 if (s->mode != WPAS_MODE_P2P_GO || s->p2p_client_list == NULL)
    6591                 :          0 :                         continue;
    6592         [ +  + ]:         16 :                 for (i = 0; i < s->num_p2p_clients; i++) {
    6593         [ +  + ]:         12 :                         if (os_memcmp(s->p2p_client_list + i * ETH_ALEN,
    6594                 :            :                                       addr, ETH_ALEN) == 0)
    6595                 :         10 :                                 return s; /* peer is P2P client in persistent
    6596                 :            :                                            * group */
    6597                 :            :                 }
    6598                 :            :         }
    6599                 :            : 
    6600                 :        253 :         return NULL;
    6601                 :            : }
    6602                 :            : 
    6603                 :            : 
    6604                 :        101 : void wpas_p2p_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s,
    6605                 :            :                                        const u8 *addr)
    6606                 :            : {
    6607         [ +  + ]:        101 :         if (eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
    6608                 :        101 :                                  wpa_s->parent, NULL) > 0) {
    6609                 :            :                 /*
    6610                 :            :                  * This can happen if WPS provisioning step is not terminated
    6611                 :            :                  * cleanly (e.g., P2P Client does not send WSC_Done). Since the
    6612                 :            :                  * peer was able to connect, there is no need to time out group
    6613                 :            :                  * formation after this, though. In addition, this is used with
    6614                 :            :                  * the initial connection wait on the GO as a separate formation
    6615                 :            :                  * timeout and as such, expected to be hit after the initial WPS
    6616                 :            :                  * provisioning step.
    6617                 :            :                  */
    6618                 :         50 :                 wpa_printf(MSG_DEBUG, "P2P: Canceled P2P group formation timeout on data connection");
    6619                 :            :         }
    6620         [ +  + ]:        101 :         if (!wpa_s->p2p_go_group_formation_completed) {
    6621                 :         57 :                 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Marking group formation completed on GO on first data connection");
    6622                 :         57 :                 wpa_s->p2p_go_group_formation_completed = 1;
    6623                 :         57 :                 wpa_s->global->p2p_group_formation = NULL;
    6624                 :         57 :                 wpa_s->p2p_in_provisioning = 0;
    6625                 :            :         }
    6626                 :        101 :         wpa_s->global->p2p_go_wait_client.sec = 0;
    6627         [ +  + ]:        101 :         if (addr == NULL)
    6628                 :        101 :                 return;
    6629                 :         85 :         wpas_p2p_add_persistent_group_client(wpa_s, addr);
    6630                 :            : }
    6631                 :            : 
    6632                 :            : 
    6633                 :          0 : static void wpas_p2p_fallback_to_go_neg(struct wpa_supplicant *wpa_s,
    6634                 :            :                                         int group_added)
    6635                 :            : {
    6636                 :          0 :         struct wpa_supplicant *group = wpa_s;
    6637         [ #  # ]:          0 :         if (wpa_s->global->p2p_group_formation)
    6638                 :          0 :                 group = wpa_s->global->p2p_group_formation;
    6639                 :          0 :         wpa_s = wpa_s->parent;
    6640                 :          0 :         offchannel_send_action_done(wpa_s);
    6641         [ #  # ]:          0 :         if (group_added)
    6642                 :          0 :                 wpas_p2p_group_delete(group, P2P_GROUP_REMOVAL_SILENT);
    6643                 :          0 :         wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Fall back to GO Negotiation");
    6644                 :          0 :         wpas_p2p_connect(wpa_s, wpa_s->pending_join_dev_addr, wpa_s->p2p_pin,
    6645                 :          0 :                          wpa_s->p2p_wps_method, wpa_s->p2p_persistent_group, 0,
    6646                 :            :                          0, 0, wpa_s->p2p_go_intent, wpa_s->p2p_connect_freq,
    6647                 :            :                          wpa_s->p2p_persistent_id,
    6648                 :          0 :                          wpa_s->p2p_pd_before_go_neg,
    6649                 :          0 :                          wpa_s->p2p_go_ht40,
    6650                 :          0 :                          wpa_s->p2p_go_vht);
    6651                 :          0 : }
    6652                 :            : 
    6653                 :            : 
    6654                 :        133 : int wpas_p2p_scan_no_go_seen(struct wpa_supplicant *wpa_s)
    6655                 :            : {
    6656 [ -  + ][ #  # ]:        133 :         if (!wpa_s->p2p_fallback_to_go_neg ||
    6657                 :          0 :             wpa_s->p2p_in_provisioning <= 5)
    6658                 :        133 :                 return 0;
    6659                 :            : 
    6660         [ #  # ]:          0 :         if (wpas_p2p_peer_go(wpa_s, wpa_s->pending_join_dev_addr) > 0)
    6661                 :          0 :                 return 0; /* peer operating as a GO */
    6662                 :            : 
    6663                 :          0 :         wpa_dbg(wpa_s, MSG_DEBUG, "P2P: GO not found for p2p_connect-auto - "
    6664                 :            :                 "fallback to GO Negotiation");
    6665                 :          0 :         wpas_p2p_fallback_to_go_neg(wpa_s, 1);
    6666                 :            : 
    6667                 :        133 :         return 1;
    6668                 :            : }
    6669                 :            : 
    6670                 :            : 
    6671                 :        151 : unsigned int wpas_p2p_search_delay(struct wpa_supplicant *wpa_s)
    6672                 :            : {
    6673                 :            :         struct wpa_supplicant *ifs;
    6674                 :            : 
    6675         [ +  + ]:        151 :         if (wpa_s->wpa_state > WPA_SCANNING) {
    6676                 :          4 :                 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use %u ms search delay due to "
    6677                 :            :                         "concurrent operation",
    6678                 :            :                         P2P_CONCURRENT_SEARCH_DELAY);
    6679                 :          4 :                 return P2P_CONCURRENT_SEARCH_DELAY;
    6680                 :            :         }
    6681                 :            : 
    6682         [ +  + ]:        294 :         dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
    6683                 :            :                          radio_list) {
    6684 [ -  + ][ #  # ]:        147 :                 if (ifs != wpa_s && ifs->wpa_state > WPA_SCANNING) {
    6685                 :          0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use %u ms search "
    6686                 :            :                                 "delay due to concurrent operation on "
    6687                 :            :                                 "interface %s",
    6688                 :            :                                 P2P_CONCURRENT_SEARCH_DELAY, ifs->ifname);
    6689                 :          0 :                         return P2P_CONCURRENT_SEARCH_DELAY;
    6690                 :            :                 }
    6691                 :            :         }
    6692                 :            : 
    6693                 :        151 :         return 0;
    6694                 :            : }
    6695                 :            : 
    6696                 :            : 
    6697                 :          5 : static int wpas_p2p_remove_psk_entry(struct wpa_supplicant *wpa_s,
    6698                 :            :                                      struct wpa_ssid *s, const u8 *addr,
    6699                 :            :                                      int iface_addr)
    6700                 :            : {
    6701                 :            :         struct psk_list_entry *psk, *tmp;
    6702                 :          5 :         int changed = 0;
    6703                 :            : 
    6704         [ +  + ]:         10 :         dl_list_for_each_safe(psk, tmp, &s->psk_list, struct psk_list_entry,
    6705                 :            :                               list) {
    6706 [ -  + ][ #  # ]:          5 :                 if ((iface_addr && !psk->p2p &&
                 [ #  # ]
    6707         [ +  - ]:          5 :                      os_memcmp(addr, psk->addr, ETH_ALEN) == 0) ||
    6708 [ +  - ][ +  + ]:          5 :                     (!iface_addr && psk->p2p &&
    6709                 :          5 :                      os_memcmp(addr, psk->addr, ETH_ALEN) == 0)) {
    6710                 :          3 :                         wpa_dbg(wpa_s, MSG_DEBUG,
    6711                 :            :                                 "P2P: Remove persistent group PSK list entry for "
    6712                 :            :                                 MACSTR " p2p=%u",
    6713                 :            :                                 MAC2STR(psk->addr), psk->p2p);
    6714                 :          3 :                         dl_list_del(&psk->list);
    6715                 :          3 :                         os_free(psk);
    6716                 :          3 :                         changed++;
    6717                 :            :                 }
    6718                 :            :         }
    6719                 :            : 
    6720                 :          5 :         return changed;
    6721                 :            : }
    6722                 :            : 
    6723                 :            : 
    6724                 :          8 : void wpas_p2p_new_psk_cb(struct wpa_supplicant *wpa_s, const u8 *mac_addr,
    6725                 :            :                          const u8 *p2p_dev_addr,
    6726                 :            :                          const u8 *psk, size_t psk_len)
    6727                 :            : {
    6728                 :          8 :         struct wpa_ssid *ssid = wpa_s->current_ssid;
    6729                 :            :         struct wpa_ssid *persistent;
    6730                 :            :         struct psk_list_entry *p;
    6731                 :            : 
    6732         [ -  + ]:          8 :         if (psk_len != sizeof(p->psk))
    6733                 :          0 :                 return;
    6734                 :            : 
    6735         [ +  - ]:          8 :         if (p2p_dev_addr) {
    6736                 :          8 :                 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: New PSK for addr=" MACSTR
    6737                 :            :                         " p2p_dev_addr=" MACSTR,
    6738                 :            :                         MAC2STR(mac_addr), MAC2STR(p2p_dev_addr));
    6739         [ +  + ]:          8 :                 if (is_zero_ether_addr(p2p_dev_addr))
    6740                 :          1 :                         p2p_dev_addr = NULL;
    6741                 :            :         } else {
    6742                 :          0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: New PSK for addr=" MACSTR,
    6743                 :            :                         MAC2STR(mac_addr));
    6744                 :            :         }
    6745                 :            : 
    6746         [ +  + ]:          8 :         if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
    6747                 :          4 :                 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: new_psk_cb during group formation");
    6748                 :            :                 /* To be added to persistent group once created */
    6749         [ +  - ]:          4 :                 if (wpa_s->global->add_psk == NULL) {
    6750                 :          4 :                         wpa_s->global->add_psk = os_zalloc(sizeof(*p));
    6751         [ -  + ]:          4 :                         if (wpa_s->global->add_psk == NULL)
    6752                 :          0 :                                 return;
    6753                 :            :                 }
    6754                 :          4 :                 p = wpa_s->global->add_psk;
    6755         [ +  - ]:          4 :                 if (p2p_dev_addr) {
    6756                 :          4 :                         p->p2p = 1;
    6757                 :          4 :                         os_memcpy(p->addr, p2p_dev_addr, ETH_ALEN);
    6758                 :            :                 } else {
    6759                 :          0 :                         p->p2p = 0;
    6760                 :          0 :                         os_memcpy(p->addr, mac_addr, ETH_ALEN);
    6761                 :            :                 }
    6762                 :          4 :                 os_memcpy(p->psk, psk, psk_len);
    6763                 :          4 :                 return;
    6764                 :            :         }
    6765                 :            : 
    6766 [ +  - ][ +  + ]:          4 :         if (ssid->mode != WPAS_MODE_P2P_GO || !ssid->p2p_persistent_group) {
    6767                 :          2 :                 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Ignore new_psk_cb on not-persistent GO");
    6768                 :          2 :                 return;
    6769                 :            :         }
    6770                 :            : 
    6771                 :          2 :         persistent = wpas_p2p_get_persistent(wpa_s->parent, NULL, ssid->ssid,
    6772                 :            :                                              ssid->ssid_len);
    6773         [ -  + ]:          2 :         if (!persistent) {
    6774                 :          0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Could not find persistent group information to store the new PSK");
    6775                 :          0 :                 return;
    6776                 :            :         }
    6777                 :            : 
    6778                 :          2 :         p = os_zalloc(sizeof(*p));
    6779         [ -  + ]:          2 :         if (p == NULL)
    6780                 :          0 :                 return;
    6781         [ +  - ]:          2 :         if (p2p_dev_addr) {
    6782                 :          2 :                 p->p2p = 1;
    6783                 :          2 :                 os_memcpy(p->addr, p2p_dev_addr, ETH_ALEN);
    6784                 :            :         } else {
    6785                 :          0 :                 p->p2p = 0;
    6786                 :          0 :                 os_memcpy(p->addr, mac_addr, ETH_ALEN);
    6787                 :            :         }
    6788                 :          2 :         os_memcpy(p->psk, psk, psk_len);
    6789                 :            : 
    6790         [ -  + ]:          2 :         if (dl_list_len(&persistent->psk_list) > P2P_MAX_STORED_CLIENTS) {
    6791                 :            :                 struct psk_list_entry *last;
    6792         [ #  # ]:          0 :                 last = dl_list_last(&persistent->psk_list,
    6793                 :            :                                     struct psk_list_entry, list);
    6794                 :          0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Remove oldest PSK entry for "
    6795                 :            :                         MACSTR " (p2p=%u) to make room for a new one",
    6796                 :            :                         MAC2STR(last->addr), last->p2p);
    6797                 :          0 :                 dl_list_del(&last->list);
    6798                 :          0 :                 os_free(last);
    6799                 :            :         }
    6800                 :            : 
    6801         [ +  - ]:          2 :         wpas_p2p_remove_psk_entry(wpa_s->parent, persistent,
    6802                 :            :                                   p2p_dev_addr ? p2p_dev_addr : mac_addr,
    6803                 :            :                                   p2p_dev_addr == NULL);
    6804         [ +  - ]:          2 :         if (p2p_dev_addr) {
    6805                 :          2 :                 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Add new PSK for p2p_dev_addr="
    6806                 :            :                         MACSTR, MAC2STR(p2p_dev_addr));
    6807                 :            :         } else {
    6808                 :          0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Add new PSK for addr=" MACSTR,
    6809                 :            :                         MAC2STR(mac_addr));
    6810                 :            :         }
    6811                 :          2 :         dl_list_add(&persistent->psk_list, &p->list);
    6812                 :            : 
    6813   [ -  +  #  # ]:          2 :         if (wpa_s->parent->conf->update_config &&
    6814                 :          0 :             wpa_config_write(wpa_s->parent->confname, wpa_s->parent->conf))
    6815                 :          8 :                 wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration");
    6816                 :            : }
    6817                 :            : 
    6818                 :            : 
    6819                 :          3 : static void wpas_p2p_remove_psk(struct wpa_supplicant *wpa_s,
    6820                 :            :                                 struct wpa_ssid *s, const u8 *addr,
    6821                 :            :                                 int iface_addr)
    6822                 :            : {
    6823                 :            :         int res;
    6824                 :            : 
    6825                 :          3 :         res = wpas_p2p_remove_psk_entry(wpa_s, s, addr, iface_addr);
    6826         [ +  - ]:          3 :         if (res > 0 && wpa_s->conf->update_config &&
           [ -  +  #  # ]
    6827                 :          0 :             wpa_config_write(wpa_s->confname, wpa_s->conf))
    6828                 :          0 :                 wpa_dbg(wpa_s, MSG_DEBUG,
    6829                 :            :                         "P2P: Failed to update configuration");
    6830                 :          3 : }
    6831                 :            : 
    6832                 :            : 
    6833                 :          4 : static void wpas_p2p_remove_client_go(struct wpa_supplicant *wpa_s,
    6834                 :            :                                       const u8 *peer, int iface_addr)
    6835                 :            : {
    6836                 :            :         struct hostapd_data *hapd;
    6837                 :            :         struct hostapd_wpa_psk *psk, *prev, *rem;
    6838                 :            :         struct sta_info *sta;
    6839                 :            : 
    6840 [ +  - ][ +  - ]:          4 :         if (wpa_s->ap_iface == NULL || wpa_s->current_ssid == NULL ||
                 [ -  + ]
    6841                 :          4 :             wpa_s->current_ssid->mode != WPAS_MODE_P2P_GO)
    6842                 :          4 :                 return;
    6843                 :            : 
    6844                 :            :         /* Remove per-station PSK entry */
    6845                 :          4 :         hapd = wpa_s->ap_iface->bss[0];
    6846                 :          4 :         prev = NULL;
    6847                 :          4 :         psk = hapd->conf->ssid.wpa_psk;
    6848         [ +  + ]:         12 :         while (psk) {
    6849 [ -  + ][ #  # ]:          8 :                 if ((iface_addr && os_memcmp(peer, psk->addr, ETH_ALEN) == 0) ||
                 [ +  - ]
    6850         [ +  + ]:          8 :                     (!iface_addr &&
    6851                 :          8 :                      os_memcmp(peer, psk->p2p_dev_addr, ETH_ALEN) == 0)) {
    6852                 :          3 :                         wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Remove operating group PSK entry for "
    6853                 :            :                                 MACSTR " iface_addr=%d",
    6854                 :            :                                 MAC2STR(peer), iface_addr);
    6855         [ -  + ]:          3 :                         if (prev)
    6856                 :          0 :                                 prev->next = psk->next;
    6857                 :            :                         else
    6858                 :          3 :                                 hapd->conf->ssid.wpa_psk = psk->next;
    6859                 :          3 :                         rem = psk;
    6860                 :          3 :                         psk = psk->next;
    6861                 :          3 :                         os_free(rem);
    6862                 :            :                 } else {
    6863                 :          5 :                         prev = psk;
    6864                 :          5 :                         psk = psk->next;
    6865                 :            :                 }
    6866                 :            :         }
    6867                 :            : 
    6868                 :            :         /* Disconnect from group */
    6869         [ -  + ]:          4 :         if (iface_addr)
    6870                 :          0 :                 sta = ap_get_sta(hapd, peer);
    6871                 :            :         else
    6872                 :          4 :                 sta = ap_get_sta_p2p(hapd, peer);
    6873         [ +  - ]:          4 :         if (sta) {
    6874                 :          4 :                 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Disconnect peer " MACSTR
    6875                 :            :                         " (iface_addr=%d) from group",
    6876                 :            :                         MAC2STR(peer), iface_addr);
    6877                 :          4 :                 hostapd_drv_sta_deauth(hapd, sta->addr,
    6878                 :            :                                        WLAN_REASON_DEAUTH_LEAVING);
    6879                 :          4 :                 ap_sta_deauthenticate(hapd, sta, WLAN_REASON_DEAUTH_LEAVING);
    6880                 :            :         }
    6881                 :            : }
    6882                 :            : 
    6883                 :            : 
    6884                 :          4 : void wpas_p2p_remove_client(struct wpa_supplicant *wpa_s, const u8 *peer,
    6885                 :            :                             int iface_addr)
    6886                 :            : {
    6887                 :            :         struct wpa_ssid *s;
    6888                 :            :         struct wpa_supplicant *w;
    6889                 :            : 
    6890                 :          4 :         wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Remove client " MACSTR, MAC2STR(peer));
    6891                 :            : 
    6892                 :            :         /* Remove from any persistent group */
    6893         [ +  + ]:         11 :         for (s = wpa_s->parent->conf->ssid; s; s = s->next) {
    6894 [ +  + ][ -  + ]:          7 :                 if (s->disabled != 2 || s->mode != WPAS_MODE_P2P_GO)
    6895                 :          4 :                         continue;
    6896         [ +  - ]:          3 :                 if (!iface_addr)
    6897                 :          3 :                         wpas_remove_persistent_peer(wpa_s, s, peer, 0);
    6898                 :          3 :                 wpas_p2p_remove_psk(wpa_s->parent, s, peer, iface_addr);
    6899                 :            :         }
    6900                 :            : 
    6901                 :            :         /* Remove from any operating group */
    6902         [ +  + ]:          8 :         for (w = wpa_s->global->ifaces; w; w = w->next)
    6903                 :          4 :                 wpas_p2p_remove_client_go(w, peer, iface_addr);
    6904                 :          4 : }
    6905                 :            : 
    6906                 :            : 
    6907                 :          2 : static void wpas_p2p_psk_failure_removal(void *eloop_ctx, void *timeout_ctx)
    6908                 :            : {
    6909                 :          2 :         struct wpa_supplicant *wpa_s = eloop_ctx;
    6910                 :          2 :         wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_PSK_FAILURE);
    6911                 :          2 : }
    6912                 :            : 
    6913                 :            : 
    6914                 :          0 : static void wpas_p2p_group_freq_conflict(void *eloop_ctx, void *timeout_ctx)
    6915                 :            : {
    6916                 :          0 :         struct wpa_supplicant *wpa_s = eloop_ctx;
    6917                 :            : 
    6918                 :          0 :         wpa_printf(MSG_DEBUG, "P2P: Frequency conflict - terminate group");
    6919                 :          0 :         wpas_p2p_group_delete(wpa_s, P2P_GROUP_REMOVAL_FREQ_CONFLICT);
    6920                 :          0 : }
    6921                 :            : 
    6922                 :            : 
    6923                 :          0 : int wpas_p2p_handle_frequency_conflicts(struct wpa_supplicant *wpa_s, int freq,
    6924                 :            :                                         struct wpa_ssid *ssid)
    6925                 :            : {
    6926                 :            :         struct wpa_supplicant *iface;
    6927                 :            : 
    6928         [ #  # ]:          0 :         for (iface = wpa_s->global->ifaces; iface; iface = iface->next) {
    6929 [ #  # ][ #  # ]:          0 :                 if (!iface->current_ssid ||
    6930         [ #  # ]:          0 :                     iface->current_ssid->frequency == freq ||
    6931         [ #  # ]:          0 :                     (iface->p2p_group_interface == NOT_P2P_GROUP_INTERFACE &&
    6932                 :          0 :                      !iface->current_ssid->p2p_group))
    6933                 :          0 :                         continue;
    6934                 :            : 
    6935                 :            :                 /* Remove the connection with least priority */
    6936         [ #  # ]:          0 :                 if (!wpas_is_p2p_prioritized(iface)) {
    6937                 :            :                         /* STA connection has priority over existing
    6938                 :            :                          * P2P connection, so remove the interface. */
    6939                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: Removing P2P connection due to single channel concurrent mode frequency conflict");
    6940                 :          0 :                         eloop_register_timeout(0, 0,
    6941                 :            :                                                wpas_p2p_group_freq_conflict,
    6942                 :            :                                                iface, NULL);
    6943                 :            :                         /* If connection in progress is P2P connection, do not
    6944                 :            :                          * proceed for the connection. */
    6945         [ #  # ]:          0 :                         if (wpa_s == iface)
    6946                 :          0 :                                 return -1;
    6947                 :            :                         else
    6948                 :          0 :                                 return 0;
    6949                 :            :                 } else {
    6950                 :            :                         /* P2P connection has priority, disable the STA network
    6951                 :            :                          */
    6952                 :          0 :                         wpa_supplicant_disable_network(wpa_s->global->ifaces,
    6953                 :            :                                                        ssid);
    6954                 :          0 :                         wpa_msg(wpa_s->global->ifaces, MSG_INFO,
    6955                 :            :                                 WPA_EVENT_FREQ_CONFLICT " id=%d", ssid->id);
    6956                 :          0 :                         os_memset(wpa_s->global->ifaces->pending_bssid, 0,
    6957                 :            :                                   ETH_ALEN);
    6958                 :            :                         /* If P2P connection is in progress, continue
    6959                 :            :                          * connecting...*/
    6960         [ #  # ]:          0 :                         if (wpa_s == iface)
    6961                 :          0 :                                 return 0;
    6962                 :            :                         else
    6963                 :          0 :                                 return -1;
    6964                 :            :                 }
    6965                 :            :         }
    6966                 :            : 
    6967                 :          0 :         return 0;
    6968                 :            : }
    6969                 :            : 
    6970                 :            : 
    6971                 :          9 : int wpas_p2p_4way_hs_failed(struct wpa_supplicant *wpa_s)
    6972                 :            : {
    6973                 :          9 :         struct wpa_ssid *ssid = wpa_s->current_ssid;
    6974                 :            : 
    6975 [ +  - ][ +  + ]:          9 :         if (ssid == NULL || !ssid->p2p_group)
    6976                 :          2 :                 return 0;
    6977                 :            : 
    6978 [ +  + ][ +  - ]:          7 :         if (wpa_s->p2p_last_4way_hs_fail &&
    6979                 :          2 :             wpa_s->p2p_last_4way_hs_fail == ssid) {
    6980                 :            :                 u8 go_dev_addr[ETH_ALEN];
    6981                 :            :                 struct wpa_ssid *persistent;
    6982                 :            : 
    6983         [ -  + ]:          2 :                 if (wpas_p2p_persistent_group(wpa_s, go_dev_addr,
    6984                 :          2 :                                               ssid->ssid,
    6985                 :            :                                               ssid->ssid_len) <= 0) {
    6986                 :          0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Could not determine whether 4-way handshake failures were for a persistent group");
    6987                 :          0 :                         goto disconnect;
    6988                 :            :                 }
    6989                 :            : 
    6990                 :          2 :                 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Two 4-way handshake failures for a P2P group - go_dev_addr="
    6991                 :            :                         MACSTR, MAC2STR(go_dev_addr));
    6992                 :          2 :                 persistent = wpas_p2p_get_persistent(wpa_s->parent, go_dev_addr,
    6993                 :          2 :                                                      ssid->ssid,
    6994                 :            :                                                      ssid->ssid_len);
    6995 [ +  - ][ -  + ]:          2 :                 if (persistent == NULL || persistent->mode != WPAS_MODE_INFRA) {
    6996                 :          0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "P2P: No matching persistent group stored");
    6997                 :          0 :                         goto disconnect;
    6998                 :            :                 }
    6999                 :          2 :                 wpa_msg_global(wpa_s->parent, MSG_INFO,
    7000                 :            :                                P2P_EVENT_PERSISTENT_PSK_FAIL "%d",
    7001                 :            :                                persistent->id);
    7002                 :            :         disconnect:
    7003                 :          2 :                 wpa_s->p2p_last_4way_hs_fail = NULL;
    7004                 :            :                 /*
    7005                 :            :                  * Remove the group from a timeout to avoid issues with caller
    7006                 :            :                  * continuing to use the interface if this is on a P2P group
    7007                 :            :                  * interface.
    7008                 :            :                  */
    7009                 :          2 :                 eloop_register_timeout(0, 0, wpas_p2p_psk_failure_removal,
    7010                 :            :                                        wpa_s, NULL);
    7011                 :          2 :                 return 1;
    7012                 :            :         }
    7013                 :            : 
    7014                 :          5 :         wpa_s->p2p_last_4way_hs_fail = ssid;
    7015                 :          9 :         return 0;
    7016                 :            : }
    7017                 :            : 
    7018                 :            : 
    7019                 :            : #ifdef CONFIG_WPS_NFC
    7020                 :            : 
    7021                 :         21 : static struct wpabuf * wpas_p2p_nfc_handover(int ndef, struct wpabuf *wsc,
    7022                 :            :                                              struct wpabuf *p2p)
    7023                 :            : {
    7024                 :            :         struct wpabuf *ret;
    7025                 :            :         size_t wsc_len;
    7026                 :            : 
    7027         [ -  + ]:         21 :         if (p2p == NULL) {
    7028                 :          0 :                 wpabuf_free(wsc);
    7029                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: No p2p buffer for handover");
    7030                 :          0 :                 return NULL;
    7031                 :            :         }
    7032                 :            : 
    7033         [ +  + ]:         21 :         wsc_len = wsc ? wpabuf_len(wsc) : 0;
    7034                 :         21 :         ret = wpabuf_alloc(2 + wsc_len + 2 + wpabuf_len(p2p));
    7035         [ -  + ]:         21 :         if (ret == NULL) {
    7036                 :          0 :                 wpabuf_free(wsc);
    7037                 :          0 :                 wpabuf_free(p2p);
    7038                 :          0 :                 return NULL;
    7039                 :            :         }
    7040                 :            : 
    7041                 :         21 :         wpabuf_put_be16(ret, wsc_len);
    7042         [ +  + ]:         21 :         if (wsc)
    7043                 :         20 :                 wpabuf_put_buf(ret, wsc);
    7044                 :         21 :         wpabuf_put_be16(ret, wpabuf_len(p2p));
    7045                 :         21 :         wpabuf_put_buf(ret, p2p);
    7046                 :            : 
    7047                 :         21 :         wpabuf_free(wsc);
    7048                 :         21 :         wpabuf_free(p2p);
    7049                 :         21 :         wpa_hexdump_buf(MSG_DEBUG,
    7050                 :            :                         "P2P: Generated NFC connection handover message", ret);
    7051                 :            : 
    7052 [ +  - ][ +  - ]:         21 :         if (ndef && ret) {
    7053                 :            :                 struct wpabuf *tmp;
    7054                 :         21 :                 tmp = ndef_build_p2p(ret);
    7055                 :         21 :                 wpabuf_free(ret);
    7056         [ -  + ]:         21 :                 if (tmp == NULL) {
    7057                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: Failed to NDEF encapsulate handover request");
    7058                 :          0 :                         return NULL;
    7059                 :            :                 }
    7060                 :         21 :                 ret = tmp;
    7061                 :            :         }
    7062                 :            : 
    7063                 :         21 :         return ret;
    7064                 :            : }
    7065                 :            : 
    7066                 :            : 
    7067                 :         40 : static int wpas_p2p_cli_freq(struct wpa_supplicant *wpa_s,
    7068                 :            :                              struct wpa_ssid **ssid, u8 *go_dev_addr)
    7069                 :            : {
    7070                 :            :         struct wpa_supplicant *iface;
    7071                 :            : 
    7072         [ +  + ]:         40 :         if (go_dev_addr)
    7073                 :         21 :                 os_memset(go_dev_addr, 0, ETH_ALEN);
    7074         [ +  + ]:         40 :         if (ssid)
    7075                 :         21 :                 *ssid = NULL;
    7076         [ +  + ]:         78 :         for (iface = wpa_s->global->ifaces; iface; iface = iface->next) {
    7077 [ +  + ][ +  - ]:         40 :                 if (iface->wpa_state < WPA_ASSOCIATING ||
    7078 [ +  - ][ +  - ]:         11 :                     iface->current_ssid == NULL || iface->assoc_freq == 0 ||
    7079         [ +  + ]:         11 :                     !iface->current_ssid->p2p_group ||
    7080                 :         11 :                     iface->current_ssid->mode != WPAS_MODE_INFRA)
    7081                 :         38 :                         continue;
    7082         [ +  + ]:          2 :                 if (ssid)
    7083                 :          1 :                         *ssid = iface->current_ssid;
    7084         [ +  + ]:          2 :                 if (go_dev_addr)
    7085                 :          1 :                         os_memcpy(go_dev_addr, iface->go_dev_addr, ETH_ALEN);
    7086                 :          2 :                 return iface->assoc_freq;
    7087                 :            :         }
    7088                 :         40 :         return 0;
    7089                 :            : }
    7090                 :            : 
    7091                 :            : 
    7092                 :          8 : struct wpabuf * wpas_p2p_nfc_handover_req(struct wpa_supplicant *wpa_s,
    7093                 :            :                                           int ndef)
    7094                 :            : {
    7095                 :            :         struct wpabuf *wsc, *p2p;
    7096                 :            :         struct wpa_ssid *ssid;
    7097                 :            :         u8 go_dev_addr[ETH_ALEN];
    7098                 :          8 :         int cli_freq = wpas_p2p_cli_freq(wpa_s, &ssid, go_dev_addr);
    7099                 :            : 
    7100 [ +  - ][ -  + ]:          8 :         if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) {
    7101                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: P2P disabled - cannot build handover request");
    7102                 :          0 :                 return NULL;
    7103                 :            :         }
    7104                 :            : 
    7105   [ +  +  -  + ]:          9 :         if (wpa_s->conf->wps_nfc_dh_pubkey == NULL &&
    7106                 :          1 :             wps_nfc_gen_dh(&wpa_s->conf->wps_nfc_dh_pubkey,
    7107                 :          1 :                            &wpa_s->conf->wps_nfc_dh_privkey) < 0) {
    7108                 :          0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: No DH key available for handover request");
    7109                 :          0 :                 return NULL;
    7110                 :            :         }
    7111                 :            : 
    7112         [ +  + ]:          8 :         if (cli_freq == 0) {
    7113                 :          7 :                 wsc = wps_build_nfc_handover_req_p2p(
    7114                 :         14 :                         wpa_s->parent->wps, wpa_s->conf->wps_nfc_dh_pubkey);
    7115                 :            :         } else
    7116                 :          1 :                 wsc = NULL;
    7117 [ +  + ][ +  + ]:          8 :         p2p = p2p_build_nfc_handover_req(wpa_s->global->p2p, cli_freq,
    7118                 :          9 :                                          go_dev_addr, ssid ? ssid->ssid : NULL,
    7119                 :          9 :                                          ssid ? ssid->ssid_len : 0);
    7120                 :            : 
    7121                 :          8 :         return wpas_p2p_nfc_handover(ndef, wsc, p2p);
    7122                 :            : }
    7123                 :            : 
    7124                 :            : 
    7125                 :         13 : struct wpabuf * wpas_p2p_nfc_handover_sel(struct wpa_supplicant *wpa_s,
    7126                 :            :                                           int ndef, int tag)
    7127                 :            : {
    7128                 :            :         struct wpabuf *wsc, *p2p;
    7129                 :            :         struct wpa_ssid *ssid;
    7130                 :            :         u8 go_dev_addr[ETH_ALEN];
    7131                 :         13 :         int cli_freq = wpas_p2p_cli_freq(wpa_s, &ssid, go_dev_addr);
    7132                 :            : 
    7133 [ +  - ][ -  + ]:         13 :         if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
    7134                 :          0 :                 return NULL;
    7135                 :            : 
    7136         [ +  + ]:         15 :         if (!tag && wpa_s->conf->wps_nfc_dh_pubkey == NULL &&
           [ +  +  -  + ]
    7137                 :          2 :             wps_nfc_gen_dh(&wpa_s->conf->wps_nfc_dh_pubkey,
    7138                 :          2 :                            &wpa_s->conf->wps_nfc_dh_privkey) < 0)
    7139                 :          0 :                 return NULL;
    7140                 :            : 
    7141         [ +  - ]:         13 :         if (cli_freq == 0) {
    7142 [ +  + ][ +  + ]:         13 :                 wsc = wps_build_nfc_handover_sel_p2p(
    7143                 :         13 :                         wpa_s->parent->wps,
    7144                 :          5 :                         tag ? wpa_s->conf->wps_nfc_dev_pw_id :
    7145                 :            :                         DEV_PW_NFC_CONNECTION_HANDOVER,
    7146                 :         13 :                         wpa_s->conf->wps_nfc_dh_pubkey,
    7147                 :          5 :                         tag ? wpa_s->conf->wps_nfc_dev_pw : NULL);
    7148                 :            :         } else
    7149                 :          0 :                 wsc = NULL;
    7150 [ -  + ][ -  + ]:         13 :         p2p = p2p_build_nfc_handover_sel(wpa_s->global->p2p, cli_freq,
    7151                 :         13 :                                          go_dev_addr, ssid ? ssid->ssid : NULL,
    7152                 :         13 :                                          ssid ? ssid->ssid_len : 0);
    7153                 :            : 
    7154                 :         13 :         return wpas_p2p_nfc_handover(ndef, wsc, p2p);
    7155                 :            : }
    7156                 :            : 
    7157                 :            : 
    7158                 :          4 : static int wpas_p2p_nfc_join_group(struct wpa_supplicant *wpa_s,
    7159                 :            :                                    struct p2p_nfc_params *params)
    7160                 :            : {
    7161                 :          4 :         wpa_printf(MSG_DEBUG, "P2P: Initiate join-group based on NFC "
    7162                 :            :                    "connection handover (freq=%d)",
    7163                 :            :                    params->go_freq);
    7164                 :            : 
    7165 [ +  - ][ +  - ]:          4 :         if (params->go_freq && params->go_ssid_len) {
    7166                 :          4 :                 wpa_s->p2p_wps_method = WPS_NFC;
    7167                 :          4 :                 wpa_s->pending_join_wps_method = WPS_NFC;
    7168                 :          4 :                 os_memset(wpa_s->pending_join_iface_addr, 0, ETH_ALEN);
    7169                 :          4 :                 os_memcpy(wpa_s->pending_join_dev_addr, params->go_dev_addr,
    7170                 :            :                           ETH_ALEN);
    7171                 :          4 :                 return wpas_p2p_join_start(wpa_s, params->go_freq,
    7172                 :          4 :                                            params->go_ssid,
    7173                 :            :                                            params->go_ssid_len);
    7174                 :            :         }
    7175                 :            : 
    7176                 :          4 :         return wpas_p2p_connect(wpa_s, params->peer->p2p_device_addr, NULL,
    7177                 :          0 :                                 WPS_NFC, 0, 0, 1, 0, wpa_s->conf->p2p_go_intent,
    7178                 :            :                                 params->go_freq, -1, 0, 1, 1);
    7179                 :            : }
    7180                 :            : 
    7181                 :            : 
    7182                 :          4 : static int wpas_p2p_nfc_auth_join(struct wpa_supplicant *wpa_s,
    7183                 :            :                                   struct p2p_nfc_params *params, int tag)
    7184                 :            : {
    7185                 :            :         int res, persistent;
    7186                 :            :         struct wpa_ssid *ssid;
    7187                 :            : 
    7188                 :          4 :         wpa_printf(MSG_DEBUG, "P2P: Authorize join-group based on NFC "
    7189                 :            :                    "connection handover");
    7190         [ +  - ]:          4 :         for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
    7191                 :          4 :                 ssid = wpa_s->current_ssid;
    7192         [ -  + ]:          4 :                 if (ssid == NULL)
    7193                 :          0 :                         continue;
    7194         [ -  + ]:          4 :                 if (ssid->mode != WPAS_MODE_P2P_GO)
    7195                 :          0 :                         continue;
    7196         [ -  + ]:          4 :                 if (wpa_s->ap_iface == NULL)
    7197                 :          0 :                         continue;
    7198                 :          4 :                 break;
    7199                 :            :         }
    7200         [ -  + ]:          4 :         if (wpa_s == NULL) {
    7201                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Could not find GO interface");
    7202                 :          0 :                 return -1;
    7203                 :            :         }
    7204                 :            : 
    7205         [ +  + ]:          4 :         if (wpa_s->parent->p2p_oob_dev_pw_id !=
    7206         [ -  + ]:          2 :             DEV_PW_NFC_CONNECTION_HANDOVER &&
    7207                 :          2 :             !wpa_s->parent->p2p_oob_dev_pw) {
    7208                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: No NFC Dev Pw known");
    7209                 :          0 :                 return -1;
    7210                 :            :         }
    7211         [ +  - ]:          4 :         res = wpas_ap_wps_add_nfc_pw(
    7212                 :          4 :                 wpa_s, wpa_s->parent->p2p_oob_dev_pw_id,
    7213                 :          4 :                 wpa_s->parent->p2p_oob_dev_pw,
    7214                 :          4 :                 wpa_s->parent->p2p_peer_oob_pk_hash_known ?
    7215                 :          4 :                 wpa_s->parent->p2p_peer_oob_pubkey_hash : NULL);
    7216         [ -  + ]:          4 :         if (res)
    7217                 :          0 :                 return res;
    7218                 :            : 
    7219         [ +  + ]:          4 :         if (!tag) {
    7220                 :          2 :                 wpa_printf(MSG_DEBUG, "P2P: Negotiated handover - wait for peer to join without invitation");
    7221                 :          2 :                 return 0;
    7222                 :            :         }
    7223                 :            : 
    7224 [ +  - ][ -  + ]:          2 :         if (!params->peer ||
    7225                 :          2 :             !(params->peer->dev_capab & P2P_DEV_CAPAB_INVITATION_PROCEDURE))
    7226                 :          0 :                 return 0;
    7227                 :            : 
    7228                 :          2 :         wpa_printf(MSG_DEBUG, "P2P: Static handover - invite peer " MACSTR
    7229                 :         12 :                    " to join", MAC2STR(params->peer->p2p_device_addr));
    7230                 :            : 
    7231                 :          2 :         wpa_s->global->p2p_invite_group = wpa_s;
    7232   [ -  +  #  # ]:          2 :         persistent = ssid->p2p_persistent_group &&
    7233                 :          0 :                 wpas_p2p_get_persistent(wpa_s->parent,
    7234                 :          0 :                                         params->peer->p2p_device_addr,
    7235                 :          0 :                                         ssid->ssid, ssid->ssid_len);
    7236                 :          2 :         wpa_s->parent->pending_invite_ssid_id = -1;
    7237                 :            : 
    7238                 :          4 :         return p2p_invite(wpa_s->global->p2p, params->peer->p2p_device_addr,
    7239                 :          2 :                           P2P_INVITE_ROLE_ACTIVE_GO, wpa_s->own_addr,
    7240                 :          4 :                           ssid->ssid, ssid->ssid_len, ssid->frequency,
    7241                 :          2 :                           wpa_s->global->p2p_dev_addr, persistent, 0,
    7242                 :          2 :                           wpa_s->parent->p2p_oob_dev_pw_id);
    7243                 :            : }
    7244                 :            : 
    7245                 :            : 
    7246                 :          6 : static int wpas_p2p_nfc_init_go_neg(struct wpa_supplicant *wpa_s,
    7247                 :            :                                     struct p2p_nfc_params *params,
    7248                 :            :                                     int forced_freq)
    7249                 :            : {
    7250                 :          6 :         wpa_printf(MSG_DEBUG, "P2P: Initiate GO Negotiation based on NFC "
    7251                 :            :                    "connection handover");
    7252                 :          6 :         return wpas_p2p_connect(wpa_s, params->peer->p2p_device_addr, NULL,
    7253                 :          6 :                                 WPS_NFC, 0, 0, 0, 0, wpa_s->conf->p2p_go_intent,
    7254                 :            :                                 forced_freq, -1, 0, 1, 1);
    7255                 :            : }
    7256                 :            : 
    7257                 :            : 
    7258                 :          4 : static int wpas_p2p_nfc_resp_go_neg(struct wpa_supplicant *wpa_s,
    7259                 :            :                                     struct p2p_nfc_params *params,
    7260                 :            :                                     int forced_freq)
    7261                 :            : {
    7262                 :            :         int res;
    7263                 :            : 
    7264                 :          4 :         wpa_printf(MSG_DEBUG, "P2P: Authorize GO Negotiation based on NFC "
    7265                 :            :                    "connection handover");
    7266                 :          4 :         res = wpas_p2p_connect(wpa_s, params->peer->p2p_device_addr, NULL,
    7267                 :          4 :                                WPS_NFC, 0, 0, 0, 1, wpa_s->conf->p2p_go_intent,
    7268                 :            :                                forced_freq, -1, 0, 1, 1);
    7269         [ -  + ]:          4 :         if (res)
    7270                 :          0 :                 return res;
    7271                 :            : 
    7272                 :          4 :         res = wpas_p2p_listen(wpa_s, 60);
    7273         [ -  + ]:          4 :         if (res) {
    7274                 :          0 :                 p2p_unauthorize(wpa_s->global->p2p,
    7275                 :          0 :                                 params->peer->p2p_device_addr);
    7276                 :            :         }
    7277                 :            : 
    7278                 :          4 :         return res;
    7279                 :            : }
    7280                 :            : 
    7281                 :            : 
    7282                 :         22 : static int wpas_p2p_nfc_connection_handover(struct wpa_supplicant *wpa_s,
    7283                 :            :                                             const struct wpabuf *data,
    7284                 :            :                                             int sel, int tag, int forced_freq)
    7285                 :            : {
    7286                 :            :         const u8 *pos, *end;
    7287                 :            :         u16 len, id;
    7288                 :            :         struct p2p_nfc_params params;
    7289                 :            :         int res;
    7290                 :            : 
    7291                 :         22 :         os_memset(&params, 0, sizeof(params));
    7292                 :         22 :         params.sel = sel;
    7293                 :            : 
    7294                 :         22 :         wpa_hexdump_buf(MSG_DEBUG, "P2P: Received NFC tag payload", data);
    7295                 :            : 
    7296                 :         22 :         pos = wpabuf_head(data);
    7297                 :         22 :         end = pos + wpabuf_len(data);
    7298                 :            : 
    7299         [ -  + ]:         22 :         if (end - pos < 2) {
    7300                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Not enough data for Length of WSC "
    7301                 :            :                            "attributes");
    7302                 :          0 :                 return -1;
    7303                 :            :         }
    7304                 :         22 :         len = WPA_GET_BE16(pos);
    7305                 :         22 :         pos += 2;
    7306         [ -  + ]:         22 :         if (pos + len > end) {
    7307                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Not enough data for WSC "
    7308                 :            :                            "attributes");
    7309                 :          0 :                 return -1;
    7310                 :            :         }
    7311                 :         22 :         params.wsc_attr = pos;
    7312                 :         22 :         params.wsc_len = len;
    7313                 :         22 :         pos += len;
    7314                 :            : 
    7315         [ -  + ]:         22 :         if (end - pos < 2) {
    7316                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Not enough data for Length of P2P "
    7317                 :            :                            "attributes");
    7318                 :          0 :                 return -1;
    7319                 :            :         }
    7320                 :         22 :         len = WPA_GET_BE16(pos);
    7321                 :         22 :         pos += 2;
    7322         [ -  + ]:         22 :         if (pos + len > end) {
    7323                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Not enough data for P2P "
    7324                 :            :                            "attributes");
    7325                 :          0 :                 return -1;
    7326                 :            :         }
    7327                 :         22 :         params.p2p_attr = pos;
    7328                 :         22 :         params.p2p_len = len;
    7329                 :         22 :         pos += len;
    7330                 :            : 
    7331                 :         22 :         wpa_hexdump(MSG_DEBUG, "P2P: WSC attributes",
    7332                 :         22 :                     params.wsc_attr, params.wsc_len);
    7333                 :         22 :         wpa_hexdump(MSG_DEBUG, "P2P: P2P attributes",
    7334                 :         22 :                     params.p2p_attr, params.p2p_len);
    7335         [ -  + ]:         22 :         if (pos < end) {
    7336                 :          0 :                 wpa_hexdump(MSG_DEBUG,
    7337                 :            :                             "P2P: Ignored extra data after P2P attributes",
    7338                 :          0 :                             pos, end - pos);
    7339                 :            :         }
    7340                 :            : 
    7341                 :         22 :         res = p2p_process_nfc_connection_handover(wpa_s->global->p2p, &params);
    7342         [ -  + ]:         22 :         if (res)
    7343                 :          0 :                 return res;
    7344                 :            : 
    7345         [ -  + ]:         22 :         if (params.next_step == NO_ACTION)
    7346                 :          0 :                 return 0;
    7347                 :            : 
    7348         [ +  + ]:         22 :         if (params.next_step == BOTH_GO) {
    7349                 :          2 :                 wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_NFC_BOTH_GO "peer=" MACSTR,
    7350                 :         12 :                         MAC2STR(params.peer->p2p_device_addr));
    7351                 :          2 :                 return 0;
    7352                 :            :         }
    7353                 :            : 
    7354         [ +  + ]:         20 :         if (params.next_step == PEER_CLIENT) {
    7355         [ +  - ]:          1 :                 if (!is_zero_ether_addr(params.go_dev_addr)) {
    7356                 :          1 :                         wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_NFC_PEER_CLIENT
    7357                 :            :                                 "peer=" MACSTR " freq=%d go_dev_addr=" MACSTR
    7358                 :            :                                 " ssid=\"%s\"",
    7359                 :          6 :                                 MAC2STR(params.peer->p2p_device_addr),
    7360                 :            :                                 params.go_freq,
    7361                 :          6 :                                 MAC2STR(params.go_dev_addr),
    7362                 :            :                                 wpa_ssid_txt(params.go_ssid,
    7363                 :            :                                              params.go_ssid_len));
    7364                 :            :                 } else {
    7365                 :          0 :                         wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_NFC_PEER_CLIENT
    7366                 :            :                                 "peer=" MACSTR " freq=%d",
    7367                 :          0 :                                 MAC2STR(params.peer->p2p_device_addr),
    7368                 :            :                                 params.go_freq);
    7369                 :            :                 }
    7370                 :          1 :                 return 0;
    7371                 :            :         }
    7372                 :            : 
    7373         [ +  + ]:         19 :         if (wpas_p2p_cli_freq(wpa_s, NULL, NULL)) {
    7374                 :          1 :                 wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_NFC_WHILE_CLIENT "peer="
    7375                 :          6 :                         MACSTR, MAC2STR(params.peer->p2p_device_addr));
    7376                 :          1 :                 return 0;
    7377                 :            :         }
    7378                 :            : 
    7379                 :         18 :         wpabuf_free(wpa_s->p2p_oob_dev_pw);
    7380                 :         18 :         wpa_s->p2p_oob_dev_pw = NULL;
    7381                 :            : 
    7382         [ -  + ]:         18 :         if (params.oob_dev_pw_len < WPS_OOB_PUBKEY_HASH_LEN + 2) {
    7383                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: No peer OOB Dev Pw "
    7384                 :            :                            "received");
    7385                 :          0 :                 return -1;
    7386                 :            :         }
    7387                 :            : 
    7388                 :         18 :         id = WPA_GET_BE16(params.oob_dev_pw + WPS_OOB_PUBKEY_HASH_LEN);
    7389                 :         18 :         wpa_printf(MSG_DEBUG, "P2P: Peer OOB Dev Pw %u", id);
    7390                 :         18 :         wpa_hexdump(MSG_DEBUG, "P2P: Peer OOB Public Key hash",
    7391                 :            :                     params.oob_dev_pw, WPS_OOB_PUBKEY_HASH_LEN);
    7392                 :         18 :         os_memcpy(wpa_s->p2p_peer_oob_pubkey_hash,
    7393                 :            :                   params.oob_dev_pw, WPS_OOB_PUBKEY_HASH_LEN);
    7394                 :         18 :         wpa_s->p2p_peer_oob_pk_hash_known = 1;
    7395                 :            : 
    7396         [ +  + ]:         18 :         if (tag) {
    7397         [ -  + ]:          6 :                 if (id < 0x10) {
    7398                 :          0 :                         wpa_printf(MSG_DEBUG, "P2P: Static handover - invalid "
    7399                 :            :                                    "peer OOB Device Password Id %u", id);
    7400                 :          0 :                         return -1;
    7401                 :            :                 }
    7402                 :          6 :                 wpa_printf(MSG_DEBUG, "P2P: Static handover - use peer OOB "
    7403                 :            :                            "Device Password Id %u", id);
    7404                 :          6 :                 wpa_hexdump_key(MSG_DEBUG, "P2P: Peer OOB Device Password",
    7405                 :            :                                 params.oob_dev_pw + WPS_OOB_PUBKEY_HASH_LEN + 2,
    7406                 :          6 :                                 params.oob_dev_pw_len -
    7407                 :            :                                 WPS_OOB_PUBKEY_HASH_LEN - 2);
    7408                 :          6 :                 wpa_s->p2p_oob_dev_pw_id = id;
    7409                 :          6 :                 wpa_s->p2p_oob_dev_pw = wpabuf_alloc_copy(
    7410                 :            :                         params.oob_dev_pw + WPS_OOB_PUBKEY_HASH_LEN + 2,
    7411                 :          6 :                         params.oob_dev_pw_len -
    7412                 :            :                         WPS_OOB_PUBKEY_HASH_LEN - 2);
    7413         [ -  + ]:          6 :                 if (wpa_s->p2p_oob_dev_pw == NULL)
    7414                 :          0 :                         return -1;
    7415                 :            : 
    7416   [ -  +  #  # ]:          6 :                 if (wpa_s->conf->wps_nfc_dh_pubkey == NULL &&
    7417                 :          0 :                     wps_nfc_gen_dh(&wpa_s->conf->wps_nfc_dh_pubkey,
    7418                 :          0 :                                    &wpa_s->conf->wps_nfc_dh_privkey) < 0)
    7419                 :          0 :                         return -1;
    7420                 :            :         } else {
    7421                 :         12 :                 wpa_printf(MSG_DEBUG, "P2P: Using abbreviated WPS handshake "
    7422                 :            :                            "without Device Password");
    7423                 :         12 :                 wpa_s->p2p_oob_dev_pw_id = DEV_PW_NFC_CONNECTION_HANDOVER;
    7424                 :            :         }
    7425                 :            : 
    7426   [ -  +  +  +  :         18 :         switch (params.next_step) {
                   +  - ]
    7427                 :            :         case NO_ACTION:
    7428                 :            :         case BOTH_GO:
    7429                 :            :         case PEER_CLIENT:
    7430                 :            :                 /* already covered above */
    7431                 :          0 :                 return 0;
    7432                 :            :         case JOIN_GROUP:
    7433                 :          4 :                 return wpas_p2p_nfc_join_group(wpa_s, &params);
    7434                 :            :         case AUTH_JOIN:
    7435                 :          4 :                 return wpas_p2p_nfc_auth_join(wpa_s, &params, tag);
    7436                 :            :         case INIT_GO_NEG:
    7437                 :          6 :                 return wpas_p2p_nfc_init_go_neg(wpa_s, &params, forced_freq);
    7438                 :            :         case RESP_GO_NEG:
    7439                 :            :                 /* TODO: use own OOB Dev Pw */
    7440                 :          4 :                 return wpas_p2p_nfc_resp_go_neg(wpa_s, &params, forced_freq);
    7441                 :            :         }
    7442                 :            : 
    7443                 :         22 :         return -1;
    7444                 :            : }
    7445                 :            : 
    7446                 :            : 
    7447                 :          6 : int wpas_p2p_nfc_tag_process(struct wpa_supplicant *wpa_s,
    7448                 :            :                              const struct wpabuf *data, int forced_freq)
    7449                 :            : {
    7450 [ +  - ][ -  + ]:          6 :         if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
    7451                 :          0 :                 return -1;
    7452                 :            : 
    7453                 :          6 :         return wpas_p2p_nfc_connection_handover(wpa_s, data, 1, 1, forced_freq);
    7454                 :            : }
    7455                 :            : 
    7456                 :            : 
    7457                 :         16 : int wpas_p2p_nfc_report_handover(struct wpa_supplicant *wpa_s, int init,
    7458                 :            :                                  const struct wpabuf *req,
    7459                 :            :                                  const struct wpabuf *sel, int forced_freq)
    7460                 :            : {
    7461                 :            :         struct wpabuf *tmp;
    7462                 :            :         int ret;
    7463                 :            : 
    7464 [ +  - ][ -  + ]:         16 :         if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
    7465                 :          0 :                 return -1;
    7466                 :            : 
    7467                 :         16 :         wpa_printf(MSG_DEBUG, "NFC: P2P connection handover reported");
    7468                 :            : 
    7469                 :         16 :         wpa_hexdump_ascii(MSG_DEBUG, "NFC: Req",
    7470                 :            :                           wpabuf_head(req), wpabuf_len(req));
    7471                 :         16 :         wpa_hexdump_ascii(MSG_DEBUG, "NFC: Sel",
    7472                 :            :                           wpabuf_head(sel), wpabuf_len(sel));
    7473         [ -  + ]:         16 :         if (forced_freq)
    7474                 :          0 :                 wpa_printf(MSG_DEBUG, "NFC: Forced freq %d", forced_freq);
    7475         [ +  + ]:         16 :         tmp = ndef_parse_p2p(init ? sel : req);
    7476         [ -  + ]:         16 :         if (tmp == NULL) {
    7477                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Could not parse NDEF");
    7478                 :          0 :                 return -1;
    7479                 :            :         }
    7480                 :            : 
    7481                 :         16 :         ret = wpas_p2p_nfc_connection_handover(wpa_s, tmp, init, 0,
    7482                 :            :                                                forced_freq);
    7483                 :         16 :         wpabuf_free(tmp);
    7484                 :            : 
    7485                 :         16 :         return ret;
    7486                 :            : }
    7487                 :            : 
    7488                 :            : 
    7489                 :          5 : int wpas_p2p_nfc_tag_enabled(struct wpa_supplicant *wpa_s, int enabled)
    7490                 :            : {
    7491                 :            :         const u8 *if_addr;
    7492                 :          5 :         int go_intent = wpa_s->conf->p2p_go_intent;
    7493                 :            :         struct wpa_supplicant *iface;
    7494                 :            : 
    7495         [ -  + ]:          5 :         if (wpa_s->global->p2p == NULL)
    7496                 :          0 :                 return -1;
    7497                 :            : 
    7498         [ -  + ]:          5 :         if (!enabled) {
    7499                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: Disable use of own NFC Tag");
    7500         [ #  # ]:          0 :                 for (iface = wpa_s->global->ifaces; iface; iface = iface->next)
    7501                 :            :                 {
    7502         [ #  # ]:          0 :                         if (!iface->ap_iface)
    7503                 :          0 :                                 continue;
    7504                 :          0 :                         hostapd_wps_nfc_token_disable(iface->ap_iface->bss[0]);
    7505                 :            :                 }
    7506                 :          0 :                 p2p_set_authorized_oob_dev_pw_id(wpa_s->global->p2p, 0,
    7507                 :            :                                                  0, NULL);
    7508         [ #  # ]:          0 :                 if (wpa_s->p2p_nfc_tag_enabled)
    7509                 :          0 :                         wpas_p2p_remove_pending_group_interface(wpa_s);
    7510                 :          0 :                 wpa_s->p2p_nfc_tag_enabled = 0;
    7511                 :          0 :                 return 0;
    7512                 :            :         }
    7513                 :            : 
    7514         [ -  + ]:          5 :         if (wpa_s->global->p2p_disabled)
    7515                 :          0 :                 return -1;
    7516                 :            : 
    7517 [ +  - ][ +  - ]:          5 :         if (wpa_s->conf->wps_nfc_dh_pubkey == NULL ||
    7518         [ +  - ]:          5 :             wpa_s->conf->wps_nfc_dh_privkey == NULL ||
    7519         [ -  + ]:          5 :             wpa_s->conf->wps_nfc_dev_pw == NULL ||
    7520                 :          5 :             wpa_s->conf->wps_nfc_dev_pw_id < 0x10) {
    7521                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: NFC password token not configured "
    7522                 :            :                            "to allow static handover cases");
    7523                 :          0 :                 return -1;
    7524                 :            :         }
    7525                 :            : 
    7526                 :          5 :         wpa_printf(MSG_DEBUG, "P2P: Enable use of own NFC Tag");
    7527                 :            : 
    7528                 :          5 :         wpa_s->p2p_oob_dev_pw_id = wpa_s->conf->wps_nfc_dev_pw_id;
    7529                 :          5 :         wpabuf_free(wpa_s->p2p_oob_dev_pw);
    7530                 :          5 :         wpa_s->p2p_oob_dev_pw = wpabuf_dup(wpa_s->conf->wps_nfc_dev_pw);
    7531         [ -  + ]:          5 :         if (wpa_s->p2p_oob_dev_pw == NULL)
    7532                 :          0 :                 return -1;
    7533                 :          5 :         wpa_s->p2p_peer_oob_pk_hash_known = 0;
    7534                 :            : 
    7535                 :          5 :         wpa_s->create_p2p_iface = wpas_p2p_create_iface(wpa_s);
    7536                 :            : 
    7537         [ -  + ]:          5 :         if (wpa_s->create_p2p_iface) {
    7538                 :            :                 enum wpa_driver_if_type iftype;
    7539                 :            :                 /* Prepare to add a new interface for the group */
    7540                 :          0 :                 iftype = WPA_IF_P2P_GROUP;
    7541         [ #  # ]:          0 :                 if (go_intent == 15)
    7542                 :          0 :                         iftype = WPA_IF_P2P_GO;
    7543         [ #  # ]:          0 :                 if (wpas_p2p_add_group_interface(wpa_s, iftype) < 0) {
    7544                 :          0 :                         wpa_printf(MSG_ERROR, "P2P: Failed to allocate a new "
    7545                 :            :                                    "interface for the group");
    7546                 :          0 :                         return -1;
    7547                 :            :                 }
    7548                 :            : 
    7549                 :          0 :                 if_addr = wpa_s->pending_interface_addr;
    7550                 :            :         } else
    7551                 :          5 :                 if_addr = wpa_s->own_addr;
    7552                 :            : 
    7553                 :          5 :         wpa_s->p2p_nfc_tag_enabled = enabled;
    7554                 :            : 
    7555         [ +  + ]:         10 :         for (iface = wpa_s->global->ifaces; iface; iface = iface->next) {
    7556                 :            :                 struct hostapd_data *hapd;
    7557         [ +  + ]:          5 :                 if (iface->ap_iface == NULL)
    7558                 :          4 :                         continue;
    7559                 :          1 :                 hapd = iface->ap_iface->bss[0];
    7560                 :          1 :                 wpabuf_free(hapd->conf->wps_nfc_dh_pubkey);
    7561                 :          2 :                 hapd->conf->wps_nfc_dh_pubkey =
    7562                 :          1 :                         wpabuf_dup(wpa_s->conf->wps_nfc_dh_pubkey);
    7563                 :          1 :                 wpabuf_free(hapd->conf->wps_nfc_dh_privkey);
    7564                 :          2 :                 hapd->conf->wps_nfc_dh_privkey =
    7565                 :          1 :                         wpabuf_dup(wpa_s->conf->wps_nfc_dh_privkey);
    7566                 :          1 :                 wpabuf_free(hapd->conf->wps_nfc_dev_pw);
    7567                 :          2 :                 hapd->conf->wps_nfc_dev_pw =
    7568                 :          1 :                         wpabuf_dup(wpa_s->conf->wps_nfc_dev_pw);
    7569                 :          1 :                 hapd->conf->wps_nfc_dev_pw_id = wpa_s->conf->wps_nfc_dev_pw_id;
    7570                 :            : 
    7571         [ -  + ]:          1 :                 if (hostapd_wps_nfc_token_enable(iface->ap_iface->bss[0]) < 0) {
    7572                 :          0 :                         wpa_dbg(iface, MSG_DEBUG,
    7573                 :            :                                 "P2P: Failed to enable NFC Tag for GO");
    7574                 :            :                 }
    7575                 :            :         }
    7576                 :          5 :         p2p_set_authorized_oob_dev_pw_id(
    7577                 :         10 :                 wpa_s->global->p2p, wpa_s->conf->wps_nfc_dev_pw_id, go_intent,
    7578                 :            :                 if_addr);
    7579                 :            : 
    7580                 :          5 :         return 0;
    7581                 :            : }
    7582                 :            : 
    7583                 :            : #endif /* CONFIG_WPS_NFC */

Generated by: LCOV version 1.9