GFP谷歌快连及其认证流程指引
📎 原始文档:https://www.kdocs.cn/l/cdHBXEhCW2Mq GFP谷歌快连及其认证流程指引
官方文档说明指引
快速配对 3.2 认证指南 (v2.0) | Fast Pair | Google for Developers
说明
概览
The Google Fast Pair Service (GFPS) utilizes Bluetooth Low Energy (BLE) to discover nearby Bluetooth devices without using significant phone battery, enabling “magical” scenarios based on device proximity.
即基于BLE广播实现手机发现耳机并弹窗,使得用户可以在手机上进行快速配对的功能
自测APP
Fast Pair Validator
使用说明参考如下官方说明:
音频切换验证器应用用户手册 | Fast Pair | Google for Developers
环境搭建
快速配对帮助 | Fast Pair | Google for Developers
手机需要科学上网,然后在设备中打开包含调试结果(不同手机,该配置项的位置可能会有点不一样,以下仅供参考)



代码填写用的Model ID和Private\Public Key
申请Model ID的时候如果没有特殊需求建议填3.1的GFP版本号,ini pair/auto pair, sub pair, calib, e2e四项用app测,剩下的手测。
谷歌官方给到的密钥是Base64转换后得到的,因此填入代码中的内容需要经过Base64转十六进制填入BUFFER,此处提供如下在线工具
Base64与十六进制互转 - 在线工具 (toolhelper.cn)

调整GFP的弹窗距离
- 确认好样机的RF性能符合要求,且无异常
- 调整BLE广播包的TxPower和BLE本身的发射功率
- TxPower计算方式
谷歌手机将自身位置的TxPower假设为0dB,以1m距离做41dBm的信号强度衰减
因此此处需要结合手机本身和耳机本身的rf,调节耳机的BLE发射功率,配合BLE广播包中的TxPower - TxPower测试方式参考 官方提供的自测APP(Fast Pair Validator)中存在该测试项,当账号测试群组中添加申请耳机的资料找到对应的Model ID后,点击对应的设备进入后,可看见如下页面
其中Calibration即提供测试TxPower及相应的BLE发射功率在该手机上是否能符合预期距离
注:自测APP的测试TxPower数值大小,仅提供调试方向,具体距离以实际弹窗测试距离为准 - 代码调试方向 结合第3点计算方式,即当BLE广播中的TxPower数值越小,手机会认为耳机的发射功率本身越低,则在相同距离下会越容易弹窗。
因此首先:根据实际弹窗情况调用接口调整耳机的BLE广播包中的TxPower,且用nrf connect确认好
BLE广播包中的TxPower确实更新
void gfps_tx_power_set(u8 value)//需要BLE广播包开启前调用设置
可视化的设置TX POWER函数如下:
extern void gfps_tx_power_set(u8 value)
当TxPower为最大0xff下,耳机在1.2m外依然容易弹窗,此时修改BLE本身的tx power,并重新调整BLE广播包中的tx power以达到GFP认证标准
初始配对广播和后续配对广播
初始配对广播:耳机未连接手机或者耳机回连超时后开启,广播包中仅带有Model ID和TxPower,用于未绑定耳机的谷歌账号进行初次配对,调用接口如下:
void gfps_set_pair_mode(void *priv)
后续配对广播:当耳机在A手机上同谷歌账号绑定设备后,耳机的GFP广播包变为后续配对广播,用于登陆与A手机相同谷歌账号的B手机弹窗已绑定设备用,不调用gfps_set_pair_mode()接口即为后续配对广播
注:GFP认证会要求耳机有按键操作可以在绑定后的情况下重新打开初始配对广播,不支持一拖多的耳机,如果用户在另一台登陆了谷歌账号的手机上点击初始配对广播,需要耳机断开已连接的手机,以便连接新手机
耳机连接后的电量弹窗
协议如下:
代码中控制接口为:
void gfps_set_battery_ui_enable(uint8_t enable)
默认流程中支持GFP的手机连接耳机后,会连接到GFP的SPP通道,此时会打开电池电量广播
头戴式耳机不需要弹电量框
TWS入仓关盖需要添加消窗流程,维持1秒以上
gfps_set_battery_ui_enable(0);
GFP自定义设备名
耳机与谷歌账号绑定后,用户可在手机蓝牙界面修改耳机的设备名,该设备名为谷歌手机连接专用的设备名。
GFP认证要求存在按键操作可以在用户修改设备名后恢复默认的设备名,调用如下接口:
void gfps_all_info_recover(void);//报错就用下面的函数
void gfps_factory_reset(void);
可视化的SDK,使用下面这句
//extern void gfps_all_info_recover(u8 name_reset);
gfps_all_info_recover(1)
demo代码
700N/701N普通SDK进入GFP配对的demo
extern void gfps_set_pair_mode(void);
static u16 gfp_check_pair_timer = 0;
void gfp_check_pair(void *p)
{
printf("%s %x\n", __func__, tws_api_get_tws_state());
if((tws_api_get_tws_state() & TWS_STA_PHONE_DISCONNECTED) && (tws_api_get_role() == TWS_ROLE_MASTER)){
sys_timer_del(gfp_check_pair_timer);
gfp_check_pair_timer = 0;
bt_user_priv_var.auto_connection_counter = 0;
tws_cancle_all_noconn();
user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_ENABLE, 0, NULL);
user_send_cmd_prepare(USER_CTRL_WRITE_CONN_ENABLE, 0, NULL);
gfps_set_pair_mode();
}
if(tws_api_get_role() != TWS_ROLE_MASTER){
sys_timer_del(gfp_check_pair_timer);
gfp_check_pair_timer = 0;
}
}
//使用此函数进入gfp配对状态
void user_ctrl_bt_enter_gfp_pair_mode(void)
{
if(tws_api_get_role() != TWS_ROLE_MASTER){
return;
}
if((tws_api_get_tws_state() & TWS_STA_PHONE_CONNECTED) || hci_standard_connect_check()){
user_send_cmd_prepare(USER_CTRL_PAGE_CANCEL, 0, NULL);
user_send_cmd_prepare(USER_CTRL_CONNECTION_CANCEL, 0, NULL);
user_send_cmd_prepare(USER_CTRL_POWER_OFF, 0, NULL);
}
if(gfp_check_pair_timer == 0){
gfp_check_pair_timer = sys_timer_add(NULL, gfp_check_pair, 200);
}
}
可视化SDK进入GFP配对的demo
void gfps_set_pair_mode_by_user(u8 disconn_ble);
static u16 gfp_check_pair_timer = 0;
void gfp_check_pair(void *p)
{
printf("%s %x\n", __func__, tws_api_get_tws_state());
if(tws_api_get_tws_state() & TWS_STA_PHONE_DISCONNECTED){
sys_timer_del(gfp_check_pair_timer);
gfp_check_pair_timer = 0;
gfps_set_pair_mode_by_user(1);
}
}
//使用此函数进入gfp配对状态
void user_ctrl_bt_enter_gfp_pair_mode(void)
{
if(tws_api_get_role() != TWS_ROLE_MASTER){
return;
}
if(tws_api_get_tws_state() & TWS_STA_PHONE_CONNECTED){
bt_cmd_prepare(USER_CTRL_PAGE_CANCEL, 0, NULL);
bt_cmd_prepare(USER_CTRL_CONNECTION_CANCEL, 0, NULL);
bt_cmd_prepare(USER_CTRL_POWER_OFF, 0, NULL);
}
if(gfp_check_pair_timer == 0){
gfp_check_pair_timer = sys_timer_add(NULL, gfp_check_pair, 200);
}
}
常见问题
- 可视化SDK后续配对报错Frequency超范围 Frequency of BLE advertisements (573) is higher than threshold (500) while not in pairing mode
调整后续配对广播时间为150
#define SUBS_PAIR_ADV_INTERVAL 150
- 700N普通SDK GFP需要替换库 公版的库在gfp认证测试过程中会出现从机回连手机的问题,需要替换下面的库rebuild:
btstack-SDK-700N v138修改gpf测试断开产生回连.zip - 可视化SDK电量显示异常问题


if (tws_api_get_role() == TWS_ROLE_MASTER) {
gfps_ble_adv_enable(0);
u8 buf[8];
buf[0] = get_gfps_pair_state();
buf[1] = gfps_rfcomm_connect_state_get();
memcpy(buf + 2, app_ble_adv_addr_get(gfps_app_ble_hdl), 6);
gfps_sibling_data_send(GFPS_SIBLING_SYNC_TYPE_ADV_MAC_STATE, buf, sizeof(buf));
printf("gfps_send_pair_state:%d, spp_state:%d, ble_addr:", buf[0], buf[1]);
put_buf(buf + 2, 6);
}
- 可视化GFP需要电量按照10%间隔显示的修改

- 非对耳,GFP“让设备响铃”无法点击的问题
解决方法:GFP返回的第一个电量值要传0XFF
非可视化:
可视化:
- 谷歌手机连接wifi出现网络受限 修正手机日期即可
- 手机不弹窗问题排查
- 先保证耳机有配对广播出来,配对广播如下,如果没有广播就看demo代码、代码填写用的Model ID和Private\Public Key

- 按照环境搭建配置好手机端环境
- 避免频繁手动消窗,手机机制会导致不弹窗,这种情况要重启手机
- 打开GFPS的库打印

- 700N普通SDK,gfp连上后还会弹窗的问题 连接手机成功时修改一下广播类型
case BT_STATUS_FIRST_CONNECTED:
extern void gfps_enter_nopair_mode();
gfps_enter_nopair_mode();
- ANC 耳机,页面显示ANC状态,但点击耳机没有响应以及耳机操作ANC后,页面没有更新
在切换ANC的位置进行上报 - Android 15无法弹窗问题(要开开发者选项和包含调试结果)

