BLE 的连接都是由主机在前篇所描述的广播扫描响应后主动发起连接请求去连接从设备。
最后还调用了 app_task_msg_hdl ,
至此 主机和从机连接成功,主机可以对从机进行操作,比如,查找从机Profiles Server UUID ,读写characteristic 等操作。
做为从机的防丢器端,会被动地等待主机的连接,当系统初始化并开启广播后就开始等待主机的连接,如果主机发送连接请求过来,GAP 层会做相应的处理,如果接受该连接请求,就会向APP 层发送 GAP_LE_CREATE_CONN_REQ_CMP_EVT 消息,
{GAP_LE_CREATE_CONN_REQ_CMP_EVT, (ke_msg_func_t) app_gap_le_create_conn_req_cmp_evt_handler},
app_gap_le_create_conn_req_cmp_evt_handler 里设置 TASK_APP 的任务状态为IDLE,环境角色为PERIPHERAL,并保存主机的相关信息
然后启用从机服务器的服务,关键代码如下:
if (APP_ADV == ke_state_get(TASK_APP))
{ //设置 TASK_APP 的任务状态为IDLE,环境角色为PERIPHERAL
ke_state_set(TASK_APP, APP_IDLE);
app_set_role(GAP_PERIPHERAL_SLV);
}
else
{
app_set_role(GAP_CENTRAL_MST);
}
if (param->conn_info.status == CO_ERROR_NO_ERROR)
{ //保存主机的相关信息
app_set_link_status_by_conhdl(param->conn_info.conhdl, ¶m->conn_info, true);
// 使能从机服务器的服务
#if (BLE_PERIPHERAL)
app_enable_server_service(true, param->conn_info.conhdl);
#endif
}
app_task_msg_hdl(msgid, param);
最后还调用了 app_task_msg_hdl ,
case GAP_LE_CREATE_CONN_REQ_CMP_EVT:
if(((struct gap_le_create_conn_req_cmp_evt *)param)->conn_info.status == CO_ERROR_NO_ERROR)
{
if(GAP_PERIPHERAL_SLV == app_get_role())
{
//清除APP_ADV_INTV_UPDATE_TIMER 定时器,该定时器用意为开始广播30S 后变为慢速广播
//避免长时间无主机连接,而又一直频繁广播,浪费不必要的功耗
ke_timer_clear(APP_ADV_INTV_UPDATE_TIMER, TASK_APP);
//主机已连接上从机,设置LED1为常亮
usr_led1_set(LED_ON_DUR_CON, LED_OFF_DUR_CON);
//如果主机的连接时间过于频密,更新连接时间
if (((struct gap_le_create_conn_req_cmp_evt *)param)->conn_info.con_interval < GAP_PPCP_CONN_INTV_MIN)
{
// Update connection parameters here
struct gap_conn_param_update conn_par;
/// Connection interval minimum
conn_par.intv_min = GAP_PPCP_CONN_INTV_MIN;
/// Connection interval maximum
conn_par.intv_max = GAP_PPCP_CONN_INTV_MAX;
/// Latency
conn_par.latency = GAP_PPCP_SLAVE_LATENCY;
/// Supervision timeout, Time = N * 10 msec
conn_par.time_out = GAP_PPCP_STO_MULT;
app_gap_param_update_req(((struct gap_le_create_conn_req_cmp_evt *)param)->conn_info.conhdl, &conn_par);
}
}
}
break;
至此 主机和从机连接成功,主机可以对从机进行操作,比如,查找从机Profiles Server UUID ,读写characteristic 等操作。
在struct gap_le_create_conn_req_cmp_evt 里面我们得知BLE 的连接参数如下
struct gap_link_info { /// 确认状态:0x00表示连接成功,其他表示连接失败 uint8_t status; /// 连接句柄 uint16_t conhdl; /// 对方设备的地址类型:0x00(Public) 0x01(Random) uint8_t peer_addr_type; /// 对方设备的地址 struct bd_addr peer_addr; ///连接的时间间隔 uint16_t con_interval; /// 连接的潜伏期 uint16_t con_latency; ///链接超时 uint16_t sup_to; /// Master 的时钟精度 uint8_t clk_accuracy; }
这里比较重要的是
1. con_interval; ///连接的时间间隔
连接事件的时间间隙为1.25ms 的倍数 在7.5ms~4S 之间
2.con_latency; /// 连接的潜伏期
连接的潜伏也是为1.25ms 的倍数 在7.5ms~4S 之间,
3.sup_to ///链接超时
链接超时时间为10ms 的倍数,在100ms~32S 之间
BLE 的连接事件
连接建立后所有的通信都在两个设备的连接事件 ,连接事件周期地发生,按照连接参数的时间间隙发生连接通信,如下图
con_interval 时间间隔设定小时,两设备都会以较高功耗运行,通信频密,数据吞吐量高,数据延时小;反之,时间间隔设定大时,两设备都会以较低功耗运行,通信疏密,数据吞吐量低,数据延时大。
con_latency 潜伏期设定小,功耗相对提高,但设备可以快速收到主设备发来的数据。反之,设定较大,从设备在没有数据发送的情况下,可以与较低的功耗运行,从设备不能无法及时收到主设备发来的数据,主设备能及时收到从设备的数据。