/** * Copyright (c) 2019, Freqchip * * All rights reserved. * * */ /* * INCLUDES (包含头文件) */ #include #include "co_log.h" #include "gap_api.h" #include "gatt_api.h" #include "simple_gatt_service.h" #include "ble_simple_peripheral.h" /* * MACROS (宏定义) */ #undef LOG_LOCAL_LEVEL #define LOG_LOCAL_LEVEL (LOG_LEVEL_INFO) extern const char *app_tag; /* * CONSTANTS (常量定义) */ // GAP - Advertisement data (max size = 31 bytes, though this is // best kept short to conserve power while advertisting) // GAP-广播包的内容,最长31个字节.短一点的内容可以节省广播时的系统功耗. static uint8_t adv_data[] = { // service UUID, to notify central devices what services are included // in this peripheral. 告诉central本机有什么服务, 但这里先只放一个主要的. 0x03, // length of this data GAP_ADVTYPE_16BIT_MORE, // some of the UUID's, but not all 0xFF, 0xFE, }; // GAP - Scan response data (max size = 31 bytes, though this is // best kept short to conserve power while advertisting) // GAP-Scan response内容,最长31个字节.短一点的内容可以节省广播时的系统功耗. static uint8_t scan_rsp_data[] = { // complete name 设备名字 0x12, // length of this data GAP_ADVTYPE_LOCAL_NAME_COMPLETE, 'S','i','m','p','l','e',' ','P','e','r','i','p','h','e','r','a','l', // Tx power level 发射功率 0x02, // length of this data GAP_ADVTYPE_POWER_LEVEL, 0, // 0dBm }; /* * TYPEDEFS (类型定义) */ /* * GLOBAL VARIABLES (全局变量) */ /* * LOCAL VARIABLES (本地变量) */ /* * LOCAL FUNCTIONS (本地函数) */ static void sp_start_adv(void); /* * EXTERN FUNCTIONS (外部函数) */ /* * PUBLIC FUNCTIONS (全局函数) */ /** @function group ble peripheral device APIs (ble外设相关的API) * @{ */ /********************************************************************* * @fn app_gap_evt_cb * * @brief Application layer GAP event callback function. Handles GAP evnets. * * @param p_event - GAP events from BLE stack. * * * @return None. */ void app_gap_evt_cb(gap_event_t *p_event) { switch(p_event->type) { case GAP_EVT_ADV_END: { LOG_INFO(app_tag, "adv_end,status:0x%02x\r\n",p_event->param.adv_end.status); } break; case GAP_EVT_ALL_SVC_ADDED: { LOG_INFO(app_tag, "All service added\r\n"); sp_start_adv(); } break; case GAP_EVT_SLAVE_CONNECT: { LOG_INFO(app_tag, "slave[%d],connect. link_num:%d\r\n",p_event->param.slave_connect.conidx,gap_get_connect_num()); } break; case GAP_EVT_DISCONNECT: { LOG_INFO(app_tag, "Link[%d] disconnect,reason:0x%02X\r\n",p_event->param.disconnect.conidx ,p_event->param.disconnect.reason); gap_start_advertising(0); } break; case GAP_EVT_LINK_PARAM_REJECT: LOG_INFO(app_tag, "Link[%d]param reject,status:0x%02x\r\n" ,p_event->param.link_reject.conidx,p_event->param.link_reject.status); break; case GAP_EVT_LINK_PARAM_UPDATE: LOG_INFO(app_tag, "Link[%d]param update,interval:%d,latency:%d,timeout:%d\r\n",p_event->param.link_update.conidx ,p_event->param.link_update.con_interval,p_event->param.link_update.con_latency,p_event->param.link_update.sup_to); break; case GAP_EVT_PEER_FEATURE: LOG_INFO(app_tag, "peer[%d] feats ind\r\n",p_event->param.peer_feature.conidx); break; case GAP_EVT_MTU: LOG_INFO(app_tag, "mtu update,conidx=%d,mtu=%d\r\n" ,p_event->param.mtu.conidx,p_event->param.mtu.value); break; case GAP_EVT_LINK_RSSI: LOG_INFO(app_tag, "link rssi %d\r\n",p_event->param.link_rssi); break; case GAP_SEC_EVT_SLAVE_ENCRYPT: LOG_INFO(app_tag, "slave[%d]_encrypted\r\n",p_event->param.slave_encrypt_conidx); break; default: break; } } /********************************************************************* * @fn sp_start_adv * * @brief Set advertising data & scan response & advertising parameters and start advertising * * @param None. * * * @return None. */ static void sp_start_adv(void) { // Set advertising parameters gap_adv_param_t adv_param; adv_param.adv_mode = GAP_ADV_MODE_UNDIRECT; adv_param.adv_addr_type = GAP_ADDR_TYPE_PUBLIC; adv_param.adv_chnl_map = GAP_ADV_CHAN_ALL; adv_param.adv_filt_policy = GAP_ADV_ALLOW_SCAN_ANY_CON_ANY; adv_param.adv_intv_min = 300; adv_param.adv_intv_max = 300; gap_set_advertising_param(&adv_param); // Set advertising data & scan response data gap_set_advertising_data(adv_data, sizeof(adv_data)); gap_set_advertising_rsp_data(scan_rsp_data, sizeof(scan_rsp_data)); // Start advertising LOG_INFO(app_tag, "Start advertising...\r\n"); gap_start_advertising(0); } /********************************************************************* * @fn simple_peripheral_init * * @brief Initialize simple peripheral profile, BLE related parameters. * * @param None. * * * @return None. */ void simple_peripheral_init(void) { // set local device name uint8_t local_name[] = "Simple Peripheral"; gap_dev_name_set(local_name, sizeof(local_name)); // Initialize security related settings. gap_security_param_t param = { .mitm = false, .ble_secure_conn = false, .io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT, .pair_init_mode = GAP_PAIRING_MODE_WAIT_FOR_REQ, .bond_auth = true, .password = 0, }; gap_security_param_init(¶m); gap_set_cb_func(app_gap_evt_cb); mac_addr_t addr; enum ble_addr_type addr_type; gap_address_get(&addr, &addr_type); LOG_INFO(app_tag, "Local BDADDR: 0x%2X%2X%2X%2X%2X%2X\r\n", addr.addr[5], addr.addr[4], addr.addr[3], addr.addr[2], addr.addr[1], addr.addr[0]); // Adding services to database sp_gatt_add_service(); }