bk7256集成WIFI6和BLE,本篇讲述其蓝牙使用。
定义蓝牙广播与服务属性
static int actv_idx = 0;
static ble_adv_param_t adv_param={
.chnl_map=7,
.adv_intv_min = 120,
.adv_intv_max = 160,
.own_addr_type = OWN_ADDR_TYPE_PUBLIC_OR_STATIC_ADDR,
.adv_type = 0,
.adv_prop = 3,
.prim_phy = 1,
.second_phy = 1,
};
enum {
BOARDING_IDX_SVC,
BOARDING_IDX_CHAR_DECL,
BOARDING_IDX_CHAR_VALUE,
BOARDING_IDX_CHAR_DESC,
BOARDING_IDX_CHAR_SSID_DECL,
BOARDING_IDX_CHAR_SSID_VALUE,
BOARDING_IDX_CHAR_PASSWORD_DECL,
BOARDING_IDX_CHAR_PASSWORD_VALUE,
BOARDING_IDX_CHAR_USER_W_DECL,
BOARDING_IDX_CHAR_USER_W_VALUE,
BOARDING_IDX_NB,
};
/*
服务声明
特征声明
特征client配置声明。这是一个特殊的UUID,表示这条记录用于配置被描述的特征,一般有notify、indicate
*/
#define DECL_PRIMARY_SERVICE_128 {0x00,0x28,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
#define DECL_CHARACTERISTIC_128 {0x03,0x28,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
#define DESC_CLIENT_CHAR_CFG_128 {0x02,0x29,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
static ble_attm_desc_t boarding_service_db[BOARDING_IDX_NB] = {
// Service Declaration
[BOARDING_IDX_SVC] = {DECL_PRIMARY_SERVICE_128, BK_BLE_PERM_SET(RD, ENABLE), 0, 0},
[BOARDING_IDX_CHAR_DECL] = {DECL_CHARACTERISTIC_128, BK_BLE_PERM_SET(RD, ENABLE), 0, 0},
[BOARDING_IDX_CHAR_VALUE] = {{(uint8_t)(APP_CHAR_N_UUID), (uint8_t)(APP_CHAR_N_UUID>>8), 0}, BK_BLE_PERM_SET(NTF, ENABLE), BK_BLE_PERM_SET(RI, ENABLE) | BK_BLE_PERM_SET(UUID_LEN, UUID_16), 128},
[BOARDING_IDX_CHAR_DESC] = {DESC_CLIENT_CHAR_CFG_128, BK_BLE_PERM_SET(RD, ENABLE) | BK_BLE_PERM_SET(WRITE_REQ, ENABLE), 0, 0},
[BOARDING_IDX_CHAR_SSID_DECL] = {DECL_CHARACTERISTIC_128, BK_BLE_PERM_SET(RD, ENABLE), 0, 0},
[BOARDING_IDX_CHAR_SSID_VALUE] = {{0xbc, 0x9a, 0}, BK_BLE_PERM_SET(WRITE_REQ, ENABLE) | BK_BLE_PERM_SET(RD, ENABLE), BK_BLE_PERM_SET(RI, ENABLE) | BK_BLE_PERM_SET(UUID_LEN, UUID_16), 128},
[BOARDING_IDX_CHAR_PASSWORD_DECL] = {DECL_CHARACTERISTIC_128, BK_BLE_PERM_SET(RD, ENABLE), 0, 0},
[BOARDING_IDX_CHAR_PASSWORD_VALUE] = {{0xf0, 0xde, 0}, BK_BLE_PERM_SET(WRITE_REQ, ENABLE) | BK_BLE_PERM_SET(RD, ENABLE), BK_BLE_PERM_SET(RI, ENABLE) | BK_BLE_PERM_SET(UUID_LEN, UUID_16), 128},
[BOARDING_IDX_CHAR_USER_W_DECL] = {DECL_CHARACTERISTIC_128, BK_BLE_PERM_SET(RD, ENABLE), 0, 0},
[BOARDING_IDX_CHAR_USER_W_VALUE] = {{(uint8_t)(APP_CHAR_W_UUID), (uint8_t)(APP_CHAR_W_UUID>>8), 0}, BK_BLE_PERM_SET(WRITE_REQ, ENABLE) , BK_BLE_PERM_SET(RI, ENABLE) | BK_BLE_PERM_SET(UUID_LEN, UUID_16), 128},
};
/*
服务声明
特征声明
特征client配置声明。这是一个特殊的UUID,表示这条记录用于配置被描述的特征,一般有notify、indicate
*/
#define DECL_PRIMARY_SERVICE_128 {0x00,0x28,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
#define DECL_CHARACTERISTIC_128 {0x03,0x28,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
#define DESC_CLIENT_CHAR_CFG_128 {0x02,0x29,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
static ble_attm_desc_t boarding_service_db[BOARDING_IDX_NB] = {
// Service Declaration
[BOARDING_IDX_SVC] = {DECL_PRIMARY_SERVICE_128, BK_BLE_PERM_SET(RD, ENABLE), 0, 0},
[BOARDING_IDX_CHAR_DECL] = {DECL_CHARACTERISTIC_128, BK_BLE_PERM_SET(RD, ENABLE), 0, 0},
[BOARDING_IDX_CHAR_VALUE] = {{(uint8_t)(APP_CHAR_N_UUID), (uint8_t)(APP_CHAR_N_UUID>>8), 0}, BK_BLE_PERM_SET(NTF, ENABLE), BK_BLE_PERM_SET(RI, ENABLE) | BK_BLE_PERM_SET(UUID_LEN, UUID_16), 128},
[BOARDING_IDX_CHAR_DESC] = {DESC_CLIENT_CHAR_CFG_128, BK_BLE_PERM_SET(RD, ENABLE) | BK_BLE_PERM_SET(WRITE_REQ, ENABLE), 0, 0},
[BOARDING_IDX_CHAR_SSID_DECL] = {DECL_CHARACTERISTIC_128, BK_BLE_PERM_SET(RD, ENABLE), 0, 0},
[BOARDING_IDX_CHAR_SSID_VALUE] = {{0xbc, 0x9a, 0}, BK_BLE_PERM_SET(WRITE_REQ, ENABLE) | BK_BLE_PERM_SET(RD, ENABLE), BK_BLE_PERM_SET(RI, ENABLE) | BK_BLE_PERM_SET(UUID_LEN, UUID_16), 128},
[BOARDING_IDX_CHAR_PASSWORD_DECL] = {DECL_CHARACTERISTIC_128, BK_BLE_PERM_SET(RD, ENABLE), 0, 0},
[BOARDING_IDX_CHAR_PASSWORD_VALUE] = {{0xf0, 0xde, 0}, BK_BLE_PERM_SET(WRITE_REQ, ENABLE) | BK_BLE_PERM_SET(RD, ENABLE), BK_BLE_PERM_SET(RI, ENABLE) | BK_BLE_PERM_SET(UUID_LEN, UUID_16), 128},
[BOARDING_IDX_CHAR_USER_W_DECL] = {DECL_CHARACTERISTIC_128, BK_BLE_PERM_SET(RD, ENABLE), 0, 0},
[BOARDING_IDX_CHAR_USER_W_VALUE] = {{(uint8_t)(APP_CHAR_W_UUID), (uint8_t)(APP_CHAR_W_UUID>>8), 0}, BK_BLE_PERM_SET(WRITE_REQ, ENABLE) , BK_BLE_PERM_SET(RI, ENABLE) | BK_BLE_PERM_SET(UUID_LEN, UUID_16), 128},
};
int ble_boarding_legacy_func(void)
{
int err = kNoErr;
char *msg = NULL;
uint16 service_uuid = APP_SERVICE_UUID;
uint16 char_uuid = APP_CHAR_N_UUID;
struct bk_ble_db_cfg ble_db_cfg;
uint8_t adv_index = 0;
uint8_t len_index = 0;
uint8_t mac[6];
int ret;
len_index = adv_index;
adv_data[adv_index++] = 0x00;
adv_data[adv_index++] = ADV_TYPE_FLAGS;
adv_data[adv_index++] = 0x06;
adv_data[len_index] = 2;
bk_wifi_sta_get_mac(mac);
os_printf("WIFI_STA_MAC:[%02x:%02x:%02x:%02x:%02x:%02x]\n", mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
bk_ble_get_mac(mac);
os_printf("BLE_MAC:[%02x:%02x:%02x:%02x:%02x:%02x]\n", mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
bk_get_mac(mac,MAC_TYPE_BASE);
os_printf("Base_MAC:[%02x:%02x:%02x:%02x:%02x:%02x]\n", mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
len_index = adv_index;
adv_data[adv_index++] = 0x00;
adv_data[adv_index++] = ADV_TYPE_LOCAL_NAME;
ret = sprintf((char *)&adv_data[adv_index], "%s_%02X%02X%02X",
BLE_DEVICE_NAME, mac[3], mac[4], mac[5]);
adv_index += ret;
adv_data[len_index] = ret + 1;
len_index = adv_index;
adv_data[adv_index++] = 0x00;
adv_data[adv_index++] = ADV_TYPE_SERVICE_DATA;
adv_data[adv_index++] = BOARDING_UUID & 0xFF;
adv_data[adv_index++] = BOARDING_UUID >> 8;
adv_data[adv_index++] = 1;
adv_data_index=adv_index-1;
os_printf("%s adv_index:%d--%d\n", __func__,adv_index,adv_data_index);
adv_data[len_index] = 4;
len_index = adv_index;
adv_data[adv_index++] = 0x00;
adv_data[adv_index++] = ADV_TYPE_MANUFACTURER_SPECIFIC;
adv_data[adv_index++] = BEKEN_COMPANY_ID & 0xFF;
adv_data[adv_index++] = BEKEN_COMPANY_ID >> 8;
adv_data[len_index] = 3;
adv_len = adv_index;
os_printf("adv_len:%d\n", adv_len);
if (adv_len > 31 )
{
os_printf("input adv len over limited\n");
err = kParamErr;
goto error;
}
err = rtos_init_semaphore(&ble_boarding_sema, 1);
if(err != kNoErr){
goto error;
}
os_memcpy(&(boarding_service_db[BOARDING_IDX_CHAR_VALUE].uuid[0]), &char_uuid, 2);
os_memset(&ble_db_cfg, 0, sizeof(ble_db_cfg));
ble_db_cfg.att_db = (ble_attm_desc_t *)boarding_service_db;
ble_db_cfg.att_db_nb = BOARDING_IDX_NB;
ble_db_cfg.prf_task_id = PRF_TASK_ID_BOARDING;
ble_db_cfg.start_hdl = 0;
ble_db_cfg.svc_perm = BK_BLE_PERM_SET(SVC_UUID_LEN, UUID_16);
os_memcpy(&(ble_db_cfg.uuid[0]), &service_uuid, 2);
bk_ble_set_notice_cb(ble_at_legacy_notice_cb);
err = bk_ble_create_db(&ble_db_cfg);
if (err != BK_ERR_BLE_SUCCESS) {
goto error;
} else {
err = rtos_get_semaphore(&ble_boarding_sema, AT_SYNC_CMD_TIMEOUT_MS);
if (err != kNoErr){
goto error;
} else {
if (s_at_cmd_status == BK_ERR_BLE_SUCCESS) {
msg = AT_CMD_RSP_SUCCEED;
} else {
err = s_at_cmd_status;
s_at_cmd_status = BK_ERR_BLE_SUCCESS;
goto error;
}
}
}
os_printf("creat boarding service successfully!\r\n");
os_memset(&adv_param, 0, sizeof(ble_adv_param_t));
adv_param.chnl_map = 7;
adv_param.adv_intv_min = 120;
adv_param.adv_intv_max = 160;
adv_param.own_addr_type = OWN_ADDR_TYPE_PUBLIC_OR_STATIC_ADDR;
adv_param.adv_type = 0;
adv_param.adv_prop = 3;
adv_param.prim_phy = 1;
adv_param.second_phy = 1;
err = bk_ble_create_advertising(actv_idx, &adv_param, ble_at_cmd_cb);
if (err != BK_ERR_BLE_SUCCESS) {
goto error;
} else {
err = rtos_get_semaphore(&ble_boarding_sema, AT_SYNC_CMD_TIMEOUT_MS);
if (err != kNoErr){
goto error;
} else {
if (s_at_cmd_status == BK_ERR_BLE_SUCCESS) {
msg = AT_CMD_RSP_SUCCEED;
} else {
err = s_at_cmd_status;
s_at_cmd_status = BK_ERR_BLE_SUCCESS;
goto error;
}
}
}
os_printf("set adv param and creat adv successfully!\r\n");
err = bk_ble_set_adv_data(actv_idx, adv_data, adv_len,ble_at_cmd_cb);
if (err != BK_ERR_BLE_SUCCESS) {
goto error;
} else {
err = rtos_get_semaphore(&ble_boarding_sema, AT_SYNC_CMD_TIMEOUT_MS);
if (err != kNoErr){
goto error;
} else {
if (s_at_cmd_status == BK_ERR_BLE_SUCCESS) {
msg = AT_CMD_RSP_SUCCEED;
} else {
err = s_at_cmd_status;
s_at_cmd_status = BK_ERR_BLE_SUCCESS;
goto error;
}
}
}
os_printf("set adv data successfully!\r\n");
err = bk_ble_start_advertising(actv_idx, 0, ble_at_cmd_cb);
if (err != BK_ERR_BLE_SUCCESS) {
goto error;
} else {
if (s_at_cmd_status == BK_ERR_BLE_SUCCESS)
{
msg = AT_CMD_RSP_SUCCEED;
rtos_deinit_semaphore(&ble_boarding_sema);
ble_boarding_sema=NULL;
os_printf("start adv successfully!\r\n");
return err;
}
else
{
err = s_at_cmd_status;
s_at_cmd_status = BK_ERR_BLE_SUCCESS;
goto error;
}
}
error:
os_printf("%s failed\n", func);
msg = AT_CMD_RSP_ERROR;
// os_memcpy(pcWriteBuffer, msg, os_strlen(msg));
if (ble_boarding_sema != NULL)
{
rtos_deinit_semaphore(&ble_boarding_sema);
ble_boarding_sema=NULL;
}
return err;
}
///////////////////////////////////////
蓝牙广播开始与停止回调
static void ble_at_cmd_cb(ble_cmd_t cmd, ble_cmd_param_t *param)
{
s_at_cmd_status = param->status;
os_printf("\r\n\r\n>>>%s,cmd:%d ,status:%d\r\n",func,cmd,s_at_cmd_status);
switch (cmd)
{
case BLE_CREATE_ADV:
case BLE_SET_ADV_DATA:
case BLE_SET_RSP_DATA:
case BLE_START_ADV:
case BLE_STOP_ADV:
case BLE_CREATE_SCAN:
case BLE_START_SCAN:
case BLE_STOP_SCAN:
case BLE_INIT_CREATE:
case BLE_INIT_START_CONN:
case BLE_INIT_STOP_CONN:
case BLE_CONN_DIS_CONN:
case BLE_CONN_UPDATE_PARAM:
case BLE_DELETE_ADV:
case BLE_DELETE_SCAN:
case BLE_CONN_READ_PHY:
case BLE_CONN_SET_PHY:
case BLE_CONN_UPDATE_MTU:
if(cmd==BLE_START_ADV)
{
g_ble_status=BLE_ADV_START;
app_msg_send(BLE_ADV_START,NULL,0);
}
else if(cmd==BLE_STOP_ADV)
{
g_ble_status=BLE_ADV_STOP;
app_msg_send(BLE_ADV_STOP,NULL,0);
}
if (ble_boarding_sema != NULL)
rtos_set_semaphore( &ble_boarding_sema );
break;
default:
break;
}
}
////////////////////////////
`
蓝牙服务数据接收处理,可用于蓝牙配网
static void ble_at_legacy_notice_cb(ble_notice_t notice, void *param)
{
uint8_t con_idx = *(uint8_t *)param;
uint8_t value[3] = {0};
switch (notice) {
case BLE_5_STACK_OK:
os_printf("ble stack ok");
break;
case BLE_5_WRITE_EVENT: {
ble_write_req_t *w_req = (ble_write_req_t *)param;
os_printf("write_cb:conn_idx:%d, prf_id:%d, att_idx:%d, len:%d, data[0]:0x%02x\r\n",
w_req->conn_idx, w_req->prf_id, w_req->att_idx, w_req->len, w_req->value[0]);
//#if (CONFIG_BTDM_5_2)
if (bk_ble_get_controller_stack_type() == BK_BLE_CONTROLLER_STACK_TYPE_BTDM_5_2
&& w_req->prf_id == PRF_TASK_ID_BOARDING) {
switch(w_req->att_idx)
{
case BOARDING_IDX_CHAR_DECL:
break;
case BOARDING_IDX_CHAR_VALUE:
break;
case BOARDING_IDX_CHAR_DESC:
break;
}}
///////////////////////////////////////
相关宏定义,如蓝牙广播名称,服务UUID等。
总的来说,官方sdk 例程可以作为参考,根据需要做调整修改调试验证。