当前位置: 首页 > news >正文

wifi驱动适配源码实现分析

概述

它是典型的适配器模式——屏蔽底层 HCI 操作细节,给上层提供统一的扫描发现能力

上层 (shareservice 等) ↓ 调用标准接口 driver_ble_discovery.c ← 适配层,承上启下 ↓ 操作 HCI socket Linux 内核蓝牙协议栈

1. 向上:提供统一接口

通过 softbus_ble_discovery_interface.h 对上层暴露标准接口,如:

  • SoftbusBleDiscoveryStartScan— 开始扫描
  • SoftbusBleDiscoveryStopScan— 停止扫描
  • SoftbusBleDiscoveryRegisterScanListener— 注册扫描监听
  • SoftbusBleDiscoveryUnRegisterScanListener— 反注册扫描监听

上层(如 shareservice)只调用这些接口,不关心底层实现。

2. 向下:适配 Linux HCI 层

通过直接操作 Linux Bluetooth HCI socket 实现扫描功能:

  • DriverExtendBleScanSwitch— 发送 HCI 命令控制扫描开关
  • ExtendedEventListenerThread— 通过 HCI socket 轮询读取 BLE 广播包
  • ProcessExtendedBleAdvEvent— 解析 HCI 层上报的扩展广播数据

SoftbusBleDiscoveryStartScan

参数说明

scannerId扫描通道ID,项目定义了8个通道,可实际上只用到了1个1号。每个通道包含

| 字段 | 含义 | |----------------|-----------------------| | `isUsed` | 该通道是否已被注册占用 | | `isScanning` | 该通道是否正在扫描 | | `scannerId` | 通道编号(等于数组下标)| | `scanCallback` | 上层注册的回调函数 |

softbusscanparams----HCI扫描物理参数

typedef struct { uint8_t scanType; // 扫描类型:被动扫描(0) / 主动扫描(1) uint8_t scanPhy; // 扫描物理信道:1M PHY / 2M PHY / Coded PHY uint8_t scanFilterPolicy; // 过滤策略:接受所有 / 只接受白名单 uint8_t frameType; // 帧类型 uint16_t scanInterval; // 扫描间隔(单位 0.625ms) uint16_t scanWindow; // 扫描窗口(单位 0.625ms) } SoftBusBcScanParams;

这些参数会通过ConvertSoftbus2HciExtScanParams转换成 HCI 命令,直接下发给蓝牙控制器,控制硬件层面怎么扫描

参数作用举例
scanInterval每隔多久扫描一次100(即 62.5ms)
scanWindow每次扫描持续多久50(即 31.25ms)
scanPhy用哪个物理信道Coded PHY(远距离)
scanType主动扫描会发 SCAN_REQ 请求更多数据主动扫描可获取 ScanRsp

SoftBusBcScanFilter *scanFilter— 过滤条件数组

typedef struct { uint16_t serviceUuid; // 服务 UUID uint32_t serviceDataLength; // 服务数据长度 uint16_t manufactureId; // 厂商 ID uint32_t manufactureDataLength; // 厂商数据长度 int8_t *address; // 设备 MAC 地址 int8_t *deviceName; // 设备名称 uint8_t *serviceData; // 服务数据 uint8_t *serviceDataMask; // 服务数据掩码 uint8_t *manufactureData; // 厂商数据 uint8_t *manufactureDataMask; // 厂商数据掩码 uint8_t filterIndex; // 过滤器索引 } SoftBusBcScanFilter;

作用:启动蓝牙扫描

阶段一:参数校验

① 检查入参 param / scanFilter / filterSize 是否合法 ② 检查 scanCallback 是否已注册(否则启动后无法回调通知上层)
LOGI("Enter scannerId=%d", scannerId); if (param == NULL || scanFilter == NULL || filterSize <= 0) { LOGE("invalid param, scannerId=%d", scannerId); return SOFTBUS_INVALID_PARAM; } // 调用启动回调 if (g_scanChannel[scannerId].scanCallback == NULL || g_scanChannel[scannerId].scanCallback->OnStartScanCallback == NULL) { LOGE("invalid param, OnStartScanCallback is null"); return SOFTBUS_INVALID_PARAM; }

阶段二:状态检查

作用:检查通道未注册或者已经在扫描就提前解锁返回错误

加锁 g_scannerLock → 检查扫描通道是否已注册(isUsed) → 检查是否已经在扫描(isScanning) 解锁 g_scannerLock
// 获取互斥锁 if (pthread_mutex_lock(&g_scannerLock) != 0) { LOGE("lock failed, scannerId=%d", scannerId); return SOFTBUS_LOCK_ERR; } // 检查扫描通道状态 if (!CheckScanChannelInUsed(scannerId)) { LOGE("scanner is not in used, scannerId=%d", scannerId); pthread_mutex_unlock(&g_scannerLock); return SOFTBUS_BC_ADAPTER_NOT_IN_USED_FAIL; } // 检查是否已经在扫描 if (g_scanChannel[scannerId].isScanning) { LOGE("already scanning, scannerId=%d, btScanId=%d", scannerId, g_scanChannel[scannerId].scannerId); pthread_mutex_unlock(&g_scannerLock); return SOFTBUS_ALREADY_TRIGGERED; } pthread_mutex_unlock(&g_scannerLock);

sharkit暂时先看到这吧,PL和我说让我负责文件互传模块,WiFi适配暂时搁置

阶段三:启动底层扫描

调用 DriverBleDiscoveryStartScan() → 向 HCI 层发送扫描命令 再次加锁 g_scannerLock → 根据 HCI 返回值更新 isScanning 状态 解锁 g_scannerLock

阶段四:通知上层启动结果

作用:不直接在当前线程回调上层,而是丢到线程池异步执行。这是为了避免回调中如果上层又调用了其他接口(比如 StopScan),形成同线程递归调用导致死锁。

malloc 一个 ScanResultReportData ThreadPoolAdd(ThreadOnStartScanCallback) → 通过线程池异步回调上层

阶段五:启动事件监听线程

作用:事件监听线程通过 HCI socket 持续读取 BLE 广播包。如果线程创建失败,会回滚:调用DriverExtendBleScanSwitch(false)停止 HCI 扫描,并将isScanning置回 false。

设置全局 g_scannerId = scannerId pthread_create(ExtendedEventListenerThread) → 创建事件监听线程
http://www.jsqmd.com/news/1117068/

相关文章:

  • 【Java踩坑笔记】22_ThreadLocal用完不remove,内存泄漏在等你
  • Grok 4.3 长上下文使用教程:如何阅读 PDF、会议记录和项目文档
  • 隐藏WIN10开始菜单应用[系统]标签
  • STM32与MC6470 IMU的硬件协同与姿态控制实现
  • 困难任务推进不动时,我用0.1%最小成功法自救
  • 跨境电商蓝海模式:反向海淘搭建
  • AI 搜索工具烹饪查询结果直链原始食谱,却因 AI 生成食谱问题遭部分美食作家不满
  • 自动驾驶场景下YOLO系列实时目标检测:性能实测与选型避坑指南
  • IIM-42652 IMU与STM32L152ZD的6DoF运动解算实践
  • AI生成式设计:从创意辅助到全流程赋能,重构设计产业底层逻辑
  • 如何精准识别高校与地方产业的协同发展机会?
  • NoFences:开源免费的Windows桌面栅栏工具,终结桌面混乱时代
  • 字节序转换 + 模板
  • 杰理之IO默认对电压1/2分压,还要开下拉【篇】
  • PX4多旋翼无人机集群协同控制:从集中式指挥到分布式自治的技术演进
  • 3PEAK思瑞浦 LM393-SO1R SOP8 比较器
  • 终极指南:如何用SecGPT网络安全大模型提升你的安全防御能力
  • LED驱动电源选型标准与工程应用技术避坑指南
  • 2026年7月1日“每日芯闻”
  • AI生产力流水线:从业务场景出发的工具选型与工程化落地
  • 【解压即用】Ltx2.3 文生视频/图生视频本地一体化整合包发布与全面评测
  • BiSheng JDK 21模块化系统深度解析:Java模块化架构最佳实践
  • 中小音乐团队版权方案,知保链低成本电子存证批量登记音频
  • 2026照片抠图工具全解:电脑手机免费软件与在线网站实操指南
  • [042][数据模块]Mybatis Plus 数据库级租户:基于多数据源路由的动态隔离实现
  • 靠谱无轨龙门架销售厂家揭秘,满足你对高品质设备的需求!
  • 生成引擎优化(GEO)在内容创作领域的实用分析与未来展望
  • 射阳空调维修上门服务
  • Java后端面试突击指南:构建应对八股文、场景题与AI融合的知识体系
  • 72.潮汐