1. 新增对端 Device Info 缓存字段
在 struct wifidirect_info 中新增 peer_devinfo,用于缓存对端的完整 P2P_ATTR_DEVICE_INFO:
c
enum P2P_ROLE role;
enum P2P_STATE pre_p2p_state;
enum P2P_STATE p2p_state;
u8 device_addr[ETH_ALEN]; /* The device address should be the mac address of this device. */
u8 interface_addr[ETH_ALEN];
u8 social_chan[4];
u8 listen_channel;
u8 operating_channel;
u8 listen_dwell; /* This value should be between 1 and 3 */
u8 support_rate[8];
u8 p2p_wildcard_ssid[P2P_WILDCARD_SSID_LEN];
u8 intent; /* should only include the intent value. */
u8 p2p_peer_interface_addr[ETH_ALEN];
u8 p2p_peer_device_addr[ETH_ALEN];
struct p2p_device_info_ex peer_devinfo; /* Store full P2P Device Info of peer */
u8 peer_intent; /* Included the intent value and tie breaker value. */
u8 device_name[WPS_MAX_DEVICE_NAME_LEN]; /* Device name for displaying on searching device screen */
u16 device_name_len;
u8 profileindex; /* Used to point to the index of profileinfo array */
u8 peer_operating_ch;
u8 ch_list_inclusioned[MAX_CHANNEL_NUM];
u8 ch_num_inclusioned;
u32 operating_invaild_ch_list;
u8 find_phase_state_exchange_cnt;
u16 device_password_id_for_nego; /* The device password ID for group negotation */
u8 negotiation_dialog_token;
u8 nego_ssid[WLAN_SSID_MAXLEN]; /* SSID information for group negotitation */
u8 nego_ssidlen;
u8 p2p_peer_interface_ssid[WLAN_SSID_MAXLEN];
u8 p2p_group_ssid[WLAN_SSID_MAXLEN];
u8 p2p_group_ssid_len;
2. 新增通用解析函数 rtw_p2p_parse_p2p_attr_device_info
在 rtw_p2p.c 中实现统一的 P2P_ATTR_DEVICE_INFO 解析逻辑:
c
void rtw_p2p_parse_p2p_attr_device_info(struct wifidirect_info *pwdinfo, u8 *p2p_ie, u32 p2p_ielen)
{
u8 *devinfo = NULL;
u8 *p = NULL;
u32 devinfo_len = 0;
struct p2p_device_info_ex *info = &pwdinfo->peer_devinfo;
if (!p2p_ie || !p2p_ielen)
return;
_rtw_memset(info, 0x00, sizeof(*info));
/* first query length of DEVICE_INFO */
if (!rtw_get_p2p_attr_content(p2p_ie, p2p_ielen,
P2P_ATTR_DEVICE_INFO,
NULL, &devinfo_len) || !devinfo_len)
return;
devinfo = rtw_zmalloc(devinfo_len);
if (!devinfo)
return;
/* get DEVICE_INFO content */
if (!rtw_get_p2p_attr_content(p2p_ie, p2p_ielen,
P2P_ATTR_DEVICE_INFO,
devinfo, &devinfo_len))
goto exit_parse;
p = devinfo;
/* 1) P2P Device Address (6 bytes) */
if (p + ETH_ALEN > devinfo + devinfo_len)
goto exit_parse;
_rtw_memcpy(info->dev_addr, p, ETH_ALEN);
_rtw_memcpy(pwdinfo->p2p_peer_device_addr, p, ETH_ALEN);
p += ETH_ALEN;
/* 2) Config Methods (2 bytes, big endian) */
if (p + 2 > devinfo + devinfo_len)
goto exit_parse;
_rtw_memcpy(&info->config_methods, p, 2);
info->config_methods = be16_to_cpu(info->config_methods);
p += 2;
/* 3) Primary Device Type (8 bytes) */
if (p + 8 > devinfo + devinfo_len)
goto exit_parse;
_rtw_memcpy(info->primary_dev_type, p, 8);
p += 8;
/* 4) Secondary Device Types */
if (p + 1 > devinfo + devinfo_len)
goto exit_parse;
info->num_of_secdev_type = *p;
p += 1;
if (info->num_of_secdev_type) {
u32 need = info->num_of_secdev_type * 8;
u32 copy_len = need;
if (copy_len > sizeof(info->secdev_types_list))
copy_len = sizeof(info->secdev_types_list);
if (p + need > devinfo + devinfo_len)
goto exit_parse;
_rtw_memcpy(info->secdev_types_list, p, copy_len);
p += need;
}
/* 5) Device Name (WPS Attr TLV: ID(2)+Len(2)+Value(len)) */
if (p + 4 <= devinfo + devinfo_len) {
u16 attr_id, attr_len;
_rtw_memcpy(&attr_id, p, 2);
attr_id = be16_to_cpu(attr_id);
p += 2;
_rtw_memcpy(&attr_len, p, 2);
attr_len = be16_to_cpu(attr_len);
p += 2;
if (attr_id == WPS_ATTR_DEVICE_NAME &&
p + attr_len <= devinfo + devinfo_len) {
if (attr_len > WPS_MAX_DEVICE_NAME_LEN)
attr_len = WPS_MAX_DEVICE_NAME_LEN;
_rtw_memcpy(info->dev_name, p, attr_len);
info->dev_name_len = attr_len;
}
}
RTW_INFO("[%s] peer_devinfo: mac="MAC_FMT", cfg_m=0x%04x, dev_name=%.*s\n",
__FUNCTION__,
MAC_ARG(info->dev_addr),
info->config_methods,
info->dev_name_len, info->dev_name);
exit_parse:
if (devinfo)
rtw_mfree(devinfo, devinfo_len);
}
对应声明加在 rtw_p2p.h 中:
c
u8 process_p2p_group_negotation_resp(struct wifidirect_info *pwdinfo, u8 *pframe, uint len);
u8 process_p2p_group_negotation_confirm(struct wifidirect_info *pwdinfo, u8 *pframe, uint len);
u8 process_p2p_presence_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len);
int process_p2p_cross_connect_ie(PADAPTER padapter, u8 *IEs, u32 IELength);
void rtw_p2p_parse_p2p_attr_device_info(struct wifidirect_info *pwdinfo, u8 *p2p_ie, u32 p2p_ielen);
s32 p2p_protocol_wk_hdl(_adapter *padapter, int intCmdType, u8 *buf);
3. 在 GO Negotiation Request 中解析 P2P_ATTR_DEVICE_INFO
在 process_p2p_group_negotation_req() 的 while (p2p_ie) 中,对 GO Negotiation Request 的 P2P IE 调用解析(片段略前一点你可以在本地看到):
c
while (p2p_ie) {
u8 attr_content = 0x00;
u32 attr_contentlen = 0;
uint ch_cnt = 0;
u8 peer_ch_num = 0;
u8 ch_num_inclusioned = 0;
u16 cap_attr;
u8 listen_ch_attr[5] = { 0x00 };
/* ... */
/* Parse peer P2P Device Info ATTR (GO Nego Req) */
rtw_p2p_parse_p2p_attr_device_info(pwdinfo, p2p_ie, p2p_ielen);
_rtw_memset(ch_content, 0, 100);
/* 后续继续走原有 ch list / GO intent 等逻辑 */
4. 在 Invitation Request 中解析 P2P_ATTR_DEVICE_INFO
在 on_action_public_p2p() 的 P2P_INVIT_REQ 分支中,合并 P2P IEs 后调用同一解析函数:
c
_rtw_memset(merged_p2pie, 0x00, merged_p2p_ielen);
merged_p2p_ielen = rtw_p2p_merge_ies(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, merged_p2pie);
attr_contentlen = sizeof(invitation_flag);
rtw_get_p2p_attr_content(merged_p2pie, merged_p2p_ielen, P2P_ATTR_INVITATION_FLAGS, &invitation_flag, &attr_contentlen);
if (attr_contentlen) {
attr_contentlen = sizeof(pwdinfo->p2p_peer_interface_addr);
rtw_get_p2p_attr_content(merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_BSSID, pwdinfo->p2p_peer_interface_addr, &attr_contentlen);
/* ... 打印 GO BSSID ... */
/* Parse full P2P Device Info Attr into pwdinfo->peer_devinfo */
rtw_p2p_parse_p2p_attr_device_info(pwdinfo, merged_p2pie, merged_p2p_ielen);
if (invitation_flag & P2P_INVITATION_FLAGS_PERSISTENT) {
/* 后续保持原有 Invitation 处理逻辑 */
5. 在 iwpriv p2p_get peer_ifa 中输出 DEVICE_NAME
rtw_p2p_get_peer_ifaddr_ex() 增加 DEVICE_NAME 字段,并使用 pwdinfo->peer_devinfo.dev_name:
c
RTW_INFO("[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X mac=%.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n",\
__FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2],
pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5],\
pwdinfo->rx_prov_disc_info.peerDevAddr[0], pwdinfo->rx_prov_disc_info.peerDevAddr[1],
pwdinfo->rx_prov_disc_info.peerDevAddr[2], pwdinfo->rx_prov_disc_info.peerDevAddr[3],
pwdinfo->rx_prov_disc_info.peerDevAddr[4], pwdinfo->rx_prov_disc_info.peerDevAddr[5]);
if (rtw_p2p_state(pwdinfo) == P2P_STATE_RECV_INVITE_REQ_MATCH) {
sprintf(extra,
"\nMAC=%.2X:%.2X:%.2X:%.2X:%.2X:%.2X\nSSID=%s\nPEER_ADDR=%.2X:%.2X:%.2X:%.2X:%.2X:%.2X\nDEVICE_NAME=%s",
pwdinfo->p2p_peer_device_addr[0], pwdinfo->p2p_peer_device_addr[1], pwdinfo->p2p_peer_device_addr[2],
pwdinfo->p2p_peer_device_addr[3], pwdinfo->p2p_peer_device_addr[4], pwdinfo->p2p_peer_device_addr[5],
pwdinfo->p2p_peer_interface_ssid,
pwdinfo->rx_prov_disc_info.peerDevAddr[0], pwdinfo->rx_prov_disc_info.peerDevAddr[1],
pwdinfo->rx_prov_disc_info.peerDevAddr[2], pwdinfo->rx_prov_disc_info.peerDevAddr[3],
pwdinfo->rx_prov_disc_info.peerDevAddr[4], pwdinfo->rx_prov_disc_info.peerDevAddr[5],
pwdinfo->peer_devinfo.dev_name);
} else {
sprintf(extra,
"\nMAC=%.2X:%.2X:%.2X:%.2X:%.2X:%.2X\nSSID=%s\nPEER_ADDR=%.2X:%.2X:%.2X:%.2X:%.2X:%.2X\nDEVICE_NAME=%s",
pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2],
pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5],
pwdinfo->p2p_peer_interface_ssid,
pwdinfo->rx_prov_disc_info.peerDevAddr[0], pwdinfo->rx_prov_disc_info.peerDevAddr[1],
pwdinfo->rx_prov_disc_info.peerDevAddr[2], pwdinfo->rx_prov_disc_info.peerDevAddr[3],
pwdinfo->rx_prov_disc_info.peerDevAddr[4], pwdinfo->rx_prov_disc_info.peerDevAddr[5],
pwdinfo->peer_devinfo.dev_name);
}
wrqu->data.length = strlen(extra);
return ret;

c
raw devinfo (len=42):
C6:8A:96:8C:CC:93 (device address)
01:88 (config methods)
00:0A 00:50:F2:04 00:05 (category+OUT+sub category id)
00 (secondary device types)
10:11 (WPS_ATTR_DEVICE_NAME)
00:15 (device name len)
E6:9D:8E:E5:98:89:E9:AA:8F:E7:9A:84:52:65:64:6D:69:20:4B:37:30 (device name)