TLSR827x FindMy网络SDK
SDK介绍
Telink Find My Network Accessories SDK是基于Apple Find My Network ADK开发的应用方案,并已经通过Apple Find My Network Self-Certification Test Cases认证测试,用户可以基于此SDK快速开发FMN Accessory完整功能应用产品的方案。目前泰凌微TLSR9和TLSR827X系列芯片都已经实现Find My Network Accessories (FMNA)方案,接下来详细介绍基于TLSR827X的Find My Network Accessories SDK方案。
SDK组织架构
文件结构
在IDE中导⼊Telink Find My Network Accessories SDK后,显示的文件组织结构如下图所示(以telink_b87_fmn_sdk为例)。顶层文件夹有10个:algorithm、application、boot、common、crypto、drivers、proj_lib、stack、UARPDK、vendor。
algorithm:提供一些通用的算法,如aes_ccm。大多数算法对应的C文件被封装在库文件中,只留对应的头文件。
application:提供一些通用的应用处理程序,如print、keyboard等。
boot:提供MCU的software bootloader,即MCU上电启动或deep sleep唤醒后的汇编处理程序,为后面C程序的运⾏做准备。
common:提供一些通用的跨平台的处理函数,如内存处理函数、字符串处理函数等。
crypto:包含开源的第3方的mbedtls标准算法库,并提供FMN ADK中的crypto接口实现以及sample测试。
drivers:提供MCU外设驱动程序,如Clock、Flash、I2C、USB、GPIO、UART等。
proj_lib:存放SDK运⾏所必需的库文件。BLE协议栈、RF驱动、PM驱动等文件被封装在库文件中。
stack:存放 BLE 协议栈相关的头文件。源文件被编译到库文件里面,对于用户不可见。
UARPDK:用于FMN UARP功能的底层逻辑实现。
vendor:用于存放demo code或者用户自己的code。
vendor目录下有3个工程:b85m_demo、b85m_feature、b85m_slave。目前仅在b85m_slave上支持FMN功能。Vendor目录还包含common、platform文件夹。
main.c
main.c文件中包含main函数和中断处理函数。main函数是程序执⾏的入口,包含了系统正常工作所需的配置,考虑到程序进入deep retention的功耗,建议用户不要对它进⾏任何修改。中断处理函数是系统触发中断时候的入口函数。
app_config.h
这是用户配置文件,用于对整个系统的相关参数(例如:BLE参数、GPIO配置、低功耗使能/失能、加密使能/失能等)进⾏配置。
后面介绍SDK配置时会对app_config.h中的各个参数的含义进⾏详细说明。
Application文件
app.c:用于完成BLE系统初始化、事件/数据处理、低功耗处理、FMNA初始化、mainloop处理等。
app_att.c:这个文件提供了GATT service表和profile,GATT service表中已提供了标准的GATT服务、标准的GAP服务、FMNA相关服务等。用户可以参考这些添加自己的service和profile。
app_ui.c:该文件主要提供了按键功能。
app_buffer.c:该文件用于定义stack各层使用的buffer,例如:Link Layer TX & RX buffer、L2CAP layer MTU TX & RX buffer、HCI TX & RX buffer等。
app_opt.c:该文件用于CPU唤醒初始化、rf drv初始化等。
battery_check.c:该文件用于电池电量检测,低电处理。
FMNA文件
fmna_adv.c:用于fmna广播包内容的设置。
fmna_akm_platform.c:用于fmna key的store和restore。
fmna_config_control_point.c:用于fmna相关参数、状态的设置,声音播放/暂停,以及解除配对等命令交互。
fmna_connection.c:用于fmna连接、断开状态的切换、查询、判断,以及解除配对逻辑处理等。
fmna_crypto.c:用于fmna crypto的初始化,pairing流程的数据处理,fmna key的生成机制,serial number的处理逻辑等。
fmna_debug_control_point.c:用于在debug模式下,工具app FMCA对FMNA设备的参数设置,log获取等。
fmna_gatt.c:fmna通过BLE GATT进行write request和indicate交互操作的回调函数实现等。
fmna_motion_detection.c:fmna设备在separated状态下motion detection的处理实现等。
fmna_nfc.c:用于NFC的初始化,NFC url key的获取和更新等。
fmna_nonowner_control_point.c:用于non-owner控制fmna设备播放、暂停声音等。
fmna_paired_owner_control_point.c:用于owner从fmna设备获取current primary key、iCloud ID、serial number等。
fmna_pairing_control_point.c:用于fmna设备处理pairing命令。
fmna_state_machine.c:用于状态机的逻辑实现、包含boot、pair、separated、nearby、connecting、fmna pair、fmna pair complete、connected、disconnecting等事件处理。
fmna_version.c:用于fmna version的初始化和获取。
./UARP/fmna_uarp_control_point.c:用于uarp初始化、连接、断开、收发包处理等。
./UARP/FMNASampleUARP.c:用于fmna smaple初始化、controller add/remove、message收发、buffer malloc/free、查询固件信息、固件存储等。
platform文件
fmna_adv_platform.c:用于fmna实现设置fmna pair、separated、nearby 3种状态广播内容。
fmna_battery_platform.c:用于获取电量等级。
fmna_connection_platform.c:用于主动断开、请求sec info、获取serial number、token存flash等。
fmna_gatt_platform.c:用于fmna实现indicate逻辑。
fmna_malloc_platform.c:用于实现malloc和free功能。
fmna_motion_detection_platform.c:用于硬件模拟实现motion detection功能。
fmna_sound_platform.c:用于硬件模拟实现声音播放、暂停的功能。
common文件
app_sched.c:用于事件调度器的实现方案。
blt_common.c:用于蓝牙设备mac地址的设置。
blt_fw_sign.c:用于固件签名检查。
blt_led.c:基于硬件实现的LED控制逻辑。
blt_soft_timer.c:用于软件定时器的实现。
common_dbg.c:用于低功耗下硬件debug串口初始化。
custom_pair.c:用于绑定设备的信息处理、mac地址管理等。
device_manage.c:用于连接设备信息的管理(例如:connection handle、attribute handle、BLE device address、address type等)。
flash_fw_check.c:用于固件crc检查。
nfc.c:用于nfc功能的实现。
simple_sdp.c:用于Master的SDP(Service Discovery Protocol)功能的实现。
tl_audio.c:用于audio设备的数据格式转换。
BLE stack entry
BLE中断处理入口函数是blc_sdk_irq_handler()。
BLE逻辑和数据处理入口函数是blc_sdk_main_loop(),它负责处理BLE协议栈相关的数据和事件。
Software bootloader介绍
Telink FMN SDK中,不同型号的MCU对应不同的bootloader文件。bootloader文件存放在boot文件夹下。Telink FMN SDK的bootloader文件是由两部分构成,link文件和cstartup.S汇编文件。
bootloader文件
Telink FMN SDK的bootloader文件如下图所示:
Telink FMN SDK中的link文件有两个,boot.link(支持suspend mode)和boot_32k_retn.link(支持 suspend mode和deep sleep retention mode)。
注意:
- 编译工程时,真正生效的link文件是b85m_ble_sdk/boot.link。
- Telink FMN SDK只支持boot_32k_retn.link,且b85m_ble_sdk/boot/boot_32k_retn.link的内容已经默认拷贝到b85m_ble_sdk/boot.link中。
Telink FMN SDK中的cstartup.S文件依据芯⽚SRAM资源⼤⼩而不同。每种MCU对应2个cstartup.S文件,‘RET_32K’表示支持deep sleep retention 32K mode。由于8273与8278的SRAM都是64 KB,所以它们的cstartup.S文件完全相同,统一用8278的配置。
注意:
Telink FMN SDK只支持RET_32K模式。
以827x_slave,MCU选择8278为例,用户设置对应的cstartup.S文件⽅法如下:
在boot/8278文件夹下找到“cstartup_8278_RET_32K.S”文件,在该文件中找到宏 MCU_STARTUP_8278_RET_32K,然后在工程的属性设置窗口中按下图所示的⽅式配置即可。
Library 介绍
Telink FMN SDK配置project对应的library如下图所示。
注意:
Telink FMN SDK目前只支持liblt_8278_m0s4.a这个库。
SDK配置
SDK工程编译配置
SDK工程编译配置:827x_slave。
Flash配置
Flash配置:默认支持是1MB flash(可缩小至512KB flash)。
RAM配置
RAM配置:RAM为64KB,其中Deep Retention RAM为32KB。
多连接模式
多连接模式:默认支持0路master + 2路slave。
SMP配置
SMP配置:SMP默认打开,SMP等级:just work。
PM配置
PM配置:PM使能,并支持deepsleep_retention。
LED配置
LED配置:默认打开,用于LED开关动作模拟FMNA的声音播放、暂停功能。
Software timer配置
Software timer配置:默认打开,需要支持FMNA多种定时器设定,目前最大支持16个定时器任务。
Debug功能
Debug功能:默认关闭,但必须在使用工具app FMCA做test case测试才打开。
Motion detection配置
Motion detection配置:默认打开,使用GPIO高低电平模拟motion动作。
NFC功能
NFC功能:可选配置,8278由于retention RAM资源有限,目前暂不支持NFC功能。
UARP功能
UARP功能:默认支持,需在使用工具app FMCA做test case验证固件升级功能。
低电检测功能
低电检测功能:默认支持,电量低于设定阈值时需要停止广播,并关机。
低电检测GPIO配置
事件调度配置
事件调度配置:最大支持处理4个event,8个队列缓冲。
串口调试功能
a. 串口调式功能配置:使能宏UART_PRINT_DEBUG_ENABLE,打开串口log打印功能。
b. 串口参数设置:支持1Mbps波特率,GPIO口设置为PB0。
c. UARP调试功能配置:使能UART_PRINT_DEBUG_ENABLE后,再关闭UARP_DISABLE_LOGS和UARP_DISABLE_REQUIRE_LOG,即可开启调试UARP功能。
系统主频配置
系统主频配置:支持12M、16M、24M、32M、48M,单位Hz,建议用户使用默认值32M,此值过小影响算法运行速度,过大影响低功耗。
DLE和MTU设置
DLE和MTU设置:DLE默认值为200,MTU默认值为200。
RF power设置
RF power设置:按FMN协议要求默认配置为4dBm。
SDK flash布局
a. Mac地址:0xFF000,大小8 bytes。频偏地址:0xFE000,大小根据用户需求设定(512 bytes范围内)。
b. SMP pairing key:0xF2000 - 0xF5000,大小16KB,正常配对使用前8KB,配对次数过多,会使用到接下来的8KB backup区域。
c. Telink FMN功能相关数据存储
-
Primary key地址:0xF7000 - 0xF8000,大小8KB, 0xF8000只是作为primary key的备份区域。
-
secondary key地址:0xF6000, 大小4KB。
-
software auth uuid地址:0xF9000, 大小16 bytes。
-
software auth Token地址:0xF9010, 大小1040 bytes。
-
icloud id 地址:0xF9600, 大小60 bytes。
-
M_P key地址:0xFA000, 大小57 bytes。
-
Shared secret key地址:0xFA100, 大小 32 bytes。
-
Current separated key地址:0xFB000, 大小28 bytes。
SDK功能
FMN profile
Accessory information service
Service uuid: 87290102-3C51-43B1-A1A9-11B9DC38478B
Characteristics uuid: 6AA5XXXX-6352-4D57-A7B4-003A416FBB0B
Find My network service
Service uuid: 0xFD44
Characteristics uuid: 4F86XXXX-943B-49EF-BED4-2F730304427A
Firmware update service
Service uuid: 0xFD43
Characteristics uuid: 94110001-6D9B-4225-A4F1-6A4A7F01B0DE
Pairing命令处理逻辑
FMNA_SERVICE_OPCODE_INITIATE_PAIRING
由于retention ram不够,设备在接收到发起配对命令,关闭deep retention功能,保证配对过程中所有的变量内容保持不变,并从flash中读取token用于配对。
FMNA_SERVICE_OPCODE_FINALIZE_PAIRING
用来给Apple设备验证和确认配对(包含accessory验证S2,解密E3,生成C3,生成E4,发送pairing status给owner设备等步骤)。
FMNA_SERVICE_OPCODE_PAIRING_COMPLETE
计算primary key 和 secondary key,并启动key rotate定时器定时生成key,pairing完成后使能deep retention功能,降低功耗。
声音播放和暂停来指示物品位置
Owner控制播放和暂停命令处理逻辑
Non-Owner控制播放和暂停命令处理逻辑
声音播放和暂停处理
声音播放、暂停处理是通过LED亮灭进行模拟演示,用户需要实现此功能。
Motion detection功能
开启Motion检测
Motion检测方法
通过gpio口模拟演示motion detect,用户需要实现此功能。
检测到motion后的处理逻辑
会判断motion检测次数超过10次后,就切换到backoff模式检测,如果未超过10次则在20秒超时后进入backoff模式检测。
检测切换到backoff模式
Unwanted tracking检测
Unwanted tracking detection功能用来通知用户存在一个无法识别的accessory可能会跟随移动,用户可以通过蓝牙控制播放声音来找到这个accessory。
UARP升级固件
UARP接口初始化
UARP收包处理
由于retention ram不够,设备在收到第一个包后,关闭deep retention功能,保证固件升级过程中,所有变量内容保持不变,收到包后对数据做组包(append)处理。
UARP组包后的数据处理
对组包后的数据进行处理完成后,并清除数据接收buffer。
UARP组包数据写入flash
在收到固件数据时,每接收到512 bytes,会写入flash。由于程序运行到写第一笔数据位置时,意味着固件版本等信息已经确认无误,可以继续升级,此时为保证固件升级速度和正常执行,程序会关闭睡眠不进入sleep,故此处恢复deep retention功能以防止OTA异常时无法进入deep retention。
UARP response
数据处理完毕后,发送response给owner设备。
UARP接收完固件后的重启处理
固件数据接收完成后,执行重启。
SDK模块
mbedtls算法库
它是一套开源的算法库,实现了加密算法、X.509证书操作以及SSL/TLS和DTLS协议,并提供PSA加密的API规范的参考实现。Telink FMN SDK中用到了其中的sha256(hash计算),ANSI x9.63 KDF(key计算生成),NIST P-224 elliptic curve(椭圆曲线点的计算和校验),ECDSA/ECDH(签名验证),AES-128-GCM(加解密)等算法功能。
fm-crypto函数接口
FMN应用层主要是通过fm-crypto.c这个文件的函数转接口(如下图所示)来调用到mebedtls这个算法库,实现配对和加解密、签名验签、key生成、hash计算等逻辑操作。
状态机
FMN状态机
Accessory操作可以使用状态机来描述,它们之间进行的转换是基于accessory与owner设备的交互逻辑。
FMN unpaired event handlers
Unpaired:在第一次上电启动后或在accessory配对完成之前,accessory必须处于未配对状态。 在这种状态下accessory必须将Find My network service作为connectable 广播包中的primary service。用户在owner设备发起配对,accessory随后进入配对流程。
FMN连接和配对
Connected:与owner设备配对成功后,accessory必须进入connected状态。配对完成后,owner设备可能会断开与accessory的连接。一旦配对,该accessory不能与其它Apple设备配对。它必须保持配对,直到它成功地完成与owner设备的解配对过程。Accessory必须从nearby或separated状态或当owner设备连接时重新进入connected状态。accessory可以同时连接到同一iCloud账户上的两个Apple设备。Motion detection 和 unwanted tracking detection协议在connected状态下不可用。当accessory进入connected状态时,广播payload应该设置成nearby key。如果链路加密没有在10秒内完成,则配对的accessory必须断开连接。
注意:
pairing过程也属于connected状态机的一部分。
FMN Nearby
Nearby:accessory在断开owner设备后必须立即进入nearby状态。accessory在设定的时间内(默认15分钟)保持nearby状态。Motion detection 和 unwanted tracking detection协议在nearby状态下不可用。当accessory进入此状态时,广播payload应该设置成nearby key。
FMN Separated
Separated:accessory在2种条件下进入separated状态:1. accessory已配对,并从复位、上电重新初始化启动。 2. accessory在nearby状态超时后进入separated状态。Motion detection 和 unwanted tracking detection协议在separated状态下可用。当accessory进入separated状态时,广播payload应该设置成primary或者secondary key。
SDK流程
配对流程图
具体配对流程
Generate pairing data:在蓝牙连接配对后,accessory在收到owner设备发送的initiate pairing data后会生成pairing data中的C1并启动pairing过程,再生成每个配对会话的密钥种子(SeedK1),然后由输入参数(SessionNonce, Software auth token, Software auth UUID, Serial Number, Product Data, FW Version, E1, SeedK1)经加密密钥(Q_E)加密生成pairing data中的E2。
注意:
accessory必须为每次配对任务重新生成SeedK1。
Send pairing data:accessory通过ble indicate发送前一个步骤生成的pairing data(包含C1 和 E2)。
Finalize pairing:owner设备发送finalize pairing data给到accessory,并启动最终的配对过程,以完成配对。
Validate and confirm pairing:accessory解析finalize pairing data。accessory使用签名验证密钥(Q_A)验证finalize pairing data中的签名(S2),解密finalize pairing data中的E3获得apple server下发的new token,并根据finalize pairing data中的C2生成pairing status中的C3,把new token以及其他参数(Software auth UUID, Serial Number, SessionNonce, E1, Status)组装并加密生成pairing status中的E4,最后accessory保存new token到flash,以用于下一次配对。
Send pairing status: accessory 通过ble indicate 接口发送由前一个步骤生成的pairing status(包含C3 和 E4)。Owner设备收到pairing status后即可确认此前下发的new token是否被accessory完整接收到,以此判断pairing是否成功。
Pairing complete:owner确认pairing成功,并下发pairing complete给accessory。accessory会设置paired 标志位,并进入nearby状态,再生成Primary 和 secondary key并启动 key rotate定时器以此开启Primary 和 secondary key的迭代。