Skip to content

Commit 9cb9c8a

Browse files
committed
BLEテスト
1 parent dd6f943 commit 9cb9c8a

File tree

4 files changed

+446
-0
lines changed

4 files changed

+446
-0
lines changed

libraries/Nefy_BLE/NefryBLE.cpp

Lines changed: 355 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,355 @@
1+
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "NefryBLE.h"
16+
#include "esp32-hal-log.h"
17+
18+
/* HCI Command opcode group field(OGF) */
19+
#define HCI_GRP_HOST_CONT_BASEBAND_CMDS (0x03 << 10) /* 0x0C00 */
20+
#define HCI_GRP_BLE_CMDS (0x08 << 10)
21+
22+
/* HCI Command opcode command field(OCF) */
23+
#define HCI_RESET (0x0003 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
24+
#define HCI_BLE_WRITE_ADV_ENABLE (0x000A | HCI_GRP_BLE_CMDS)
25+
#define HCI_BLE_WRITE_ADV_PARAMS (0x0006 | HCI_GRP_BLE_CMDS)
26+
#define HCI_BLE_WRITE_ADV_DATA (0x0008 | HCI_GRP_BLE_CMDS)
27+
28+
#define HCI_H4_CMD_PREAMBLE_SIZE (4)
29+
#define HCIC_PARAM_SIZE_WRITE_ADV_ENABLE (1)
30+
#define HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS (15)
31+
#define HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA (31)
32+
33+
/* EIR/AD data type definitions */
34+
#define BT_DATA_FLAGS 0x01 /* AD flags */
35+
#define BT_DATA_UUID16_SOME 0x02 /* 16-bit UUID, more available */
36+
#define BT_DATA_UUID16_ALL 0x03 /* 16-bit UUID, all listed */
37+
#define BT_DATA_UUID32_SOME 0x04 /* 32-bit UUID, more available */
38+
#define BT_DATA_UUID32_ALL 0x05 /* 32-bit UUID, all listed */
39+
#define BT_DATA_UUID128_SOME 0x06 /* 128-bit UUID, more available */
40+
#define BT_DATA_UUID128_ALL 0x07 /* 128-bit UUID, all listed */
41+
#define BT_DATA_NAME_SHORTENED 0x08 /* Shortened name */
42+
#define BT_DATA_NAME_COMPLETE 0x09 /* Complete name */
43+
#define BT_DATA_TX_POWER 0x0a /* Tx Power */
44+
#define BT_DATA_SOLICIT16 0x14 /* Solicit UUIDs, 16-bit */
45+
#define BT_DATA_SOLICIT128 0x15 /* Solicit UUIDs, 128-bit */
46+
#define BT_DATA_SVC_DATA16 0x16 /* Service data, 16-bit UUID */
47+
#define BT_DATA_GAP_APPEARANCE 0x19 /* GAP appearance */
48+
#define BT_DATA_SOLICIT32 0x1f /* Solicit UUIDs, 32-bit */
49+
#define BT_DATA_SVC_DATA32 0x20 /* Service data, 32-bit UUID */
50+
#define BT_DATA_SVC_DATA128 0x21 /* Service data, 128-bit UUID */
51+
#define BT_DATA_MANUFACTURER_DATA 0xff /* Manufacturer Specific Data */
52+
53+
54+
/* Advertising types */
55+
#define BLE_GAP_ADV_TYPE_ADV_IND 0x00
56+
#define BLE_GAP_ADV_TYPE_ADV_DIRECT_IND 0x01
57+
#define BLE_GAP_ADV_TYPE_ADV_SCAN_IND 0x02
58+
#define BLE_GAP_ADV_TYPE_ADV_NONCONN_IND 0x03
59+
60+
61+
/* Advertising Discovery Flags */
62+
#define BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE (0x01)
63+
#define BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE (0x02)
64+
#define BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED (0x04)
65+
#define BLE_GAP_ADV_FLAG_LE_BR_EDR_CONTROLLER (0x08)
66+
#define BLE_GAP_ADV_FLAG_LE_BR_EDR_HOST (0x10)
67+
#define BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE (BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED)
68+
#define BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE (BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED)
69+
70+
71+
/* Advertising Filter Policies */
72+
#define BLE_GAP_ADV_FP_ANY 0x00
73+
#define BLE_GAP_ADV_FP_FILTER_SCANREQ 0x01
74+
#define BLE_GAP_ADV_FP_FILTER_CONNREQ 0x02
75+
#define BLE_GAP_ADV_FP_FILTER_BOTH 0x03
76+
77+
78+
/* Advertising Device Address Types */
79+
#define BLE_GAP_ADDR_TYPE_PUBLIC 0x00
80+
#define BLE_GAP_ADDR_TYPE_RANDOM_STATIC 0x01
81+
#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE 0x02
82+
#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE 0x03
83+
84+
85+
/* GAP Advertising Channel Maps */
86+
#define GAP_ADVCHAN_37 0x01
87+
#define GAP_ADVCHAN_38 0x02
88+
#define GAP_ADVCHAN_39 0x04
89+
#define GAP_ADVCHAN_ALL GAP_ADVCHAN_37 | GAP_ADVCHAN_38 | GAP_ADVCHAN_39
90+
91+
92+
/* GAP Filter Policies */
93+
#define BLE_GAP_ADV_FP_ANY 0x00
94+
#define BLE_GAP_ADV_FP_FILTER_SCANREQ 0x01
95+
#define BLE_GAP_ADV_FP_FILTER_CONNREQ 0x02
96+
#define BLE_GAP_ADV_FP_FILTER_BOTH 0x03
97+
98+
#define BD_ADDR_LEN (6) /* Device address length */
99+
100+
101+
/*
102+
* BLE System
103+
*
104+
* */
105+
106+
/* HCI H4 message type definitions */
107+
enum {
108+
H4_TYPE_COMMAND = 1,
109+
H4_TYPE_ACL = 2,
110+
H4_TYPE_SCO = 3,
111+
H4_TYPE_EVENT = 4
112+
};
113+
114+
volatile bool _vhci_host_send_available = false;
115+
volatile bool _vhci_host_command_running = false;
116+
static uint16_t _vhci_host_command = 0x0000;
117+
static uint8_t _vhci_host_command_result = 0x00;
118+
119+
//controller is ready to receive command
120+
static void _on_tx_ready(void)
121+
{
122+
_vhci_host_send_available = true;
123+
}
124+
/*
125+
static void _dump_buf(const char * txt, uint8_t *data, uint16_t len){
126+
log_printf("%s[%u]:", txt, len);
127+
for (uint16_t i=0; i<len; i++)
128+
log_printf(" %02x", data[i]);
129+
log_printf("\n");
130+
}
131+
*/
132+
//controller has a packet
133+
static int _on_rx_data(uint8_t *data, uint16_t len)
134+
{
135+
if (len == 7 && *data == 0x04) {
136+
//baseband response
137+
uint16_t cmd = (((uint16_t)data[5] << 8) | data[4]);
138+
uint8_t res = data[6];
139+
if (_vhci_host_command_running && _vhci_host_command == cmd) {
140+
//_dump_buf("BLE: res", data, len);
141+
_vhci_host_command_result = res;
142+
_vhci_host_command_running = false;
143+
return 0;
144+
}
145+
else if (cmd == 0) {
146+
log_e("error %u", res);
147+
}
148+
}
149+
150+
//_dump_buf("BLE: rx", data, len);
151+
return 0;
152+
}
153+
154+
155+
156+
157+
static esp_vhci_host_callback_t vhci_host_cb = {
158+
_on_tx_ready,
159+
_on_rx_data
160+
};
161+
162+
static bool _esp_ble_start()
163+
{
164+
if (btStart()) {
165+
esp_vhci_host_register_callback(&vhci_host_cb);
166+
uint8_t i = 0;
167+
while (!esp_vhci_host_check_send_available() && i++ < 100) {
168+
delay(10);
169+
}
170+
if (i >= 100) {
171+
log_e("esp_vhci_host_check_send_available failed");
172+
return false;
173+
}
174+
_vhci_host_send_available = true;
175+
}
176+
else
177+
log_e("BT Failed");
178+
return true;
179+
}
180+
181+
static bool _esp_ble_stop()
182+
{
183+
if (btStarted()) {
184+
_vhci_host_send_available = false;
185+
btStop();
186+
esp_vhci_host_register_callback(NULL);
187+
}
188+
return true;
189+
}
190+
191+
//public
192+
193+
static uint8_t ble_send_cmd(uint16_t cmd, uint8_t * data, uint8_t len) {
194+
static uint8_t buf[36];
195+
if (len > 32) {
196+
//too much data
197+
return 2;
198+
}
199+
uint16_t i = 0;
200+
while (!_vhci_host_send_available && i++ < 1000) {
201+
delay(1);
202+
}
203+
if (i >= 1000) {
204+
log_e("_vhci_host_send_available failed");
205+
return 1;
206+
}
207+
uint8_t outlen = len + HCI_H4_CMD_PREAMBLE_SIZE;
208+
buf[0] = H4_TYPE_COMMAND;
209+
buf[1] = (uint8_t)(cmd & 0xFF);
210+
buf[2] = (uint8_t)(cmd >> 8);
211+
buf[3] = len;
212+
if (len) {
213+
memcpy(buf + 4, data, len);
214+
}
215+
_vhci_host_send_available = false;
216+
_vhci_host_command_running = true;
217+
_vhci_host_command = cmd;
218+
219+
//log_printf("BLE: cmd: 0x%04X, data[%u]:", cmd, len);
220+
//for (uint16_t i=0; i<len; i++) log_printf(" %02x", buf[i+4]);
221+
//log_printf("\n");
222+
223+
esp_vhci_host_send_packet(buf, outlen);
224+
while (_vhci_host_command_running);
225+
int res = _vhci_host_command_result;
226+
//log_printf("BLE: cmd: 0x%04X, res: %u\n", cmd, res);
227+
return res;
228+
}
229+
230+
231+
/*
232+
* BLE Arduino
233+
*
234+
* */
235+
236+
enum {
237+
UNIT_0_625_MS = 625, /* Number of microseconds in 0.625 milliseconds. */
238+
UNIT_1_25_MS = 1250, /* Number of microseconds in 1.25 milliseconds. */
239+
UNIT_10_MS = 10000 /* Number of microseconds in 10 milliseconds. */
240+
};
241+
242+
/* BLE Advertising parameters struct */
243+
typedef struct ble_gap_adv_params_s {
244+
uint8_t type;
245+
uint8_t own_addr_type;
246+
uint8_t addr_type;
247+
uint8_t addr[BD_ADDR_LEN];
248+
uint8_t fp; // filter policy
249+
uint16_t interval_min; // minimum advertising interval between 0x0020 and 0x4000 in 0.625 ms units (20ms to 10.24s)
250+
uint16_t interval_max;
251+
uint8_t chn_map;
252+
} ble_adv_params_t;
253+
254+
#define MSEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000) / (RESOLUTION))
255+
#define UINT16_TO_STREAM(p, u16) {*(p)++ = (uint8_t)(u16); *(p)++ = (uint8_t)((u16) >> 8);}
256+
#define UINT8_TO_STREAM(p, u8) {*(p)++ = (uint8_t)(u8);}
257+
#define BDADDR_TO_STREAM(p, a) {int i; for (i = 0; i < BD_ADDR_LEN; i++) *(p)++ = (uint8_t) a[BD_ADDR_LEN - 1 - i];}
258+
#define ARRAY_TO_STREAM(p, a, len) {int i; for (i = 0; i < len; i++) *(p)++ = (uint8_t) a[i];}
259+
260+
Nefry_BLE::Nefry_BLE()
261+
{
262+
uint8_t peerAddr[BD_ADDR_LEN] = { 0x80, 0x81, 0x82, 0x83, 0x84, 0x85 };
263+
_ble_adv_param = (ble_adv_params_t*)malloc(sizeof(ble_adv_params_t));
264+
memset(_ble_adv_param, 0x00, sizeof(ble_adv_params_t));
265+
_ble_adv_param->type = BLE_GAP_ADV_TYPE_ADV_NONCONN_IND;//not connectable
266+
_ble_adv_param->chn_map = GAP_ADVCHAN_ALL; // 37, 38, 39 channels
267+
_ble_adv_param->fp = 0;//any
268+
_ble_adv_param->interval_min = 512;
269+
_ble_adv_param->interval_max = 1024;
270+
_ble_adv_param->addr_type = 0;//public
271+
memcpy(_ble_adv_param->addr, peerAddr, BD_ADDR_LEN);
272+
local_name = "esp32";
273+
}
274+
275+
Nefry_BLE::~Nefry_BLE(void)
276+
{
277+
free(_ble_adv_param);
278+
_esp_ble_stop();
279+
}
280+
281+
bool Nefry_BLE::begin()
282+
{
283+
if (!_esp_ble_start()) {
284+
return false;
285+
}
286+
ble_send_cmd(HCI_RESET, NULL, 0);
287+
288+
_ble_send_adv_param();
289+
_ble_send_adv_data();
290+
291+
uint8_t adv_enable = 1;
292+
ble_send_cmd(HCI_BLE_WRITE_ADV_ENABLE, &adv_enable, HCIC_PARAM_SIZE_WRITE_ADV_ENABLE);
293+
return true;
294+
}
295+
296+
297+
void Nefry_BLE::end()
298+
{
299+
uint8_t adv_enable = 0;
300+
ble_send_cmd(HCI_BLE_WRITE_ADV_ENABLE, &adv_enable, HCIC_PARAM_SIZE_WRITE_ADV_ENABLE);
301+
ble_send_cmd(HCI_RESET, NULL, 0);
302+
_esp_ble_stop();
303+
}
304+
305+
void Nefry_BLE::_ble_send_adv_param(void)
306+
{
307+
uint8_t dbuf[HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS];
308+
uint8_t *buf = dbuf;
309+
UINT16_TO_STREAM(buf, _ble_adv_param->interval_min);
310+
UINT16_TO_STREAM(buf, _ble_adv_param->interval_max);
311+
UINT8_TO_STREAM(buf, _ble_adv_param->type);
312+
UINT8_TO_STREAM(buf, _ble_adv_param->own_addr_type);
313+
UINT8_TO_STREAM(buf, _ble_adv_param->addr_type);
314+
ARRAY_TO_STREAM(buf, _ble_adv_param->addr, BD_ADDR_LEN);
315+
UINT8_TO_STREAM(buf, _ble_adv_param->chn_map);
316+
UINT8_TO_STREAM(buf, _ble_adv_param->fp);
317+
ble_send_cmd(HCI_BLE_WRITE_ADV_PARAMS, dbuf, HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS);
318+
}
319+
320+
void Nefry_BLE::_ble_send_adv_data(void)
321+
{
322+
uint8_t adv_data[31];
323+
uint8_t adv_data_len;
324+
325+
adv_data[0] = 2; // Len
326+
adv_data[1] = 0x01; // Type Flags
327+
adv_data[2] = 0x06; // GENERAL_DISC_MODE 0x02 | BR_EDR_NOT_SUPPORTED 0x04
328+
adv_data[3] = 3; // Len
329+
adv_data[4] = 0x03; // Type 16-Bit UUID
330+
adv_data[5] = 0xAA; // Eddystone UUID 2 -> 0xFEAA LSB
331+
adv_data[6] = 0xFE; // Eddystone UUID 1 MSB
332+
adv_data[7] = 19; // Length of Beacon Data
333+
adv_data[8] = 0x16; // Type Service Data
334+
adv_data[9] = 0xAA; // Eddystone UUID 2 -> 0xFEAA LSB
335+
adv_data[10] = 0xFE; // Eddystone UUID 1 MSB
336+
adv_data[11] = 0x10; // Eddystone Frame Type
337+
adv_data[12] = 0x20; // Beacons TX power at 0m
338+
adv_data[13] = 0x03; // URL Scheme 'https://'
339+
adv_data[14] = 0x67; // URL add 1 'g'
340+
adv_data[15] = 0x6F; // URL add 2 'o'
341+
adv_data[16] = 0x6F; // URL add 3 'o'
342+
adv_data[17] = 0x2E; // URL add 4 '.'
343+
adv_data[18] = 0x67; // URL add 5 'g'
344+
adv_data[19] = 0x6C; // URL add 6 'l'
345+
adv_data[20] = 0x2F; // URL add 7 '/'
346+
adv_data[21] = 0x32; // URL add 8 '2'
347+
adv_data[22] = 0x79; // URL add 9 'y'
348+
adv_data[23] = 0x43; // URL add 10 'C'
349+
adv_data[24] = 0x36; // URL add 11 '6'
350+
adv_data[25] = 0x4B; // URL add 12 'K'
351+
adv_data[26] = 0x58; // URL add 13 'X'
352+
353+
adv_data_len = 27;
354+
ble_send_cmd(HCI_BLE_WRITE_ADV_DATA, (uint8_t *)adv_data, HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1);
355+
}

0 commit comments

Comments
 (0)