【解析并缓存 P2P_ATTR_DEVICE_INFO】

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)

相关推荐
Net蚂蚁代码10 分钟前
【如何在ASP.Net Core中使用 IHostedService的方法】执行自动服务运行
后端·asp.net
jayaccc13 分钟前
前端缓存全解析:提升性能的关键策略
前端·缓存
无限大.13 分钟前
为什么“缓存“能提高系统性能?——从 CPU 缓存到分布式缓存
分布式·缓存
num_killer18 分钟前
小白的RAG缓存
缓存·ai·aigc
一顿操作猛如虎,啥也不是!23 分钟前
redis注册成windows服务,开机启动
数据库·redis·缓存
code_li24 分钟前
P2P加速 vs. CDN加速
网络·网络协议·p2p
@淡 定9 小时前
Redis热点Key独立集群实现方案
数据库·redis·缓存
Caco.D10 小时前
Aneiang.Pa.News:属于你自己的全平台热点聚合阅读器
爬虫·asp.net·aneiang.pa·热榜新闻
longson.15 小时前
怎样避免空间碎片而且高效的分配空间
嵌入式硬件·缓存
不染尘.15 小时前
进程切换和线程调度
linux·数据结构·windows·缓存