【Action帧简要分析】

文章目录


Action分析

p2p_rx_action为P2P接收action帧入口函数。

  1. 判断category_code为WLAN_ACTION_PUBLIC(4)则调用p2p_rx_action_public函数。
  2. 判断action_code为WLAN_PA_VENDOR_SPECIFIC(9)且OUI和Subtype为P2P_IE_VENDOR_TYPE(0x506f9a09),则调用p2p_rx_p2p_action。
  3. 根据不同的OUI Subtype选择不同的处理流程。
c 复制代码
/* P2P public action frames */
enum p2p_action_frame_type {
	P2P_GO_NEG_REQ = 0,
	P2P_GO_NEG_RESP = 1,
	P2P_GO_NEG_CONF = 2,
	P2P_INVITATION_REQ = 3,
	P2P_INVITATION_RESP = 4,
	P2P_DEV_DISC_REQ = 5,
	P2P_DEV_DISC_RESP = 6,
	P2P_PROV_DISC_REQ = 7,
	P2P_PROV_DISC_RESP = 8
};

Wi-Fi Direct分析

调用p2p_parse函数,先获取dialog_token,然后调用p2p_parse_ies进行解析。

ieee802_11_parse_elems解析elems字段。

  1. 判断element_id为WLAN_EID_VENDOR_SPECIFIC(221),调用ieee802_11_parse_vendor_specific。
  2. 判断OUI为OUI_WFA(0x506f9a)且OUI_type为P2P_OUI_TYPE。

p2p_attributes字段解析

调用p2p_parse_p2p_ie中p2p_parse_attribute解析P2P Attribute。

根据不同的ID走不同的流程,把解析出来的数据存入p2p_message。

c 复制代码
enum p2p_attr_id {
	P2P_ATTR_STATUS = 0,
	P2P_ATTR_MINOR_REASON_CODE = 1,
	P2P_ATTR_CAPABILITY = 2,
	P2P_ATTR_DEVICE_ID = 3,
	P2P_ATTR_GROUP_OWNER_INTENT = 4,
	P2P_ATTR_CONFIGURATION_TIMEOUT = 5,
	P2P_ATTR_LISTEN_CHANNEL = 6,
	P2P_ATTR_GROUP_BSSID = 7,
	P2P_ATTR_EXT_LISTEN_TIMING = 8,
	P2P_ATTR_INTENDED_INTERFACE_ADDR = 9,
	P2P_ATTR_MANAGEABILITY = 10,
	P2P_ATTR_CHANNEL_LIST = 11,
	P2P_ATTR_NOTICE_OF_ABSENCE = 12,
	P2P_ATTR_DEVICE_INFO = 13,
	P2P_ATTR_GROUP_INFO = 14,
	P2P_ATTR_GROUP_ID = 15,
	P2P_ATTR_INTERFACE = 16,
	P2P_ATTR_OPERATING_CHANNEL = 17,
	P2P_ATTR_INVITATION_FLAGS = 18,
	P2P_ATTR_OOB_GO_NEG_CHANNEL = 19,
	P2P_ATTR_SERVICE_HASH = 21,
	P2P_ATTR_SESSION_INFORMATION_DATA = 22,
	P2P_ATTR_CONNECTION_CAPABILITY = 23,
	P2P_ATTR_ADVERTISEMENT_ID = 24,
	P2P_ATTR_ADVERTISED_SERVICE = 25,
	P2P_ATTR_SESSION_ID = 26,
	P2P_ATTR_FEATURE_CAPABILITY = 27,
	P2P_ATTR_PERSISTENT_GROUP = 28,
	P2P_ATTR_VENDOR_SPECIFIC = 221
};

wfd_subelems字段解析

c 复制代码
enum wifi_display_subelem {
	WFD_SUBELEM_DEVICE_INFO = 0,
	WFD_SUBELEM_ASSOCIATED_BSSID = 1,
	WFD_SUBELEM_AUDIO_FORMATS = 2,
	WFD_SUBELEM_VIDEO_FORMATS = 3,
	WFD_SUBELEM_3D_VIDEO_FORMATS = 4,
	WFD_SUBELEM_CONTENT_PROTECTION = 5,
	WFD_SUBELEM_COUPLED_SINK = 6,
	WFD_SUBELEM_EXT_CAPAB = 7,
	WFD_SUBELEM_LOCAL_IP_ADDRESS = 8,
	WFD_SUBELEM_SESSION_INFO = 9
};

wps字段解析

根据OUI_MICROSOFT进行解析。

p2p_message分析

c 复制代码
/**
 1. struct p2p_message - Parsed P2P message (or P2P IE)
 */
struct p2p_message {
	struct wpabuf *p2p_attributes;//p2p属性
	struct wpabuf *wps_attributes;
	struct wpabuf *wfd_subelems;//wfd子属性

	u8 dialog_token;

	const u8 *capability;
	const u8 *go_intent;
	const u8 *status;//状态
	const u8 *listen_channel;//监听信道
	const u8 *operating_channel;//协商信道
	const u8 *channel_list;//信道列表
	u8 channel_list_len;
	const u8 *config_timeout;
	const u8 *intended_addr;
	const u8 *group_bssid;//对端MAC地址
	const u8 *invitation_flags;

	const u8 *group_info;
	size_t group_info_len;

	const u8 *group_id;
	size_t group_id_len;

	const u8 *device_id;//设备ID

	const u8 *manageability;

	const u8 *noa;
	size_t noa_len;

	const u8 *ext_listen_timing;

	const u8 *minor_reason_code;

	const u8 *oob_go_neg_channel;

	/* P2P Device Info */
	//P2P_ATTR_DEVICE_INFO
	const u8 *p2p_device_info;
	size_t p2p_device_info_len;
	const u8 *p2p_device_addr;
	const u8 *pri_dev_type;
	u8 num_sec_dev_types;
	char device_name[WPS_DEV_NAME_MAX_LEN + 1];
	u16 config_methods;

	/* WPS IE */
	u16 dev_password_id;
	int dev_password_id_present;
	u16 wps_config_methods;
	const u8 *wps_pri_dev_type;
	const u8 *wps_sec_dev_type_list;
	size_t wps_sec_dev_type_list_len;
	const u8 *wps_vendor_ext[P2P_MAX_WPS_VENDOR_EXT];
	size_t wps_vendor_ext_len[P2P_MAX_WPS_VENDOR_EXT];
	const u8 *manufacturer;
	size_t manufacturer_len;
	const u8 *model_name;
	size_t model_name_len;
	const u8 *model_number;
	size_t model_number_len;
	const u8 *serial_number;
	size_t serial_number_len;
	const u8 *oob_dev_password;
	size_t oob_dev_password_len;

	/* DS Parameter Set IE */
	const u8 *ds_params;

	/* SSID IE */
	const u8 *ssid;

	/* P2PS */
	u8 service_hash_count;
	const u8 *service_hash;

	const u8 *session_info;
	size_t session_info_len;

	const u8 *conn_cap;

	const u8 *adv_id;
	const u8 *adv_mac;

	const u8 *adv_service_instance;
	size_t adv_service_instance_len;

	const u8 *session_id;
	const u8 *session_mac;

	const u8 *feature_cap;
	size_t feature_cap_len;

	const u8 *persistent_dev;
	const u8 *persistent_ssid;
	size_t persistent_ssid_len;

	const u8 *pref_freq_list;
	size_t pref_freq_list_len;
};

邀请应答包构造

p2p_build_invitation_resp进行邀请应答包构造。

c 复制代码
static struct wpabuf * p2p_build_invitation_resp(struct p2p_data *p2p,
						 struct p2p_device *peer,
						 u8 dialog_token, u8 status,
						 const u8 *group_bssid,
						 u8 reg_class, u8 channel,
						 struct p2p_channels *channels)
{
	struct wpabuf *buf;
	u8 *len;
	size_t extra = 0;

#ifdef CONFIG_WIFI_DISPLAY
	struct wpabuf *wfd_ie = p2p->wfd_ie_invitation;
	if (wfd_ie && group_bssid) {
		size_t i;
		for (i = 0; i < p2p->num_groups; i++) {
			struct p2p_group *g = p2p->groups[i];
			struct wpabuf *ie;
			if (os_memcmp(p2p_group_get_interface_addr(g),
				      group_bssid, ETH_ALEN) != 0)
				continue;
			ie = p2p_group_get_wfd_ie(g);
			if (ie) {
				wfd_ie = ie;
				break;
			}
		}
	}
	if (wfd_ie)
		extra = wpabuf_len(wfd_ie);
#endif /* CONFIG_WIFI_DISPLAY */

	if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_INV_RESP])
		extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_INV_RESP]);

	buf = wpabuf_alloc(1000 + extra);
	if (buf == NULL)
		return NULL;
	//构造头部
	p2p_buf_add_public_action_hdr(buf, P2P_INVITATION_RESP,
				      dialog_token);
	//构造Wi-Fi Direct
	len = p2p_buf_add_ie_hdr(buf);
	//构造状态
	p2p_buf_add_status(buf, status);
	//构造超时
	p2p_buf_add_config_timeout(buf, 0, 0); /* FIX */
	//构造协商信道
	if (reg_class && channel)
		p2p_buf_add_operating_channel(buf, p2p->cfg->country,
					      reg_class, channel);
	//构造MAC地址
	if (group_bssid)
		p2p_buf_add_group_bssid(buf, group_bssid);
	//构造信道列表
	if (channels)
		p2p_buf_add_channel_list(buf, p2p->cfg->country, channels);
	p2p_buf_update_ie_hdr(buf, len);

#ifdef CONFIG_WIFI_DISPLAY
	if (wfd_ie)
		wpabuf_put_buf(buf, wfd_ie);
#endif /* CONFIG_WIFI_DISPLAY */

	if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_INV_RESP])
		wpabuf_put_buf(buf, p2p->vendor_elem[VENDOR_ELEM_P2P_INV_RESP]);

	return buf;
}

发送Action帧

调用p2p_send_action发送。

相关推荐
小小不董13 分钟前
深入理解oracle ADG和RAC
linux·服务器·数据库·oracle·dba
胚芽鞘6811 小时前
查询依赖冲突工具maven Helper
java·数据库·maven
狄加山6751 小时前
Cadence模块复用
服务器·硬件架构·硬件工程·信号处理·智能硬件
宇钶宇夕1 小时前
SIMATIC S7-1200的以太网通信能力:协议与资源详细解析
运维·服务器·数据库·程序人生·自动化
该用户已不存在1 小时前
关于我把Mac Mini托管到机房,后续来了,还有更多玩法
服务器·前端·mac
LuckyLay2 小时前
1.1.1数据类型与变量——AI教你学Django
数据库·django·sqlite
%d%d22 小时前
python 在运行时没有加载修改后的版本
java·服务器·python
汤姆大聪明2 小时前
Redis 持久化机制
数据库·redis·缓存
CodeWithMe2 小时前
【Note】Linux Kernel 实时技术深入:详解 PREEMPT_RT 与 Xenomai
linux·运维·服务器