【修复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);
相关推荐
Victor3561 小时前
Redis(166)如何使用Redis实现实时统计?
后端
小虎哥-技术博客1 小时前
apache服务器.htaccess屏蔽所有搜索引擎蜘蛛/爬虫访问网站图片资源(避免带宽占用)
服务器·搜索引擎·apache
wanhengidc1 小时前
云手机 高算力 快速便捷
运维·服务器·科技·游戏·智能手机
饕餮争锋1 小时前
Linux 常用命令分类详解
linux·运维·服务器
咖丨喱1 小时前
【修复miracast协商失败问题】
服务器·数据库·asp.net
wanhengidc1 小时前
云手机如何进行数据备份
运维·服务器·科技·智能手机·云计算
资深web全栈开发1 小时前
从零构建即时通讯系统:Go + Vue3 实战指南
开发语言·后端·golang·im 通许
阿巴~阿巴~1 小时前
HTTP头部字段:高效通信的关键
服务器·网络·网络协议·http·http头部字段
minji...1 小时前
Linux 进程控制(三) (进程程序替换,exec系列函数)
linux·运维·服务器