290 lines
7.7 KiB
C
290 lines
7.7 KiB
C
#include "include.h"
|
||
#include "bsp_ble.h"
|
||
#include "protocol_device.h"
|
||
#include "app_variable.h"
|
||
#include "bsp_sys.h"
|
||
#if LE_EN
|
||
|
||
#define TRACE_EN 0
|
||
|
||
#if TRACE_EN
|
||
#define TRACE(...) printf(__VA_ARGS__)
|
||
#else
|
||
#define TRACE(...)
|
||
#endif
|
||
|
||
|
||
const bool cfg_ble_security_en = LE_PAIR_EN;
|
||
bool cfg_ble_sm_sc_en = LE_SM_SC_EN;
|
||
bool cfg_bt_ble_adv = LE_ADV_POWERON_EN;
|
||
|
||
#if LE_SM_SC_EN
|
||
//我方作为从机进行BLE加密时,延迟发送Pairing Confirm Value,避免出现手机计算慢而直接回复Pairing Failed
|
||
//目前测试到需要进行配置的机型有iPhone6s
|
||
//建议配置值:80,单位:ms
|
||
uint32_t cfg_ble_send_confirm_delay = 0;
|
||
#endif
|
||
|
||
static ble_gatt_characteristic_cb_info_t *characteristic_cb_info[LE_ATT_NUM] AT(.ble_cache.att);
|
||
static uint8_t gatts_profile_table[LE_ATT_NUM * 10] AT(.ble_cache.att);
|
||
ble_cb_t ble_cb;
|
||
|
||
int hid_report_write_callback(uint16_t con_handle, uint16_t handle, uint32_t flag, uint8_t *buffer, uint16_t buffer_size){ return 0;}
|
||
|
||
void bt_get_local_bd_addr(u8 *addr);
|
||
|
||
//上电默认BLE广播的间隔
|
||
uint16_t ble_get_adv_pwron_interval(void)
|
||
{
|
||
return 0x60; //625us * 90 = 60ms
|
||
}
|
||
|
||
//可重定义该函数修改ble地址类型
|
||
u8 ble_get_local_addr_mode(void)
|
||
{
|
||
#if LE_SM_SC_EN
|
||
return GAP_RANDOM_ADDRESS_TYPE_OFF;
|
||
#else
|
||
return GAP_RANDOM_ADDRESS_TYPE_STATIC;
|
||
#endif
|
||
}
|
||
|
||
//ble通知蓝牙线程回调
|
||
void ble_emit_notice(ble_cb_enum evt, u8 *param)
|
||
{
|
||
u16 interval, latency, timeout;
|
||
switch (evt) {
|
||
|
||
case LE_NOTICE_CONNECTED: {
|
||
interval = param[14] | (param[15] << 8);
|
||
latency = param[16] | (param[17] << 8);
|
||
timeout = param[18] | (param[19] << 8);
|
||
ble_cb.ble_connected = true;
|
||
ble_app_connect_callback();
|
||
// printf("LE_NOTICE_CONNECTED: interval: %d, latency: %d, timeout: %d\n",
|
||
// interval, latency, timeout);
|
||
|
||
msg_enqueue(EVT_READY_EXCHANGE_MTU);
|
||
|
||
/* Bt scan is automatically opened after BLE connection */
|
||
msg_enqueue(EVT_BT_SCAN_START);
|
||
}
|
||
break;
|
||
|
||
case LE_NOTICE_DISCONNECT:
|
||
ble_cb.ble_connected = false;
|
||
ble_app_disconnect_callback();
|
||
// printf("LE_NOTICE_DISCONNECT:%x\n", param[5]);
|
||
break;
|
||
|
||
case LE_NOTICE_CONN_PARAM_UPDATE: {
|
||
interval = param[6] | (param[7] << 8);
|
||
latency = param[8] | (param[9] << 8);
|
||
timeout = param[10] | (param[11] << 8);
|
||
// printf("LE_NOTICE_CONN_PARAM_UPDATE: interval: %d, latency: %d, timeout: %d\n",
|
||
// interval, latency, timeout);
|
||
}
|
||
break;
|
||
|
||
case LE_NOTICE_DATA_LEN_CHANGE: {
|
||
uint16_t max_rx_octets = param[5] | (param[6] << 8);
|
||
uint16_t max_tx_octets = param[9] | (param[10] << 8);
|
||
// printf("LE_NOTICE_DATA_LEN_CHANGE: rx: %d, tx: %d\n", max_rx_octets, max_tx_octets);
|
||
}
|
||
break;
|
||
|
||
case LE_NOTICE_CLINET_CFG: {
|
||
u16 handle = param[0] | (param[1] << 8);
|
||
u8 cfg = param[2];
|
||
// ble_app_client_cfg_callback(handle, cfg);
|
||
// printf("LE_NOTICE_CLINET_CFG: handle: %d, cfg: %d\n", handle, cfg);
|
||
}
|
||
break;
|
||
|
||
#if LE_ANCS_CLIENT_EN
|
||
case LE_NOTICE_ANCS_CONN_EVT:
|
||
if (param[0]) {
|
||
ble_cb.ancs_connected = true;
|
||
// printf("ANCS connect\n");
|
||
} else {
|
||
ble_cb.ancs_connected = false;
|
||
// printf("ANCS disconnect\n");
|
||
}
|
||
break;
|
||
#endif // LE_ANCS_CLIENT_EN
|
||
|
||
#if LE_AMS_CLIENT_EN
|
||
case LE_NOTICE_AMS_CONN_EVT:
|
||
if (param[0]) {
|
||
ble_cb.ams_connected = true;
|
||
printf("AMS connect\n");
|
||
} else {
|
||
ble_cb.ams_connected = false;
|
||
ble_ams_var_init();
|
||
printf("AMS disconnect\n");
|
||
}
|
||
break;
|
||
#endif // LE_AMS_CLIENT_EN
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
//att_exchange_mtu_finish_callback(蓝牙线程请勿阻塞)
|
||
void ble_att_exchange_mtu_finish_callback(uint16_t mtu)
|
||
{
|
||
ble_update_conn_param(200,0,400);
|
||
}
|
||
|
||
void ble_init_att(void)
|
||
{
|
||
memset(&ble_cb, 0, sizeof(ble_cb));
|
||
ble_gatts_init(gatts_profile_table, sizeof(gatts_profile_table),
|
||
characteristic_cb_info,
|
||
LE_ATT_NUM);
|
||
ble_app_init();
|
||
ble_ams_var_init();
|
||
}
|
||
|
||
//可重定义该函数修改ble地址
|
||
void ble_get_local_bd_addr(u8 *addr)
|
||
{
|
||
memcpy(addr, xcfg_cb.bt_addr, 6);
|
||
#if !LE_SM_SC_EN
|
||
addr[5] ^= 0x55;
|
||
#endif
|
||
}
|
||
|
||
#if LE_SM_SC_EN
|
||
|
||
//发起一键双连
|
||
void ble_bt_connect(void)
|
||
{
|
||
// printf("ble_bt_connect[%d]\n",bt_is_connected());
|
||
if (!bt_is_connected()) {
|
||
ble_send_sm_req();
|
||
}
|
||
}
|
||
|
||
//重置bt地址为bt_get_local_bd_addr的返回值
|
||
void bsp_change_bt_mac(void)
|
||
{
|
||
bool bt_dual = (bt_get_scan() == 0x3) ? true: false;
|
||
|
||
bt_reset_addr();
|
||
delay_5ms(10);
|
||
bt_set_scan(0, 0);
|
||
|
||
if (bt_dual) {
|
||
delay_5ms(10);
|
||
bt_set_scan(1, 1);
|
||
}
|
||
}
|
||
|
||
void ble_get_link_info(void *buf, u16 addr, u16 size)
|
||
{
|
||
//printf("bt_read: %04x,%04x, %08lx\n", addr, size, BLE_CM_PAGE(addr));
|
||
|
||
cm_read(buf, BLE_CM_PAGE(addr), size);
|
||
|
||
//print_r(buf, size);
|
||
}
|
||
|
||
void ble_put_link_info(void *buf, u16 addr, u16 size)
|
||
{
|
||
//printf("bt_write: %04x,%04x, %08lx\n", addr, size, BLE_CM_PAGE(addr));
|
||
//print_r(buf, size);
|
||
|
||
cm_write(buf, BLE_CM_PAGE(addr), size);
|
||
}
|
||
|
||
void ble_sync_link_info(void)
|
||
{
|
||
cm_sync();
|
||
}
|
||
#endif //LE_SM_SC_EN
|
||
|
||
#if BT_CONNECT_REQ_FROM_WATCH_EN
|
||
void cross_transport_key_derivation_cb(void)
|
||
{
|
||
msg_enqueue(EVT_BT_CONNECT_ONCE);
|
||
}
|
||
#endif
|
||
|
||
static void reconnt_timer_callback (co_timer_t *timer, void *param)
|
||
{
|
||
bt_connect(3);
|
||
}
|
||
|
||
|
||
//一键双连应用示例
|
||
void app_once_connect(u8 ble_app_ios)
|
||
{
|
||
SysVariable.set_device_flag = 1;
|
||
static co_timer_t reconnt_timer;
|
||
|
||
SysVariable.set_device_flag = 1;
|
||
if (SysVariable.deviceType != ble_app_ios) {
|
||
SysVariable.deviceType = Device_IS_IOS;
|
||
bsp_change_bt_mac();
|
||
}
|
||
|
||
if (ble_app_ios && !bt_is_connected()) { //IOS
|
||
// printf("app_once_connect [%d]~~~~~~~~~~~~~~~~~~~~~~~~~\n",bt_nor_get_link_info(NULL));
|
||
sys_cb.reconnect_flag = true;
|
||
if(SysVariable.bt_state_set == false){
|
||
if (bt_nor_get_link_info(NULL)) { // 如果存在配对信息
|
||
sys_cb.bt_reconn_flag = true;
|
||
bt_disconnect(0);
|
||
bt_abort_reconnect();
|
||
|
||
co_timer_set(&reconnt_timer, 1000, TIMER_ONE_SHOT, LEVEL_LOW_PRI, reconnt_timer_callback, NULL);
|
||
co_timer_set_sleep(&reconnt_timer, true);
|
||
} else {
|
||
// printf("app_once_connect 4444\n");
|
||
ble_bt_connect(); // 一键双联
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// //一键双连地址恢复为安卓
|
||
// void app_once_connect_to_android(void)
|
||
// {
|
||
// if((!bt_is_connected()) && (!ble_is_connect()) && (SysVariable.deviceType != Device_IS_Android)) {
|
||
// // printf("app_once_connect_to_android\n");
|
||
// SysVariable.deviceType = Device_IS_Android;
|
||
// bsp_change_bt_mac();
|
||
// }
|
||
// }
|
||
|
||
// void ble_connect_callback(void)
|
||
// {
|
||
// printf("--->ble_connect_callback\n");
|
||
// }
|
||
|
||
// void ble_disconnect_callback(void)
|
||
// {
|
||
// printf("--->ble_disconnect_callback\n");
|
||
// }
|
||
// void ble_disconnect_callback(void)
|
||
// {
|
||
// printf("----> ble_disconnect_callback\n");
|
||
// if(Device_IS_IOS){
|
||
// ble_ancs_stop();
|
||
// }
|
||
|
||
// }
|
||
bool sinff_auto_is_disable(void)
|
||
{
|
||
return ble_ancs_is_connected();
|
||
}
|
||
|
||
unsigned short att_get_max_mtu(void)
|
||
{
|
||
return 256;
|
||
}
|
||
|
||
#endif // LE_EN
|