HarmonyOS角落里的知识:WLAN器件驱动开发-WLAN

 概述

功能简介

无线局域网数据传输是端侧设备不可或缺的一部分,用户可以方便地接入到无线网络进行数据传输和共享,并且在无线网络覆盖区域自由移动,彻底摆脱有线的束缚。基于HDF(Hardware Driver Foundation)驱动框架开发的WLAN驱动,能够屏蔽硬件器件差异,为上层WLAN服务提供稳定的基础能力接口,包括启动扫描、关联/取消关联热点、获取MAC地址、设置MAC地址、获取链路信息等。

基本概念

开发前,开发者应了解一下WLAN涉及的基本:

  • AP

    无线接入点(Access Point,简称AP),是网络的中心节点,提供无线接入服务。其它无线设备接入后,可以进行数据访问。

  • STA

    站点(Station,简称STA),是无线局域网的最基本组成单元。每一个连接到无线网络中的终端(如笔记本电脑、PDA及其它可以联网的用户设备)都可称为一个站点。

  • ssid

    无线网络的名称,用来标识一个无线网络,每个无线网络都有自己的ssid。

  • bssid

    用于标识WLAN中的基本服务集,是唯一的48位MAC地址。

  • Scan

    终端设备扫描环境中的无线网络,获取到周围的无线网络信息。包括热点名称(ssid)、工作频带和信号强度等。

  • Associate

    终端设备指定有效的热点进行连接,成功后即可与AP端数据通信。终端同一时刻只可以和一个AP建立链路。

运作机制

本文主要介绍基于HDF(Hardware Driver Foundation)驱动框架开发的WLAN功能。WLAN整体框架:

image

  1. 上层服务基于业务需要调用HDI接口,将用户态消息通过WPA层或HAL层下发至Client层。WPA层接口提供设置加密方式、关联热点、设置信道、隐藏热点等功能,HAL层接口作为WPA接口的补充,提供设置国家码、设置MAC地址、获取信道信息等功能。

  2. Message模块将用户态的消息按组件分发至AP、STA等模块。

  3. Hdf_Mac80211定义底层驱动相关的MAC层接口。命令字段下发至Hdf_Mac80211,再通过Bus模块发送到WLAN芯片固件侧。

  4. Bus模块向上提供统一的总线抽象接口。通过向下调用Platform层提供的SDIO接口和封装适配USB、PCIE接口,屏蔽不同内核的差异;通过对不同类型的总线操作进行统一封装,屏蔽不同芯片差异,能够对不同芯片厂商提供完备的总线驱动能力,不同厂商共用此模块接口,从而使厂商的开发更为便捷和统一。

  5. EAPOL(Extensible Authentication Protocol Over LAN),基于局域网的扩展认证协议,主要用于在客户端和设备(接入设备、服务器)之间传送EAP协议报文,以允许EAP协议报文在LAN上传送,完成认证流程,实现设备上线功能。

  6. NetDevice用于建立专属网络设备,屏蔽不同OS的差异,对WiFi驱动提供统一接口,提供统一的HDF NetDevice数据结构,及其统一管理、注册、去注册能力;对接轻设备及富设备上的Linux的网络设备层。

  7. NetBuf为WLAN驱动提供Linux或者LiteOS原生的网络数据缓冲的统一数据结构的封装以及对网络数据的操作接口的封装。

  8. 协议栈与NetDevice模块、NetBuf模块共同协同完成数据流交互。

点击领取→【纯血版鸿蒙全套最新学习资料】(安全链接,放心点击希望这一份鸿蒙学习资料能够给大家带来帮助,有需要的小伙伴自行领取~

约束与限制

WLAN驱动为上层WLAN服务提供稳定的基础能力接口,HDI接口适用于标准系统,HAL接口适用于小型系统及轻量系统。

开发指导

场景介绍

WLAN驱动的主要工作是为上层WLAN服务提供稳定的基础能力接口,保证用户可以方便地接入到无线网络,实现数据传输和共享。不同WLAN模组需要适配OpenHarmony时,请参考如下的接口说明和开发步骤。

接口说明

WLAN模块有三部分对外开放的API接口:

  1. 对上层服务提供HDI以及HAL能力接口。

  2. 提供给各厂商实现的能力接口。

  3. 驱动直接调用WLAN模块能力接口。

  • WLAN驱动模块对上层服务提供的能力接口,主要功能有:创建/销毁IWiFi对象、设置MAC地址、设置发射功率等。以下接口列举的为IDL接口描述生成的对应C语言函数接口,如表1、表2所示。接口声明见idl文件(/drivers/interface/wlan/v1_1/)。

    表1 wifi_hal.h

    接口名称 功能描述
    int32_t WifiConstruct(struct IWiFi **wifiInstance) 创建IWiFi对象,提供IWiFi基本能力。
    int32_t WifiDestruct(struct IWiFi **wifiInstance) 销毁IWiFi对象。
    int32_t (*start)(struct IWiFi *) 创建HAL和驱动之间的通道及获取驱动支持的网卡信息。
    int32_t (*stop)(struct IWiFi *) 销毁通道。

    表2 wifi_hal_base_feature.h

    接口名称 功能描述
    int32_t (*getFeatureType)(const struct IWiFiBaseFeature *) 获取特性的类型。
    int32_t (*setMacAddress)(const struct IWiFiBaseFeature *, unsigned char *, uint8_t) 设置MAC地址。
    int32_t (*getDeviceMacAddress)(const struct IWiFiBaseFeature *, unsigned char *, uint8_t) 获取设备持久化的MAC地址。
    int32_t (*setTxPower)(const struct IWiFiBaseFeature *, int32_t) 设置发射功率。
  • WLAN驱动模块提供了需要驱动开发人员自行去填充具体实现内容的能力接口,主要功能有:初始化/注销NetDevice、打开/关闭NetDevice、获取NetDevice的状态等。提供的部分接口说明如表3所示:

    表3 net_device.h

    接口名称 功能描述
    int32_t (*init)(struct NetDevice *netDev) 初始化NetDevice。
    struct NetDevStats *(*getStats)(struct NetDevice *netDev) 获取NetDevice的状态。
    int32_t (*setMacAddr)(struct NetDevice *netDev, void *addr) 设置Mac地址。
    void (*deInit)(struct NetDevice *netDev) 注销NetDevice。
    int32_t (*open)(struct NetDevice *netDev) 打开NetDevice。
    int32_t (*stop)(struct NetDevice *netDev) 关闭NetDevice。
  • WLAN驱动模块提供给驱动开发人员可直接调用的能力接口,主要功能有:创建/释放WifiModule、关联/取消关联、申请/释放NetBuf、lwip的pbuf和NetBuf的相互转换等。

    可直接调用的接口如表4、表5和表6所示。

    表4 wifi_module.h

    接口名称 功能描述
    struct WifiModule *WifiModuleCreate(const struct HdfConfigWifiModuleConfig *config) 基于HDF开发WLAN驱动时,创建一个WifiModule。
    void WifiModuleDelete(struct WifiModule *module) 基于HDF开发WLAN驱动时,删除并释放WifiModule所有数据。
    int32_t DelFeature(struct WifiModule *module, uint16_t featureType) 基于HDF开发WLAN驱动时,从WifiModule删除一个功能组件。
    int32_t AddFeature(struct WifiModule *module, uint16_t featureType,
     struct WifiFeature *featureData)
    基于HDF开发WLAN驱动时,注册一个功能组件到WifiModule。

    表5 wifi_mac80211_ops.h

    接口名称 功能描述
    int32_t (*startAp)(NetDevice *netDev) 启动AP。
    int32_t (*stopAp)(NetDevice *netDev) 停止AP
<think>我们正在解决“wpa_cli 无法连接到 wpa_supplicant”的问题,具体错误信息是:“Interactive mode Could not connect to wpa_supplicant wlan0 re-trying” 根据引用[1]和引用[2],以及我们已有的知识,我们可以按照以下步骤进行排查和解决。 注意:以下步骤需要root权限,请使用sudo或切换到root用户。 步骤1:检查wpa_supplicant进程是否存在 使用命令:`ps aux | grep wpa_supplicant` 如果存在,输出中会显示wpa_supplicant进程,并带有对应的接口(如-i wlan0)和配置文件(-c /path/to/config)。 如果不存在,则需要启动wpa_supplicant。 步骤2:启动wpa_supplicant(如果未运行) 根据引用[2]中的命令,我们可以这样启动: `wpa_supplicant -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf -B` 注意:不同系统的配置文件路径可能不同,常见的路径有: - /etc/wpa_supplicant/wpa_supplicant.conf - /system/etc/wifi/wpa_supplicant.conf(Android系统) - /data/misc/wifi/wpa_supplicant.conf(Android系统) 步骤3:检查socket文件是否存在 引用[1]提到socket路径(如/data/misc/wifi/sockets/wlan0)是否存在。这个路径是wpa_supplicant和wpa_cli通信的套接字文件。 在启动wpa_supplicant时,可以通过`-O`参数指定控制接口的路径(如`-O /var/run/wpa_supplicant`),如果没有指定,则使用默认路径。 默认路径可能因系统而异,常见的有: - /var/run/wpa_supplicant - /run/wpa_supplicant - /data/misc/wifi/sockets(Android) 检查对应接口的socket文件是否存在,例如: `ls /var/run/wpa_supplicant/wlan0` 步骤4:检查wpa_supplicant启动参数中的控制接口设置 在wpa_supplicant的配置文件(如/etc/wpa_supplicant/wpa_supplicant.conf)中,可以设置控制接口(ctrl_interface)和权限(ctrl_interface_group): ``` ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=wheel ``` 确保配置文件中设置了控制接口,并且路径与步骤3中检查的路径一致。 步骤5:确保wpa_cli使用的socket路径正确 wpa_cli默认会尝试连接/var/run/wpa_supplicant/<interface>。如果wpa_supplicant的socket文件不在默认路径,可以通过环境变量`WPA_CTRL_DIR`指定目录,或者使用`-p`参数指定路径: `wpa_cli -i wlan0 -p /custom/path` 步骤6:权限问题 确保当前用户对控制接口的socket文件有读写权限。可以通过以下命令修改权限: `sudo chmod 777 /var/run/wpa_supplicant` (不推荐,仅用于测试) 或者,将当前用户加入控制接口配置中指定的组(例如GROUP=wheel),然后重启wpa_supplicant。 步骤7:如果以上步骤都无效,尝试重启网络服务 重启wpa_supplicant服务(如果系统使用systemd): `sudo systemctl restart wpa_supplicant` 或者,如果系统没有systemd,则手动结束进程再启动: `sudo killall wpa_supplicant` `sudo wpa_supplicant -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf -B` 步骤8:Android系统特殊处理 在Android系统中,wpa_supplicant通常由系统服务启动,并且socket文件位于/data/misc/wifi/sockets/。如果手动启动,需要确保以root用户运行,并且使用正确的配置文件和参数。 总结流程: 1. 检查wpa_supplicant进程 -> 不存在则启动。 2. 检查socket文件是否存在 -> 不存在则检查配置文件和启动参数。 3. 检查权限 -> 确保当前用户有权访问socket。 4. 尝试指定路径连接:`wpa_cli -i wlan0 -p /path/to/socket` 下面是一个具体的解决示例(以Linux系统为例):</think>### 解决 "Could not connect to wpa_supplicant" 错误 当出现 `Interactive mode Could not connect to wpa_supplicant wlan0 re-trying` 错误时,表明 `wpa_cli` 无法与 `wpa_supplicant` 守护进程通信。以下是系统级排查和解决方法: --- #### 🔍 **步骤 1:检查 wpa_supplicant 进程状态** ```bash ps aux | grep wpa_supplicant ``` - **预期输出**:应显示包含 `-i wlan0` 参数的进程(`wlan0` 替换为你的接口名) - **若无输出**:说明服务未运行,需手动启动(见步骤 2) --- #### ⚙️ **步骤 2:启动 wpa_supplicant 服务** ```bash sudo wpa_supplicant -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf -B ``` - **关键参数说明**: - `-i wlan0`:指定无线接口名 - `-c`:配置文件路径(常见路径见下表) - `-B`:后台运行模式 - **配置文件常见路径**: | 系统类型 | 配置文件路径 | |----------|--------------| | Linux | `/etc/wpa_supplicant/wpa_supplicant.conf` | | Android | `/system/etc/wifi/wpa_supplicant.conf` | | OpenWRT | `/var/run/wpa_supplicant-$INTERFACE.conf` | --- #### 📂 **步骤 3:检查 Socket 文件路径** ```bash sudo ls -l /var/run/wpa_supplicant/ # 或 Android 路径 sudo ls -l /data/misc/wifi/sockets/ ``` - **预期结果**:应存在接口对应的 socket 文件(如 `wlan0`) - **若文件不存在**: 1. 在配置文件中添加 socket 路径声明: ```ini ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=wheel ``` 2. 重启服务: ```bash sudo pkill wpa_supplicant sudo wpa_supplicant -i wlan0 -c /etc/wpa_supplicant.conf -B ``` --- #### 🔐 **步骤 4:权限修复(关键步骤)** ```bash # 检查 socket 文件权限 sudo ls -l /var/run/wpa_supplicant/wlan0 # 修复权限(Linux 示例) sudo chown root:wheel /var/run/wpa_supplicant/wlan0 sudo chmod 660 /var/run/wpa_supplicant/wlan0 # Android 设备需 remount 分区 adb root adb remount ``` --- #### 🚨 **步骤 5:深度诊断** ```bash # 查看实时日志(需保持终端打开) sudo wpa_supplicant -d -i wlan0 -c /path/to/config.conf # 检查常见错误标志: # - "Failed to initialize control interface": socket 创建失败 # - "nl80211: Driver does not support authentication/association": 驱动问题 ``` --- #### 🛠️ **备选解决方案** 1. **强制重建 socket**: ```bash sudo rm /var/run/wpa_supplicant/wlan0 sudo systemctl restart wpa_supplicant ``` 2. **驱动重载**: ```bash sudo modprobe -r ath9k # 卸载驱动(ath9k 替换为你的驱动名) sudo modprobe ath9k # 重新加载 ``` 3. **DBus 模式替代方案**(若支持): ```bash sudo wpa_supplicant -i wlan0 -c config.conf -u ``` --- ### 💡 技术原理 错误根本原因是控制接口(ctrl_interface)通信中断,可能由以下情况导致: 1. `wpa_supplicant` 进程崩溃或被终止 2. Socket 文件权限错误(如 SELinux 限制) 3. 配置文件未声明 `ctrl_interface` 路径 4. 文件系统只读导致无法创建 socket(常见于 Android 系统分区) > 通过上述步骤,90% 的 `wpa_cli` 连接问题可被解决[^1][^2]。若问题持续,建议检查内核日志 `dmesg | grep wlan0` 排查驱动级错误。 --- ### 🔍 相关问题 1. 如何永久修复 Android 设备的 `wpa_supplicant` socket 权限问题? 2. 如何通过 `wpa_cli` 命令手动触发 Wi-Fi 重新认证? 3. `nl80211` 和 `wext` 驱动模式在 `wpa_supplicant` 中有何区别?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值