LCOV - code coverage report
Current view: top level - src/p2p - p2p_build.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1401264779 Lines: 238 266 89.5 %
Date: 2014-05-28 Functions: 23 24 95.8 %

          Line data    Source code
       1             : /*
       2             :  * P2P - IE builder
       3             :  * Copyright (c) 2009-2010, Atheros Communications
       4             :  *
       5             :  * This software may be distributed under the terms of the BSD license.
       6             :  * See README for more details.
       7             :  */
       8             : 
       9             : #include "includes.h"
      10             : 
      11             : #include "common.h"
      12             : #include "common/ieee802_11_defs.h"
      13             : #include "wps/wps_i.h"
      14             : #include "p2p_i.h"
      15             : 
      16             : 
      17           2 : void p2p_buf_add_action_hdr(struct wpabuf *buf, u8 subtype, u8 dialog_token)
      18             : {
      19           2 :         wpabuf_put_u8(buf, WLAN_ACTION_VENDOR_SPECIFIC);
      20           2 :         wpabuf_put_be32(buf, P2P_IE_VENDOR_TYPE);
      21             : 
      22           2 :         wpabuf_put_u8(buf, subtype); /* OUI Subtype */
      23           2 :         wpabuf_put_u8(buf, dialog_token);
      24           2 :         wpa_printf(MSG_DEBUG, "P2P: * Dialog Token: %d", dialog_token);
      25           2 : }
      26             : 
      27             : 
      28         575 : void p2p_buf_add_public_action_hdr(struct wpabuf *buf, u8 subtype,
      29             :                                    u8 dialog_token)
      30             : {
      31         575 :         wpabuf_put_u8(buf, WLAN_ACTION_PUBLIC);
      32         575 :         wpabuf_put_u8(buf, WLAN_PA_VENDOR_SPECIFIC);
      33         575 :         wpabuf_put_be32(buf, P2P_IE_VENDOR_TYPE);
      34             : 
      35         575 :         wpabuf_put_u8(buf, subtype); /* OUI Subtype */
      36         575 :         wpabuf_put_u8(buf, dialog_token);
      37         575 :         wpa_printf(MSG_DEBUG, "P2P: * Dialog Token: %d", dialog_token);
      38         575 : }
      39             : 
      40             : 
      41        5513 : u8 * p2p_buf_add_ie_hdr(struct wpabuf *buf)
      42             : {
      43             :         u8 *len;
      44             : 
      45             :         /* P2P IE header */
      46        5513 :         wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
      47        5513 :         len = wpabuf_put(buf, 1); /* IE length to be filled */
      48        5513 :         wpabuf_put_be32(buf, P2P_IE_VENDOR_TYPE);
      49        5513 :         wpa_printf(MSG_DEBUG, "P2P: * P2P IE header");
      50        5513 :         return len;
      51             : }
      52             : 
      53             : 
      54        7484 : void p2p_buf_update_ie_hdr(struct wpabuf *buf, u8 *len)
      55             : {
      56             :         /* Update P2P IE Length */
      57        7484 :         *len = (u8 *) wpabuf_put(buf, 0) - len - 1;
      58        7484 : }
      59             : 
      60             : 
      61        5028 : void p2p_buf_add_capability(struct wpabuf *buf, u8 dev_capab, u8 group_capab)
      62             : {
      63             :         /* P2P Capability */
      64        5028 :         wpabuf_put_u8(buf, P2P_ATTR_CAPABILITY);
      65        5028 :         wpabuf_put_le16(buf, 2);
      66        5028 :         wpabuf_put_u8(buf, dev_capab); /* Device Capabilities */
      67        5028 :         wpabuf_put_u8(buf, group_capab); /* Group Capabilities */
      68        5028 :         wpa_printf(MSG_DEBUG, "P2P: * Capability dev=%02x group=%02x",
      69             :                    dev_capab, group_capab);
      70        5028 : }
      71             : 
      72             : 
      73         223 : void p2p_buf_add_go_intent(struct wpabuf *buf, u8 go_intent)
      74             : {
      75             :         /* Group Owner Intent */
      76         223 :         wpabuf_put_u8(buf, P2P_ATTR_GROUP_OWNER_INTENT);
      77         223 :         wpabuf_put_le16(buf, 1);
      78         223 :         wpabuf_put_u8(buf, go_intent);
      79         223 :         wpa_printf(MSG_DEBUG, "P2P: * GO Intent: Intent %u Tie breaker %u",
      80             :                    go_intent >> 1, go_intent & 0x01);
      81         223 : }
      82             : 
      83             : 
      84        1957 : void p2p_buf_add_listen_channel(struct wpabuf *buf, const char *country,
      85             :                                 u8 reg_class, u8 channel)
      86             : {
      87             :         /* Listen Channel */
      88        1957 :         wpabuf_put_u8(buf, P2P_ATTR_LISTEN_CHANNEL);
      89        1957 :         wpabuf_put_le16(buf, 5);
      90        1957 :         wpabuf_put_data(buf, country, 3);
      91        1957 :         wpabuf_put_u8(buf, reg_class); /* Regulatory Class */
      92        1957 :         wpabuf_put_u8(buf, channel); /* Channel Number */
      93        1957 :         wpa_printf(MSG_DEBUG, "P2P: * Listen Channel: Regulatory Class %u "
      94             :                    "Channel %u", reg_class, channel);
      95        1957 : }
      96             : 
      97             : 
      98         295 : void p2p_buf_add_operating_channel(struct wpabuf *buf, const char *country,
      99             :                                    u8 reg_class, u8 channel)
     100             : {
     101             :         /* Operating Channel */
     102         295 :         wpabuf_put_u8(buf, P2P_ATTR_OPERATING_CHANNEL);
     103         295 :         wpabuf_put_le16(buf, 5);
     104         295 :         wpabuf_put_data(buf, country, 3);
     105         295 :         wpabuf_put_u8(buf, reg_class); /* Regulatory Class */
     106         295 :         wpabuf_put_u8(buf, channel); /* Channel Number */
     107         295 :         wpa_printf(MSG_DEBUG, "P2P: * Operating Channel: Regulatory Class %u "
     108             :                    "Channel %u", reg_class, channel);
     109         295 : }
     110             : 
     111             : 
     112         344 : void p2p_buf_add_channel_list(struct wpabuf *buf, const char *country,
     113             :                               struct p2p_channels *chan)
     114             : {
     115             :         u8 *len;
     116             :         size_t i;
     117             : 
     118             :         /* Channel List */
     119         344 :         wpabuf_put_u8(buf, P2P_ATTR_CHANNEL_LIST);
     120         344 :         len = wpabuf_put(buf, 2); /* IE length to be filled */
     121         344 :         wpabuf_put_data(buf, country, 3); /* Country String */
     122             : 
     123         762 :         for (i = 0; i < chan->reg_classes; i++) {
     124         418 :                 struct p2p_reg_class *c = &chan->reg_class[i];
     125         418 :                 wpabuf_put_u8(buf, c->reg_class);
     126         418 :                 wpabuf_put_u8(buf, c->channels);
     127         418 :                 wpabuf_put_data(buf, c->channel, c->channels);
     128             :         }
     129             : 
     130             :         /* Update attribute length */
     131         344 :         WPA_PUT_LE16(len, (u8 *) wpabuf_put(buf, 0) - len - 2);
     132         344 :         wpa_hexdump(MSG_DEBUG, "P2P: * Channel List",
     133         344 :                     len + 2, (u8 *) wpabuf_put(buf, 0) - len - 2);
     134         344 : }
     135             : 
     136             : 
     137         219 : void p2p_buf_add_status(struct wpabuf *buf, u8 status)
     138             : {
     139             :         /* Status */
     140         219 :         wpabuf_put_u8(buf, P2P_ATTR_STATUS);
     141         219 :         wpabuf_put_le16(buf, 1);
     142         219 :         wpabuf_put_u8(buf, status);
     143         219 :         wpa_printf(MSG_DEBUG, "P2P: * Status: %d", status);
     144         219 : }
     145             : 
     146             : 
     147        2882 : void p2p_buf_add_device_info(struct wpabuf *buf, struct p2p_data *p2p,
     148             :                              struct p2p_device *peer)
     149             : {
     150             :         u8 *len;
     151             :         u16 methods;
     152             :         size_t nlen, i;
     153             : 
     154             :         /* P2P Device Info */
     155        2882 :         wpabuf_put_u8(buf, P2P_ATTR_DEVICE_INFO);
     156        2882 :         len = wpabuf_put(buf, 2); /* IE length to be filled */
     157             : 
     158             :         /* P2P Device address */
     159        2882 :         wpabuf_put_data(buf, p2p->cfg->dev_addr, ETH_ALEN);
     160             : 
     161             :         /* Config Methods */
     162        2882 :         methods = 0;
     163        2882 :         if (peer && peer->wps_method != WPS_NOT_READY) {
     164         398 :                 if (peer->wps_method == WPS_PBC)
     165          51 :                         methods |= WPS_CONFIG_PUSHBUTTON;
     166         228 :                 else if (peer->wps_method == WPS_PIN_DISPLAY ||
     167          80 :                          peer->wps_method == WPS_PIN_KEYPAD)
     168         132 :                         methods |= WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD;
     169        2683 :         } else if (p2p->cfg->config_methods) {
     170        2683 :                 methods |= p2p->cfg->config_methods &
     171             :                         (WPS_CONFIG_PUSHBUTTON | WPS_CONFIG_DISPLAY |
     172             :                          WPS_CONFIG_KEYPAD);
     173             :         } else {
     174           0 :                 methods |= WPS_CONFIG_PUSHBUTTON;
     175           0 :                 methods |= WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD;
     176             :         }
     177        2882 :         wpabuf_put_be16(buf, methods);
     178             : 
     179             :         /* Primary Device Type */
     180        2882 :         wpabuf_put_data(buf, p2p->cfg->pri_dev_type,
     181             :                         sizeof(p2p->cfg->pri_dev_type));
     182             : 
     183             :         /* Number of Secondary Device Types */
     184        2882 :         wpabuf_put_u8(buf, p2p->cfg->num_sec_dev_types);
     185             : 
     186             :         /* Secondary Device Type List */
     187        3006 :         for (i = 0; i < p2p->cfg->num_sec_dev_types; i++)
     188         124 :                 wpabuf_put_data(buf, p2p->cfg->sec_dev_type[i],
     189             :                                 WPS_DEV_TYPE_LEN);
     190             : 
     191             :         /* Device Name */
     192        2882 :         nlen = p2p->cfg->dev_name ? os_strlen(p2p->cfg->dev_name) : 0;
     193        2882 :         wpabuf_put_be16(buf, ATTR_DEV_NAME);
     194        2882 :         wpabuf_put_be16(buf, nlen);
     195        2882 :         wpabuf_put_data(buf, p2p->cfg->dev_name, nlen);
     196             : 
     197             :         /* Update attribute length */
     198        2882 :         WPA_PUT_LE16(len, (u8 *) wpabuf_put(buf, 0) - len - 2);
     199        2882 :         wpa_printf(MSG_DEBUG, "P2P: * Device Info");
     200        2882 : }
     201             : 
     202             : 
     203         261 : void p2p_buf_add_device_id(struct wpabuf *buf, const u8 *dev_addr)
     204             : {
     205             :         /* P2P Device ID */
     206         261 :         wpabuf_put_u8(buf, P2P_ATTR_DEVICE_ID);
     207         261 :         wpabuf_put_le16(buf, ETH_ALEN);
     208         261 :         wpabuf_put_data(buf, dev_addr, ETH_ALEN);
     209         261 :         wpa_printf(MSG_DEBUG, "P2P: * Device ID: " MACSTR, MAC2STR(dev_addr));
     210         261 : }
     211             : 
     212             : 
     213         287 : void p2p_buf_add_config_timeout(struct wpabuf *buf, u8 go_timeout,
     214             :                                 u8 client_timeout)
     215             : {
     216             :         /* Configuration Timeout */
     217         287 :         wpabuf_put_u8(buf, P2P_ATTR_CONFIGURATION_TIMEOUT);
     218         287 :         wpabuf_put_le16(buf, 2);
     219         287 :         wpabuf_put_u8(buf, go_timeout);
     220         287 :         wpabuf_put_u8(buf, client_timeout);
     221         287 :         wpa_printf(MSG_DEBUG, "P2P: * Configuration Timeout: GO %d (*10ms)  "
     222             :                    "client %d (*10ms)", go_timeout, client_timeout);
     223         287 : }
     224             : 
     225             : 
     226         223 : void p2p_buf_add_intended_addr(struct wpabuf *buf, const u8 *interface_addr)
     227             : {
     228             :         /* Intended P2P Interface Address */
     229         223 :         wpabuf_put_u8(buf, P2P_ATTR_INTENDED_INTERFACE_ADDR);
     230         223 :         wpabuf_put_le16(buf, ETH_ALEN);
     231         223 :         wpabuf_put_data(buf, interface_addr, ETH_ALEN);
     232        1338 :         wpa_printf(MSG_DEBUG, "P2P: * Intended P2P Interface Address " MACSTR,
     233        1338 :                    MAC2STR(interface_addr));
     234         223 : }
     235             : 
     236             : 
     237          25 : void p2p_buf_add_group_bssid(struct wpabuf *buf, const u8 *bssid)
     238             : {
     239             :         /* P2P Group BSSID */
     240          25 :         wpabuf_put_u8(buf, P2P_ATTR_GROUP_BSSID);
     241          25 :         wpabuf_put_le16(buf, ETH_ALEN);
     242          25 :         wpabuf_put_data(buf, bssid, ETH_ALEN);
     243         150 :         wpa_printf(MSG_DEBUG, "P2P: * P2P Group BSSID " MACSTR,
     244         150 :                    MAC2STR(bssid));
     245          25 : }
     246             : 
     247             : 
     248         139 : void p2p_buf_add_group_id(struct wpabuf *buf, const u8 *dev_addr,
     249             :                           const u8 *ssid, size_t ssid_len)
     250             : {
     251             :         /* P2P Group ID */
     252         139 :         wpabuf_put_u8(buf, P2P_ATTR_GROUP_ID);
     253         139 :         wpabuf_put_le16(buf, ETH_ALEN + ssid_len);
     254         139 :         wpabuf_put_data(buf, dev_addr, ETH_ALEN);
     255         139 :         wpabuf_put_data(buf, ssid, ssid_len);
     256         834 :         wpa_printf(MSG_DEBUG, "P2P: * P2P Group ID " MACSTR,
     257         834 :                    MAC2STR(dev_addr));
     258         139 :         wpa_hexdump_ascii(MSG_DEBUG, "P2P: P2P Group ID SSID", ssid, ssid_len);
     259         139 : }
     260             : 
     261             : 
     262          26 : void p2p_buf_add_invitation_flags(struct wpabuf *buf, u8 flags)
     263             : {
     264             :         /* Invitation Flags */
     265          26 :         wpabuf_put_u8(buf, P2P_ATTR_INVITATION_FLAGS);
     266          26 :         wpabuf_put_le16(buf, 1);
     267          26 :         wpabuf_put_u8(buf, flags);
     268          26 :         wpa_printf(MSG_DEBUG, "P2P: * Invitation Flags: bitmap 0x%x", flags);
     269          26 : }
     270             : 
     271             : 
     272           4 : static void p2p_buf_add_noa_desc(struct wpabuf *buf, struct p2p_noa_desc *desc)
     273             : {
     274           4 :         if (desc == NULL)
     275           7 :                 return;
     276             : 
     277           1 :         wpabuf_put_u8(buf, desc->count_type);
     278           1 :         wpabuf_put_le32(buf, desc->duration);
     279           1 :         wpabuf_put_le32(buf, desc->interval);
     280           1 :         wpabuf_put_le32(buf, desc->start_time);
     281             : }
     282             : 
     283             : 
     284           2 : void p2p_buf_add_noa(struct wpabuf *buf, u8 noa_index, u8 opp_ps, u8 ctwindow,
     285             :                      struct p2p_noa_desc *desc1, struct p2p_noa_desc *desc2)
     286             : {
     287             :         /* Notice of Absence */
     288           2 :         wpabuf_put_u8(buf, P2P_ATTR_NOTICE_OF_ABSENCE);
     289           2 :         wpabuf_put_le16(buf, 2 + (desc1 ? 13 : 0) + (desc2 ? 13 : 0));
     290           2 :         wpabuf_put_u8(buf, noa_index);
     291           2 :         wpabuf_put_u8(buf, (opp_ps ? 0x80 : 0) | (ctwindow & 0x7f));
     292           2 :         p2p_buf_add_noa_desc(buf, desc1);
     293           2 :         p2p_buf_add_noa_desc(buf, desc2);
     294           2 :         wpa_printf(MSG_DEBUG, "P2P: * Notice of Absence");
     295           2 : }
     296             : 
     297             : 
     298          18 : void p2p_buf_add_ext_listen_timing(struct wpabuf *buf, u16 period,
     299             :                                    u16 interval)
     300             : {
     301             :         /* Extended Listen Timing */
     302          18 :         wpabuf_put_u8(buf, P2P_ATTR_EXT_LISTEN_TIMING);
     303          18 :         wpabuf_put_le16(buf, 4);
     304          18 :         wpabuf_put_le16(buf, period);
     305          18 :         wpabuf_put_le16(buf, interval);
     306          18 :         wpa_printf(MSG_DEBUG, "P2P: * Extended Listen Timing (period %u msec  "
     307             :                    "interval %u msec)", period, interval);
     308          18 : }
     309             : 
     310             : 
     311           0 : void p2p_buf_add_p2p_interface(struct wpabuf *buf, struct p2p_data *p2p)
     312             : {
     313             :         /* P2P Interface */
     314           0 :         wpabuf_put_u8(buf, P2P_ATTR_INTERFACE);
     315           0 :         wpabuf_put_le16(buf, ETH_ALEN + 1 + ETH_ALEN);
     316             :         /* P2P Device address */
     317           0 :         wpabuf_put_data(buf, p2p->cfg->dev_addr, ETH_ALEN);
     318             :         /*
     319             :          * FIX: Fetch interface address list from driver. Do not include
     320             :          * the P2P Device address if it is never used as interface address.
     321             :          */
     322             :         /* P2P Interface Address Count */
     323           0 :         wpabuf_put_u8(buf, 1);
     324           0 :         wpabuf_put_data(buf, p2p->cfg->dev_addr, ETH_ALEN);
     325           0 : }
     326             : 
     327             : 
     328          29 : void p2p_buf_add_oob_go_neg_channel(struct wpabuf *buf, const char *country,
     329             :                                     u8 oper_class, u8 channel,
     330             :                                     enum p2p_role_indication role)
     331             : {
     332             :         /* OOB Group Owner Negotiation Channel */
     333          29 :         wpabuf_put_u8(buf, P2P_ATTR_OOB_GO_NEG_CHANNEL);
     334          29 :         wpabuf_put_le16(buf, 6);
     335          29 :         wpabuf_put_data(buf, country, 3);
     336          29 :         wpabuf_put_u8(buf, oper_class); /* Operating Class */
     337          29 :         wpabuf_put_u8(buf, channel); /* Channel Number */
     338          29 :         wpabuf_put_u8(buf, (u8) role); /* Role indication */
     339          29 :         wpa_printf(MSG_DEBUG, "P2P: * OOB GO Negotiation Channel: Operating "
     340             :                    "Class %u Channel %u Role %d",
     341             :                    oper_class, channel, role);
     342          29 : }
     343             : 
     344             : 
     345        7695 : static int p2p_add_wps_string(struct wpabuf *buf, enum wps_attribute attr,
     346             :                               const char *val)
     347             : {
     348             :         size_t len;
     349             : 
     350        7695 :         len = val ? os_strlen(val) : 0;
     351        7695 :         if (wpabuf_tailroom(buf) < 4 + len)
     352           0 :                 return -1;
     353        7695 :         wpabuf_put_be16(buf, attr);
     354             : #ifndef CONFIG_WPS_STRICT
     355        7695 :         if (len == 0) {
     356             :                 /*
     357             :                  * Some deployed WPS implementations fail to parse zeor-length
     358             :                  * attributes. As a workaround, send a space character if the
     359             :                  * device attribute string is empty.
     360             :                  */
     361        6189 :                 if (wpabuf_tailroom(buf) < 3)
     362           0 :                         return -1;
     363        6189 :                 wpabuf_put_be16(buf, 1);
     364        6189 :                 wpabuf_put_u8(buf, ' ');
     365        6189 :                 return 0;
     366             :         }
     367             : #endif /* CONFIG_WPS_STRICT */
     368        1506 :         wpabuf_put_be16(buf, len);
     369        1506 :         if (val)
     370        1506 :                 wpabuf_put_data(buf, val, len);
     371        1506 :         return 0;
     372             : }
     373             : 
     374             : 
     375        1764 : int p2p_build_wps_ie(struct p2p_data *p2p, struct wpabuf *buf, int pw_id,
     376             :                      int all_attr)
     377             : {
     378             :         u8 *len;
     379             :         int i;
     380             : 
     381        1764 :         if (wpabuf_tailroom(buf) < 6)
     382           0 :                 return -1;
     383        1764 :         wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
     384        1764 :         len = wpabuf_put(buf, 1);
     385        1764 :         wpabuf_put_be32(buf, WPS_DEV_OUI_WFA);
     386             : 
     387        1764 :         if (wps_build_version(buf) < 0)
     388           0 :                 return -1;
     389             : 
     390        1764 :         if (all_attr) {
     391        1539 :                 if (wpabuf_tailroom(buf) < 5)
     392           0 :                         return -1;
     393        1539 :                 wpabuf_put_be16(buf, ATTR_WPS_STATE);
     394        1539 :                 wpabuf_put_be16(buf, 1);
     395        1539 :                 wpabuf_put_u8(buf, WPS_STATE_NOT_CONFIGURED);
     396             :         }
     397             : 
     398        1764 :         if (pw_id >= 0) {
     399         526 :                 if (wpabuf_tailroom(buf) < 6)
     400           0 :                         return -1;
     401             :                 /* Device Password ID */
     402         526 :                 wpabuf_put_be16(buf, ATTR_DEV_PASSWORD_ID);
     403         526 :                 wpabuf_put_be16(buf, 2);
     404         526 :                 wpa_printf(MSG_DEBUG, "P2P: WPS IE Device Password ID: %d",
     405             :                            pw_id);
     406         526 :                 wpabuf_put_be16(buf, pw_id);
     407             :         }
     408             : 
     409        1764 :         if (all_attr) {
     410        1539 :                 if (wpabuf_tailroom(buf) < 5)
     411           0 :                         return -1;
     412        1539 :                 wpabuf_put_be16(buf, ATTR_RESPONSE_TYPE);
     413        1539 :                 wpabuf_put_be16(buf, 1);
     414        1539 :                 wpabuf_put_u8(buf, WPS_RESP_ENROLLEE_INFO);
     415             : 
     416        3078 :                 if (wps_build_uuid_e(buf, p2p->cfg->uuid) < 0 ||
     417        1539 :                     p2p_add_wps_string(buf, ATTR_MANUFACTURER,
     418        3078 :                                        p2p->cfg->manufacturer) < 0 ||
     419        1539 :                     p2p_add_wps_string(buf, ATTR_MODEL_NAME,
     420        3078 :                                        p2p->cfg->model_name) < 0 ||
     421        1539 :                     p2p_add_wps_string(buf, ATTR_MODEL_NUMBER,
     422        3078 :                                        p2p->cfg->model_number) < 0 ||
     423        1539 :                     p2p_add_wps_string(buf, ATTR_SERIAL_NUMBER,
     424        1539 :                                        p2p->cfg->serial_number) < 0)
     425           0 :                         return -1;
     426             : 
     427        1539 :                 if (wpabuf_tailroom(buf) < 4 + WPS_DEV_TYPE_LEN)
     428           0 :                         return -1;
     429        1539 :                 wpabuf_put_be16(buf, ATTR_PRIMARY_DEV_TYPE);
     430        1539 :                 wpabuf_put_be16(buf, WPS_DEV_TYPE_LEN);
     431        1539 :                 wpabuf_put_data(buf, p2p->cfg->pri_dev_type, WPS_DEV_TYPE_LEN);
     432             : 
     433        1539 :                 if (p2p_add_wps_string(buf, ATTR_DEV_NAME, p2p->cfg->dev_name)
     434             :                     < 0)
     435           0 :                         return -1;
     436             : 
     437        1539 :                 if (wpabuf_tailroom(buf) < 6)
     438           0 :                         return -1;
     439        1539 :                 wpabuf_put_be16(buf, ATTR_CONFIG_METHODS);
     440        1539 :                 wpabuf_put_be16(buf, 2);
     441        1539 :                 wpabuf_put_be16(buf, p2p->cfg->config_methods);
     442             :         }
     443             : 
     444        1764 :         if (wps_build_wfa_ext(buf, 0, NULL, 0) < 0)
     445           0 :                 return -1;
     446             : 
     447        1764 :         if (all_attr && p2p->cfg->num_sec_dev_types) {
     448         144 :                 if (wpabuf_tailroom(buf) <
     449          72 :                     4 + WPS_DEV_TYPE_LEN * p2p->cfg->num_sec_dev_types)
     450           0 :                         return -1;
     451          72 :                 wpabuf_put_be16(buf, ATTR_SECONDARY_DEV_TYPE_LIST);
     452          72 :                 wpabuf_put_be16(buf, WPS_DEV_TYPE_LEN *
     453          72 :                                 p2p->cfg->num_sec_dev_types);
     454          72 :                 wpabuf_put_data(buf, p2p->cfg->sec_dev_type,
     455             :                                 WPS_DEV_TYPE_LEN *
     456          72 :                                 p2p->cfg->num_sec_dev_types);
     457             :         }
     458             : 
     459             :         /* Add the WPS vendor extensions */
     460        1764 :         for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) {
     461        1764 :                 if (p2p->wps_vendor_ext[i] == NULL)
     462        1764 :                         break;
     463           0 :                 if (wpabuf_tailroom(buf) <
     464           0 :                     4 + wpabuf_len(p2p->wps_vendor_ext[i]))
     465           0 :                         continue;
     466           0 :                 wpabuf_put_be16(buf, ATTR_VENDOR_EXT);
     467           0 :                 wpabuf_put_be16(buf, wpabuf_len(p2p->wps_vendor_ext[i]));
     468           0 :                 wpabuf_put_buf(buf, p2p->wps_vendor_ext[i]);
     469             :         }
     470             : 
     471        1764 :         p2p_buf_update_ie_hdr(buf, len);
     472             : 
     473        1764 :         return 0;
     474             : }

Generated by: LCOV version 1.10