soundcore APP流程解析
📎 原始文档:https://www.kdocs.cn/l/cnKuPxXqlZwi soundcore APP流程解析
整机框架
- APP交互

- 耳机状态主动上报
- 对耳间的状态变化 tws组队、回连:
soundcore_event_handler_deal.c:tws数据互相交互(更新对方的按键、同步eq参数等)
👇
soundcore_app.c:tws状态数据上报app
tws断开:
soundcore_app.c:tws状态数据上报app - 耳机电量变化 soundcore_event_handler_deal.c:对耳电量互相更新同步\单耳更新本地电量
👇
soundcore_app.c:电量数据上报app
指令说明(以soundcore A20i为例)
协议格式说明
| APP至设备 | ||
|---|---|---|
| Byte No | Value | Description |
| 0 | 0x08 | command header1 |
| 1 | 0xEE | command header2 |
| 2 | NN | Packet amount (reserved) |
| 3 | NN | Packet sequence ID (reserved) |
| 4 | 0 | resvered |
| 5 | NN | Command Group |
| 6 | NN | Command ID |
| 7 | NN | Command Length 0, which is lower byte of command length |
| 8 | NN | Command Length 1, which is higher byte of command length |
| 9 …. N-1 | NN | Optional. Command Parameter 1 … n bytes |
| N | NN | 前面N项之和,用1byte表示,范围0-255 |
| 设备至APP | ||
|---|---|---|
| Byte No | Value | Description |
| 0 | 0x09 | command header1 |
| 1 | 0xFF | command header2 |
| 2 | NN | Packet amount (reserved) |
| 3 | NN | Packet sequence ID (reserved) |
| 4 | NN | SuccessFlag(0x00: failed, 0x01: success, 0x02: checksum, 0x03: 通话状态 error) |
| 5 | NN | Command Group |
| 6 | NN | Command ID |
| 7 | NN | Command Length 0, which is lower byte of command length |
| 8 | NN | Command Length 1, which is higher byte of command length |
| 9 …. N-1 | NN | Optional. Response data 1 … n bytes |
| N | NN | 前面N项之和,用1byte表示,范围0-255 |
- 获取设备信息
获取设备全部信息
APP->耳机:0x08 0xEE 0x00 0x00 0x00 0x01 0x01 LL LH CS
耳机->APP:0x09 0xFF 0x00 0x00 0x01 0x01 0x01 LL LH NN CS
NN:
基础信息模块(32bytes): 设备连接手机状态(1byte) + tws连接状态(1byte) + 左耳设备电量(1byte) + 右耳设备电量(1byte) + 左耳设备充电状态(1byte) + 右耳设备充电状态(1byte) + 左FW(5byte)+ 右FW(5byte) + SN(16byte)
EQ模块(22bytes):EQ Index(2byte)+ CustomEQ(10bytes) + reserved(10byte)
CustomUI模块(1+N4+1 bytes):CustomUI模块(1+N4+1 bytes):CustomUI模块总长度(1byte) + [左耳设备XX是否响应(1byte) + 左耳设备XX按键功能(1byte) + 右耳设备XX是否响应(1byte) + 右耳设备XX按键功能(1byte)] + ANC当前模式(1byte)
扩展模块(20bytes): 充电盒电量(1byte) + bass up(1byte) + 设备颜色(1byte) + gaming状态(1byte) + 触控提示音开关状态(1byte) + reserved(没有发0xFF)
无法获取的数据统一回复0xFF,例如EQ、按键功能等信息。
其它数据的详细定义,请参照以下的各个指令对应的具体定义
CustomUI模块 总长度 = 1+N4+1 。 N4数组形式顺序为:单击/双击/长按。 (按键功能:unTWS与tws 按高低位组合出来的),这个项目没有controll开关,固件是否相应固定回复0x01
AN,
环境音切换状态(1byte)含义:按位处理- 0b00000111。后面3位代表:ANC、transprancy、normal的开关(1 = open,0=close)
EQ放大10倍传输。
双击和长按功能 1byte: 0000 0000 前4个为单耳时对应功能项,后4个为双耳时对应功能项。
共41个字节
扩展模块中 bass up 1byte,上报0xFF即可(12/22)
查询设备连接状态
APP->耳机:0x08 0xEE 0x00 0x00 0x00 0x01 0x02 LL LH CS
耳机->APP:0x09 0xFF 0x00 0x00 0x01 0x01 0x02 LL LH NN CS
NN:
设备连接手机状态(1byte) + tws连接状态(1byte)
设备连接手机状态:0x00:左耳设备连接手机;0x01:右耳设备连接手机。
tws连接状态:0x00:tws未连接;0x01:tws已连接
例如:0x0101表示右耳设备连接手机,且tws已连接,此时两个设备都处于连接状态;0x0100表示右耳设备连接手机,且tws未连接,则只有右耳处于连接状态,而左耳未连接。
当连接状态发生变化时,通过响应指令实时上报数据
获取设备电量等级
APP->耳机:0x08 0xEE 0x00 0x00 0x00 0x01 0x03 LL LH CS
耳机->APP:0x09 0xFF 0x00 0x00 0x01 0x01 0x03 LL LH NN CS
NN:
左耳设备电量(1byte) + 右耳设备电量(1byte) + 充电盒电量(1byte)
电量值:0~5,代表6个电量等级(低 -> 高),具体定义:0:1%~5%;1:6%~20%;2:21%~40%;3:41%~60%;4:61%~80%;5:81%~100%;当设备未连接时:0xFF。
例如:0x0000表示两个设备电量均为0;0x0103表示左耳设备电量为1,右耳设备电量为3;0xFF04表示左耳设备未连接,右耳设备电量为4。
百分比电量显示 0-9,分别对应10%-100%
例如:0x030900表示左耳电量为40%,右耳电量为100%,充电盒电量为10%
当电量发生变化时,通过响应指令实时上报数据。
获取设备充电状态
APP->耳机:0x08 0xEE 0x00 0x00 0x00 0x01 0x04 LL LH CS
耳机->APP:0x09 0xFF 0x00 0x00 0x01 0x01 0x04 LL LH NN CS
NN:
左耳设备充电状态(1byte) + 右耳设备充电状态(1byte)
充电状态:0x00:未充电;0x01:充电中。
当充电状态发生变化时,通过响应指令实时上报数据。
设置游戏模式
APP->耳机:0x08 0xEE 0x00 0x00 0x00 0x01 0x87 LL LH NN CS
耳机->APP:0x09 0xFF 0x00 0x00 0x01 0x01 0x87 LL LH CS
NN:
0x00 = close 0x01 = open
2. EQ
获取EQ信息
APP->耳机:0x08 0xEE 0x00 0x00 0x00 0x01 0x04 LL LH CS
耳机->APP:0x09 0xFF 0x00 0x00 0x01 0x01 0x04 LL LH NN CS
NN:
EQ Index(2bytes)
EQ Index:0~0xFFFF, 代表EQ的具体编码。APP需根据具体编码显示不同UI。
当EQ发生变化时,通过响应指令实时上报数据。
切换EQ(包含Custom EQ)和 生效后的EQ(支持DRC和非DRC)
APP->耳机:0x08 0xEE 0x00 0x00 0x00 0x02 0x83 LL LH NN CS
耳机->APP:0x09 0xFF 0x00 0x00 0x01 0x02 0x83 LL LH CS
NN:
EQ Index(2byte) + 设备EQ(10bytes) + 实际生效设备EQ(10bytes)
EQ Index:0~0xFFFF, 代表EQ的具体编码。固件只需存储,不需要解析。
设备EQ:10个频点的gain值。每个值:0~24,设备上是-12dB ~ 12dB,指令传送时转化为0~240)。固件只需存储,不需要解析
实际生效设备EQ:模拟DRC后计算出最终生效的10个频点gain值。每个值:0~24,设备上是-12dB ~ 12dB,指令传送时转化为0~240)
注*:固件只需关注实际生效设备EQ,当前产品只支持8个频点,10byte里面前8byte是有效值,后2byte是填充值;
EQ Index(2byte) + 设备EQ(10bytes) 需填充到设备全部信息的EQ模块
3. Custom UI
设置按键功能
APP->耳机:0x08 0xEE 0x00 0x00 0x00 0x04 0x81 LL LH NN CS
耳机->APP:0x09 0xFF 0x00 0x00 0x01 0x04 0x81 LL LH CS
NN:
左耳或右耳设备(1byte) + 按键动作(1byte) + 按键功能(1byte)
左耳或右耳设备:0x00:左耳设备;0x01:右耳设备
按键动作:范围:0~2;具体定义:0:双击;1:长按 2: 单击,3:从前到后滑动 4:从后向前滑动,5: 三击
功能数值:范围:0~0x0f;具体定义:0:Volume+;1:Volume-;2:Previous;3:Next;4:Trans(环境音);5:Siri;6:play/pause 7:Bass up on/off; 8:3D环绕 on/off;0x0f:无
重置按键功能
APP->耳机:0x08 0xEE 0x00 0x00 0x00 0x04 0x82 LL LH CS
耳机->APP:0x09 0xFF 0x00 0x00 0x01 0x04 0x82 LL LH CS
4. 更多
设置触控提示音开关状态
APP->耳机:0x08 0xEE 0x00 0x00 0x00 0x01 0x83 LL LH NN CS
耳机->APP:0x09 0xFF 0x00 0x00 0x01 0x01 0x83 LL LH CS
NN:
0x00 = close 0x01 = open
5. Server data
获取设备上报数据
APP->耳机:0x08 0xEE 0x00 0x00 0x00 0x05 0x01 LL LH CS
耳机->APP:0x09 0xFF 0x00 0x00 0x01 0x05 0x01 LL LH NN CS
NN:
低字节在前,高字节在后(收到APP发送0581的清除指令后才清除数据)
左耳控制次数(2byte)+右耳控制次数(2byte)
+左耳电量档位(1byte)+右耳电量档位(1byte)
+通话次数(2byte)
+通话时长(4 byte)
+媒体次数(2 byte)
+媒体时长(4 byte)
+双耳使用总时长(4 byte)+左耳单用使用总时长(4 byte)+ 右耳单用使用总时长(4 byte)
+TWS 时SBC次数(2 byte)+左耳单用时SBC次数(2 byte)+右耳单用时SBC次数(2 byte)
+TWS 时AAC次数(2 byte)+左耳单用时AAC次数(2 byte)+右耳单用时AAC次数(2 byte)
+TWS 时 SBC码率使用时长(4 byte) + 左耳单用时 SBC 码率使用时长(4byte) + 右耳单用时 SBC 码率使用时长(4byte)
+TWS 时AAC码率使用时长(4 byte) + 左耳单用时 AAC 码率使用时长(4byte) + 右耳单用时 AAC 码率使用时长(4byte)
清空设备上报的数据
APP->耳机:0x08 0xEE 0x00 0x00 0x00 0x05 0x81 LL LH CS
耳机->APP:0x09 0xFF 0x00 0x00 0x01 0x05 0x81 LL LH CS
NN:
将所有的计数统计置为0
模块说明
固件协议声明
统一的app协议格式,定义在soundcore_app.h中,具体见该头文件
指令长度

指令格式

指令解析(APP下发COMMAND GROUP及对应的COMMAND ID)
因此若APP协议有做更新,固件的头文件中的协议声明也需要同步更新
APP下发数据包格式解析
app下发数据相关处理统一入口在soundcore_app.c中
APP下发交互数据处理主干
/**
* @brief soundcore spp data deal主干
* @param ch ?
* @param *packet:数据包
* @param size:包长
* @return >= 0:成功 <0:异常
*/
int soundcore_spp_data_receive_cb(u16 ch, u8 *packet, u16 size)
APP下发交互数据解包
/**
* @brief 解包
* @param *packet:获取数据包指针
* @param len:获取数据包长度
* @return 0:成功 <0:异常
*/
static int soundcore_spp_data_receive(u8 *packet, u16 len)
APP交互事件翻译及分配
/**
* @brief 事件分配
* @return <0:异常 0:完成
*/
static int soundcore_spp_data_hander(void)
固件回复APP
/**
* @brief 发包拼接
* @param *data:处理结果数据
* @param data_have:是否有发送数据
* @return >0:成功,返回包长 <0:失败
*/
int soundcore_spp_data_send(u8 *data, u8 data_have)
APP事件固件本地处理
app事件固件本地相关处理统一入口在soundcore_event_handler_deal.c中
事件处理主干
/**
* @brief app事件执行主干
* @param app_event:app事件
*/
int soundcore_app_event_deal(struct soundcore_event *app_event)
{
/**
* @brief 事件数据翻译,将APP下发数据转换成对应的事件并推送给app_core处理
* @param app_command_event:app下发命令对应的事件
* @return 0:正常 <0:异常
*/
static int soundcore_spp_data_trans(u8 app_command_event)
}
固件设备信息相关事件入口
//设备信息处理主入口
static int soundcore_app_get_info_event(struct soundcore_event *app_event, u8 event)
{
//全信息入口
static int soundcore_app_get_all_info(u8 *data, u16 len)
//连接信息
case SOUNDCORE_EVENT_GET_CONNSTA_INFO
//电量信息
case SOUNDCORE_EVENT_GET_BATTERY_INFO
//充电信息
case SOUNDCORE_EVENT_GET_CHARGE_STATUS_INFO
//eq信息
case SOUNDCORE_EVENT_GET_EQ_INFO
}
//设置游戏模式
static int soundcore_app_set_gaming(struct soundcore_event *app_event)
EQ相关处理入口
eq相关处理统一入口在soundcore_event_eq_deal.c
//EQ相关流程主入口
//下发数据转换 EQ Index(2byte) + 设备EQ(10bytes) + 实际设备EQ(10bytes)
int soundcore_app_eq_event(struct soundcore_event *app_event, u8 key_event_type)
{
//APP更新EQ
static int soundcore_app_eq_deal(u8 *eq_data)
}
按键相关处理入口
按键相关处理统一入口在soundcore_event_key_deal.c
//按键相关流程主入口
//按键事件更新、重置
int souncore_app_key_event(struct soundcore_event *app_event, u8 key_event_type)
{
//按键设置
static void soundcore_app_key_table_update(u8 key_val, u8 key_index, u8 key_event, u8 update_type, u8 remote){
//更新按键表
case SOUNDCORE_EVENT_SET_KEY
//重置按键表
case SOUNDCORE_EVENT_RESET_KEY
}
}
Server data(埋点数据)
//埋点数据定时器
static void soundcore_buried_timer_deal(void)
流程解析
此处只引用函数名说明,具体结合上一节模块说明,具体实现见代码
APP数据下发
//收到数据后,进入数据处理主干
soundcore_spp_data_receive_cb()
//固件进行解包和收到的数据校验
soundcore_spp_data_receive()
//数据校验通过后,根据解包结果,固件进行APP下发数据和本地事件转换
soundcore_spp_data_hander()
//事件翻译,此处会根据soundcore_app.h内的数据协议规定设置对应事件的NN数据包长度
soundcore_spp_data_trans()
//推出event,并转入事件处理主干
soundcore_app_event_deal()
//根据拿到的event中的翻译出来的事件走对应的处理,处理完进行数据回复APP
soundcore_spp_data_send()
注意:此处EQ更新流程较为特殊,具体如下
EQ更新
soundcore_spp_data_trans()
//存储APP EQ数据,进行延时生效
soundcore_app_receive()
//固件立刻回复APP
soundcore_spp_data_send()
//800ms内无再次APP EQ更新,EQ开始生效
soundcore_app_eq_event()
按键相关
按键设置\按键重置:
//事件处理主干
soundcore_app_event_deal()
//按键设置
souncore_app_key_event()
//按键表更新
soundcore_app_key_table_update()
//tws状态下告知从机
tws_api_send_data_to_sibling()
触摸提示音开关
//事件处理主干
soundcore_app_event_deal()
//设置触摸提示音开关
soundcore_app_set_key_tone()
soundcore_lp_touch_key_tone_ctr()