KDocs 研发资料库
  • 音频技术应用文档入口汇总
  • 杰理WINDOWS环境安装及其他事项
  • LINUX安装和编译
  • Linux环境编译SDK教程(ubuntu18.04)
  • 音频类补丁汇总表
  • 认证资料获取汇总(最新资料后台会更新)
  • 《Hi-Res申请指南v1.0》
  • FreeRTOS 开源协议版本
  • uCOS 开源协议版本信息
  • 各个模块关键资料汇总
  • 软件调试方法
  • Makefile编译
  • 提bug的规范
  • 常规设备使用指导
  • 对外特别发布开发注意点信息汇总
  • AD697X软件问题整理
  • AC700N软件问题整理
  • AC701X耳机软件问题整理
  • 951&961软件问题整理
  • AC104X软件问题整理
  • AC128N问题整理文档
  • 可视化工具调试问题整理
  • 耳机资料汇总
  • AC704N、 AC705N相关应用
  • AC695N&AC696N&AC608N音箱问题整理
  • JL701N音箱问题整理
  • AC692X软件问题整理
  • AC706N音箱问题整理
  • JL701N音箱问题整理(可视化工具SDK)
  • JL703N音箱问题整理
  • JL709N(JL689N)音箱问题整理
  • JL7094系列-入门到进阶开发指导
  • AC210N音箱问题整理
  • 无线麦系列版本支持指南
  • AW32N无线麦问题整理
  • lAD697X&JL701X 无线麦软件共性问题整理
  • AC706N无线麦问题整理
  • AW36N无线麦问题整理
  • AC710X无线麦问题整理
  • 唤醒源获取及唤醒IO设置
  • 电源
  • LVD
  • 长按复位配置方法
  • 低功耗应用
  • TIMER
  • UART
  • SPI
  • 内部FLASH空间添加用户自定义区域
  • IIC
  • GPIO
  • MCPWM
  • SD&U盘
  • 时钟&晶振
  • GPCNT
  • IO口crossbar映射功能
  • 文件系统使用总结
  • 复用应用
  • LINEIN_AUX相关应用
  • IIS音频接口应用
  • SPDIF模式相关(HDMI_ARC、光纤、同轴)
  • PDM LINK
  • 外设相关应用
  • 蓝牙相关
  • 杰理蓝牙距离调试文档
  • TWS耳机配对方式使用及生产把控指南
  • GFP谷歌快连及其认证流程指引
  • 蓝牙发射器(bt_emitter)相关
  • BLE应用
  • 关于提升BLE传输速率说明
  • BLE测试数据
  • MUSIC 模式相关应用
  • MIDI音乐实现
  • PC相关应用
  • FM相关应用
  • AC695N_AC696N FM天线ESD静电防护措施说明V2.0_20250107
  • fm应用详细设计说明书
  • 杰理FM硬件指南-20230315
  • ADC模块
  • AUDIO相关应用
  • 新Tools的音效调试使用
  • 混响应用使用说明
  • 音效调式
  • 音箱耳机低音小音量增强实现方法
  • DAC输出功率调试
  • DAC性能测试指南
  • 针对各类底噪、电流声分析流程
  • 录音相关应用
  • OPUS编解码相关
  • RTC相关应用
  • 升级相关
  • UI相关应用
  • 通话调试流程指南
  • 通话相关应用
  • 省电容mic使用手册
  • 如何测试验证手表通话系统的语音失真 V1.0
  • AC695X_AC696X_AD697X 常见通话问题处理参考资料
  • 通话调试问题确定步骤
  • 内置触摸调试指南
  • 低功耗内置触摸介绍V2.2
  • 触摸相关文档
  • AC697X、AC698X内置触摸调试及整改方法V1.0
  • 产测相关应用
  • AC63X BLE DUT测试介绍
  • 兆华序列使用简易说明
  • JL_1T2蓝牙测试盒音频文件更换说明
  • ENC相关应用入口汇总
  • ANC相关应用入口汇总
  • JL DMS通话调试手册-V3.9.4
  • ANC-ENC结构设计要点-20240407
  • 半入耳式ANC耳机器件选型与结构设计指南V1.0
  • JL 耳道自适应调试指南
  • ANC相关问题处理
  • ANC调试文档
  • 评估蓝牙耳机通话上行降噪性能的方法 V1.0 (2)
  • FCC 或者 BQB 认证相关应用
  • BQB profile 测试中常遇到的问题点汇总
  • 蓝牙参数整理20210811
  • 杰理科技认证问题参考
  • 无线音频产品开发指南
  • 无线麦系列从入门到进阶开发指导
  • 量产烧录相关说明
  • 一拖八烧录器远程过程调用说明
  • 量产相关建议
  • EffectTool(eq)调试工具说明文档
  • AC897AD697系列的EQ调试方法-V3
  • 杰理调音指南-20220622
  • 音效模块总结
  • 简要调音步骤指引(可视化)
  • 耳机充电与通信调试指南
  • 充电仓硬件调试指南
  • 充电仓软件问题整理
  • AC951常用说明
  • AC951_AC961_开发板使用说明V1.0
  • 彩屏仓AC982 入门指导及FAQ
  • 蓝牙音频APP相关应用
  • 手机APP的简介和开发流程
  • 蓝牙音频系列-硬件设计指南
  • 静电测试及整改方法-20220706
  • TWS耳机底噪整改指南V1.2
  • 杰理蓝牙距离调试文档
  • 蓝牙RF硬件设计与调试V1.1-20250219
  • AC695N_AC696N FM天线ESD静电防护措施说明V2.0_20241228
  • 音效调试指南
  • 无线话筒K歌音箱标准开发流程
  • 杰理科技 700N TWS耳机产品标准-202303
  • 杰理科技 701N 广播产品标准-202303
  • JL-HAT ANC高效产测自适应
  • 无线话筒测试板使用介绍
  • 一拖八频偏校准使用说明
  • 领夹麦产测工具使用介绍
  • Dongle量产测试说明
  • Dongle+Tws或头戴式 SDK通过工具绑定配对功能说明文档
  • 双麦ENC产测宏配置验证方法 V1.0
  • JL耳机方案麦克风声学测试指令_V1.0
  • JL耳机方案麦克风声学测试指令_V2.0
  • JL_ENC自动测试命令_V0.0.1
  • JL蓝牙测试盒用例说明
  • LDAC自测环境搭建_ubuntu
  • 延迟小板使用手册
  • 杰理库文件的制作及添加实现过程
  • 关于 AC635N&AC636N系列免晶振兼容性补丁 说明
  • 关于 AC63系列VM兼容性修复补丁_20250224 说明
  • 关于 AC632N &AE632N_ 蓝牙& 低功耗兼容性修复补丁 说明
  • AD698N和AC638N电压优化补丁V3说明
  • 关于 AC635N&AC636N漏电和E&G版兼容联合补丁 说明
  • AD698N和AC638N电压优化补丁V2说明
  • 702相关应用
  • 2024-4-30 发布歌词显示SDK开发注意事项
  • BQB RF & FCC 认证测试固件问题汇总及源码
  • BQB profile 测试中常遇到的问题点汇总
  • 进dut测试模式方法及固件
  • 704-频偏修改bin文件合集
  • 701手表BQB PROFILE认证注意事项
  • 认证的干扰规避整改
  • 海外CRA认证报告生成说明
  • JL700N可视化工具问题处理文档
  • JL701X可视化工具问题处理文档
  • JL701N_earphone_release_v1.6.0_ANC 低功耗问题补丁
  • JL708X可视化工具问题处理文档
  • JL709N可视化工具问题处理文档
  • JLstudio可视化工具使用说明
  • 一拖二-串口_蓝牙_app在线EQ、通话参数及调试方式和内置触摸调试
  • 可视化JL701M_DONGLE_SDK添加MIC为发射源
  • 可视化JL701M_DONGLE_SDK添加按键切换usb audio与MIC发射源
  • JL701M_DONGLE_SDK_1.0.0_dongle输入linein输出dac
  • 701可视化_a2dp_to_le_demo说明
  • 耳机系列demo汇总
  • JL7018F&JL7006F_7003F AUX IIS
  • 一键连接应用
  • 普通SDK动态开关一拖二功能
  • 蓝牙分析仪(EllisysBluetoothAnalyzer)抓包例程
  • TWS配对常见应用
  • APP自定义按键的demo
  • AC700N 播歌双EQ DEMO示例及说明
  • AC698V164 MIC与蓝牙音乐共同输出DAC demo
  • 添加第三方算法以及多算法授权流程
  • 空间音频配置方法
  • 普通高低电平TWS耳机控制通讯
  • 入耳检测状态更新demo解析
  • 资源优化(非可视化的SDK)
  • 资源优化(可视化SDK)
  • 翻译耳机、语音识别应用demo
  • 耳机抗干扰问题排查和优化
  • AC698D2 抗干扰优化
  • AC696X软件问题整理
  • AC695X软件问题整理
  • AC695X软件问题整理_1722249702
  • AC608X软件问题整理
  • JL701N_2T1_DUPLEX 应用软件问题汇总
  • le_audio_1.0.0_patch05 以及之前的版本IRkey 功能异常修改
  • AC706N-le_audio-200SDK有线_无线麦录音demo
  • jl701n_le_audio_v200patch02 IO串口升级修改串口单次发送字节长度的修改办法
  • 703创建IIS 输入dac输出音频流demo
  • 703将媒体流音频同时上传PC_mic录音demo实现
  • 703四路IIS输入输出demo
  • 底噪调试
  • AW328A烧录说明
  • 文档合集
  • AC706N_wireless_mic_release_PATCH_20240712 补丁 说明
  • AC706N_wireless_mic_release_PATCH_20240726 补丁 说明
  • AC706N_wireless_mic_release_V1.0.0、1.0.1、1.0.2 补丁 说明
  • AC706N_wireless_mic_release_V1.1.2 中的2T1应用 RX端不绑定配对,TX端实现绑定配对的修改方法
  • 各系列省晶振实现方法
  • iis tx rx说明文档
  • spdif信号
  • 蓝牙电话本
  • 安卓手机同步时间补丁
  • CDC配置
  • PC模式下增加Teams唤起功能
  • 杰理HDMIARC开发实现过程
  • AC701N patch06之前的版本用第三方算法节点实现新版本的pcm delay节点功能
  • (K歌音箱)各SDK音效配置相关说明
  • 长文件录音
  • 点阵屏歌词字库相关(蓝牙歌词,普通歌词)
  • 字模提取工具说明
  • 音箱可视化彩屏-入门到进阶开发指导
  • 彩屏LVGL UI设计及工具使用
  • 使用内部UI框架进行UI调试的系列步骤
  • AD101C使用强制升级工具spi 烧录不了问题处理(测试版本)
  • AD161扩展灯板说明文档
  • 歌词显示器开发注意项
  • 使用硬件数字增益控制通话下行音量(可视化)
  • 杰理小牛产测资料
  • ENC配置说明
  • 通话调试流程指引
  • ANC相关功能demo
  • 无线麦硬件资料汇总
  • 无线麦相关应用
  • 无线麦复杂功能补丁包汇总
  • 无线话筒形态SDK程序&开发经验&问题点分享
  • 双模式结合应用问题汇总
  • 无线麦距离优化案例
  • 无线麦系列中的双工形态(duplex)演变开发对讲机方案开发资料
  • 音箱入门到进阶指导文档(编写中)
  • 蓝牙耳机品控和生产技巧
  • 982过_欠压标志获取异常
  • 如何获取最新涂鸦SDK及库文件
  • 无线话筒K歌音响-调音标准流程
  • 无线话筒产测流程

蓝牙和TWS的连接原理

📎 原始文档:https://www.kdocs.cn/l/csR4lgOlWnsj 蓝牙和TWS的连接原理

文档简介

本文简单介绍蓝牙连接和TWS连接的原理,简单说明SDK相关命令和接口的使用方法,提供常见问题分析处理思路和解决办法。

一、蓝牙常用的几种状态

网络资料参考:蓝牙的状态详解

  1. Page连接 主动对其他蓝牙设备发起连接;
  2. Page Scan连接扫描 可被其他蓝牙设备连接;
    当其他蓝牙设备处于Page Scan状态时,才能被发起page 的蓝牙设备连接。
  3. Inquiry搜索 搜索周围的蓝牙设备;
  4. Inquiry Scan搜索扫描 可被其他蓝牙设备搜素到;
    当其他蓝牙设备处于Inquiry Scan状态时,才能被发起Inquiry 的蓝牙设备搜索到。
  5. Connection连接状态 已经处于连接状态;
    蓝牙设备A通过page或者Inquiry获取到目标蓝牙设备B后,会经过一系列的连接过程,连接完成后两个蓝牙设备A和B就处于连接状态了。

二、蓝牙连接

  1. 首次配对 手机:由手机发起Inquiry,搜索周围的蓝牙设备;
    耳机:耳机要处于Inquiry Scan,才能被手机搜索到;
    配对完成:手机和耳机都会记录配对信息,配对信息中包含对方的蓝牙地址。
  2. 耳机回连手机 耳机:由耳机发起Page,page的蓝牙地址是手机的蓝牙地址
    手机:手机要处于Page Scan状态,才能被耳机回连上
    特殊点:
    1. page用的蓝牙地址可以从配对信息中获取,这样的过程就是耳机回连已经配对过的手机;
    2. page用的蓝牙地址来源于其他方式,如uart上报,或者代码指定:
      1. 如果耳机已经跟手机配对过,就正常回连;
      2. 如果耳机没有跟手机配对过,会经过一个配对过程,如果手机允许配对,就正常配对连接,产生配对信息,否则连接失败。
  3. 耳机回连手机失败后 耳机处于Inquiry Scan和Page Scan的可发现可连接状态,可被手机发现和连接。

三、TWS连接

  1. 手机、TWS主机、TWS从机的关系(仅讨论AC697N以后的方案) image TWS(true wireless stereo 真无线蓝牙)不属于标准蓝牙协议,每家方案都有所区别。我们方案有以下三种方案:
  2. 转发:主机和手机连接,同时和从机连接,主机收到手机数据后,转发给从机。
  3. 监听:监听模式,主从机可以对于手机来说是同一个设备,从机能监听到手机和主机之间的通讯,从而减小主从之间的数据交流。
  4. 监听+转发:
  1. 根据使用的场景切换监听或者转发模式
  2. 监听的前提下,再加入转发机制
    //在lib_btctrler_config.c里面配对TWS方式
    //0 监听 1 转发 2 监听+转发
    const int CONFIG_TWS_WORK_MODE
  1. TWS配对
    1. 左右耳使用公共的配对地址
    2. 左右耳分别在Page <--> Page Scan之间切换
    3. 在同一个时间段内,当左右耳中,有一个处于Page,另一个处于Page Scan,则可以建立连接
    4. 连接成功后记录配对信息
  2. TWS回连
    1. 左右耳使用特有的配对地址(可能是配对信息中的地址,或者只有左右耳知道,没有第三者知道的某个地址)
    2. 左右耳分别在Page <--> Page Scan之间切换
    3. 在同一个时间段内,当左右耳中,有一个处于Page,另一个处于Page Scan,则可以建立连接
  3. TWS的配对信息
    1. 另一只耳机的地址(REMOTE地址)
    2. 通过特定方式生成的公共地址(COMMON地址)
  4. 其他相关信息
    1. 蓝牙地址(BT_MAC)
    2. TWS本地地址(LOCAL地址)
    3. 在实际应用中,TWS的连接还受左右声道限制,固定了左右声道后,不允许相同声道的对耳进行连接
  5. 四个蓝牙地址的关系
    1. 用于TWS配对连接的地址:LOCAL地址、REMOTE地址,丢失、更改LOCAL地址或者REMOTE地址都会导致TWS无法回连;
    2. 用于跟手机配对连接的地址:BT_MAC、COMMON地址;
    3. 当TWS左右耳已经配对上或者配对过且有配对记录:使用COMMON地址跟手机配对连接;
    4. 当TWS左右耳从来都没有配对过,也就是没有配对记录:使用BT_MAC跟手机配对连接。

四、代码中相关的命令和接口

  1. 蓝牙连接

Page

USER_CTRL_START_CONNEC_VIA_ADDR,TWS主机或单耳使用这个命令page回连手机

//从配对记录中获取手机的蓝牙地址
get_current_poweron_memory_search_index(bt_user_priv_var.auto_connection_addr);
//结束上一次的page流程
user_send_cmd_prepare(USER_CTRL_PAGE_CANCEL, 0, NULL);
//启动当前的page流程
user_send_cmd_prepare(USER_CTRL_START_CONNEC_VIA_ADDR, 6, bt_user_priv_var.auto_connection_addr);

Inquiry

耳机方案不涉及Inquiry。

Inquiry Scan

TWS主机或单耳执行:
打开:USER_CTRL_WRITE_SCAN_ENABLE
关闭:USER_CTRL_WRITE_SCAN_DISABLE

Page Scan

TWS主机或单耳执行:
打开:USER_CTRL_WRITE_CONN_ENABLE
关闭:USER_CTRL_WRITE_CONN_DISABLE

/*可发现(1)可连接(1),只能被手机搜索连接*/
user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_ENABLE, 0, NULL);
user_send_cmd_prepare(USER_CTRL_WRITE_CONN_ENABLE, 0, NULL);
/*打开可发现, 可连接,可被手机和tws搜索连接*/
int tws_api_wait_pair_by_code(u16 code, const char *name, int timeout_ms);
/*不可发现(0)不可连接(0)*/
user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_DISABLE, 0, NULL);
user_send_cmd_prepare(USER_CTRL_WRITE_CONN_DISABLE, 0, NULL);
/*不可发现(0)可连接(1)*/
user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_DISABLE, 0, NULL);
user_send_cmd_prepare(USER_CTRL_WRITE_CONN_ENABLE, 0, NULL);

配对

TWS主机或单耳执行:有两种方式

//第一种:
/*可发现(1)可连接(1),只能被手机搜索连接*/
user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_ENABLE, 0, NULL);
user_send_cmd_prepare(USER_CTRL_WRITE_CONN_ENABLE, 0, NULL);
/*===========================================================================*/
//第二种:
/*打开可发现, 可连接,可被手机和tws搜索连接*/
int tws_api_wait_pair_by_code(u16 code, const char *name, int timeout_ms);

回连

TWS主机或单耳执行:

//从配对记录中获取手机的蓝牙地址
get_current_poweron_memory_search_index(bt_user_priv_var.auto_connection_addr);
//结束上一次的page流程
user_send_cmd_prepare(USER_CTRL_PAGE_CANCEL, 0, NULL);
//启动当前的page流程
user_send_cmd_prepare(USER_CTRL_START_CONNEC_VIA_ADDR, 6, bt_user_priv_var.auto_connection_addr);

回连流程:
手机处于page scan时,会根据自己的mac地址计算出32个频点,每个频点在page scan时会停留1.28秒。
耳机处于page状态时,会根据手机的mac地址计算出32个频点,分成A、B两组,每组16个频点。
为了保证手机能够收到耳机的page包,每组频点会page 1.28+1.28=2.56秒,A、B组都page完需要2.56+2.56=5.12秒。

其他命令

TWS主机或单耳执行:
USER_CTRL_DISCONNECTION_HCI:已经处于连接状态时,执行该命令会断开耳机和手机的连接
USER_CTRL_CONNECTION_CANCEL:正在建立连接时,执行该命令会中断连接流程
USER_CTRL_PAGE_CANCEL:发起回连后,执行该命令会中断回连流程
2. TWS连接

配置配对地址

//调用tws_api_set_quick_connect_addr配置, addr为配对地址
void tws_api_set_quick_connect_addr(u8 *addr);
//或使用配对码的方式间接配置配对地址,code为配对码,底层会将code转换为配对地址
int tws_api_search_sibling_by_code(u16 code, int timeout_ms);

TWS配对

TWS配对的两种方式

//第一种,自动配对
//设置配对地址为跟配对码相关的地址,配对码相同的耳机可以进行TWS配对
tws_api_set_quick_connect_addr(tws_set_auto_pair_code());
tws_api_create_connection(timeout);//timeout单位为ms,经过timeout时间后结束配对流程
/*==========================================================================*/
//第二种,按键配对
//耳机开机先进入等待配对的状态,配对地址为跟配对码相关的地址
tws_api_wait_pair_by_code(bt_get_tws_device_indicate(NULL), bt_get_local_name(), 0);
//按键触发后发起配对,配对地址为跟配对码相关的地址,有其他耳机处于等待配对状态且双方配对码一致时,可以进行配对
tws_api_search_sibling_by_code(bt_get_tws_device_indicate(NULL), timeout);//timeout单位为ms,经过timeout时间后结束配对流程

TWS回连

//设置配对地址,addr为跟配对记录相关的地址,公版SDK中使用左耳local地址或者左右local地址相加,也可以使用没有第三者知道的某个地址
tws_api_set_quick_connect_addr(addr);
tws_api_create_connection(timeout);//timeout单位为ms,经过timeout时间后结束配对流程

其他接口

tws_api_cancle_wait_pair:取消可发现, 可连接,不可被tws搜索到
tws_api_cancle_create_connection:取消tws配对连接流程
tws_api_wait_connection:等待tws连接

五、连接产生的事件

  1. 蓝牙连接

Page

//page流程的相关状态会出现在hci事件中
static int bt_hci_event_handler(struct bt_event *bt)
{
    switch (bt->event) {
    case HCI_EVENT_CONNECTION_COMPLETE:
        switch (bt->value) {
        case ERROR_CODE_SUCCESS://page成功,或者被其他设备page成功
        case ERROR_CODE_PAGE_TIMEOUT://page流程超时
        case CUSTOM_BB_AUTO_CANCEL_PAGE://使用USER_CTRL_PAGE_CANCEL命令主动取消
        }
    }
}

HCI层的其他连接事件

查看apps\earphone\include\earphone.h中的注释。
常用事件:

///这个事件上来目前是做了一个连接确认的操作,跟手机配对的时候会有这个事件
#define HCI_EVENT_USER_CONFIRMATION_REQUEST                   0x33
///<连接过程中linkkey丢失,手机删除了linkkey,回连就会出现一次,SDK会默认在这种情况下清掉耳机上的配对记录
#define ERROR_CODE_PIN_OR_KEY_MISSING                         0x06
///<连接超时,一般拿远就会断开有这个消息
#define ERROR_CODE_CONNECTION_TIMEOUT                         0x08
///<需要回连的设备资源不够。有些手机连了一个设备之后就会用这个拒绝。或者其它的资源原因,苹果手机在通知栏点蓝牙按钮断开之后(这时候手机蓝牙已经是不可连接的状态),耳机再回连大概率会出现这个事件
#define ERROR_CODE_CONNECTION_REJECTED_DUE_TO_LIMITED_RESOURCES       0x0D
///<经常用的连接断开消息。就认为断开就行,目前发现手机端主动断开才会有这个事件
#define ERROR_CODE_REMOTE_USER_TERMINATED_CONNECTION          0x13

协议栈的连接事件

连接是否完整和完成,依赖于协议栈的事件。
查看include_lib\btstack\avctp_user.h中STATUS_FOR_USER的注释。
常用事件:

    BT_STATUS_FIRST_CONNECTED,        /*连接成功*/
    BT_STATUS_SECOND_CONNECTED,        /*连接成功*/
    ...
    BT_STATUS_FIRST_DISCONNECT,       /*断开连接*/
    BT_STATUS_SECOND_DISCONNECT,        /*断开连接*/
    BT_STATUS_PHONE_INCOME,     /*来电*/
    BT_STATUS_PHONE_NUMBER,     /*来电话号码*/
    BT_STATUS_PHONE_MANUFACTURER,     /*获取手机的厂商*/
    BT_STATUS_PHONE_OUT,        /*打出电话*/
    BT_STATUS_PHONE_ACTIVE,     /*接通电话*/
    BT_STATUS_PHONE_HANGUP,     /*挂断电话*/
    ...
    BT_STATUS_CALL_VOL_CHANGE,     /*通话过程中设置音量会产生这个状态变化*/
    BT_STATUS_SCO_STATUS_CHANGE,    /*当esco/sco连接或者断开时会产生这个状态变化*/
    ...
    BT_STATUS_VOICE_RECOGNITION,   /*手机报告当前手机语音助手的状态*/
    ...
    BT_STATUS_A2DP_MEDIA_START, /*手机开始发送音频数据过来*/
    BT_STATUS_A2DP_MEDIA_STOP,  /*手机停止发送音频数据*/
  1. TWS连接 include_lib\btctrler\classic\tws_event.h
enum {
    TWS_EVENT_SEARCH_TIMEOUT = 1, //调用tws_api_search_sibling_by_code,timeout后会有此事件
    TWS_EVENT_CONNECTED,          //对耳连接成功,配对成功和连接成功都是这个事件
    TWS_EVENT_CONNECTION_TIMEOUT, //调用tws_api_search_sibling_by_code搜索到,但是连接超时,或者调用tws_api_create_connection连接超时,会有这个事件
    TWS_EVENT_CONNECTION_DETACH,  //对耳连接成功后,由于某些原因断开,会有这个事件,该事件会带一个参数表示断开的原因(见enum tws_detach_reason)
    TWS_EVENT_REMOVE_PAIRS,  //调用tws_api_remove_pairs函数断开产生的事件
    TWS_EVENT_PHONE_LINK_DETACH,  //tws和手机断开会有这个事件
    TWS_EVENT_SYNC_FUN_CMD,  //调用tws_api_sync_call_by_uuid做对耳同步执行,且uuid是'T'时,会有这个事件,该事件会带一个参数表示同步的事件
    TWS_EVENT_SYNC_FUN_TRANID, //没有用到
    TWS_EVENT_CONNECT_TEST, //没有用到
    TWS_EVENT_ROLE_SWITCH, //主从切换成功事件
    TWS_EVENT_LOCAL_MEDIA_START, //没有用到
    TWS_EVENT_LOCAL_MEDIA_STOP,  //没有用到
    TWS_EVENT_ESCO_ADD_CONNECT,  //对耳连上ESCO通话链路事件
    TWS_EVENT_SETUP_MONITOR_LINK,//没有用到
    TWS_EVENT_MONITOR_START,     //对耳进入监听状态的事件
    TWS_EVENT_DATA_TRANS_OPEN,   //没有用到
    TWS_EVENT_DATA_TRANS_START,  //没有用到
    TWS_EVENT_DATA_TRANS_STOP,   //没有用到
    TWS_EVENT_DATA_TRANS_CLOSE,  //没有用到

    TWS_EVENT_MODE_CHANGE,      //sniff without phone,没连手机时tws进入低功耗的事件

    TWS_EVENT_ROLE_SWITCH_START, //对耳开始进行主从切换的事件
    TWS_EVENT_TONE_TEST = 0xff,  //没有用到
};

enum tws_detach_reason { //调用tws_api_detach函数断开TWS的传参,可以根据需要选择
    TWS_DETACH_BY_SUPER_TIMEOUT = 8, //对耳已经连接上,但是连接中断导致长时间通信不上而断开
    TWS_DETACH_BY_LOCAL, //本地主动断开
    TWS_DETACH_BY_REMOTE, //remote主动断开
    TWS_DETACH_BY_POWEROFF, //因为要执行关机而断开,最常用的是这个
    TWS_DETACH_BY_REMOVE_PAIRS, //调用tws_api_remove_pairs函数断开,但目前已经不常用
    TWS_DETACH_BY_TESTBOX_CON, //暂时没有用到
    TWS_DETACH_BY_REMOVE_NO_RECONN,//暂时没有用到
};

六、TWS主从切换

手机、TWS主机、TWS从机的关系(仅讨论AC697N以后的方案)
TWS连接手机时,实际上只有主机和手机进行通信,主机会将一些重要的连接信息同步给从机。
主从切换就是让从机切换成主机,接替原来主机的工作去跟手机通信。
产生主从切换的情况一般有以下几种:

  1. 关机主从切换,主机关机,从机切换为主机:这种情况,是在对耳还没断开的情况下,先进行主从切换,切换完成后TWS断开然后才关机。
  2. 信号主从切换/超距主从切换,主机信号差,从机信号好,从机切换为主机:这种情况,需要在有业务通信的情况下才会产生主从切换,比如播歌或者通话过程中(通话信号主从切换仅限可视化SDK),同时还要求主从机之间、耳机和手机之间的RF正常。
  3. 电量主从切换,主机电量低,从机电量高,从机切换为主机:当耳机不处于第二点情况时,才会产生电量主从切换,也就是信号主从切换优先于电量主从切换。 注意:所有的主从切换场景都要求TWS主从之间能正常通信。突然切断TWS通信的场景无法进行主从切换(例如耳机直接复位或关机、断电、放屏蔽箱等)

七、TWS数据透传和同步指令

interface\btctrler\classic\tws_api.h
具体使用方法可参考SDK已有代码

/*
 * 通过uuid,主从同步调用相同函数
 */
int tws_api_sync_call_by_uuid(int uuid, int priv, int delay_ms);

/*
 * tws 数据发送函数, 要求 len <= 512
 */
int tws_api_send_data_to_sibling(void *data, u16 len, u32 func_id);//支持主从互发数据
int tws_api_send_data_to_slave(void *data, int len, u32 func_id);//只支持主机发给从机

demo:
1、anc同步提示音
image 2、主从间透传数据:主从间同步电量
image

常见问题处理

  1. 蓝牙连接

开机不回连手机

根据上面蓝牙连接章节的内容,我们知道耳机回连手机,需要耳机处于page状态,而手机处于page scan状态,耳机page 的地址必须是手机的蓝牙地址,并且回连时间要大于5.12秒。
基于上述,分析思路如下:
1. 先确保手机的蓝牙处于打开状态,并且没有在回连其他蓝牙设备 2. 通过打印log检查耳机是否处于page的回连状态: 1. 有没有执行到USER_CTRL_START_CONNEC_VIA_ADDR命令 2. USER_CTRL_START_CONNEC_VIA_ADDR带的蓝牙地址是否正确(手机蓝牙地址) 3. 打印中有没有出现大写字母C的打印(蓝牙底层的打印) 3. 检查开机回连时间,最好设置10秒以上,否则回连苹果手机会有小概率回连不了

一些常用的连接状态

1. 区分是首次配对还是回连:配对和回连会有不一样的流程,主要体现在HCI层的连接,当出现HCI_EVENT_USER_CONFIRMATION_REQUEST事件时,可认为当前连接是首次配对。
2. 区分断连是否为超距断连:耳机和手机处于连接状态时,由于某些原因导致了连接中断,比如手机和耳机拉远,由于连接中断导致的断连,会附带一个ERROR_CODE_CONNECTION_TIMEOUT的HCI错误事件,在连接成功之后收到此事件可以认为是超距断连。
3. 区分是否手机主动断开了连接:有些应用需要判断是否手机主动断开,来做不同的动作,手机端主动断开连接时会附带一个ERROR_CODE_REMOTE_USER_TERMINATED_CONNECTION的HCI错误事件,在连接成功之后收到这个事件可以认为是手机主动断开了连接。
  1. TWS连接

对耳开机TWS不回连/不配对

根据TWS连接章节的内容,对耳不管是配对还是回连:
1. 左右耳必须使用同一个地址进行配对和回连 2. 同时TWS的左右耳固定方式也会制约TWS的连接 3. 对耳的连接必须保证,同一段时间内一个耳机处于page状态,另一个耳机处于page scan状态 基于上述条件,分析思路如下:
1. 检查TWS配对时是否使用相同配对码(检查配置工具中的配对码),TWS回连时是否使用相同地址(检查传入tws_api_set_quick_connect_addr的地址),对于回连的,也可以直接检查对耳的LOCAL地址、REMOTE地址是否正常(是否被擦除、更改) 2. 检查两个耳机是否都是左声道,或者都是右声道 3. 检查配对或者回连过程中,log有无类似"CPCPCPCPCPPCPCP"这样C和P随机组合的打印 4. 检查是否有其他途径擦除了TWS配对记录,如是否存在按键功能清除TWS配对记录,存在这种按键功能的时候很容易误触,尤其是触摸按键。不建议使用按键进行清除配对记录,可用测试盒串口配对功能替代 5. 是否开启了交叉配对功能,交叉配对功能允许配对后的耳机跟第三者配对,进而导致丢失原配的配对记录。不建议使用交叉配对功能,可用测试盒串口配对功能替代