一、基本信息

项目 内容
产品/平台 V6.1 / 大屏项目
模块 WiFi / 个人热点(SoftAP)
问题概率 必现
预期 修改热点名称(中文/英文/数字)或密码(英文/数字)后,客户端可搜索并连接新热点
实际 设置界面显示修改成功,但客户端无法连接(改名后搜索不到或连接卡死,改密后认证失败)
最终方案 路径 2:保存配置 + Settings 自动关开热点重启生效
相关 Patch 007_softap_reconfig_reopen.patchwlan_hostapd_reconfig_reopen.patch

二、问题现象

在主干 大屏项目版本(V6.1 B0XXX)上进行个人热点功能测试,依次修改热点设备名称(中文/英文/数字)和热点密码(英文/数字)后:

  1. 设置界面显示修改成功;
  2. 修改名称后,客户端扫描仍看到旧 SSID,或搜索不到新热点,连接卡死;
  3. 修改密码后,客户端提示认证失败,旧密码、新密码均可能无法连接;
  4. 问题必现,无可靠恢复手段,严重影响热点功能可用性。

三、根因分析

3.1 直接原因(原逻辑缺陷)

原逻辑在热点已开启时修改 SSID/密码,会优先调用 ApServiceSetHotspotConfig 做运行中热更新;若热更新成功,配置不会写入持久化文件。Settings 应用随后会自动执行 DisableHotspotEnableHotspot,AP 重新启动时通过 GetHotspotConfig() 从配置文件读取,此时读到的仍是旧配置,导致:

  • 改名:广播的仍是旧 SSID,或关开过程中热点异常关闭;
  • 改密:hostapd 使用旧密码,客户端用新密码认证失败。

3.2 修改热点配置的两条路径

路径 作用 关键代码
路径 1(运行中热更新) 热点开启时修改 SSID/密码,立即生效 ProcessCmdSetHotspotConfigRestartApForConfigUpdateHotConfigToggleGuard
路径 2(保存配置,重启生效) 修改后写入配置文件,关开热点时读取新配置 SetHotspotConfig + SyncHotspotConfig

3.3 路径 1 探索过程(已调通但未采用)

首先尝试路径 1(运行中热更新),该路径涉及框架、平台 hostapd、Settings 应用行为、状态机回调四层问题叠加:

(1)框架层ApStartedState 未注册 CMD_SET_HOTSPOT_CONFIG,改名请求被丢弃(关键日志:msg = [5] is not handled)。

(2)平台层:hostapd 全局 ctrl 接口不支持 RELOAD 命令,返回 FAIL;单独 SET ssid 也无法让 SoftAP 以新 SSID 广播。需改用 REMOVE wlan0 + ADD wlan0 config=... + ENABLE

(3)应用层:Settings 在 SetHotspotConfig 成功后会无条件调用 DisableHotspot + EnableHotspot,与框架异步热更新并发,导致 NL80211_CMD_STOP_APFailed to set beacon parametersStartAp is failed!

(4)状态机层RestartApForConfigUpdate 过程中 hostapd 上报 AP_DISABLE(111),状态机误判为失败并切换 IdleState,热点被关闭。

路径 1 经多轮修复后已验证通过(热更新成功、两次改名均 OK),但实现复杂度高,涉及状态机、HAL、驱动、Settings 竞态拦截等多层改动,维护成本和平台适配风险较大。

3.4 最终选择路径 2 的原因

对比项 路径 1(已移除) 路径 2(当前方案)
热点开启时改配置 运行中热更新,立即生效 只写配置文件,由 Settings 自动关开热点后生效
配置持久化 热更新成功时易漏写文件 每次修改都先 SetHotspotConfig + SyncHotspotConfig
Settings 开关 HotConfigToggleGuard 拦截多余 toggle 正常执行 disable → enable,无需拦截
代码复杂度 涉及状态机、HAL、驱动多层 框架仅改两行,驱动仅稳定性修复
用户体验 不断连(理想情况) 修改配置时热点短暂关闭再开启,已连接设备需重连
适用性 需全平台 hostapd 适配 与 OpenHarmony 标准 Settings 行为一致,逻辑清晰可靠

综合考虑可维护性、配置落盘可靠性和交付风险,最终移除路径 1 相关代码,采用路径 2


四、解决方案

4.1 核心思路

把「改配置」和「应用配置」解耦:修改名称/密码时一律先保存到配置文件,再由 Settings 自动 DisableHotspotEnableHotspot,在 AP 重新启动时从 WifiSettings 读取新配置并启动 hostapd。

img

4.2 实际流程(路径 2 + Settings 自动开关)

热点开启时修改名称/密码,Settings 按顺序执行:

SettingsSetHotspotConfigSetHotspotConfigExtralSetHotspotConfig + SyncHotspotConfig 落盘)
         → DisableHotspot(自动)
         → EnableHotspot(自动)
         → ApService::EnableHotspotSetConfig() → GetHotspotConfig()SetSoftApConfig + EnableAphostapd 以新配置启动)

修正后的行为:

  • 热点关闭时改名称/密码:保存配置,下次开启生效;
  • 热点开启时改名称/密码:保存配置 → Settings 自动关开热点 → 新 SSID/密码在重新开启后生效。

用户无需手动关开热点,Settings 会自动完成关开步骤。

4.3 Patch 文件说明

Patch 内容
007_softap_reconfig_reopen.patch SetHotspotConfigExtral 始终保存配置(移除 ApServiceSetHotspotConfig 热更新入口)
wlan_hostapd_reconfig_reopen.patch hostapd HDF 驱动稳定性修复(HostapdInterfaceDriverClearStop、NULL 检查、stubObject 置空)

4.4 代码修改说明

4.4.1 007_softap_reconfig_reopen.patch(WiFi 框架)

修改文件wifi_hotspot_service_impl.cppSetHotspotConfigExtral()

修改前(原逻辑):

if (!IsApServiceRunning() ||
    WifiServiceManager::GetInstance().ApServiceSetHotspotConfig(innerConfig, m_id) == false) {
    WifiSettings::GetInstance().SetHotspotConfig(innerConfig, m_id);
    WifiSettings::GetInstance().SyncHotspotConfig();
}

含义:热点未开启时保存配置;热点已开启时先走热更新,成功则不保存。问题即出在此:热更新成功时配置未落盘,Settings 自动关开热点后仍读到旧配置。

修改后(当前逻辑):

WifiSettings::GetInstance().SetHotspotConfig(innerConfig, m_id);
WifiSettings::GetInstance().SyncHotspotConfig();

无论热点是否已开启,都先把经业务处理(密码默认值、随机 MAC 等)后的 innerConfig 写入内存并同步到持久化存储。新 SSID/密码的应用交给 Settings 自动关开热点 + AP 启动时的 GetHotspotConfig()

4.4.2 wlan_hostapd_reconfig_reopen.patch(hostapd HDF 驱动)

修改文件drivers/peripheral/wlan/hostapd/interfaces/hdi_service/hostapd_interface_drivers.c

Settings 自动关开热点会反复走 hostapd 的 ReleaseInit/BindDispatch。原逻辑中 g_stopstubObject 处理不当,可能导致驱动卸载后无法再次响应 HDI 调用(日志:invalid service obj)。

改动 目的
新增 HostapdInterfaceDriverClearStop(),在 Init/Bind 中调用 Releaseg_stop=1,重新加载时清零,避免 HDI 永久失败
ReleasedeviceObject == NULL 检查 防止卸载时空指针崩溃
Release 中将 stubObjectNULL g_stop 配合,避免卸载窗口内 use-after-free

本 patch仅为路径 2 的关开热点提供可靠的底层 HDI 通道。

与路径2的配合关系

img


五、测试验证

序号 测试项 预期结果 实际结果
1 热点开启时修改名称(中/英/数字) 短暂断连后以新名称广播,客户端可搜索并连接 通过
2 热点开启时修改密码 需输入新密码连接,旧密码拒绝 通过
3 热点关闭时修改名称/密码 下次开启后新配置生效 通过
4 连续快速多次修改 热点始终可连,无卡死 通过
5 重启设备后 配置仍正确,热点以最新 SSID/密码启动 通过

六、经验与影响总结

6.1 教训

  1. 配置持久化优先:运行中热更新成功时若不同步写盘,与应用层「关开热点」行为组合后必然出现配置回退。
  2. 平台差异需尽早识别:该平台hostapd 不支持全局 RELOAD,路径 1 需在 HAL/驱动层做大量适配。
  3. 应用与框架契约:Settings 改配置后会自动 disable+enable,框架设计需与之匹配,而非假设可静默热更新。
  4. 方案选型:在客户可接受短暂断连的前提下,路径 2 以最小改动获得可靠落盘,优于高复杂度的路径 1。
  5. 驱动生命周期:关开热点场景下 HDF 驱动的 g_stop/stubObject 管理直接影响 HDI 可用性,需单独验证。

6.2 影响范围

  • 修改配置到生效之间,热点会短暂关闭再开启
  • 已连接设备会断开,需用新 SSID/密码重连;
  • 仅涉及 WiFi 框架 SetHotspotConfigExtral 及 hostapd HDF 驱动,无 Settings 应用改动

6.3 后续建议

  1. 若产品后续要求「运行中改配置不断连」,可基于路径 1 的方案评估回归,但需同步修改 Settings 去掉多余 toggle,并保证多 SO 全量部署。
  2. 新增平台移植时,优先验证 hostapd ctrl 接口能力(RELOADREMOVE+ADD+ENABLE),再决定热更新实现方式。
  3. 热点相关改动建议保留完整 hilog 对比(改前/改后、关开热点前后),便于快速定位框架/驱动/应用层问题。

七、一句话总结

原逻辑在热点运行时热更新成功却不落盘,Settings 自动关开热点后仍用旧配置启动,导致改名/改密后客户端无法连接;最终采用路径 2,每次修改都先持久化配置,配合 hostapd HDF 驱动稳定性修复,由 Settings 自动关开热点使新配置生效,改动小、逻辑清晰、验证通过。

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐