Control Surface main
MIDI Control Surface library for Arduino
Loading...
Searching...
No Matches
advertising.c
Go to the documentation of this file.
1#ifdef ESP32
2#include <sdkconfig.h>
3#if CONFIG_BT_BLE_ENABLED
4
5#include "advertising.h"
6#include "logging.h"
7#include <esp_gap_ble_api.h>
8#include <string.h>
9
10// https://web.archive.org/web/20240318204212/https://developer.apple.com/accessories/Accessory-Design-Guidelines.pdf §49.4
11// Advertising data should contain: Flags, TX power, Local Name, Service
12// The primary services should always be advertised in the advertising PDU.
13// Secondary services should not be advertised.
14
15// Initial advertising data: Flags, TX power, Service
16static esp_ble_adv_data_t adv_data = {
17 .set_scan_rsp = false,
18 .include_name = false,
19 .include_txpower = true,
20 // Intervals as multiples of 1.25 milliseconds (e.g.0x000C = 15 ms)
21 // May be updated later:
22 .min_interval = 0x000C,
23 .max_interval = 0x000C,
24 .appearance = 0x00,
25 .manufacturer_len = 0,
26 .p_manufacturer_data = NULL,
27 .service_data_len = 0,
28 .p_service_data = NULL,
29 // Service advertisement will be set later:
30 .service_uuid_len = 0,
31 .p_service_uuid = NULL,
32 .flag = ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT,
33};
34
35// Scan response: Name
36static esp_ble_adv_data_t adv_data_rsp = {
37 .set_scan_rsp = true,
38 .include_name = true,
39 .include_txpower = false,
40 // Zero means not included
41 .min_interval = 0x0000,
42 .max_interval = 0x0000,
43 .appearance = 0x00,
44 .manufacturer_len = 0,
45 .p_manufacturer_data = NULL,
46 .service_data_len = 0,
47 .p_service_data = NULL,
48 .service_uuid_len = 0,
49 .p_service_uuid = NULL,
50 .flag = ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT,
51};
52
53// https://web.archive.org/web/20240318204212/https://developer.apple.com/accessories/Accessory-Design-Guidelines.pdf §49.5
54// The accessory should first use the recommended advertising interval of 20 ms for at least 30 seconds.
55static esp_ble_adv_params_t adv_params = {
56 .adv_int_min = 0x20, // 20 ms
57 .adv_int_max = 0x20,
58 .adv_type = ADV_TYPE_IND,
59 .own_addr_type = BLE_ADDR_TYPE_RPA_PUBLIC,
60 .channel_map = ADV_CHNL_ALL,
61 .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
62};
63
64uint8_t adv_config_done = 0;
65const uint8_t adv_config_flag = 1 << 0;
66const uint8_t scan_rsp_config_flag = 1 << 1;
67
68void advertising_set_service_uuid(const uint8_t uuid[], uint16_t length) {
69 ESP_LOGI("MIDIBLE", "advertising_set_service_uuid");
70 adv_data.p_service_uuid = (uint8_t *)uuid;
71 adv_data.service_uuid_len = length;
72}
73
74void advertising_set_connection_interval(uint16_t itvl_min, uint16_t itvl_max) {
75 adv_data.min_interval = itvl_min;
76 adv_data.max_interval = itvl_max;
77}
78
79void advertising_get_connection_interval(uint16_t *itvl_min,
80 uint16_t *itvl_max) {
81 *itvl_min = adv_data.min_interval;
82 *itvl_max = adv_data.max_interval;
83}
84
85bool advertising_config(void) {
86 ESP_LOGI("MIDIBLE", "advertising_config");
87 esp_err_t ret = esp_ble_gap_config_adv_data(&adv_data);
88 if (ret) {
89 ESP_LOGE("MIDIBLE", "config adv data failed, error code = %x", ret);
90 return false;
91 }
92 adv_config_done |= adv_config_flag;
93 ret = esp_ble_gap_config_adv_data(&adv_data_rsp);
94 if (ret) {
95 ESP_LOGE("MIDIBLE", "config adv rsp data failed, error code = %x", ret);
96 return false;
97 }
98 adv_config_done |= scan_rsp_config_flag;
99 return true;
100}
101
102bool advertising_handle_config_complete_event(esp_ble_gap_cb_param_t *param) {
103 if (param->adv_data_cmpl.status != ESP_BT_STATUS_SUCCESS) {
104 ESP_LOGE("MIDIBLE", "esp_ble_gap_config_adv_data failed: %d",
105 param->adv_data_cmpl.status);
106 return false;
107 }
108 // If this completes the config, start advertising (could be before or
109 // after the response config)
110 adv_config_done &= (~adv_config_flag);
111 if (adv_config_done == 0) {
113 }
114 return true;
115}
116
118 esp_ble_gap_cb_param_t *param) {
119 if (param->scan_rsp_data_cmpl.status != ESP_BT_STATUS_SUCCESS) {
120 ESP_LOGE("MIDIBLE", "esp_ble_gap_config_adv_data response failed: %d",
121 param->scan_rsp_data_cmpl.status);
122 return false;
123 }
124 // If this completes the config, start advertising (could be before or
125 // after the advertising config)
126 adv_config_done &= (~scan_rsp_config_flag);
127 if (adv_config_done == 0) {
129 }
130 return true;
131}
132
133void advertising_start(void) { esp_ble_gap_start_advertising(&adv_params); }
134
135#endif
136#endif
Advertising the MIDI service for Bluetooth Low Energy.
void advertising_set_service_uuid(const uint8_t uuid[], uint16_t length)
Set the UUID of the service to be advertised.
void advertising_get_connection_interval(uint16_t *itvl_min, uint16_t *itvl_max)
Get the connection interval range from the advertising data.
void advertising_start(void)
Start advertising, after already being configured.
void advertising_set_connection_interval(uint16_t itvl_min, uint16_t itvl_max)
Set the connection interval range in the advertising data.
bool advertising_handle_config_complete_event(esp_ble_gap_cb_param_t *param)
Callback that indicates that the configuration of the advertising data was complete.
bool advertising_config(void)
Configure the advertising data, register with the Bluetooth driver.
bool advertising_handle_config_response_complete_event(esp_ble_gap_cb_param_t *param)
Callback that indicates that the configuration of the advertising response data was complete.