【修复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);
相关推荐
乌恩大侠6 小时前
GH200 新增 NVMe SSD 分区、格式化与挂载完整流程
运维·服务器·前端
步行cgn7 小时前
YAML 的语法规则
spring boot·后端
Mr.朱鹏7 小时前
Linux 服务器 LVM 根分区在线动态扩容
linux·服务器·数据库
骇客野人7 小时前
SpringBoot电商系统用户注册、登录、留存及数据埋点设计与落地实施方案
java·spring boot·后端
mengge.cloud7 小时前
存储技术基础小白教程
linux·运维·服务器·wpf·存储
tang777898 小时前
反爬虫场景下代理IP池的动态扩容与失效IP自动清理方案实现
linux·服务器·网络·爬虫代理·住宅代理ip
新时代牛马9 小时前
Linux 系统调用与IPC 完整篇:从syscall 入口、VDSO 到pipe/shm/futex 选型
linux·运维·服务器
IT_陈寒10 小时前
React的状态更新坑得我差点加班到天亮
前端·人工智能·后端
小HANN11 小时前
Linux建站实战:CentOS7+LNMP 从零部署 ECShop 开源电商系统
linux·运维·服务器·经验分享
码事漫谈11 小时前
一天搭出 80% 的 Agent,然后卡在 95% 到死
后端