实现打开蓝牙,还需要通过make menuconfig来开启蓝牙功能。
1 /* 2 This example code is in the Public Domain (or CC0 licensed, at your option.) 3 4 Unless required by applicable law or agreed to in writing, this 5 software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 6 CONDITIONS OF ANY KIND, either express or implied. 7 */ 8 9 #include <stdio.h> 10 #include <string.h> 11 #include "freertos/FreeRTOS.h" 12 #include "freertos/task.h" 13 #include "esp_bt.h" 14 #include "esp_log.h" 15 #include "nvs_flash.h" 16 17 static const char *tag = "BLE_ADV"; 18 19 #define HCI_H4_CMD_PREAMBLE_SIZE (4) 20 21 /* HCI Command opcode group field(OGF) */ 22 #define HCI_GRP_HOST_CONT_BASEBAND_CMDS (0x03 << 10) /* 0x0C00 */ 23 #define HCI_GRP_BLE_CMDS (0x08 << 10) 24 25 #define HCI_RESET (0x0003 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) 26 #define HCI_BLE_WRITE_ADV_ENABLE (0x000A | HCI_GRP_BLE_CMDS) 27 #define HCI_BLE_WRITE_ADV_PARAMS (0x0006 | HCI_GRP_BLE_CMDS) 28 #define HCI_BLE_WRITE_ADV_DATA (0x0008 | HCI_GRP_BLE_CMDS) 29 30 #define HCIC_PARAM_SIZE_WRITE_ADV_ENABLE (1) 31 #define HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS (15) 32 #define HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA (31) 33 34 #define BD_ADDR_LEN (6) /* Device address length */ 35 typedef uint8_t bd_addr_t[BD_ADDR_LEN]; /* Device address */ 36 37 #define UINT16_TO_STREAM(p, u16) {*(p)++ = (uint8_t)(u16); *(p)++ = (uint8_t)((u16) >> 8);} 38 #define UINT8_TO_STREAM(p, u8) {*(p)++ = (uint8_t)(u8);} 39 #define BDADDR_TO_STREAM(p, a) {int ijk; for (ijk = 0; ijk < BD_ADDR_LEN; ijk++) *(p)++ = (uint8_t) a[BD_ADDR_LEN - 1 - ijk];} 40 #define ARRAY_TO_STREAM(p, a, len) {int ijk; for (ijk = 0; ijk < len; ijk++) *(p)++ = (uint8_t) a[ijk];} 41 42 enum { 43 H4_TYPE_COMMAND = 1, 44 H4_TYPE_ACL = 2, 45 H4_TYPE_SCO = 3, 46 H4_TYPE_EVENT = 4 47 }; 48 49 static uint8_t hci_cmd_buf[128]; 50 51 /* 52 * @brief: BT controller callback function, used to notify the upper layer that 53 * controller is ready to receive command 54 */ 55 static void controller_rcv_pkt_ready(void) 56 { 57 printf("controller rcv pkt ready\n"); 58 } 59 60 /* 61 * @brief: BT controller callback function, to transfer data packet to upper 62 * controller is ready to receive command 63 */ 64 static int host_rcv_pkt(uint8_t *data, uint16_t len) 65 { 66 printf("host rcv pkt: "); 67 for (uint16_t i = 0; i < len; i++) { 68 printf("%02x", data[i]); 69 } 70 printf("\n"); 71 return 0; 72 } 73 74 static esp_vhci_host_callback_t vhci_host_cb = { 75 controller_rcv_pkt_ready, 76 host_rcv_pkt 77 }; 78 79 static uint16_t make_cmd_reset(uint8_t *buf) 80 { 81 UINT8_TO_STREAM (buf, H4_TYPE_COMMAND); 82 UINT16_TO_STREAM (buf, HCI_RESET); 83 UINT8_TO_STREAM (buf, 0); 84 return HCI_H4_CMD_PREAMBLE_SIZE; 85 } 86 87 static uint16_t make_cmd_ble_set_adv_enable (uint8_t *buf, uint8_t adv_enable) 88 { 89 UINT8_TO_STREAM (buf, H4_TYPE_COMMAND); 90 UINT16_TO_STREAM (buf, HCI_BLE_WRITE_ADV_ENABLE); 91 UINT8_TO_STREAM (buf, HCIC_PARAM_SIZE_WRITE_ADV_ENABLE); 92 UINT8_TO_STREAM (buf, adv_enable); 93 return HCI_H4_CMD_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_ADV_ENABLE; 94 } 95 96 static uint16_t make_cmd_ble_set_adv_param (uint8_t *buf, uint16_t adv_int_min, uint16_t adv_int_max, 97 uint8_t adv_type, uint8_t addr_type_own, 98 uint8_t addr_type_dir, bd_addr_t direct_bda, 99 uint8_t channel_map, uint8_t adv_filter_policy) 100 { 101 UINT8_TO_STREAM (buf, H4_TYPE_COMMAND); 102 UINT16_TO_STREAM (buf, HCI_BLE_WRITE_ADV_PARAMS); 103 UINT8_TO_STREAM (buf, HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS ); 104 105 UINT16_TO_STREAM (buf, adv_int_min); 106 UINT16_TO_STREAM (buf, adv_int_max); 107 UINT8_TO_STREAM (buf, adv_type); 108 UINT8_TO_STREAM (buf, addr_type_own); 109 UINT8_TO_STREAM (buf, addr_type_dir); 110 BDADDR_TO_STREAM (buf, direct_bda); 111 UINT8_TO_STREAM (buf, channel_map); 112 UINT8_TO_STREAM (buf, adv_filter_policy); 113 return HCI_H4_CMD_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS; 114 } 115 116 117 static uint16_t make_cmd_ble_set_adv_data(uint8_t *buf, uint8_t data_len, uint8_t *p_data) 118 { 119 UINT8_TO_STREAM (buf, H4_TYPE_COMMAND); 120 UINT16_TO_STREAM (buf, HCI_BLE_WRITE_ADV_DATA); 121 UINT8_TO_STREAM (buf, HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1); 122 123 memset(buf, 0, HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA); 124 125 if (p_data != NULL && data_len > 0) { 126 if (data_len > HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA) { 127 data_len = HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA; 128 } 129 130 UINT8_TO_STREAM (buf, data_len); 131 132 ARRAY_TO_STREAM (buf, p_data, data_len); 133 } 134 return HCI_H4_CMD_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1; 135 } 136 137 static void hci_cmd_send_reset(void) 138 { 139 uint16_t sz = make_cmd_reset (hci_cmd_buf); 140 esp_vhci_host_send_packet(hci_cmd_buf, sz); 141 } 142 143 static void hci_cmd_send_ble_adv_start(void) 144 { 145 uint16_t sz = make_cmd_ble_set_adv_enable (hci_cmd_buf, 1); 146 esp_vhci_host_send_packet(hci_cmd_buf, sz); 147 } 148 149 static void hci_cmd_send_ble_set_adv_param(void) 150 { 151 uint16_t adv_intv_min = 256; // 160ms 152 uint16_t adv_intv_max = 256; // 160ms 153 uint8_t adv_type = 0; // connectable undirected advertising (ADV_IND) 154 uint8_t own_addr_type = 0; // Public Device Address 155 uint8_t peer_addr_type = 0; // Public Device Address 156 uint8_t peer_addr[6] = {0x80, 0x81, 0x82, 0x83, 0x84, 0x85}; 157 uint8_t adv_chn_map = 0x07; // 37, 38, 39 158 uint8_t adv_filter_policy = 0; // Process All Conn and Scan 159 160 uint16_t sz = make_cmd_ble_set_adv_param(hci_cmd_buf, 161 adv_intv_min, 162 adv_intv_max, 163 adv_type, 164 own_addr_type, 165 peer_addr_type, 166 peer_addr, 167 adv_chn_map, 168 adv_filter_policy); 169 esp_vhci_host_send_packet(hci_cmd_buf, sz); 170 } 171 172 static void hci_cmd_send_ble_set_adv_data(void) 173 { 174 char *adv_name = "ESP-BLE"; 175 uint8_t name_len = (uint8_t)strlen(adv_name); 176 uint8_t adv_data[31] = {0x02, 0x01, 0x06, 0x0, 0x09}; 177 uint8_t adv_data_len; 178 179 adv_data[3] = name_len + 1; 180 for (int i = 0; i < name_len; i++) { 181 adv_data[5 + i] = (uint8_t)adv_name[i]; 182 } 183 adv_data_len = 5 + name_len; 184 185 uint16_t sz = make_cmd_ble_set_adv_data(hci_cmd_buf, adv_data_len, (uint8_t *)adv_data); 186 esp_vhci_host_send_packet(hci_cmd_buf, sz); 187 } 188 189 /* 190 * @brief: send HCI commands to perform BLE advertising; 191 */ 192 void bleAdvtTask(void *pvParameters) 193 { 194 int cmd_cnt = 0; 195 bool send_avail = false; 196 esp_vhci_host_register_callback(&vhci_host_cb); 197 printf("BLE advt task start\n"); 198 while (1) { 199 vTaskDelay(1000 / portTICK_PERIOD_MS); 200 send_avail = esp_vhci_host_check_send_available(); 201 if (send_avail) { 202 switch (cmd_cnt) { 203 case 0: hci_cmd_send_reset(); ++cmd_cnt; break; 204 case 1: hci_cmd_send_ble_set_adv_param(); ++cmd_cnt; break; 205 case 2: hci_cmd_send_ble_set_adv_data(); ++cmd_cnt; break; 206 case 3: hci_cmd_send_ble_adv_start(); ++cmd_cnt; break; 207 } 208 } 209 printf("BLE Advertise, flag_send_avail: %d, cmd_sent: %d\n", send_avail, cmd_cnt); 210 } 211 } 212 213 void app_main() 214 { 215 /* Initialize NVS 鈥� it is used to store PHY calibration data */ 216 esp_err_t ret = nvs_flash_init(); 217 if (ret == ESP_ERR_NVS_NO_FREE_PAGES) { 218 ESP_ERROR_CHECK(nvs_flash_erase()); 219 ret = nvs_flash_init(); 220 } 221 ESP_ERROR_CHECK( ret ); 222 esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); 223 224 ret = esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT); 225 if (ret) { 226 ESP_LOGI(tag, "Bluetooth controller release classic bt memory failed: %s", esp_err_to_name(ret)); 227 return; 228 } 229 230 if ((ret = esp_bt_controller_init(&bt_cfg)) != ESP_OK) { 231 ESP_LOGI(tag, "Bluetooth controller initialize failed: %s", esp_err_to_name(ret)); 232 return; 233 } 234 235 if ((ret = esp_bt_controller_enable(ESP_BT_MODE_BLE)) != ESP_OK) { 236 ESP_LOGI(tag, "Bluetooth controller enable failed: %s", esp_err_to_name(ret)); 237 return; 238 } 239 240 /* 241 * If call mem release here, also work. Input ESP_BT_MODE_CLASSIC_BT, the function will 242 * release the memory of classic bt mode. 243 * esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT); 244 * 245 */ 246 247 /* 248 * If call mem release here, also work. Input ESP_BT_MODE_BTDM, the function will calculate 249 * that the BLE mode is already used, so it will release of only classic bt mode. 250 * esp_bt_controller_mem_release(ESP_BT_MODE_BTDM); 251 */ 252 253 xTaskCreatePinnedToCore(&bleAdvtTask, "bleAdvtTask", 2048, NULL, 5, NULL, 0); 254 }