WiFi Direct 在wpa_supplicant中的流程一(初始化P2P)

WIFI-Driect在WPA_S中的初始化流程:

小白一枚,有冗余以及理解不到位的地方多有体谅

Alt
直接从wpa_supplicant开始,上面的framework的流程就不跟流程了,有兴趣的可以自己跟下上面的流程,

struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
						 struct wpa_interface *iface,
						 struct wpa_supplicant *parent)
{
......
	if (wpa_supplicant_init_iface(wpa_s, &t_iface)) {
	}
......
	wpa_dbg(wpa_s, MSG_DEBUG, "Added interface %s", wpa_s->ifname);
	wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
......
#ifdef CONFIG_P2P
	if (wpa_s->global->p2p == NULL &&
	    !wpa_s->global->p2p_disabled && !wpa_s->conf->p2p_disabled &&
	    (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&
	    wpas_p2p_add_p2pdev_interface(
		    wpa_s, wpa_s->global->params.conf_p2p_dev) < 0) {
		wpa_printf(MSG_INFO,
			   "P2P: Failed to enable P2P Device interface");
		/* Try to continue without. P2P will be disabled. */
	}
#endif /* CONFIG_P2P */
}
static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
				     const struct wpa_interface *iface)
{
......
	if ((!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) ||
	     wpa_s->p2p_mgmt) &&
	    wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
		wpa_msg(wpa_s, MSG_ERROR, "Failed to init P2P");
		return -1;
	}
......
}

注册action

static int wpa_driver_nl80211_set_mode_impl(
		struct i802_bss *bss,
		enum nl80211_iftype nlmode,
		struct hostapd_freq_params *desired_freq_params)
{
.......

	mode_switch_res = nl80211_set_mode(drv, drv->ifindex, nlmode);
	if (mode_switch_res && nlmode == nl80211_get_ifmode(bss))
		mode_switch_res = 0;
		
	if (mode_switch_res == 0) {
		drv->nlmode = nlmode;
		ret = 0;
		goto done;
	}
	
.......

done:

........

	if (!bss->in_deinit && !is_ap_interface(nlmode) &&
	    !is_mesh_interface(nlmode) &&
	    nl80211_mgmt_subscribe_non_ap(bss) < 0)
		wpa_printf(MSG_DEBUG, "nl80211: Failed to register Action "
			   "frame processing - ignore for now");

	return 0;
}

该函数通过使用nl80211内核接口将非接入点(non-AP)事件添加到当前订阅列表中,并开始接收与其相关的通知。这些事件可能包括信道扫描、帧注入、关联和认证等操作

static int nl80211_mgmt_subscribe_non_ap(struct i802_bss *bss)
{
.......
	wpa_printf(MSG_DEBUG, "nl80211: Subscribe to mgmt frames with non-AP "
		   "handle %p", bss->nl_mgmt);
......
#if defined(CONFIG_P2P) || defined(CONFIG_INTERWORKING) || defined(CONFIG_DPP)
	/* GAS Initial Request */
	if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0a", 2) < 0)
		ret = -1;
..............
}


nl80211_mgmt_subscribe_non_ap 通过使用nl80211内核接口向驱动程序发送注册请求,以便在接收到特定类型的Action帧时通知用户空间应用程序
作用是当P2P设备收到对应的Action帧后,WIFI 驱动会将相应的消息传递给wpa_supplciant进行处理

wpas_p2p_init() 代码段1

int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
{
	struct p2p_config p2p;
	int i;

	if (wpa_s->conf->p2p_disabled)
		return 0;

	if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE))
		return 0;

	if (global->p2p)
		return 0;

	if (wpas_p2p_mac_setup(wpa_s) < 0) {
		wpa_msg(wpa_s, MSG_ERROR,
			"Failed to initialize P2P random MAC address.");
		return -1;
	}
.......
}
  1. 初始化一个p2p对象,其结构体类型是p2p_config
  2. 判断p2p_disabled,是否启用P2P功能,这个是上层framework行为
  3. 判断wifi驱动是否支持p2p功能,判断是否有WPA_DRIVER_FLAGS_P2P_CAPABLE
  4. 判断全局参数p2p是否已被赋值
  5. 生成mac地址用于p2p通讯

wpas_p2p_init() 代码段2

将对应函数的指针赋值改p2p中的对应成员变量,用于后期直接调用对应成员

p2p_config定义了下面的许多回调函数。这些回调函数定义了P2P模块和外界交互的接口

int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
{
	struct p2p_config p2p;
.........
    os_memset(&p2p, 0, sizeof(p2p));
	p2p.cb_ctx = wpa_s;
	p2p.debug_print = wpas_p2p_debug_print;
	p2p.p2p_scan = wpas_p2p_scan; //发起p2p的scan
	p2p.send_action = wpas_send_action; //发送action帧
	p2p.send_action_done = wpas_send_action_done;//发送action帧发送完成
	p2p.go_neg_completed = wpas_go_neg_completed;
	p2p.go_neg_req_rx = wpas_go_neg_req_rx;
	p2p.dev_found = wpas_dev_found;//发现一个P2P的设备
	p2p.dev_lost = wpas_dev_lost;//丢失一个P2P的设备
	p2p.find_stopped = wpas_find_stopped;//搜索已经停止的p2p设备,并将其在列表中移除
	p2p.start_listen = wpas_start_listen;//开始listen状态
	p2p.stop_listen = wpas_stop_listen;//关闭listen状态
	p2p.send_probe_resp = wpas_send_probe_resp; //发送Probe Response帧
	p2p.sd_request = wpas_sd_request;//发送获取其他设备的服务类型以及特征等信息的请求
	p2p.sd_response = wpas_sd_response;//回复设备的服务类型以及特征等信息的请求
	p2p.prov_disc_req = wpas_prov_disc_req;//收到建立连接请求
	p2p.prov_disc_resp = wpas_prov_disc_resp;//回应连接请求
	p2p.prov_disc_fail = wpas_prov_disc_fail;//连接请求失败
	p2p.invitation_process = wpas_invitation_process;//向GO发送邀请请求
	p2p.invitation_received = wpas_invitation_received;//收到邀请请求
	p2p.invitation_result = wpas_invitation_result;//反馈邀请结果
	p2p.get_noa = wpas_get_noa;//GO进入省电模式时,会发送一个NOA的帧,作为识别
	p2p.go_connected = wpas_go_connected;//用于判断GO的连接状态
	p2p.presence_resp = wpas_presence_resp;//处理P2P存在请求
	p2p.is_concurrent_session_active = wpas_is_concurrent_session_active;//是否存在同时会话的状态
	p2p.is_p2p_in_progress = _wpas_p2p_in_progress;//指示是否当前正在进行P2P的操作
	p2p.get_persistent_group = wpas_get_persistent_group;//获取确定是否有一个远程持久组
	p2p.get_go_info = wpas_get_go_info;//获取GO的信息参数
	p2p.remove_stale_groups = wpas_remove_stale_groups;//搜索并移除已失效的P2P组信息
	p2p.p2ps_prov_complete = wpas_p2ps_prov_complete;//处理P2P服务完成事件
	p2p.prov_disc_resp_cb = wpas_prov_disc_resp_cb;//响应prov_disc请求,提供链接所需身份信息(SSID以及密码等)
	p2p.p2ps_group_capability = p2ps_group_capability;//用于组建过程中所提供的服务类型以及参数,(设备名,信道等设置到p2ps_group_capability成员变量中)
	p2p.get_pref_freq_list = wpas_p2p_get_pref_freq_list;//用于获取P2P设备的首选信道列表

	os_memcpy(wpa_s->global->p2p_dev_addr, wpa_s->own_addr, ETH_ALEN);
	os_memcpy(p2p.dev_addr, wpa_s->global->p2p_dev_addr, ETH_ALEN);
	p2p.dev_name = wpa_s->conf->device_name;
	p2p.manufacturer = wpa_s->conf->manufacturer;
	p2p.model_name = wpa_s->conf->model_name;
	p2p.model_number = wpa_s->conf->model_number;
	p2p.serial_number = wpa_s->conf->serial_number;
.......
}

wpas_p2p_init() 代码段3

下面的部分对应代码代表对信道的设置:

int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
{
	struct p2p_config p2p;

.......

if (wpas_p2p_setup_channels(wpa_s, &p2p.channels, &p2p.cli_channels)) {
	wpa_printf(MSG_ERROR,
		   "P2P: Failed to configure supported channel list");
	return -1;
}

if (wpa_s->conf->p2p_listen_reg_class &&
	    wpa_s->conf->p2p_listen_channel) {
		p2p.reg_class = wpa_s->conf->p2p_listen_reg_class;
		p2p.channel = wpa_s->conf->p2p_listen_channel;
		p2p.channel_forced = 1;
	} else {
		/*
		 * Pick one of the social channels randomly as the listen
		 * channel.
		 */
		if (p2p_config_get_random_social(&p2p, &p2p.reg_class,
						 &p2p.channel,
						 &global->p2p_go_avoid_freq,
						 &global->p2p_disallow_freq) !=
		    0) {
			wpa_printf(MSG_INFO,
				   "P2P: No social channels supported by the driver - do not enable P2P");
			return 0;
		}
		p2p.channel_forced = 0;
	}
	wpa_printf(MSG_DEBUG, "P2P: Own listen channel: %d:%d",
		   p2p.reg_class, p2p.channel);

	if (wpa_s->conf->p2p_oper_reg_class &&
	    wpa_s->conf->p2p_oper_channel) {
		p2p.op_reg_class = wpa_s->conf->p2p_oper_reg_class;
		p2p.op_channel = wpa_s->conf->p2p_oper_channel;
		p2p.cfg_op_channel = 1;
		wpa_printf(MSG_DEBUG, "P2P: Configured operating channel: "
			   "%d:%d", p2p.op_reg_class, p2p.op_channel);

	} else {
		/*
		 * Use random operation channel from 2.4 GHz band social
		 * channels (1, 6, 11) or band 60 GHz social channel (2) if no
		 * other preference is indicated.
		 */
		if (p2p_config_get_random_social(&p2p, &p2p.op_reg_class,
						 &p2p.op_channel, NULL,
						 NULL) != 0) {
			wpa_printf(MSG_INFO,
				   "P2P: Failed to select random social channel as operation channel");
			p2p.op_reg_class = 0;
			p2p.op_channel = 0;
			/* This will be overridden during group setup in
			 * p2p_prepare_channel(), so allow setup to continue. */
		}
		p2p.cfg_op_channel = 0;
		wpa_printf(MSG_DEBUG, "P2P: Random operating channel: "
			   "%d:%d", p2p.op_reg_class, p2p.op_channel);
	}

	if (wpa_s->conf->p2p_pref_chan && wpa_s->conf->num_p2p_pref_chan) {
		p2p.pref_chan = wpa_s->conf->p2p_pref_chan;
		p2p.num_pref_chan = wpa_s->conf->num_p2p_pref_chan;
	}
.......
}

wpas_p2p_setup_channels此函数用于设置 P2P 设备支持的通道列表,

下一步就是随机选择一个信道作为listen信道

P2P: Own listen channel: 81 11(即选择11信道为listen信道,是等待其他设备接入时所使用的信道)

P2P: Random operating channel: 81:6(选取随机operating信道,是进行通讯时采用的信道)

wpas_p2p_init() 代码段4

设置p2p的相关参数用于后续使用

	if (wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
		os_memcpy(p2p.country, wpa_s->conf->country, 2);
		p2p.country[2] = 0x04;
	} else
		os_memcpy(p2p.country, "XX\x04", 3);

    os_memcpy(p2p.pri_dev_type, wpa_s->conf->device_type,
		  WPS_DEV_TYPE_LEN);

	p2p.num_sec_dev_types = wpa_s->conf->num_sec_device_types;
	os_memcpy(p2p.sec_dev_type, wpa_s->conf->sec_device_type,
		  p2p.num_sec_dev_types * WPS_DEV_TYPE_LEN);

	p2p.concurrent_operations = !!(wpa_s->drv_flags &
				       WPA_DRIVER_FLAGS_P2P_CONCURRENT);

	p2p.max_peers = 100;

	if (wpa_s->conf->p2p_ssid_postfix) {
		p2p.ssid_postfix_len =
			os_strlen(wpa_s->conf->p2p_ssid_postfix);
		if (p2p.ssid_postfix_len > sizeof(p2p.ssid_postfix))
			p2p.ssid_postfix_len = sizeof(p2p.ssid_postfix);
		os_memcpy(p2p.ssid_postfix, wpa_s->conf->p2p_ssid_postfix,
			  p2p.ssid_postfix_len);
	}

	p2p.p2p_intra_bss = wpa_s->conf->p2p_intra_bss;

	p2p.max_listen = wpa_s->max_remain_on_chan;

	if (wpa_s->conf->p2p_passphrase_len >= 8 &&
	    wpa_s->conf->p2p_passphrase_len <= 63)
		p2p.passphrase_len = wpa_s->conf->p2p_passphrase_len;
	else
		p2p.passphrase_len = 8;

设置p2p.contry的国家码,如果conf中没有的话,则P2P 程序自动检测设备所在的国家或地区
设置p2p.pri_dev_type指一台设备的主要设备类型
设置 p2p.max_peers = 100;表示可以同时连接100个p2p设备
设置 p2p.ssid_postfix_len 指定后缀名称长度
设置p2p.p2p_intra_bss默认为1,允许设备直接相互连接,无需群组中继,可提高连接速度等
设置p2p.max_listen默认为1,一次监听一个设备,可增加值,以允许在嘈杂环境中监听更多设备
设置p2p.passphrase_len默认为8,即P2P的密码最小长度,最高不得超过63位

引用文本

wpas_p2p_init() 代码段5

调用p2p_init()函数初始化p2p模块

	global->p2p = p2p_init(&p2p);
	if (global->p2p == NULL)
		return -1;

p2p_init() 代码段

主要构造了一个p2p_data结构体并设置相应的参数

struct p2p_data * p2p_init(const struct p2p_config *cfg)
{
	struct p2p_data *p2p;

	if (cfg->max_peers < 1 ||
	    cfg->passphrase_len < 8 || cfg->passphrase_len > 63)
		return NULL;

	p2p = os_zalloc(sizeof(*p2p) + sizeof(*cfg));
	if (p2p == NULL)
		return NULL;
	p2p->cfg = (struct p2p_config *) (p2p + 1);
	os_memcpy(p2p->cfg, cfg, sizeof(*cfg));
	if (cfg->dev_name)
		p2p->cfg->dev_name = os_strdup(cfg->dev_name);
	if (cfg->manufacturer)
		p2p->cfg->manufacturer = os_strdup(cfg->manufacturer);
	if (cfg->model_name)
		p2p->cfg->model_name = os_strdup(cfg->model_name);
	if (cfg->model_number)
		p2p->cfg->model_number = os_strdup(cfg->model_number);
	if (cfg->serial_number)
		p2p->cfg->serial_number = os_strdup(cfg->serial_number);
	if (cfg->pref_chan) {
		p2p->cfg->pref_chan = os_malloc(cfg->num_pref_chan *
						sizeof(struct p2p_channel));
		if (p2p->cfg->pref_chan) {
			os_memcpy(p2p->cfg->pref_chan, cfg->pref_chan,
				  cfg->num_pref_chan *
				  sizeof(struct p2p_channel));
		} else
			p2p->cfg->num_pref_chan = 0;
	}

	p2ps_gen_hash(p2p, P2PS_WILD_HASH_STR, p2p->wild_card_hash);

	p2p->min_disc_int = 1;
	p2p->max_disc_int = 3;
	p2p->max_disc_tu = -1;

	if (os_get_random(&p2p->next_tie_breaker, 1) < 0)
		p2p->next_tie_breaker = 0;
	p2p->next_tie_breaker &= 0x01;
	if (cfg->sd_request)
		p2p->dev_capab |= P2P_DEV_CAPAB_SERVICE_DISCOVERY;
	p2p->dev_capab |= P2P_DEV_CAPAB_INVITATION_PROCEDURE;
	if (cfg->concurrent_operations)
		p2p->dev_capab |= P2P_DEV_CAPAB_CONCURRENT_OPER;
	p2p->dev_capab |= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY;

	dl_list_init(&p2p->devices);

	p2p->go_timeout = 100;
	p2p->client_timeout = 20;
	p2p->num_p2p_sd_queries = 0;

	p2p_dbg(p2p, "initialized");
	p2p_channels_dump(p2p, "channels", &p2p->cfg->channels);
	p2p_channels_dump(p2p, "cli_channels", &p2p->cfg->cli_channels);

	return p2p;
}

其中

p2p->min_disc_int = 1; 表示设备进行发现操作的最小间隔时间设置为 1 秒

p2p->max_disc_int = 3;表示设备进行发现操作的最大间隔时间设置为 3 秒

p2p->max_disc_tu = -1;表示 设备进行发现操作的最长超时时间设置为默认值 (-1),即没有特定的超时时间限制。

p2p->go_timeout = 100;群组所有者的超时时间。
当一个设备成为P2P群组的所有者时,如果没有接收到任何对等设备的连接请求,那么在该时间后群组将自动取消。

p2p->client_timeout = 20;连接请求的超时时间。
当一个设备向其他设备发送P2P连接请求时,如果20S没有收到任何响应,那么在该时间后连接请求将自动取消。

p2p->num_p2p_sd_queries = 0;当前设备正在进行的服务发现请求的数量,初始值为 0。

p2p->dev_capab设置设备能力

详情已注释在代码中

/* P2P Capability - Device Capability bitmap */
//用于表示设备的能力,包括服务发现、客户端可见性、同时操作
#define P2P_DEV_CAPAB_SERVICE_DISCOVERY BIT(0)
//设备支持服务发现功能,即可以搜索和发现其他p2p设备
#define P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY BIT(1)
//设备支持客户端可见性功能,即可以使自己在其他P2P设备的搜索列表中被发现。
#define P2P_DEV_CAPAB_CONCURRENT_OPER BIT(2)
//设备支持同时处理多个P2P连接请求,即可以与多个设备进行并行连接。
#define P2P_DEV_CAPAB_INFRA_MANAGED BIT(3)
//设备支持基础设施托管功能,即可以作为 Wi-Fi 热点来提供网络连接服务。
#define P2P_DEV_CAPAB_DEVICE_LIMIT BIT(4)
//设备是否有最大对等连接数限制
#define P2P_DEV_CAPAB_INVITATION_PROCEDURE BIT(5)
//设备支持邀请过程,即可以使用 P2P邀请协议自动完成设备之间的连接。


/* P2P Capability - Group Capability bitmap */
//用于表示群组的能力,包括群组组所有权、持久群组、群组距离、跨连接等
#define P2P_GROUP_CAPAB_GROUP_OWNER BIT(0)
//群组具有组所有权功能,即可以作为群组拥有者来管理 P2P 群组。
#define P2P_GROUP_CAPAB_PERSISTENT_GROUP BIT(1)
//群组具有可以存储并恢复上次建立的群组信息的能力。
#define P2P_GROUP_CAPAB_GROUP_LIMIT BIT(2)
//群组是否有最大对等连接数限制。
#define P2P_GROUP_CAPAB_INTRA_BSS_DIST BIT(3)
//群组可以在同一 BSS(Basic Service Set)中工作,即可以使用设备之间的直接 Wi-Fi 连接。
#define P2P_GROUP_CAPAB_CROSS_CONN BIT(4)
//群组可以通过交叉连接(cross connect)进行通讯,即不同设备之间可以创建多层连接。
#define P2P_GROUP_CAPAB_PERSISTENT_RECONN BIT(5)
//群组具有持久重连(persistent reconnect)功能,即可以自动重新连接上次连接过的群组。
#define P2P_GROUP_CAPAB_GROUP_FORMATION BIT(6)
//群组支持群组建立功能,即可以使用 P2P 各种协议快速建立群组。
#define P2P_GROUP_CAPAB_IP_ADDR_ALLOCATION BIT(7)
//群组支持 IP 地址分配功能,即可以自动为群组内所有设备分配 IP 地址。

framework层调用processConfigUpdate

用于更新当前网络配置。该函数首先尝试加载指定路径下的新配置文件,如果找不到则返回错误。然后它会对比新旧配置文件,检测出新增、删除或修改的网络配置,并相应地进行处理。
最后,所有更改都会写入到文件系统中的配置文件中并返回成功。该函数还可以在运行时动态更新配置,而无需重启wpa_supplicant进程

void processConfigUpdate(struct wpa_supplicant* wpa_s, uint32_t changed_param)
{
	wpa_printf(MSG_ERROR,
						    "P2P: processConfigUpdate");
	wpa_s->conf->changed_parameters |= changed_param;
	wpa_supplicant_update_config(wpa_s);
}
void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s)
{
	if ((wpa_s->conf->changed_parameters & CFG_CHANGED_COUNTRY) &&
	    wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
		char country[3];
		country[0] = wpa_s->conf->country[0];
		country[1] = wpa_s->conf->country[1];
		country[2] = '\0';
		if (wpa_drv_set_country(wpa_s, country) < 0) {
			wpa_printf(MSG_ERROR, "Failed to set country code "
				   "'%s'", country);
		}
	}
	if (wpa_s->conf->changed_parameters & CFG_CHANGED_EXT_PW_BACKEND)
.........
	if (wpa_s->conf->changed_parameters & CFG_CHANGED_SCHED_SCAN_PLANS)
.......
......
	wpas_p2p_update_config(wpa_s);
}

wpa_s->conf->changed_parameters用于获取conf文件中是否有参数变化,变化的BIT位对应则更新对应参数,同样的 wpas_p2p_update_config()函数也是类似进行参数更新

相关log

WifiP2pNative: Setup P2P interface
SupplicantP2pIfaceHal: Completed initialization of ISupplicant interfaces.
wpa_supplicant: Override interface parameter: ctrl_interface (‘(null)’ -> ‘/data/vendor/wifi/wpa/sockets’)
wpa_supplicant: Initializing interface ‘p2p0’ conf ‘/data/vendor/wifi/wpa/p2p_supplicant.conf’ driver ‘nl80211’ ctrl_interface ‘/data/vendor/wifi/wpa/sockets’ bridge ‘N/A’
wpa_supplicant: Configuration file ‘/data/vendor/wifi/wpa/p2p_supplicant.conf’ -> ‘/data/vendor/wifi/wpa/p2p_supplicant.conf’
wpa_supplicant: Reading configuration file ‘/data/vendor/wifi/wpa/p2p_supplicant.conf’
wpa_supplicant: ctrl_interface=‘/data/vendor/wifi/wpa/sockets’
wpa_supplicant: disable_scan_offload=1
wpa_supplicant: update_config=1
wpa_supplicant: device_name=‘Android_4e95’
wpa_supplicant: config_methods=‘display push_button keypad virtual_push_button physical_display’
wpa_supplicant: persistent_reconnect=1
wpa_supplicant: pmf=1
wpa_supplicant: wowlan_triggers=‘any’
wpa_supplicant: Reading configuration file ‘/vendor/etc/wifi/p2p_supplicant_overlay.conf’
wpa_supplicant: disable_scan_offload=1
wpa_supplicant: nl80211: Supported cipher 00-0f-ac:1
wpa_supplicant: nl80211: Supported cipher 00-0f-ac:5
wpa_supplicant: nl80211: Supported cipher 00-0f-ac:2
wpa_supplicant: nl80211: Supported cipher 00-0f-ac:4
wpa_supplicant: nl80211: Supported cipher 00-0f-ac:6
wpa_supplicant: nl80211: Using driver-based off-channel TX
wpa_supplicant: nl80211: Supported vendor command: vendor_id=0xc3 subcmd=196
wpa_supplicant: nl80211: Supported vendor event: vendor_id=0x8899 subcmd=0
wpa_supplicant: nl80211: Supported vendor event: vendor_id=0x8899 subcmd=1
wpa_supplicant: nl80211: key_mgmt=0xd0f enc=0x10f auth=0x7 flags=0x4200d8c0 rrm_flags=0x0 probe_resp_offloads=0x0 max_stations=0 max_remain_on_chan=3000 max_scan_ssids=9
wpa_supplicant: nl80211: interface p2p0 in phy phy1
wpa_supplicant: nl80211: Set mode ifindex 9 iftype 2 (STATION)
wpa_supplicant: nl80211: Subscribe to mgmt frames with non-AP handle 0xecdba500
这里通过nl80211_mgmt_subscribe_non_ap()注册Action帧
wpa_supplicant: nl80211: Register frame type=0xb0 (WLAN_FC_STYPE_AUTH) nl_handle=0xecdba500 match=0300 multicast=0
wpa_supplicant: nl80211: Register frame type=0xd0 (WLAN_FC_STYPE_ACTION) nl_handle=0xecdba500 match=0104 multicast=0
wpa_supplicant: nl80211: Register frame type=0xd0 (WLAN_FC_STYPE_ACTION) nl_handle=0xecdba500 match=040a multicast=0
wpa_supplicant: nl80211: Register frame type=0xd0 (WLAN_FC_STYPE_ACTION) nl_handle=0xecdba500 match=040b multicast=0
wpa_supplicant: nl80211: Register frame type=0xd0 (WLAN_FC_STYPE_ACTION) nl_handle=0xecdba500 match=040c multicast=0
wpa_supplicant: nl80211: Register frame type=0xd0 (WLAN_FC_STYPE_ACTION) nl_handle=0xecdba500 match=040d multicast=0
wpa_supplicant: nl80211: Register frame type=0xd0 (WLAN_FC_STYPE_ACTION) nl_handle=0xecdba500 match=090a multicast=0
wpa_supplicant: nl80211: Register frame type=0xd0 (WLAN_FC_STYPE_ACTION) nl_handle=0xecdba500 match=090b multicast=0
wpa_supplicant: nl80211: Register frame type=0xd0 (WLAN_FC_STYPE_ACTION) nl_handle=0xecdba500 match=090c multicast=0
wpa_supplicant: nl80211: Register frame type=0xd0 (WLAN_FC_STYPE_ACTION) nl_handle=0xecdba500 match=090d multicast=0
wpa_supplicant: nl80211: Register frame type=0xd0 (WLAN_FC_STYPE_ACTION) nl_handle=0xecdba500 match=0409506f9a09 multicast=0
wpa_supplicant: nl80211: Register frame type=0xd0 (WLAN_FC_STYPE_ACTION) nl_handle=0xecdba500 match=7f506f9a09 multicast=0
wpa_supplicant: nl80211: Register frame type=0xd0 (WLAN_FC_STYPE_ACTION) nl_handle=0xecdba500 match=0409506f9a1a multicast=0
wpa_supplicant: nl80211: Register frame type=0xd0 (WLAN_FC_STYPE_ACTION) nl_handle=0xecdba500 match=0801 multicast=0
wpa_supplicant: nl80211: Register frame type=0xd0 (WLAN_FC_STYPE_ACTION) nl_handle=0xecdba500 match=06 multicast=0
wpa_supplicant: nl80211: Register frame type=0xd0 (WLAN_FC_STYPE_ACTION) nl_handle=0xecdba500 match=0a07 multicast=0
wpa_supplicant: nl80211: Register frame type=0xd0 (WLAN_FC_STYPE_ACTION) nl_handle=0xecdba500 match=0a11 multicast=0
wpa_supplicant: nl80211: Register frame type=0xd0 (WLAN_FC_STYPE_ACTION) nl_handle=0xecdba500 match=0a0b multicast=0
wpa_supplicant: nl80211: Register frame type=0xd0 (WLAN_FC_STYPE_ACTION) nl_handle=0xecdba500 match=0a1a multicast=0
wpa_supplicant: nl80211: Register frame type=0xd0 (WLAN_FC_STYPE_ACTION) nl_handle=0xecdba500 match=1101 multicast=0
wpa_supplicant: nl80211: Register frame type=0xd0 (WLAN_FC_STYPE_ACTION) nl_handle=0xecdba500 match=1102 multicast=0
wpa_supplicant: nl80211: Register frame type=0xd0 (WLAN_FC_STYPE_ACTION) nl_handle=0xecdba500 match=0505 multicast=0
wpa_supplicant: nl80211: Register frame type=0xd0 (WLAN_FC_STYPE_ACTION) nl_handle=0xecdba500 match=0500 multicast=0
wpa_supplicant: rfkill: Cannot open RFKILL control device
wpa_supplicant: nl80211: RFKILL status not available
wpa_supplicant: netlink: Operstate: ifindex=9 linkmode=1 (userspace-control), operstate=5 (IF_OPER_DORMANT)
WifiNative: Scan result ready event
wpa_supplicant: Add interface p2p0 to a new radio phy1
wpa_supplicant: nl80211: Regulatory information - country=US (DFS-FCC)
wpa_supplicant: nl80211: 902-904 @ 2 MHz 30 mBm
wpa_supplicant: nl80211: 904-920 @ 16 MHz 30 mBm
wpa_supplicant: nl80211: 920-928 @ 8 MHz 30 mBm
wpa_supplicant: nl80211: 2400-2472 @ 40 MHz 30 mBm
wpa_supplicant: nl80211: 5150-5250 @ 80 MHz 23 mBm
wpa_supplicant: nl80211: 5250-5350 @ 80 MHz 24 mBm (DFS)
wpa_supplicant: nl80211: 5470-5730 @ 160 MHz 24 mBm (DFS)
wpa_supplicant: nl80211: 5730-5850 @ 80 MHz 30 mBm
wpa_supplicant: nl80211: 5850-5895 @ 40 MHz 27 mBm (no outdoor) (no IR)
wpa_supplicant: nl80211: 57240-71000 @ 2160 MHz 40 mBm
wpa_supplicant: nl80211: Added 802.11b mode based on 802.11g information
wpa_supplicant: nl80211: Mode IEEE 802.11g: 2412 2417 2422 2427 2432 2437 2442 2447 2452 2457 2462 2467[DISABLED] 2472[DISABLED] 2484[DISABLED]
wpa_supplicant: nl80211: Mode IEEE 802.11a: 5180 5200 5220 5240 5260[RADAR] 5280[RADAR] 5300[RADAR] 5320[RADAR] 5500[RADAR] 5520[RADAR] 5540[RADAR] 5560[RADAR] 5580[RADAR] 5600[RADAR] 5620[RADAR] 5640[RADAR] 5660[RADAR] 5680[RADAR] 5700[RADAR] 5720[RADAR] 5745 5765 5785 5805 5825
wpa_supplicant: nl80211: Mode IEEE 802.11b: 2412 2417 2422 2427 2432 2437 2442 2447 2452 2457 2462 2467[DISABLED] 2472[DISABLED] 2484[DISABLED]
wpa_supplicant: p2p0: Own MAC address: 00:01:12:5d:d7:35
wpa_supplicant: wpa_driver_nl80211_set_key: ifindex=9 (p2p0) alg=0 addr=0x0 key_idx=0 set_tx=0 seq_len=0 key_len=0 key_flag=0x10
wpa_supplicant: nl80211: DEL_KEY
wpa_supplicant: broadcast key
wpa_supplicant: wpa_driver_nl80211_set_key: ifindex=9 (p2p0) alg=0 addr=0x0 key_idx=1 set_tx=0 seq_len=0 key_len=0 key_flag=0x10
wpa_supplicant: nl80211: DEL_KEY
wpa_supplicant: broadcast key
wpa_supplicant: wpa_driver_nl80211_set_key: ifindex=9 (p2p0) alg=0 addr=0x0 key_idx=2 set_tx=0 seq_len=0 key_len=0 key_flag=0x10
wpa_supplicant: nl80211: DEL_KEY
wpa_supplicant: broadcast key
wpa_supplicant: wpa_driver_nl80211_set_key: ifindex=9 (p2p0) alg=0 addr=0x0 key_idx=3 set_tx=0 seq_len=0 key_len=0 key_flag=0x10
wpa_supplicant: nl80211: DEL_KEY
wpa_supplicant: broadcast key
wpa_supplicant: wpa_driver_nl80211_set_key: ifindex=9 (p2p0) alg=0 addr=0x0 key_idx=4 set_tx=0 seq_len=0 key_len=0 key_flag=0x10
wpa_supplicant: nl80211: DEL_KEY
wpa_supplicant: broadcast key
wpa_supplicant: wpa_driver_nl80211_set_key: ifindex=9 (p2p0) alg=0 addr=0x0 key_idx=5 set_tx=0 seq_len=0 key_len=0 key_flag=0x10
wpa_supplicant: nl80211: DEL_KEY
wpa_supplicant: broadcast key
wpa_supplicant: p2p0: RSN: flushing PMKID list in the driver
wpa_supplicant: nl80211: Flush PMKIDs
wpa_supplicant: p2p0: State: DISCONNECTED -> INACTIVE
wpa_supplicant: Notifying state change event to hidl control: 2
wpa_supplicant: TDLS: TDLS operation not supported by driver
wpa_supplicant: TDLS: Driver uses internal link setup
wpa_supplicant: TDLS: Driver does not support TDLS channel switching
wpa_supplicant: p2p0: WPS: UUID from the first interface: 4f47a3f3-6d23-5555-8f51-a9e8f1a36b54
wpa_supplicant: EAPOL: SUPP_PAE entering state DISCONNECTED
wpa_supplicant: EAPOL: Supplicant port status: Unauthorized
wpa_supplicant: nl80211: Skip set_supp_port(unauthorized) while not associated
wpa_supplicant: EAPOL: KEY_RX entering state NO_KEY_RECEIVE
wpa_supplicant: EAPOL: SUPP_BE entering state INITIALIZE
wpa_supplicant: EAP: EAP entering state DISABLED
wpa_supplicant: Using existing control interface directory.
wpa_supplicant: P2P: Add operating class 81
wpa_supplicant: P2P: Channels - hexdump(len=11): 01 02 03 04 05 06 07 08 09 0a 0b
wpa_supplicant: P2P: Add operating class 115
wpa_supplicant: P2P: Channels - hexdump(len=4): 24 28 2c 30
wpa_supplicant: P2P: Add operating class 116
wpa_supplicant: P2P: Channels - hexdump(len=2): 24 2c
wpa_supplicant: P2P: Add operating class 117
wpa_supplicant: P2P: Channels - hexdump(len=2): 28 30
wpa_supplicant: P2P: Add operating class 124
wpa_supplicant: P2P: Channels - hexdump(len=4): 95 99 9d a1
wpa_supplicant: P2P: Add operating class 125
wpa_supplicant: P2P: Channels - hexdump(len=5): 95 99 9d a1 a5
wpa_supplicant: P2P: Add operating class 126
wpa_supplicant: P2P: Channels - hexdump(len=2): 95 9d
wpa_supplicant: P2P: Add operating class 127
wpa_supplicant: P2P: Channels - hexdump(len=2): 99 a1
wpa_supplicant: P2P: Add operating class 128
wpa_supplicant: P2P: Channels - hexdump(len=4): 24 28 2c 30
wpa_supplicant: P2P: Add operating class 130
wpa_supplicant: P2P: Channels - hexdump(len=4): 24 28 2c 30
wpa_supplicant: P2P: Own listen channel: 81:1
wpa_supplicant: P2P: Random operating channel: 81:1
wpa_supplicant: P2P: initialized
wpa_supplicant: P2P: channels: 81:1,2,3,4,5,6,7,8,9,10,11 115:36,40,44,48 116:36,44 117:40,48 124:149,153,157,161 125:149,153,157,161,165 126:149,157 127:153,161 128:36,40,44,48 130:36,40,44,48
wpa_supplicant: P2P: cli_channels:
wpa_supplicant: p2p0: wpa_bss_init(wpa_s) before
wpa_supplicant: p2p0: wpa_bss_init(wpa_s) after
wpa_supplicant: p2p0: wpas_set_wowlan_triggers(wpa_s) before
wpa_supplicant: nl80211: Setting wowlan
wpa_supplicant: p2p0: wpas_set_wowlan_triggers(wpa_s) after
wpa_supplicant: p2p0: pcsc_reader_init(wpa_s) before
wpa_supplicant: p2p0: pcsc_reader_init(wpa_s) after
wpa_supplicant: p2p0: wpas_rrm_reset(wpa_s) before
wpa_supplicant: p2p0: wpas_rrm_reset(wpa_s) after
wpa_supplicant: MBO: Update non-preferred channels, non_pref_chan=N/A
wpa_supplicant: p2p0: wpa_supplicant_set_default_scan_ies(wpa_s) before
wpa_supplicant: p2p0: wpa_supplicant_set_default_scan_ies(wpa_s) after
wpa_supplicant: Registering interface to hidl control: p2p0
wpa_supplicant: p2p0: Added interface p2p0
wpa_supplicant: p2p0: State: INACTIVE -> DISCONNECTED
wpa_supplicant: nl80211: Set p2p0 operstate 0->0 (DORMANT)
wpa_supplicant: netlink: Operstate: ifindex=9 linkmode=-1 (no change), operstate=5 (IF_OPER_DORMANT)
wpa_supplicant: Notifying state change event to hidl control: 0
wpa_supplicant: p2p0: Determining shared radio frequencies (max len 1)
wpa_supplicant: p2p0: Shared frequencies (len=0): completed iteration
wpa_supplicant: P2P: Add operating class 81
wpa_supplicant: P2P: Channels - hexdump(len=11): 01 02 03 04 05 06 07 08 09 0a 0b
wpa_supplicant: P2P: Add operating class 115
wpa_supplicant: P2P: Channels - hexdump(len=4): 24 28 2c 30
wpa_supplicant: P2P: Add operating class 116
wpa_supplicant: P2P: Channels - hexdump(len=2): 24 2c
wpa_supplicant: P2P: Add operating class 117
wpa_supplicant: P2P: Channels - hexdump(len=2): 28 30
wpa_supplicant: P2P: Add operating class 124
wpa_supplicant: P2P: Channels - hexdump(len=4): 95 99 9d a1
wpa_supplicant: P2P: Add operating class 125
wpa_supplicant: P2P: Channels - hexdump(len=5): 95 99 9d a1 a5
wpa_supplicant: P2P: Add operating class 126
wpa_supplicant: P2P: Channels - hexdump(len=2): 95 9d
wpa_supplicant: P2P: Add operating class 127
wpa_supplicant: P2P: Channels - hexdump(len=2): 99 a1
wpa_supplicant: P2P: Add operating class 128
wpa_supplicant: P2P: Channels - hexdump(len=4): 24 28 2c 30
wpa_supplicant: P2P: Add operating class 130
wpa_supplicant: P2P: Channels - hexdump(len=4): 24 28 2c 30
wpa_supplicant: P2P: Update channel list
wpa_supplicant: P2P: channels: 81:1,2,3,4,5,6,7,8,9,10,11 115:36,40,44,48 116:36,44 117:40,48 124:149,153,157,161 125:149,153,157,161,165 126:149,157 127:153,161 128:36,40,44,48 130:36,40,44,48
wpa_supplicant: P2P: cli_channels:
wpa_supplicant: RTM_NEWLINK: ifi_index=9 ifname=p2p0 operstate=0 linkmode=0 ifi_family=0 ifi_flags=0x11043 ([UP][RUNNING][LOWER_UP])
wpa_supplicant: RTM_NEWLINK: ifi_index=9 ifname=p2p0 operstate=5 linkmode=0 ifi_family=0 ifi_flags=0x11003 ([UP][LOWER_UP])
wpa_supplicant: RTM_NEWLINK: ifi_index=9 ifname=p2p0 operstate=5 linkmode=1 ifi_family=0 ifi_flags=0x11003 ([UP][LOWER_UP])
wpa_supplicant: nl80211: Ignored event 34 (NL80211_CMD_NEW_SCAN_RESULTS) for foreign interface (ifindex 8 wdev 0x0)
wpa_supplicant: nl80211: Drv Event 34 (NL80211_CMD_NEW_SCAN_RESULTS) received for wlan0
wpa_supplicant: wlan0: nl80211: New scan results available
wpa_supplicant: nl80211: Scan probed for SSID ‘’
wpa_supplicant: nl80211: Scan included frequencies: 2412 2417 2422 2427 2432 2437 2442 2447 2452 2457 2462 5180 5200 5220 5240 5260 5280 5300 5320 5500 5520 5540 5560 5580 5600 5620 5640 5660 5680 5700 5720 5745 5765 5785 5805 5825
wpa_supplicant: wlan0: Event SCAN_RESULTS (3) received
wpa_supplicant: nl80211: Received scan results (59 BSSes)
wpa_supplicant: wlan0: BSS: Start scan result update 3
wpa_supplicant: wlan0: BSS: Add new id 44 BSSID 18:f2:2c:78:98:94 SSID ‘SE-Team’ freq 2412
wpa_supplicant: wlan0: BSS: Add new id 45 BSSID 22:f2:2c:78:98:94 SSID ‘’ freq 2412
wpa_supplicant: wlan0: BSS: Add new id 46 BSSID 44:a1:91:ed:e1:cb SSID ‘hw_manage_e1c0’ freq 2412
wpa_supplicant: wlan0: BSS: Add new id 47 BSSID b0:44:14:61:51:3d SSID ‘MAXIMAGE’ freq 2412
wpa_supplicant: wlan0: BSS: Add new id 48 BSSID 00:6b:6f:66:cc:28 SSID ‘YY’ freq 2462
wpa_supplicant: wlan0: BSS: Add new id 49 BSSID 6c:c4:9f:76:eb:41 SSID ‘sunshine’ freq 2412
wpa_supplicant: wlan0: BSS: Add new id 50 BSSID 6c:c4:9f:76:eb:40 SSID ‘i-amlogic’ freq 2412
wpa_supplicant: wlan0: BSS: Add new id 51 BSSID 6c:c4:9f:76:eb:42 SSID ‘galaxy’ freq 2412
wpa_supplicant: wlan0: BSS: Add new id 52 BSSID d4:da:21:71:fd:69 SSID ‘FYD-Redmi-2.4G’ freq 2422
wpa_supplicant: wlan0: BSS: Add new id 53 BSSID d8:4a:2b:fe:00:d0 SSID ‘ChinaNet-a432’ freq 2462
wpa_supplicant: wlan0: BSS: Add new id 54 BSSID 02:60:73:72:43:0c SSID ‘’ freq 2437
wpa_supplicant: wlan0: BSS: Add new id 55 BSSID 6c:c4:9f:75:e8:a1 SSID ‘sunshine’ freq 2437
wpa_supplicant: wlan0: BSS: Add new id 56 BSSID 6c:c4:9f:75:e8:a0 SSID ‘i-amlogic’ freq 2437
wpa_supplicant: wlan0: BSS: Add new id 57 BSSID 6c:c4:9f:77:c6:80 SSID ‘i-amlogic’ freq 2462
wpa_supplicant: wlan0: BSS: Do not update scan IEs for 72:66:9d:9c:8e:84 since that would remove P2P IE information
wpa_supplicant: wlan0: BSS: Add new id 58 BSSID 6c:c4:9f:75:e8:b2 SSID ‘apollo’ freq 5300
wpa_supplicant: BSS: last_scan_res_used=59/64
wpa_supplicant: wlan0: New scan results available (own=0 ext=1)
wpa_supplicant: wlan0: Do not use results from externally requested scan operation for network selection
WifiP2pNative: P2P interface setup completed
wpa_supplicant: The random MAC is disabled already.
wpa_supplicant: nl80211: Setting wowlan
wpa_supplicant: P2P: New SSID postfix: -Android_4e95
wpa_supplicant: P2P: Stopping find
wpa_supplicant: P2P: Clear timeout (state=IDLE)
wpa_supplicant: P2P: State IDLE -> IDLE
wpa_supplicant: wpa_driver_set_ap_wps_p2p_ie: Entry
wpa_supplicant: P2P: Disabling Extended Listen Timing
wpa_supplicant: P2P: Stopping find
wpa_supplicant: P2P: Clear timeout (state=IDLE)
wpa_supplicant: P2P: State IDLE -> IDLE
wpa_supplicant: wpa_driver_set_ap_wps_p2p_ie: Entry
wpa_supplicant: P2P: All ASP advertisements flushed
wpa_supplicant: Writing configuration file ‘/data/vendor/wifi/wpa/p2p_supplicant.conf.tmp’
WificondScannerImpl: Filtering out 19 scan results.
wpa_supplicant: Configuration file ‘/data/vendor/wifi/wpa/p2p_supplicant.conf’ written successfully
WifiP2pNative: P2P InterfaceAvailableListener false
WifiP2pNative: Masking interface non-availability callback because we created a P2P iface
wpa_supplicant: WFD: Wi-Fi Display enabled
wpa_supplicant: WFD: Update WFD IE
wpa_supplicant: WFD: WFD IE for Beacon - hexdump(len=0):
wpa_supplicant: WFD: WFD IE for (Re)Association Request - hexdump(len=0):
wpa_supplicant: WFD: WFD IE for GO Negotiation - hexdump(len=0):
wpa_supplicant: WFD: WFD IE for Provision Discovery Request - hexdump(len=0):
wpa_supplicant: WFD: WFD IE for Probe Request - hexdump(len=0):
wpa_supplicant: WFD: WFD IE for Probe Response - hexdump(len=0):
wpa_supplicant: WFD: WFD IE for P2P Invitation - hexdump(len=0):
wpa_supplicant: WFD: WFD IE for Provision Discovery Response - hexdump(len=0):
wpa_supplicant: WFD: Set subelement 0
wpa_supplicant: WFD: Update WFD IE
wpa_supplicant: WFD: WFD IE for Beacon - hexdump(len=15): dd 0d 50 6f 9a 0a 00 00 06 00 11 1c 44 00 32
wpa_supplicant: WFD: WFD IE for (Re)Association Request - hexdump(len=15): dd 0d 50 6f 9a 0a 00 00 06 00 11 1c 44 00 32
wpa_supplicant: WFD: WFD IE for GO Negotiation - hexdump(len=15): dd 0d 50 6f 9a 0a 00 00 06 00 11 1c 44 00 32
wpa_supplicant: WFD: WFD IE for Provision Discovery Request - hexdump(len=15): dd 0d 50 6f 9a 0a 00 00 06 00 11 1c 44 00 32
wpa_supplicant: WFD: WFD IE for Probe Request - hexdump(len=15): dd 0d 50 6f 9a 0a 00 00 06 00 11 1c 44 00 32
wpa_supplicant: WFD: WFD IE for Probe Response - hexdump(len=15): dd 0d 50 6f 9a 0a 00 00 06 00 11 1c 44 00 32
wpa_supplicant: WFD: WFD IE for P2P Invitation - hexdump(len=15): dd 0d 50 6f 9a 0a 00 00 06 00 11 1c 44 00 32
wpa_supplicant: WFD: WFD IE for Provision Discovery Response - hexdump(len=15): dd 0d 50 6f 9a 0a 00 00 06 00 11 1c 44 00 32

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
wpa_supplicant是一个用于连接wifi网络的软件,它支持多种加密方式,如WPA、WPA2等。要连接wifi并打开Wifi Direct,我们可以按照以下步骤进行操作: 1. 首先,我们需要确保系统已安装了wpa_supplicant软件。可以通过在终端输入命令"sudo apt-get install wpasupplicant"来进行安装。 2. 安装完成后,可以使用命令"sudo nano /etc/wpa_supplicant.conf"来编辑wpa_supplicant的配置文件。在其添加以下内容来连接wifi网络: network={ ssid="你的Wifi网络名称" psk="你的Wifi密码" } 注意,将"你的Wifi网络名称"和"你的Wifi密码"替换为你自己的网络名称和密码。 3. 保存并退出配置文件。 4. 使用命令"sudo wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant.conf"来启动wpa_supplicant连接wifi网络。其,wlan0是你的无线网卡接口名,可以根据实际情况进行调整。 5. 连接成功后,可以使用命令"sudo wpa_cli"来进入wpa_supplicant的交互模式。在交互模式,我们可以使用"scan"命令来扫描附近的Wifi Direct设备,然后使用"p2p_connect"命令来连接指定的设备。 6. 如果连接成功,可以使用"interface p2p0 p2p_listen"命令来打开Wifi Direct功能。 通过以上步骤,我们可以使用wpa_supplicant连接wifi网络,并在连接成功后打开Wifi Direct功能。请注意,具体的配置和命令可能因系统版本或网络环境而有所不同,请根据实际情况进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值