【修复miracast连接兼容性问题,优化信道协商流程】

改动点详细分析

1. 修复 GO Negotiation Response 中缺少 Operating Channel Attribute 的问题

改动位置 : src/p2p/p2p_go_neg.c 第 323-326 行

改动内容:

c 复制代码
#if 0
} else if (peer && peer->go_state == REMOTE_GO && !p2p->num_pref_freq) {
    p2p_dbg(p2p, "Omit Operating Channel attribute");
#endif

原因分析:

  • 问题: 当对端设备是 REMOTE_GO(已存在的 GO)且本地没有预设频率偏好时,原代码会省略 Operating Channel attribute。
  • 影响 : 某些手机/PC 在收到没有 Operating Channel 的 GO Negotiation Response 时会拒绝连接,导致 P2P-GO-NEG-FAILURE
  • 解决方案 : 通过 #if 0 禁用这段逻辑,确保 GO Negotiation Response 总是包含 Operating Channel attribute,提高兼容性。

2. 修复 P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE 状态错误

改动位置 : src/p2p/p2p_go_neg.c 第 837-841 行

改动内容:

c 复制代码
if (msg.config_methods & WPS_CONFIG_PUSHBUTTON) {
    dev->wps_method = WPS_PBC;
    dev->oob_pw_id = p2p_wps_method_pw_id(dev->wps_method);
}

原因分析:

  • 问题 : 当收到 GO Negotiation Request 时,如果对端使用的是 PBC(Push Button Configuration)方式,但本地没有正确记录 dev->wps_methoddev->oob_pw_id,会导致后续 WPS 流程判断错误,可能返回 P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE 状态。
  • 影响: 即使双方都支持 PBC,也可能因为 WPS method 不匹配而导致协商失败。
  • 解决方案 : 在处理 GO Negotiation Request 时,如果检测到对端使用 PBC(WPS_CONFIG_PUSHBUTTON),立即设置本地 peer 设备的 WPS method 为 WPS_PBC,并更新对应的 OOB Password ID,确保双方 WPS 配置一致。

3. 使用手机/电脑的操作信道偏好

改动位置 : src/p2p/p2p_go_neg.c 第 849-870 行

改动内容:

c 复制代码
if (msg.operating_channel) {
    /* Use peer preference if specified and compatible */
    int req_freq;
    req_freq = p2p_channel_to_freq(
        msg.operating_channel[3],
        msg.operating_channel[4]);
    p2p_dbg(p2p, "Peer operating channel preference: %d MHz",
        req_freq);
    if (req_freq > 0 &&
        p2p_channels_includes(&p2p->cfg->channels,
                              msg.operating_channel[3],
                              msg.operating_channel[4])) {
        p2p->op_reg_class = msg.operating_channel[3];
        p2p->op_channel = msg.operating_channel[4];
        p2p_dbg(p2p, "Use peer preference op_class %d channel %d",
            p2p->op_reg_class, p2p->op_channel);
    }
}

原因分析:

  • 问题: 原代码在处理 GO Negotiation Request 时,主要使用本地预设的信道偏好,而忽略了对端(手机/PC)在请求中携带的 Operating Channel preference。
  • 影响 :
    • 如果手机/PC 明确指定了偏好的信道(例如 5GHz 频段的某个信道),但本地强制使用另一个信道,可能导致:
      • 对端不支持本地选择的信道(特别是某些手机只支持部分 5GHz 信道)
      • 对端虽然支持但需要切换,增加连接延迟
  • 解决方案 :
    • 解析对端 GO Negotiation Request 中的 Operating Channel attribute
    • 检查该信道是否在本地的可用信道列表中
    • 如果兼容,优先使用对端的信道偏好 ,这样可以:
      • 提高兼容性(使用对端已知支持的信道)
      • 减少信道切换时间
      • 提升首次连接成功率

4. 不使用强制信道以避免手机/电脑不支持

改动位置 : src/p2p/p2p_invitation.c 第 283-284 行

改动内容:

c 复制代码
/* don't use force freq to avoid peer not support */
op_freq = 0;
if (op_freq) {

原因分析:

  • 问题 : 在 P2P Invitation 流程中,如果本地有强制频率设置(op_freq),会强制要求对端使用该频率,但某些手机/PC 可能不支持该频率或需要额外时间切换。
  • 影响 :
    • 导致 Invitation 失败或连接延迟增加
    • 特别是当对端设备已经在一个固定频率上运行时,强制切换频率可能失败
  • 解决方案 :
    • 在处理 Invitation Request 时,op_freq 置为 0,不强制使用特定频率
    • 让 P2P 协议栈根据双方可用信道列表自动协商最佳信道
    • 这样可以避免对端设备不支持强制频率导致的连接失败

总结

这个 patch 的核心目标是:提高 Miracast 连接在不同手机/PC 设备上的兼容性和成功率

关键改进点:

  1. 保证协议完整性: 总是发送 Operating Channel attribute,避免某些设备拒绝连接
  2. 正确识别 WPS 方法: 确保 PBC 方式的 WPS method 正确设置,避免状态错误
  3. 尊重对端信道偏好: 优先使用对端指定的信道,提高兼容性和连接速度
  4. 避免强制频率冲突: 在 Invitation 流程中不强制频率,让协议栈自动协商

实际效果:

  • ✅ 减少 P2P-GO-NEG-FAILUREP2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE 错误
  • ✅ 提高首次 Miracast 连接成功率
  • ✅ 缩短连接建立时间(减少信道切换)
  • ✅ 增强对不同品牌手机/PC 的兼容性
c 复制代码
    1.fix neg resp without operating channel attribute
    2.fix P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE status error
    3.use phone/computer opertating channel
    4.don't use force channel to avoid phone/computer not support
diff --git a/src/p2p/p2p_go_neg.c b/src/p2p/p2p_go_neg.c
index b1f392e..e31c44a 100644
--- a/src/p2p/p2p_go_neg.c
+++ b/src/p2p/p2p_go_neg.c
@@ -320,8 +320,10 @@ static struct wpabuf * p2p_build_go_neg_resp(struct p2p_data *p2p,
 		p2p_buf_add_operating_channel(buf, p2p->cfg->country,
 					      p2p->override_pref_op_class,
 					      p2p->override_pref_channel);
+#if 0
 	} else if (peer && peer->go_state == REMOTE_GO && !p2p->num_pref_freq) {
 		p2p_dbg(p2p, "Omit Operating Channel attribute");
+#endif
 	} else {
 		p2p_buf_add_operating_channel(buf, p2p->cfg->country,
 					      p2p->op_reg_class,
@@ -847,6 +849,11 @@ void p2p_process_go_neg_req(struct p2p_data *p2p, const u8 *sa,
 	if (p2p->go_neg_peer && p2p->go_neg_peer == dev)
 		eloop_cancel_timeout(p2p_go_neg_wait_timeout, p2p, NULL);
 
+	if (msg.config_methods & WPS_CONFIG_PUSHBUTTON) {
+		dev->wps_method = WPS_PBC;
+		dev->oob_pw_id = p2p_wps_method_pw_id(dev->wps_method);
+	}
+
 	if (dev && dev->flags & P2P_DEV_USER_REJECTED) {
 		p2p_dbg(p2p, "User has rejected this peer");
 		status = P2P_SC_FAIL_REJECTED_BY_USER;
@@ -880,6 +887,28 @@ void p2p_process_go_neg_req(struct p2p_data *p2p, const u8 *sa,
 				p2p_dbg(p2p, "Use previously configured forced channel settings");
 			}
 		}
+		if (msg.operating_channel) {
+			/* Use peer preference if specified and compatible */
+				int req_freq;
+				req_freq = p2p_channel_to_freq(
+					msg.operating_channel[3],
+					msg.operating_channel[4]);
+				p2p_dbg(p2p, "Peer operating channel preference: %d MHz",
+					req_freq);
+				if (req_freq > 0 &&
+					p2p_channels_includes(&p2p->cfg->channels,
+										  msg.operating_channel[3],
+										  msg.operating_channel[4])) {
+					p2p->op_reg_class = msg.operating_channel[3];
+					p2p->op_channel = msg.operating_channel[4];
+					p2p_dbg(p2p, "Use peer preference op_class %d channel %d",
+						p2p->op_reg_class, p2p->op_channel);
+				}
+		}
 
 		dev->flags &= ~P2P_DEV_NOT_YET_READY;
 
diff --git a/src/p2p/p2p_invitation.c b/src/p2p/p2p_invitation.c
index a0b7f5f..5dc0a2c 100644
--- a/src/p2p/p2p_invitation.c
+++ b/src/p2p/p2p_invitation.c
@@ -283,7 +283,8 @@ void p2p_process_invitation_req(struct p2p_data *p2p, const u8 *sa,
 			goto fail;
 		}
 	}
-
+	/* don't use force freq to avoid peer not support */
+	op_freq = 0;
 	if (op_freq) {
 		p2p_dbg(p2p, "Invitation processing forced frequency %d MHz",
 			op_freq);
相关推荐
MC丶科3 小时前
【SpringBoot常见报错与解决方案】中文乱码?Spring Boot 统一解决前后端中文乱码问题(含 Postman 测试)!别再百度“加 UTF-8”了!
spring boot·后端·postman
yuanmenghao7 小时前
车载Linux 系统问题定位方法论与实战系列 - 车载 Linux 平台问题定位规范
linux·运维·服务器·网络·c++
XXOOXRT8 小时前
基于SpringBoot的加法计算器
java·spring boot·后端·html5
weixin_516023078 小时前
linux下fcitx5拼音的安装
linux·运维·服务器
moxiaoran57539 小时前
Go语言的错误处理
开发语言·后端·golang
hunter14509 小时前
Linux 进程与计划任务
linux·运维·服务器
楼田莉子9 小时前
Linux学习之磁盘与Ext系列文件
linux·运维·服务器·c语言·学习
陌上花开缓缓归以9 小时前
linux 怎么模拟系统panic重启
linux·运维·服务器
月白风清江有声10 小时前
vscode使用git
linux·运维·服务器
开开心心_Every11 小时前
免费窗口置顶小工具:支持多窗口置顶操作
服务器·前端·学习·macos·edge·powerpoint·phpstorm