【MTK平台】【wpa_supplicant】关于wpa_supplicant_8/src/p2p/p2p.c文件的介绍

这篇具有很好参考价值的文章主要介绍了【MTK平台】【wpa_supplicant】关于wpa_supplicant_8/src/p2p/p2p.c文件的介绍。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文主要介绍external/wpa_supplicant_8/src/p2p/p2p.c文件

先看下p2p_find 这个方法

P2P_find 主要用于 P2P(点对点)网络中查找其他对等方的功能。另外可以看到设置P2P模块的状态为 P2P_SEARCH

int p2p_find(struct p2p_data *p2p, unsigned int timeout,
	     enum p2p_discovery_type type,
	     unsigned int num_req_dev_types, const u8 *req_dev_types,
	     const u8 *dev_id, unsigned int search_delay,
	     u8 seek_count, const char **seek, int freq, bool include_6ghz)
{
	int res;
	struct os_reltime start;

	p2p_dbg(p2p, "Starting find (type=%d)", type);
    //确认P2P扫描已经可以使用
	if (p2p->p2p_scan_running) {
		p2p_dbg(p2p, "p2p_scan is already running");
	}

	p2p_free_req_dev_types(p2p);
	if (req_dev_types && num_req_dev_types) {
		p2p->req_dev_types = os_memdup(req_dev_types,
					       num_req_dev_types *
					       WPS_DEV_TYPE_LEN);
		if (p2p->req_dev_types == NULL)
			return -1;
		p2p->num_req_dev_types = num_req_dev_types;
	}

	if (dev_id) {
		os_memcpy(p2p->find_dev_id_buf, dev_id, ETH_ALEN);
		p2p->find_dev_id = p2p->find_dev_id_buf;
	} else
		p2p->find_dev_id = NULL;
	p2p->include_6ghz = p2p_wfd_enabled(p2p) && include_6ghz;
	if (seek_count == 0 || !seek) {
		/* Not an ASP search */
		p2p->p2ps_seek = 0;
	} else if (seek_count == 1 && seek && (!seek[0] || !seek[0][0])) {
		/*
		 * An empty seek string means no hash values, but still an ASP
		 * search.
		 */
		p2p_dbg(p2p, "ASP search");
		p2p->p2ps_seek_count = 0;
		p2p->p2ps_seek = 1;
	} else if (seek && seek_count <= P2P_MAX_QUERY_HASH) {
		u8 buf[P2PS_HASH_LEN];
		int i, count = 0;

		for (i = 0; i < seek_count; i++) {
			if (!p2ps_gen_hash(p2p, seek[i], buf))
				continue;

			p2p_dbg(p2p, "Seek service %s hash " MACSTR,
				seek[i], MAC2STR(buf));
			os_memcpy(&p2p->p2ps_seek_hash[count * P2PS_HASH_LEN],
				  buf, P2PS_HASH_LEN);
			count++;
		}

		p2p->p2ps_seek_count = count;
		p2p->p2ps_seek = 1;
	} else {
		p2p->p2ps_seek_count = 0;
		p2p->p2ps_seek = 1;
	}

	/* Special case to perform wildcard search */
	if (p2p->p2ps_seek_count == 0 && p2p->p2ps_seek) {
		p2p->p2ps_seek_count = 1;
		os_memcpy(&p2p->p2ps_seek_hash, p2p->wild_card_hash,
			  P2PS_HASH_LEN);
	}
    //P2P_AFTER_SCAN_NOTHING表示P2P设备完成scan动作后,无需做其他动作
	p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING;
	p2p_clear_timeout(p2p);
	if (p2p->pending_listen_freq) {
		p2p_dbg(p2p, "Clear pending_listen_freq for p2p_find");
		p2p->pending_listen_freq = 0;
	}
    //停止监听
	p2p->cfg->stop_listen(p2p->cfg->cb_ctx);
	p2p->find_pending_full = 0;
	p2p->find_type = type;
	if (freq != 2412 && freq != 2437 && freq != 2462 && freq != 60480)
		p2p->find_specified_freq = freq;
	else
		p2p->find_specified_freq = 0;
	p2p_device_clear_reported(p2p);
	os_memset(p2p->sd_query_no_ack, 0, ETH_ALEN);
    //设置P2P模块的状态为 P2P_SEARCH
	p2p_set_state(p2p, P2P_SEARCH);
	p2p->search_delay = search_delay;
	p2p->in_search_delay = 0;
	eloop_cancel_timeout(p2p_find_timeout, p2p, NULL);
	p2p->last_p2p_find_timeout = timeout;
	if (timeout)
        //注册一个扫描超时处理任务
		eloop_register_timeout(timeout, 0, p2p_find_timeout,
				       p2p, NULL);
	os_get_reltime(&start);
	switch (type) {
	case P2P_FIND_START_WITH_FULL:
		if (freq > 0) {
			/*
			 * Start with the specified channel and then move to
			 * scans for social channels and this specific channel.
			 */
			res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx,
						 P2P_SCAN_SPECIFIC, freq,
						 p2p->num_req_dev_types,
						 p2p->req_dev_types, dev_id,
						 DEV_PW_DEFAULT,
						 p2p->include_6ghz);
			break;
		}
		/* fall through */
	case P2P_FIND_PROGRESSIVE: //p2p_scan指向函数 wpas_p2p_scan
		res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_FULL, 0,
					 p2p->num_req_dev_types,
					 p2p->req_dev_types, dev_id,
					 DEV_PW_DEFAULT, p2p->include_6ghz);
		break;
	case P2P_FIND_ONLY_SOCIAL:
		res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_SOCIAL, 0,
					 p2p->num_req_dev_types,
					 p2p->req_dev_types, dev_id,
					 DEV_PW_DEFAULT, p2p->include_6ghz);
		break;
	default:
		return -1;
	}

	if (!res)
		p2p->find_start = start;

	if (res != 0 && p2p->p2p_scan_running) {
		p2p_dbg(p2p, "Failed to start p2p_scan - another p2p_scan was already running");
		/* wait for the previous p2p_scan to complete */
		if (type == P2P_FIND_PROGRESSIVE ||
		    (type == P2P_FIND_START_WITH_FULL && freq == 0))
			p2p->find_pending_full = 1;
		res = 0; /* do not report failure */
	} else if (res != 0) {
		p2p_dbg(p2p, "Failed to start p2p_scan");
		p2p_set_state(p2p, P2P_IDLE);
		eloop_cancel_timeout(p2p_find_timeout, p2p, NULL);
	}

	return res;
}

 接着看下P2P模块的状态为 P2P_SEARCH后如何进行进入listen状态

 也就是p2p_listen_in_find这个方法

static void p2p_listen_in_find(struct p2p_data *p2p, int dev_disc)
{
	unsigned int r, tu;
	int freq;
	struct wpabuf *ies;

	p2p_dbg(p2p, "Starting short listen state (state=%s)",
		p2p_state_txt(p2p->state));

	if (p2p->pending_listen_freq) {
		/* We have a pending p2p_listen request */
		p2p_dbg(p2p, "p2p_listen command pending already");
		return;
	}
    //根据 p2p_supplicant.conf中listen_channel等配置参数获取对应的频段
	freq = p2p_channel_to_freq(p2p->cfg->reg_class, p2p->cfg->channel);
	if (freq < 0) {
		p2p_dbg(p2p, "Unknown regulatory class/channel");
		return;
	}
    //计算需要在listen state 等待的时间
	if (os_get_random((u8 *) &r, sizeof(r)) < 0)
		r = 0;
	tu = (r % ((p2p->max_disc_int - p2p->min_disc_int) + 1) +
	      p2p->min_disc_int) * 100;
	if (p2p->max_disc_tu >= 0 && tu > (unsigned int) p2p->max_disc_tu)
		tu = p2p->max_disc_tu;
	if (!dev_disc && tu < 100)
		tu = 100; /* Need to wait in non-device discovery use cases */
	if (p2p->cfg->max_listen && 1024 * tu / 1000 > p2p->cfg->max_listen)
		tu = p2p->cfg->max_listen * 1000 / 1024;

	if (tu == 0) {
		p2p_dbg(p2p, "Skip listen state since duration was 0 TU");
		p2p_set_timeout(p2p, 0, 0);
		return;
	}
    //构造P2P Probe Response帧,当我们在Listen state收到其他设备发来的Probe Request帧后,wifi驱动将直接回复此处设置的 P2P Probe Response帧。
	ies = p2p_build_probe_resp_ies(p2p, NULL, 0);
	if (ies == NULL)
		return;

	p2p->pending_listen_freq = freq;
	p2p->pending_listen_sec = 0;
	p2p->pending_listen_usec = 1024 * tu;
    //start_listen指向 wpas_start_listen 函数
	if (p2p->cfg->start_listen(p2p->cfg->cb_ctx, freq, 1024 * tu / 1000,
		    ies) < 0) {
		p2p_dbg(p2p, "Failed to start listen mode");
		p2p->pending_listen_freq = 0;
	}
	wpabuf_free(ies);
}

在来看p2p_connect函数,其代码如下所示

这里面有3个重要的知识点

1、是 breaker值在每次发起P2P_CONNECT时都取反一次,这样做的目的是在双方的Intent值相同的情况下,多次协商时,双方都有机会做GO。并且在发送Request时才填入自己的breaker值,在回应Response时,是把对方的breaker值取反后作为breaker值发送。

2. 如果当前P2P还在扫描过程中,则设置start_after_scan为P2P_AFTER_SCAN_CONNECT标志,当scan结束后,在扫描结果处理流程中,该标志将通知P2P进入connect处理流程

3.   p2p_connect_send发送GON Request帧

int p2p_connect(struct p2p_data *p2p, const u8 *peer_addr,
		enum p2p_wps_method wps_method,
		int go_intent, const u8 *own_interface_addr,
		unsigned int force_freq, int persistent_group,
		const u8 *force_ssid, size_t force_ssid_len,
		int pd_before_go_neg, unsigned int pref_freq, u16 oob_pw_id)
{
	struct p2p_device *dev;

	p2p_dbg(p2p, "Request to start group negotiation - peer=" MACSTR
		"  GO Intent=%d  Intended Interface Address=" MACSTR
		" wps_method=%d persistent_group=%d pd_before_go_neg=%d "
		"oob_pw_id=%u allow_6ghz=%d",
		MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr),
		wps_method, persistent_group, pd_before_go_neg, oob_pw_id,
		p2p->allow_6ghz);
    //获取当前设备p2p dev设备的信息
	dev = p2p_get_device(p2p, peer_addr);
	if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) {
		p2p_dbg(p2p, "Cannot connect to unknown P2P Device " MACSTR,
			MAC2STR(peer_addr));
		return -1;
	}
    // 如果指定了工作频段,则需要判断是否支持该工作频段,否则return -1
	if (p2p_prepare_channel(p2p, dev, force_freq, pref_freq,
				go_intent == 15) < 0)
		return -1;

	if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) {
		if (!(dev->info.dev_capab &
		      P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) {
			p2p_dbg(p2p, "Cannot connect to P2P Device " MACSTR
				" that is in a group and is not discoverable",
				MAC2STR(peer_addr));
			return -1;
		}
		if (dev->oper_freq <= 0) {
			p2p_dbg(p2p, "Cannot connect to P2P Device " MACSTR
				" with incomplete information",
				MAC2STR(peer_addr));
			return -1;
		}

		/*
		 * First, try to connect directly. If the peer does not
		 * acknowledge frames, assume it is sleeping and use device
		 * discoverability via the GO at that point.
		 */
	}

	p2p->ssid_set = 0;
	if (force_ssid) {
		wpa_hexdump_ascii(MSG_DEBUG, "P2P: Forced SSID",
				  force_ssid, force_ssid_len);
		os_memcpy(p2p->ssid, force_ssid, force_ssid_len);
		p2p->ssid_len = force_ssid_len;
		p2p->ssid_set = 1;
	}

	dev->flags &= ~P2P_DEV_NOT_YET_READY;
	dev->flags &= ~P2P_DEV_USER_REJECTED;
	dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE;
	dev->flags &= ~P2P_DEV_WAIT_GO_NEG_CONFIRM;
	if (pd_before_go_neg)
		dev->flags |= P2P_DEV_PD_BEFORE_GO_NEG;
	else {
		dev->flags &= ~P2P_DEV_PD_BEFORE_GO_NEG;
		/*
		 * Assign dialog token and tie breaker here to use the same
		 * values in each retry within the same GO Negotiation exchange.
		 */
		dev->dialog_token++;
		if (dev->dialog_token == 0)
			dev->dialog_token = 1;
		dev->tie_breaker = p2p->next_tie_breaker;
		p2p->next_tie_breaker = !p2p->next_tie_breaker;//这里是对intent的值取反
	}
	dev->connect_reqs = 0;
	dev->go_neg_req_sent = 0;
	dev->go_state = UNKNOWN_GO;
	p2p_set_dev_persistent(dev, persistent_group);
	p2p->go_intent = go_intent;
	os_memcpy(p2p->intended_addr, own_interface_addr, ETH_ALEN);

	if (p2p->state != P2P_IDLE)
		p2p_stop_find(p2p);

	dev->wps_method = wps_method;
	dev->oob_pw_id = oob_pw_id;
	dev->status = P2P_SC_SUCCESS;

	if (p2p->p2p_scan_running) {
		p2p_dbg(p2p, "p2p_scan running - delay connect send");
/*
如果当前P2P还在扫描过程中,则设置start_after_scan为P2P_AFTER_SCAN_CONNECT标志,
当scan结束后,在扫描结果处理流程中,该标志将通知P2P进入connect处理流程。
*/
		p2p->start_after_scan = P2P_AFTER_SCAN_CONNECT;
		os_memcpy(p2p->after_scan_peer, peer_addr, ETH_ALEN);
		return 0;
	}
    // 下面这个函数将发送GON Request帧
  	return p2p_connect_send(p2p, dev);
}

p2p_set_state和p2p_set_timeout记录了P2P: State和Timeout文章来源地址https://www.toymoban.com/news/detail-620560.html

void p2p_set_state(struct p2p_data *p2p, int new_state)
{
	p2p_dbg(p2p, "State %s -> %s",
		p2p_state_txt(p2p->state), p2p_state_txt(new_state));
	p2p->state = new_state;

	if (new_state == P2P_IDLE && p2p->pending_channel) {
		p2p_dbg(p2p, "Apply change in listen channel");
		p2p->cfg->reg_class = p2p->pending_reg_class;
		p2p->cfg->channel = p2p->pending_channel;
		p2p->pending_reg_class = 0;
		p2p->pending_channel = 0;
	}
}


void p2p_set_timeout(struct p2p_data *p2p, unsigned int sec, unsigned int usec)
{
	p2p_dbg(p2p, "Set timeout (state=%s): %u.%06u sec",
		p2p_state_txt(p2p->state), sec, usec);
	eloop_cancel_timeout(p2p_state_timeout, p2p, NULL);
	eloop_register_timeout(sec, usec, p2p_state_timeout, p2p, NULL);
}

到了这里,关于【MTK平台】【wpa_supplicant】关于wpa_supplicant_8/src/p2p/p2p.c文件的介绍的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux|centos7操作系统|无线WiFi的命令行配置---wpa_supplicant详解

    Linux系统下,可以配置无线网卡的工具和方法有很多,比如,nmcli,iw,wap_supplicant,hostapd 或者直接安装桌面,图形化配置等等 这些工具比较多,但基本都是一个共同的流程:先利用工具扫描到AP,然后设置无线网卡的连接方式,最后无线网卡连接无线路由,完成WiFi连接 那么

    2024年01月23日
    浏览(64)
  • Linux:命令行调试WiFi(iwlist/iwconfig/iw/wpa_supplicant/wpa_cli/dhcp/hostapd/hostapd_cli的使用方法)

    【抄袭个笔记】 1、编译步骤 https://blog.csdn.net/weixin_49071468/article/details/133170711?spm=1001.2014.3001.5502 2、iwlist iwlist wlan0 scan[ning]                    列出WiFi扫描结果 iwlist wlan0 freq[uency]/channel        列出当前地区可用频率 iwlist wlan0 rate/bit[rate]                 列出支持

    2024年01月16日
    浏览(35)
  • P2P 应用

    ·在 P2P 工作方式下,所有的音频/视频文件都是在普通的互联网 用户之间传输 。 ·Napster 最早 使用 P2P 技术,提供免费下载 MP3 音乐。 ·Napster 将所有音乐文件的索引信息都集中存放在 Napster 目录服务器中。 ·使用者只要查找目录服务器,就可知道应从何处下载所要的 MP3 文件

    2024年02月19日
    浏览(42)
  • 什么是P2P?

    P2P (Peer-to-Peer) 是一种分布式的网络架构,其中各个节点(通常被称为“peers”或“节点”)直接进行数据共享和交换,而无需依赖中央服务器。P2P 网络强调平等的参与和共享,每个节点既可以是数据的消费者(下载者),也可以是提供者(上传者)。 以下是 P2P 协议和技术的

    2024年02月13日
    浏览(52)
  • P2P通信基本原理

    在数字世界的脉络中,点对点(P2P)技术如同一条悄无声息的河流,流经信息的每个角落,连接着世界各地的计算机和设备。这种去中心化的网络模型,不仅打破了传统的客户端-服务器架构的界限,还赋予了数据传输一种前所未有的自由和效率。通过P2P,每个参与者既是消费

    2024年04月16日
    浏览(48)
  • P2P协议的传输艺术

    TP 采用两个 TCP 连接来传输一个文件。 控制连接:服务器以被动的方式,打开众所周知用于 FTP 的端口 21,客户端则主动发起连接。该连接将命令从客户端传给服务器,并传回服务器的应答。常用的命令有:list——获取文件目录;reter——取一个文件;store——存一个文件。

    2024年02月07日
    浏览(43)
  • P2P 网络,PING程序。

    没有废话,直接上版本号和代码,以及讲解。 crate 版本号 libp2p 0.52.1 tokio 1.30.0 Peer-to-Peer是一种网络技术。一种点对点的通讯技术。没有client-service概念。 在P2P网络中,节点标识被成为PeerId。

    2024年02月12日
    浏览(46)
  • 区块链——p2p网络模型

            通常情况下,一个区块链系统的P2P网络层主要由以下几部分组成。         覆盖网络可以根据其对应覆盖图的性质分为两类: 无结构化覆盖网络 和 结构化覆盖网络 。无结构化覆盖网络通常基于随机图来建立节点随机从覆盖网络中选取节点作为邻居;而结构化覆盖

    2024年04月27日
    浏览(49)
  • 区块链核心技术-P2P网络

    点对点网络是区块链中核心的技术之一,主要关注的方面是为区块链提供一个稳定的网络结构,用于广播未被打包的交易(交易池中的交易)以及共识过的区块,部分共识算法也需要点对点的网络支撑(如PBFT),另外一个辅助功能,如以太坊的消息网络,也需要点对点网络的

    2023年04月17日
    浏览(58)
  • 区块链入门系列之P2P

    区块链基本概念和名词解释 P2P 共识算法 梅克尔-帕特里夏树 从零开始搭建区块链 为什么前面讲过P2P的概念了这里还要单独起一篇文章来讲解,因为前面只是讲解了P2P的基本概念,即各网络节点间是直接或间接连接起来的。但这里面还涉及到很多网络知识,如果不清楚,是没

    2023年04月19日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包