doubao_chat/apps/common/ble/le_net_cfg.c

952 lines
30 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*********************************************************************************************
* Filename : le_server_module.c
* Description :
* Author :
* Email : zh-jieli.com
* Last modifiled : 2017-01-17 11:14
* Copyright:(c)JIELI 2011-2016 @ , All Rights Reserved.
*********************************************************************************************/
// *****************************************************************************
/* EXAMPLE_START(le_counter): LE Peripheral - Heartbeat Counter over GATT
*
* @text All newer operating systems provide GATT Client functionality.
* The LE Counter examples demonstrates how to specify a minimal GATT Database
* with a custom GATT Service and a custom Characteristic that sends periodic
* notifications.
*/
// *****************************************************************************
#include "system/app_core.h"
#include "system/includes.h"
#include "event/net_event.h"
#include "app_config.h"
#include "btstack/btstack_task.h"
#include "btstack/bluetooth.h"
#include "btcontroller_modules.h"
#include "bt_common.h"
#include "system/wait.h"
#include "third_party/common/ble_user.h"
#include "le_net_cfg.h"
#include "le_common.h"
#if (TCFG_BLE_DEMO_SELECT == DEF_BLE_DEMO_NET_CFG)
#define TEST_SEND_HANDLE_VAL ATT_CHARACTERISTIC_ae82_01_VALUE_HANDLE
#if 1
extern void printf_buf(u8 *buf, u32 len);
#define log_info printf
#define log_info_hexdump printf_buf
#else
#define log_info(...)
#define log_info_hexdump(...)
#endif
/* #define LOG_TAG_CONST BT_BLE */
/* #define LOG_TAG "[LE_S_DEMO]" */
/* #define LOG_ERROR_ENABLE */
/* #define LOG_DEBUG_ENABLE */
/* #define LOG_INFO_ENABLE */
/* #define LOG_DUMP_ENABLE */
/* #define LOG_CLI_ENABLE */
/* #include "debug.h" */
//------
#define ATT_LOCAL_PAYLOAD_SIZE (128) //note: need >= 20
#define ATT_SEND_CBUF_SIZE (512) //note: need >= 20,缓存大小,可修改
#define ATT_RAM_BUFSIZE (ATT_CTRL_BLOCK_SIZE + ATT_LOCAL_PAYLOAD_SIZE + ATT_SEND_CBUF_SIZE) //note:
static u8 att_ram_buffer[ATT_RAM_BUFSIZE] __attribute__((aligned(4)));
//---------------
//---------------
#define ADV_INTERVAL_MIN (160)
static volatile hci_con_handle_t con_handle;
static void ble_module_enable(u8 en);
//连接参数设置
static const uint8_t connection_update_enable = 1; ///0--disable, 1--enable
static uint8_t connection_update_cnt = 0; //
static const struct conn_update_param_t connection_param_table[] = {
{16, 24, 10, 600},//11
{12, 28, 10, 600},//3.7
{8, 20, 10, 600},
/* {12, 28, 4, 600},//3.7 */
/* {12, 24, 30, 600},//3.05 */
};
#define CONN_PARAM_TABLE_CNT (sizeof(connection_param_table)/sizeof(struct conn_update_param_t))
// 广播包内容
/* static u8 adv_data[ADV_RSP_PACKET_MAX];//max is 31 */
// scan_rsp 内容
/* static u8 scan_rsp_data[ADV_RSP_PACKET_MAX];//max is 31 */
#if (ATT_RAM_BUFSIZE < 64)
#error "adv_data & rsp_data buffer error!!!!!!!!!!!!"
#endif
#define adv_data &att_ram_buffer[0]
#define scan_rsp_data &att_ram_buffer[32]
static char gap_device_name[BT_NAME_LEN_MAX] = "wl80_ble_test";
static u8 complete = 0;
static u8 gap_device_name_len = 0;
static u8 ble_work_state = 0;
static u8 adv_ctrl_en;
static OS_MUTEX mutex;
static void (*app_recieve_callback)(void *priv, void *buf, u16 len) = NULL;
static void (*app_ble_state_callback)(void *priv, ble_state_e state) = NULL;
static void (*ble_resume_send_wakeup)(void) = NULL;
static u32 channel_priv;
static int app_send_user_data_check(u16 len);
static int app_send_user_data_do(void *priv, u8 *data, u16 len);
static int app_send_user_data(u16 handle, const u8 *data, u16 len, u8 handle_type);
extern u8 is_in_config_network_state(void);
// Complete Local Name 默认的蓝牙名字
extern const char *bt_get_local_name();
//配网成回复命令
static const u8 rsp_cmd0[] = {
0x4A, 0x4C, 0x00, 0x0e, 0x10, 0x02,
'{', '"', 's', 't', 'a', 't', 'u', 's', '"', ':', '0', '}',
0x7C, 0xC3, 0xFF,
};
//正在配网回复命令
static const u8 rsp_cmd1[] = {
0x4A, 0x4C, 0x00, 0x0e, 0x10, 0x02,
'{', '"', 's', 't', 'a', 't', 'u', 's', '"', ':', '1', '}',
0x4F, 0xF2, 0xFF,
};
//配网失败回复命令
static const u8 rsp_cmd2[] = {
0x4A, 0x4C, 0x00, 0x0e, 0x10, 0x02,
'{', '"', 's', 't', 'a', 't', 'u', 's', '"', ':', '2', '}',
0x1A, 0xA1, 0xFF,
};
//未找到ssid回复命令
static const u8 rsp_cmd3[] = {
0x4A, 0x4C, 0x00, 0x0e, 0x10, 0x02,
'{', '"', 's', 't', 'a', 't', 'u', 's', '"', ':', '3', '}',
0x29, 0x90, 0xFF,
};
//密码错误回复命令
static const u8 rsp_cmd4[] = {
0x4A, 0x4C, 0x00, 0x0e, 0x10, 0x02,
'{', '"', 's', 't', 'a', 't', 'u', 's', '"', ':', '4', '}',
0xB0, 0x07, 0xFF,
};
//------------------------------------------------------
static void send_request_connect_parameter(u8 table_index)
{
struct conn_update_param_t *param = (void *)&connection_param_table[table_index];//static ram
log_info("update_request:-%d-%d-%d-%d-\n", param->interval_min, param->interval_max, param->latency, param->timeout);
if (con_handle) {
ble_user_cmd_prepare(BLE_CMD_REQ_CONN_PARAM_UPDATE, 2, con_handle, param);
}
}
static void check_connetion_updata_deal(void)
{
if (connection_update_enable) {
if (connection_update_cnt < CONN_PARAM_TABLE_CNT) {
send_request_connect_parameter(connection_update_cnt);
}
}
}
static void connection_update_complete_success(u8 *packet)
{
int con_handle, conn_interval, conn_latency, conn_timeout;
con_handle = hci_subevent_le_connection_update_complete_get_connection_handle(packet);
conn_interval = hci_subevent_le_connection_update_complete_get_conn_interval(packet);
conn_latency = hci_subevent_le_connection_update_complete_get_conn_latency(packet);
conn_timeout = hci_subevent_le_connection_update_complete_get_supervision_timeout(packet);
log_info("conn_interval = %d\n", conn_interval);
log_info("conn_latency = %d\n", conn_latency);
log_info("conn_timeout = %d\n", conn_timeout);
}
static void set_ble_work_state(ble_state_e state)
{
if (state != ble_work_state) {
log_info("ble_work_st:%x->%x\n", ble_work_state, state);
ble_work_state = state;
if (app_ble_state_callback) {
app_ble_state_callback((void *)channel_priv, state);
}
}
}
static ble_state_e get_ble_work_state(void)
{
return ble_work_state;
}
static void cbk_sm_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)
{
sm_just_event_t *event = (void *)packet;
u32 tmp32;
switch (packet_type) {
case HCI_EVENT_PACKET:
switch (hci_event_packet_get_type(packet)) {
case SM_EVENT_JUST_WORKS_REQUEST:
sm_just_works_confirm(sm_event_just_works_request_get_handle(packet));
log_info("Just Works Confirmed.\n");
break;
case SM_EVENT_PASSKEY_DISPLAY_NUMBER:
log_info_hexdump(packet, size);
memcpy(&tmp32, event->data, 4);
log_info("Passkey display: %06u.\n", tmp32);
break;
}
break;
}
}
static void can_send_now_wakeup(void)
{
putchar('E');
if (ble_resume_send_wakeup) {
ble_resume_send_wakeup();
}
}
static const char *const phy_result[] = {
"None",
"1M",
"2M",
"Coded",
};
static void server_profile_start(u16 con_handle)
{
ble_user_cmd_prepare(BLE_CMD_ATT_SEND_INIT, 4, con_handle, att_ram_buffer, ATT_RAM_BUFSIZE, ATT_LOCAL_PAYLOAD_SIZE);
set_ble_work_state(BLE_ST_CONNECT);
/* set_connection_data_phy(CONN_SET_CODED_PHY, CONN_SET_CODED_PHY); */
}
/*
* @section Packet Handler
*
* @text The packet handler is used to:
* - stop the counter after a disconnect
* - send a notification when the requested ATT_EVENT_CAN_SEND_NOW is received
*/
/* LISTING_START(packetHandler): Packet Handler */
static void cbk_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)
{
int mtu;
u32 tmp;
u8 status;
switch (packet_type) {
case HCI_EVENT_PACKET:
switch (hci_event_packet_get_type(packet)) {
/* case DAEMON_EVENT_HCI_PACKET_SENT: */
/* break; */
case ATT_EVENT_HANDLE_VALUE_INDICATION_COMPLETE:
log_info("ATT_EVENT_HANDLE_VALUE_INDICATION_COMPLETE\n");
case ATT_EVENT_CAN_SEND_NOW:
can_send_now_wakeup();
break;
case HCI_EVENT_LE_META:
switch (hci_event_le_meta_get_subevent_code(packet)) {
case HCI_SUBEVENT_LE_ENHANCED_CONNECTION_COMPLETE:
status = hci_subevent_le_enhanced_connection_complete_get_status(packet);
if (status) {
log_info("LE_SLAVE CONNECTION FAIL!!! %0x\n", status);
set_ble_work_state(BLE_ST_DISCONN);
break;
}
con_handle = hci_subevent_le_enhanced_connection_complete_get_connection_handle(packet);
log_info("HCI_SUBEVENT_LE_ENHANCED_CONNECTION_COMPLETE : %0x\n", con_handle);
log_info("conn_interval = %d\n", hci_subevent_le_enhanced_connection_complete_get_conn_interval(packet));
log_info("conn_latency = %d\n", hci_subevent_le_enhanced_connection_complete_get_conn_latency(packet));
log_info("conn_timeout = %d\n", hci_subevent_le_enhanced_connection_complete_get_supervision_timeout(packet));
server_profile_start(con_handle);
break;
case HCI_SUBEVENT_LE_CONNECTION_COMPLETE:
con_handle = hci_subevent_le_connection_complete_get_connection_handle(packet);
log_info("HCI_SUBEVENT_LE_CONNECTION_COMPLETE: %0x\n", con_handle);
connection_update_complete_success(packet + 8);
server_profile_start(con_handle);
break;
case HCI_SUBEVENT_LE_CONNECTION_UPDATE_COMPLETE:
connection_update_complete_success(packet);
break;
case HCI_SUBEVENT_LE_DATA_LENGTH_CHANGE:
log_info("APP HCI_SUBEVENT_LE_DATA_LENGTH_CHANGE\n");
/* set_connection_data_phy(CONN_SET_CODED_PHY, CONN_SET_CODED_PHY); */
break;
case HCI_SUBEVENT_LE_PHY_UPDATE_COMPLETE:
log_info("APP HCI_SUBEVENT_LE_PHY_UPDATE %s\n", hci_event_le_meta_get_phy_update_complete_status(packet) ? "Fail" : "Succ");
log_info("Tx PHY: %s\n", phy_result[hci_event_le_meta_get_phy_update_complete_tx_phy(packet)]);
log_info("Rx PHY: %s\n", phy_result[hci_event_le_meta_get_phy_update_complete_rx_phy(packet)]);
break;
}
break;
case HCI_EVENT_DISCONNECTION_COMPLETE:
log_info("HCI_EVENT_DISCONNECTION_COMPLETE: %0x\n", packet[5]);
con_handle = 0;
ble_user_cmd_prepare(BLE_CMD_ATT_SEND_INIT, 4, con_handle, 0, 0, 0);
set_ble_work_state(BLE_ST_DISCONN);
#if !CONFIG_POWER_ON_ENABLE_BLE
if (is_in_config_network_state()) {
#else
{
#endif
os_mutex_pend(&mutex, 0);
bt_ble_adv_enable(1);
complete = 0;
os_mutex_post(&mutex);
}
connection_update_cnt = 0;
break;
case ATT_EVENT_MTU_EXCHANGE_COMPLETE:
mtu = att_event_mtu_exchange_complete_get_MTU(packet) - 3;
log_info("ATT MTU = %u\n", mtu);
ble_user_cmd_prepare(BLE_CMD_ATT_MTU_SIZE, 1, mtu);
break;
case HCI_EVENT_VENDOR_REMOTE_TEST:
log_info("--- HCI_EVENT_VENDOR_REMOTE_TEST\n");
break;
case L2CAP_EVENT_CONNECTION_PARAMETER_UPDATE_RESPONSE:
tmp = little_endian_read_16(packet, 4);
log_info("-update_rsp: %02x\n", tmp);
if (tmp) {
connection_update_cnt++;
log_info("remoter reject!!!\n");
check_connetion_updata_deal();
} else {
connection_update_cnt = CONN_PARAM_TABLE_CNT;
}
break;
case HCI_EVENT_ENCRYPTION_CHANGE:
log_info("HCI_EVENT_ENCRYPTION_CHANGE= %d\n", packet[2]);
break;
}
break;
}
}
/* LISTING_END */
/*
* @section ATT Read
*
* @text The ATT Server handles all reads to constant data. For dynamic data like the custom characteristic, the registered
* att_read_callback is called. To handle long characteristics and long reads, the att_read_callback is first called
* with buffer == NULL, to request the total value length. Then it will be called again requesting a chunk of the value.
* See Listing attRead.
*/
/* LISTING_START(attRead): ATT Read */
// ATT Client Read Callback for Dynamic Data
// - if buffer == NULL, don't copy data, just return size of value
// - if buffer != NULL, copy data and return number bytes copied
// @param offset defines start of attribute value
static uint16_t att_read_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t offset, uint8_t *buffer, uint16_t buffer_size)
{
uint16_t att_value_len = 0;
uint16_t handle = att_handle;
log_info("read_callback, handle= 0x%04x,buffer= %08x\n", handle, (u32)buffer);
switch (handle) {
case ATT_CHARACTERISTIC_2a00_01_VALUE_HANDLE:
att_value_len = gap_device_name_len;
if ((offset >= att_value_len) || (offset + buffer_size) > att_value_len) {
break;
}
if (buffer) {
memcpy(buffer, &gap_device_name[offset], buffer_size);
att_value_len = buffer_size;
log_info("\n------read gap_name: %s \n", gap_device_name);
}
break;
case ATT_CHARACTERISTIC_ae82_01_CLIENT_CONFIGURATION_HANDLE:
if (buffer) {
buffer[0] = att_get_ccc_config(handle);
buffer[1] = 0;
}
att_value_len = 2;
break;
default:
break;
}
log_info("att_value_len= %d\n", att_value_len);
return att_value_len;
}
static u16 user_buf_offset = 0, user_data_size = 0;
static u8 user_buf[128];
extern int get_page_turning_profile(char *username, char *password);
extern int get_payment_bind_msg(char *uuid, char *clientid, char *bind_token);
static int check_profile(void)
{
char username[64] = {0}, clientid[64] = {0}, bind_token[64] = {0};
if (get_page_turning_profile(username, NULL)) {
return false;
}
if (get_payment_bind_msg(NULL, clientid, bind_token)) {
return false;
}
return true;
}
static void check_net_info_if_recv_complete(void)
{
if (user_buf[user_buf_offset - 1] == 0xFF && user_buf_offset == user_data_size + 7) {
user_buf[sizeof(user_buf) - 1] = 0;
extern int bt_net_config_set_ssid_pwd(const char *data);
extern u16 CRC16(const void *ptr, u32 len);
u16 crc16 = user_buf[user_buf_offset - 2] + (user_buf[user_buf_offset - 3] << 8);
put_buf(&user_buf[2], user_data_size + 2);
if (crc16 == CRC16(&user_buf[2], user_data_size + 2)) {
//去掉2byte crc 1byte 结束符
user_buf[user_buf_offset - 3] = 0;
if (0 == bt_net_config_set_ssid_pwd((const char *)&user_buf[6])) {
app_send_user_data(ATT_CHARACTERISTIC_ae82_01_VALUE_HANDLE, rsp_cmd1, sizeof(rsp_cmd1), ATT_OP_AUTO_READ_CCC);
complete = 1;
user_buf_offset = 0;
user_data_size = 0;
memset(user_buf, 0, sizeof(user_buf));
}
} else {
app_send_user_data(ATT_CHARACTERISTIC_ae82_01_VALUE_HANDLE, rsp_cmd2, sizeof(rsp_cmd2), ATT_OP_AUTO_READ_CCC);
user_buf_offset = 0;
user_data_size = 0;
memset(user_buf, 0, sizeof(user_buf));
}
}
}
static int payment_msg_send(void *priv)
{
char username[64] = {0}, clientid[64] = {0}, bind_token[64] = {0};
u16 len;
u8 msg_cmd[128] = {0};
char tmp_buf[256] = {0};
get_page_turning_profile(username, NULL);
get_payment_bind_msg(NULL, clientid, bind_token);
sprintf(tmp_buf, "{\"clientid\":\"%s\",\"username\":\"%s\",\"bind_token\":\"%s\"}", clientid, username, bind_token);
len = strlen(tmp_buf) + 2;
strcpy((char *)msg_cmd, "JL");
msg_cmd[2] = (u8)len >> 8;
msg_cmd[3] = (u8)len;
msg_cmd[4] = 0x10;
msg_cmd[5] = 0x04;
strcpy((char *)&msg_cmd[6], tmp_buf);
extern u16 CRC16(const void *ptr, u32 len);
u16 crc16 = CRC16(&msg_cmd[2], len + 2);
msg_cmd[len + 4] = crc16 >> 8;
msg_cmd[len + 5] = crc16;
msg_cmd[6 + len] = 0xff;
put_buf(msg_cmd, len + 7);
app_send_user_data(ATT_CHARACTERISTIC_ae82_01_VALUE_HANDLE, msg_cmd, len + 7, ATT_OP_AUTO_READ_CCC);
sys_timeout_add(0, (void (*)(void *))ble_module_enable, 100);
return 0;
}
/* LISTING_END */
/*
* @section ATT Write
*
* @text The only valid ATT write in this example is to the Client Characteristic Configuration, which configures notification
* and indication. If the ATT handle matches the client configuration handle, the new configuration value is stored and used
* in the heartbeat handler to decide if a new value should be sent. See Listing attWrite.
*/
/* LISTING_START(attWrite): ATT Write */
static int att_write_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size)
{
int result = 0;
u16 tmp16;
u16 handle = att_handle;
log_info("write_callback, handle= 0x%04x,size = %d\n", handle, buffer_size);
switch (handle) {
case ATT_CHARACTERISTIC_2a00_01_VALUE_HANDLE:
break;
case ATT_CHARACTERISTIC_ae82_01_CLIENT_CONFIGURATION_HANDLE:
set_ble_work_state(BLE_ST_NOTIFY_IDICATE);
check_connetion_updata_deal();
log_info("\n------write ccc:%04x,%02x\n", handle, buffer[0]);
att_set_ccc_config(handle, buffer[0]);
user_buf_offset = 0;
user_data_size = 0;
memset(user_buf, 0, sizeof(user_buf));
complete = 0;
break;
case ATT_CHARACTERISTIC_ae81_01_VALUE_HANDLE:
printf("\n-ae81_rx(%d):", buffer_size);
printf_buf(buffer, buffer_size);
if (!user_buf_offset) {
if (buffer[0] == 'J' && buffer[1] == 'L' && buffer[4] == 0x10 && buffer[5] == 0x01) {
user_data_size = (buffer[2] << 8) + buffer[3];
user_buf_offset += buffer_size;
if (buffer_size < sizeof(user_buf) && user_data_size < 32 + 64 + 24) {
memcpy(user_buf, buffer, buffer_size);
check_net_info_if_recv_complete();
break;
}
}
//////////
#if (defined PAYMENT_AUDIO_SDK_ENABLE)
if (buffer[0] == 'J' && buffer[1] == 'L' && buffer[4] == 0x10 && buffer[5] == 0x03) {
user_data_size = (buffer[2] << 8) + buffer[3];
if (user_data_size == 4) {
wait_completion(check_profile, payment_msg_send, NULL, NULL);
break;
}
}
#endif
///////////
} else {
if (user_buf_offset + buffer_size < sizeof(user_buf)) {
memcpy(user_buf + user_buf_offset, buffer, buffer_size);
user_buf_offset += buffer_size;
if (user_buf_offset < user_data_size + 7) {
break;
}
check_net_info_if_recv_complete();
break;
}
}
puts("error : bt net config fail !!!\n");
user_buf_offset = 0;
user_data_size = 0;
memset(user_buf, 0, sizeof(user_buf));
app_send_user_data(ATT_CHARACTERISTIC_ae82_01_VALUE_HANDLE, rsp_cmd2, sizeof(rsp_cmd2), ATT_OP_AUTO_READ_CCC);
break;
default:
break;
}
return 0;
}
static int app_send_user_data(u16 handle, const u8 *data, u16 len, u8 handle_type)
{
u32 ret = APP_BLE_NO_ERROR;
if (!con_handle) {
return APP_BLE_OPERATION_ERROR;
}
os_mutex_pend(&mutex, 0);
if (!att_get_ccc_config(handle + 1)) {
log_info("fail,no write ccc!!!,%04x\n", handle + 1);
os_mutex_post(&mutex);
return APP_BLE_NO_WRITE_CCC;
}
ret = ble_user_cmd_prepare(BLE_CMD_ATT_SEND_DATA, 4, handle, data, len, handle_type);
if (ret == BLE_BUFFER_FULL) {
ret = APP_BLE_BUFF_FULL;
}
os_mutex_post(&mutex);
if (ret) {
log_info("app_send_fail:%d !!!!!!\n", ret);
}
return ret;
}
//------------------------------------------------------
static int make_set_adv_data(void)
{
u8 offset = 0;
u8 *buf = adv_data;
/* offset += make_eir_packet_val(&buf[offset], offset, HCI_EIR_DATATYPE_FLAGS, 0x18, 1); */
/* offset += make_eir_packet_val(&buf[offset], offset, HCI_EIR_DATATYPE_FLAGS, 0x1A, 1); */
offset += make_eir_packet_val(&buf[offset], offset, HCI_EIR_DATATYPE_FLAGS, 0x06, 1);
offset += make_eir_packet_val(&buf[offset], offset, HCI_EIR_DATATYPE_COMPLETE_16BIT_SERVICE_UUIDS, 0xAF00, 2);
if (offset > ADV_RSP_PACKET_MAX) {
puts("***adv_data overflow!!!!!!\n");
return -1;
}
log_info("adv_data(%d):", offset);
log_info_hexdump(buf, offset);
ble_user_cmd_prepare(BLE_CMD_ADV_DATA, 2, offset, buf);
return 0;
}
static int make_set_rsp_data(void)
{
u8 offset = 0;
u8 *buf = scan_rsp_data;
u8 name_len = gap_device_name_len;
u8 vaild_len = ADV_RSP_PACKET_MAX - (offset + 2);
if (name_len > vaild_len) {
name_len = vaild_len;
}
offset += make_eir_packet_data(&buf[offset], offset, HCI_EIR_DATATYPE_COMPLETE_LOCAL_NAME, (void *)gap_device_name, name_len);
if (offset > ADV_RSP_PACKET_MAX) {
puts("***rsp_data overflow!!!!!!\n");
return -1;
}
log_info("rsp_data(%d):", offset);
log_info_hexdump(buf, offset);
ble_user_cmd_prepare(BLE_CMD_RSP_DATA, 2, offset, buf);
return 0;
}
//广播参数设置
static void advertisements_setup_init()
{
uint8_t adv_type = ADV_IND;
uint8_t adv_channel = ADV_CHANNEL_ALL;
int ret = 0;
ble_user_cmd_prepare(BLE_CMD_ADV_PARAM, 3, ADV_INTERVAL_MIN, adv_type, adv_channel);
ret |= make_set_adv_data();
ret |= make_set_rsp_data();
if (ret) {
puts("advertisements_setup_init fail !!!!!!\n");
return;
}
}
#define PASSKEY_ENTER_ENABLE 0 //输入passkey使能,可修改passkey
//重设passkey回调函数,在这里可以重新设置passkey
//passkey为6个数字组成,十万位、万位。。。。个位 各表示一个数字 高位不够为0
static void reset_passkey_cb(u32 *key)
{
#if 1
u32 newkey = rand32();//获取随机数
newkey &= 0xfffff;
if (newkey > 999999) {
newkey = newkey - 999999; //不能大于999999
}
*key = newkey; //小于或等于六位数
printf("set new_key= %06u\n", *key);
#else
*key = 123456; //for debug
#endif
}
extern void reset_PK_cb_register(void (*reset_pk)(u32 *));
void ble_sm_setup_init(io_capability_t io_type, u8 auth_req, uint8_t min_key_size, u8 security_en)
{
//setup SM: Display only
sm_init();
sm_set_io_capabilities(io_type);
sm_set_authentication_requirements(auth_req);
sm_set_encryption_key_size_range(min_key_size, 16);
sm_set_request_security(security_en);
sm_event_callback_set(&cbk_sm_packet_handler);
if (io_type == IO_CAPABILITY_DISPLAY_ONLY) {
reset_PK_cb_register(reset_passkey_cb);
}
}
extern void le_device_db_init(void);
void ble_profile_init(void)
{
printf("ble profile init\n");
le_device_db_init();
#if PASSKEY_ENTER_ENABLE
ble_sm_setup_init(IO_CAPABILITY_DISPLAY_ONLY, SM_AUTHREQ_BONDING | SM_AUTHREQ_MITM_PROTECTION, 7, TCFG_BLE_SECURITY_EN);
#else
ble_sm_setup_init(IO_CAPABILITY_NO_INPUT_NO_OUTPUT, SM_AUTHREQ_BONDING | SM_AUTHREQ_MITM_PROTECTION, 7, TCFG_BLE_SECURITY_EN);
#endif
/* setup ATT server */
att_server_init(profile_data, att_read_callback, att_write_callback);
att_server_register_packet_handler(cbk_packet_handler);
/* gatt_client_register_packet_handler(packet_cbk); */
// register for HCI events
hci_event_callback_set(&cbk_packet_handler);
/* ble_l2cap_register_packet_handler(packet_cbk); */
/* sm_event_packet_handler_register(packet_cbk); */
le_l2cap_register_packet_handler(&cbk_packet_handler);
}
static int set_adv_enable(void *priv, u32 en)
{
ble_state_e next_state, cur_state;
if (!adv_ctrl_en && en) {
return APP_BLE_OPERATION_ERROR;
}
if (con_handle) {
return APP_BLE_OPERATION_ERROR;
}
if (en) {
next_state = BLE_ST_ADV;
} else {
next_state = BLE_ST_IDLE;
}
cur_state = get_ble_work_state();
switch (cur_state) {
case BLE_ST_ADV:
case BLE_ST_IDLE:
case BLE_ST_INIT_OK:
case BLE_ST_NULL:
case BLE_ST_DISCONN:
break;
default:
return APP_BLE_OPERATION_ERROR;
break;
}
if (cur_state == next_state) {
return APP_BLE_NO_ERROR;
}
log_info("adv_en:%d\n", en);
set_ble_work_state(next_state);
if (en) {
advertisements_setup_init();
}
ble_user_cmd_prepare(BLE_CMD_ADV_ENABLE, 1, en);
return APP_BLE_NO_ERROR;
}
static int ble_disconnect(void *priv)
{
if (con_handle) {
if (BLE_ST_SEND_DISCONN != get_ble_work_state()) {
log_info(">>>ble send disconnect\n");
set_ble_work_state(BLE_ST_SEND_DISCONN);
ble_user_cmd_prepare(BLE_CMD_DISCONNECT, 1, con_handle);
} else {
log_info(">>>ble wait disconnect...\n");
}
return APP_BLE_NO_ERROR;
} else {
return APP_BLE_OPERATION_ERROR;
}
}
static int get_buffer_vaild_len(void *priv)
{
u32 vaild_len = 0;
ble_user_cmd_prepare(BLE_CMD_ATT_VAILD_LEN, 1, &vaild_len);
return vaild_len;
}
static int app_send_user_data_do(void *priv, u8 *data, u16 len)
{
#if PRINT_DMA_DATA_EN
if (len < 128) {
log_info("-le_tx(%d):");
log_info_hexdump(data, len);
} else {
putchar('L');
}
#endif
return app_send_user_data(ATT_CHARACTERISTIC_ae82_01_VALUE_HANDLE, data, len, ATT_OP_AUTO_READ_CCC);
}
static int app_send_user_data_check(u16 len)
{
u32 buf_space = get_buffer_vaild_len(0);
if (len <= buf_space) {
return 1;
}
return 0;
}
static int regiest_wakeup_send(void *priv, void *cbk)
{
ble_resume_send_wakeup = cbk;
return APP_BLE_NO_ERROR;
}
static int regiest_recieve_cbk(void *priv, void *cbk)
{
channel_priv = (u32)priv;
app_recieve_callback = cbk;
return APP_BLE_NO_ERROR;
}
static int regiest_state_cbk(void *priv, void *cbk)
{
channel_priv = (u32)priv;
app_ble_state_callback = cbk;
return APP_BLE_NO_ERROR;
}
void bt_ble_adv_enable(u8 enable)
{
set_adv_enable(0, enable);
}
static void ble_module_enable(u8 en)
{
os_mutex_pend(&mutex, 0);
log_info("mode_en:%d\n", en);
if (en) {
extern u8 get_ble_gatt_role(void);
if (1 == get_ble_gatt_role()) {
ble_stack_gatt_role(0);
// register for HCI events
hci_event_callback_set(&cbk_packet_handler);
le_l2cap_register_packet_handler(&cbk_packet_handler);
}
complete = 0;
adv_ctrl_en = 1;
bt_ble_adv_enable(1);
} else {
if (con_handle) {
if (complete) {
os_mutex_post(&mutex);
return;
}
adv_ctrl_en = 0;
ble_disconnect(NULL);
} else {
bt_ble_adv_enable(0);
adv_ctrl_en = 0;
}
complete = 0;
}
os_mutex_post(&mutex);
}
static const char ble_ext_name[] = "(BLE)";
void bt_ble_init(void)
{
log_info("***** ble_init******\n");
const char *name_p = bt_get_local_name();
u8 ext_name_len = sizeof(ble_ext_name) - 1;
if (!os_mutex_valid(&mutex)) {
os_mutex_create(&mutex);
}
gap_device_name_len = strlen(name_p);
if (gap_device_name_len > BT_NAME_LEN_MAX - ext_name_len) {
gap_device_name_len = BT_NAME_LEN_MAX - ext_name_len;
}
//增加后缀,区分名字
memcpy(gap_device_name, name_p, gap_device_name_len);
memcpy(&gap_device_name[gap_device_name_len], "(BLE)", ext_name_len);
gap_device_name_len += ext_name_len;
log_info("ble name(%d): %s \n", gap_device_name_len, gap_device_name);
set_ble_work_state(BLE_ST_INIT_OK);
ble_module_enable(1);
}
static void stack_exit(void)
{
ble_module_enable(0);
/* set_ble_work_state(BLE_ST_SEND_STACK_EXIT); */
/* ble_user_cmd_prepare(BLE_CMD_STACK_EXIT, 1, 0); */
/* set_ble_work_state(BLE_ST_STACK_EXIT_COMPLETE); */
}
void bt_ble_exit(void)
{
log_info("***** ble_exit******\n");
stack_exit();
}
void ble_app_disconnect(void)
{
ble_disconnect(NULL);
}
void ble_cfg_net_result_notify(int event)
{
if (!complete) {
return;
}
if (event == NET_CONNECT_TIMEOUT_NOT_FOUND_SSID) {
app_send_user_data(ATT_CHARACTERISTIC_ae82_01_VALUE_HANDLE, rsp_cmd3, sizeof(rsp_cmd3), ATT_OP_AUTO_READ_CCC);
} else if (event == NET_CONNECT_ASSOCIAT_FAIL) {
app_send_user_data(ATT_CHARACTERISTIC_ae82_01_VALUE_HANDLE, rsp_cmd4, sizeof(rsp_cmd4), ATT_OP_AUTO_READ_CCC);
} else if (event == NET_EVENT_CONNECTED) {
app_send_user_data(ATT_CHARACTERISTIC_ae82_01_VALUE_HANDLE, rsp_cmd0, sizeof(rsp_cmd0), ATT_OP_AUTO_READ_CCC);
complete = 0;
#if !defined PAYMENT_AUDIO_SDK_ENABLE && !CONFIG_POWER_ON_ENABLE_BLE
sys_timeout_add(0, (void (*)(void *))ble_module_enable, 100);
#endif
}
}
static const struct ble_server_operation_t mi_ble_operation = {
.adv_enable = set_adv_enable,
.disconnect = ble_disconnect,
.get_buffer_vaild = get_buffer_vaild_len,
.send_data = (void *)app_send_user_data_do,
.regist_wakeup_send = regiest_wakeup_send,
.regist_recieve_cbk = regiest_recieve_cbk,
.regist_state_cbk = regiest_state_cbk,
};
void ble_get_server_operation_table(struct ble_server_operation_t **interface_pt)
{
*interface_pt = (void *)&mi_ble_operation;
}
#endif