mirror of
https://github.com/meshtastic/firmware.git
synced 2025-06-25 22:20:27 +00:00
nimble WIP - add advertising boilerplate
This commit is contained in:
parent
102085808f
commit
7f6dc104f0
@ -7,8 +7,9 @@ Nimble tasks:
|
|||||||
- Nimble getting started https://espressif-esp-idf.readthedocs-hosted.com/zh_CN/release-v3.3/api-reference/bluetooth/nimble/index.html#overview? could it work with arduino esp-idf 4.2
|
- Nimble getting started https://espressif-esp-idf.readthedocs-hosted.com/zh_CN/release-v3.3/api-reference/bluetooth/nimble/index.html#overview? could it work with arduino esp-idf 4.2
|
||||||
- implement nimble device api
|
- implement nimble device api
|
||||||
- setup advertising https://mynewt.apache.org/latest/tutorials/ble/bleprph/bleprph-sections/bleprph-gap-event.html
|
- setup advertising https://mynewt.apache.org/latest/tutorials/ble/bleprph/bleprph-sections/bleprph-gap-event.html
|
||||||
- add security
|
- add security (at least bonding)
|
||||||
- test with app
|
- test with app
|
||||||
|
- remove unsecured read/write access
|
||||||
- restart advertising after client disconnects
|
- restart advertising after client disconnects
|
||||||
- make sleep work
|
- make sleep work
|
||||||
- check BLE handle stability
|
- check BLE handle stability
|
||||||
|
@ -78,7 +78,7 @@ src_filter =
|
|||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
debug_init_break = tbreak setup
|
debug_init_break = tbreak setup
|
||||||
build_flags =
|
build_flags =
|
||||||
${env.build_flags} -Wall -Wextra -Isrc/esp32 -mfix-esp32-psram-cache-issue -lnimble
|
${env.build_flags} -Wall -Wextra -Isrc/esp32 -mfix-esp32-psram-cache-issue -lnimble -std=c++11
|
||||||
# Hmm - this doesn't work yet
|
# Hmm - this doesn't work yet
|
||||||
# board_build.ldscript = linker/esp32.extram.bss.ld
|
# board_build.ldscript = linker/esp32.extram.bss.ld
|
||||||
lib_ignore = segger_rtt
|
lib_ignore = segger_rtt
|
||||||
|
12
src/BluetoothCommon.cpp
Normal file
12
src/BluetoothCommon.cpp
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#include "BluetoothCommon.h"
|
||||||
|
|
||||||
|
// NRF52 wants these constants as byte arrays
|
||||||
|
// Generated here https://yupana-engineering.com/online-uuid-to-c-array-converter - but in REVERSE BYTE ORDER
|
||||||
|
const uint8_t MESH_SERVICE_UUID_16[16u] = {0xfd, 0xea, 0x73, 0xe2, 0xca, 0x5d, 0xa8, 0x9f,
|
||||||
|
0x1f, 0x46, 0xa8, 0x15, 0x18, 0xb2, 0xa1, 0x6b};
|
||||||
|
const uint8_t TORADIO_UUID_16[16u] = {0xe7, 0x01, 0x44, 0x12, 0x66, 0x78, 0xdd, 0xa1,
|
||||||
|
0xad, 0x4d, 0x9e, 0x12, 0xd2, 0x76, 0x5c, 0xf7};
|
||||||
|
const uint8_t FROMRADIO_UUID_16[16u] = {0xd5, 0x54, 0xe4, 0xc5, 0x25, 0xc5, 0x31, 0xa5,
|
||||||
|
0x55, 0x4a, 0x02, 0xee, 0xc2, 0xbc, 0xa2, 0x8b};
|
||||||
|
const uint8_t FROMNUM_UUID_16[16u] = {0x53, 0x44, 0xe3, 0x47, 0x75, 0xaa, 0x70, 0xa6,
|
||||||
|
0x66, 0x4f, 0x00, 0xa8, 0x8c, 0xa1, 0x9d, 0xed};
|
@ -12,5 +12,9 @@
|
|||||||
#define FROMRADIO_UUID "8ba2bcc2-ee02-4a55-a531-c525c5e454d5"
|
#define FROMRADIO_UUID "8ba2bcc2-ee02-4a55-a531-c525c5e454d5"
|
||||||
#define FROMNUM_UUID "ed9da18c-a800-4f66-a670-aa7547e34453"
|
#define FROMNUM_UUID "ed9da18c-a800-4f66-a670-aa7547e34453"
|
||||||
|
|
||||||
|
// NRF52 wants these constants as byte arrays
|
||||||
|
// Generated here https://yupana-engineering.com/online-uuid-to-c-array-converter - but in REVERSE BYTE ORDER
|
||||||
|
extern const uint8_t MESH_SERVICE_UUID_16[], TORADIO_UUID_16[16u], FROMRADIO_UUID_16[], FROMNUM_UUID_16[];
|
||||||
|
|
||||||
/// Given a level between 0-100, update the BLE attribute
|
/// Given a level between 0-100, update the BLE attribute
|
||||||
void updateBatteryLevel(uint8_t level);
|
void updateBatteryLevel(uint8_t level);
|
@ -345,9 +345,37 @@ void reinitBluetooth()
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include "esp_nimble_hci.h"
|
#include "host/util/util.h"
|
||||||
#include "nimble/nimble_port.h"
|
#include "nimble/NimbleDefs.h"
|
||||||
#include "nimble/nimble_port_freertos.h"
|
#include "services/gap/ble_svc_gap.h"
|
||||||
|
#include "services/gatt/ble_svc_gatt.h"
|
||||||
|
|
||||||
|
static uint8_t own_addr_type;
|
||||||
|
|
||||||
|
int toradio_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg)
|
||||||
|
{
|
||||||
|
return BLE_ATT_ERR_UNLIKELY; // unimplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
int fromradio_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg)
|
||||||
|
{
|
||||||
|
return BLE_ATT_ERR_UNLIKELY; // unimplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
int fromnum_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg)
|
||||||
|
{
|
||||||
|
return BLE_ATT_ERR_UNLIKELY; // unimplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
// A C++ version of BLE_UUID128_INIT
|
||||||
|
#define BLE_UUID128_INIT_CPP(uuid128...) \
|
||||||
|
{ \
|
||||||
|
u : { \
|
||||||
|
type: \
|
||||||
|
BLE_UUID_TYPE_128 \
|
||||||
|
} \
|
||||||
|
, value: { uuid128 } \
|
||||||
|
}
|
||||||
|
|
||||||
// Force arduino to keep ble data around
|
// Force arduino to keep ble data around
|
||||||
bool btInUse()
|
bool btInUse()
|
||||||
@ -366,12 +394,6 @@ void deinitBLE()
|
|||||||
// FIXME - do we need to dealloc things? - what needs to stay alive across light sleep?
|
// FIXME - do we need to dealloc things? - what needs to stay alive across light sleep?
|
||||||
auto ret = nimble_port_stop();
|
auto ret = nimble_port_stop();
|
||||||
assert(ret == ESP_OK);
|
assert(ret == ESP_OK);
|
||||||
|
|
||||||
nimble_port_deinit(); // teardown nimble datastructures
|
|
||||||
nimble_port_freertos_deinit(); // delete the task
|
|
||||||
|
|
||||||
ret = esp_nimble_hci_and_controller_deinit();
|
|
||||||
assert(ret == ESP_OK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void loopBLE()
|
void loopBLE()
|
||||||
@ -379,10 +401,275 @@ void loopBLE()
|
|||||||
// FIXME
|
// FIXME
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" void ble_store_config_init(void);
|
||||||
|
|
||||||
|
/// Print a macaddr
|
||||||
|
static void print_addr(const uint8_t *v) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs information about a connection to the console.
|
||||||
|
*/
|
||||||
|
static void print_conn_desc(struct ble_gap_conn_desc *desc)
|
||||||
|
{
|
||||||
|
DEBUG_MSG("handle=%d our_ota_addr_type=%d our_ota_addr=", desc->conn_handle, desc->our_ota_addr.type);
|
||||||
|
print_addr(desc->our_ota_addr.val);
|
||||||
|
DEBUG_MSG(" our_id_addr_type=%d our_id_addr=", desc->our_id_addr.type);
|
||||||
|
print_addr(desc->our_id_addr.val);
|
||||||
|
DEBUG_MSG(" peer_ota_addr_type=%d peer_ota_addr=", desc->peer_ota_addr.type);
|
||||||
|
print_addr(desc->peer_ota_addr.val);
|
||||||
|
DEBUG_MSG(" peer_id_addr_type=%d peer_id_addr=", desc->peer_id_addr.type);
|
||||||
|
print_addr(desc->peer_id_addr.val);
|
||||||
|
DEBUG_MSG(" conn_itvl=%d conn_latency=%d supervision_timeout=%d "
|
||||||
|
"encrypted=%d authenticated=%d bonded=%d\n",
|
||||||
|
desc->conn_itvl, desc->conn_latency, desc->supervision_timeout, desc->sec_state.encrypted,
|
||||||
|
desc->sec_state.authenticated, desc->sec_state.bonded);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void advertise();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The nimble host executes this callback when a GAP event occurs. The
|
||||||
|
* application associates a GAP event callback with each connection that forms.
|
||||||
|
* bleprph uses the same callback for all connections.
|
||||||
|
*
|
||||||
|
* @param event The type of event being signalled.
|
||||||
|
* @param ctxt Various information pertaining to the event.
|
||||||
|
* @param arg Application-specified argument; unused by
|
||||||
|
* bleprph.
|
||||||
|
*
|
||||||
|
* @return 0 if the application successfully handled the
|
||||||
|
* event; nonzero on failure. The semantics
|
||||||
|
* of the return code is specific to the
|
||||||
|
* particular GAP event being signalled.
|
||||||
|
*/
|
||||||
|
static int bleprph_gap_event(struct ble_gap_event *event, void *arg)
|
||||||
|
{
|
||||||
|
struct ble_gap_conn_desc desc;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
switch (event->type) {
|
||||||
|
case BLE_GAP_EVENT_CONNECT:
|
||||||
|
/* A new connection was established or a connection attempt failed. */
|
||||||
|
DEBUG_MSG("connection %s; status=%d ", event->connect.status == 0 ? "established" : "failed", event->connect.status);
|
||||||
|
if (event->connect.status == 0) {
|
||||||
|
rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
|
||||||
|
assert(rc == 0);
|
||||||
|
print_conn_desc(&desc);
|
||||||
|
}
|
||||||
|
DEBUG_MSG("\n");
|
||||||
|
|
||||||
|
if (event->connect.status != 0) {
|
||||||
|
/* Connection failed; resume advertising. */
|
||||||
|
advertise();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case BLE_GAP_EVENT_DISCONNECT:
|
||||||
|
DEBUG_MSG("disconnect; reason=%d ", event->disconnect.reason);
|
||||||
|
// bleprph_print_conn_desc(&event->disconnect.conn);
|
||||||
|
DEBUG_MSG("\n");
|
||||||
|
|
||||||
|
/* Connection terminated; resume advertising. */
|
||||||
|
advertise();
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case BLE_GAP_EVENT_CONN_UPDATE:
|
||||||
|
/* The central has updated the connection parameters. */
|
||||||
|
DEBUG_MSG("connection updated; status=%d ", event->conn_update.status);
|
||||||
|
rc = ble_gap_conn_find(event->conn_update.conn_handle, &desc);
|
||||||
|
assert(rc == 0);
|
||||||
|
// bleprph_print_conn_desc(&desc);
|
||||||
|
DEBUG_MSG("\n");
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case BLE_GAP_EVENT_ADV_COMPLETE:
|
||||||
|
DEBUG_MSG("advertise complete; reason=%d", event->adv_complete.reason);
|
||||||
|
advertise();
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case BLE_GAP_EVENT_ENC_CHANGE:
|
||||||
|
/* Encryption has been enabled or disabled for this connection. */
|
||||||
|
DEBUG_MSG("encryption change event; status=%d ", event->enc_change.status);
|
||||||
|
rc = ble_gap_conn_find(event->enc_change.conn_handle, &desc);
|
||||||
|
assert(rc == 0);
|
||||||
|
// bleprph_print_conn_desc(&desc);
|
||||||
|
DEBUG_MSG("\n");
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case BLE_GAP_EVENT_SUBSCRIBE:
|
||||||
|
DEBUG_MSG("subscribe event; conn_handle=%d attr_handle=%d "
|
||||||
|
"reason=%d prevn=%d curn=%d previ=%d curi=%d\n",
|
||||||
|
event->subscribe.conn_handle, event->subscribe.attr_handle, event->subscribe.reason,
|
||||||
|
event->subscribe.prev_notify, event->subscribe.cur_notify, event->subscribe.prev_indicate,
|
||||||
|
event->subscribe.cur_indicate);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case BLE_GAP_EVENT_MTU:
|
||||||
|
DEBUG_MSG("mtu update event; conn_handle=%d cid=%d mtu=%d\n", event->mtu.conn_handle, event->mtu.channel_id,
|
||||||
|
event->mtu.value);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case BLE_GAP_EVENT_REPEAT_PAIRING:
|
||||||
|
/* We already have a bond with the peer, but it is attempting to
|
||||||
|
* establish a new secure link. This app sacrifices security for
|
||||||
|
* convenience: just throw away the old bond and accept the new link.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Delete the old bond. */
|
||||||
|
rc = ble_gap_conn_find(event->repeat_pairing.conn_handle, &desc);
|
||||||
|
assert(rc == 0);
|
||||||
|
ble_store_util_delete_peer(&desc.peer_id_addr);
|
||||||
|
|
||||||
|
/* Return BLE_GAP_REPEAT_PAIRING_RETRY to indicate that the host should
|
||||||
|
* continue with the pairing operation.
|
||||||
|
*/
|
||||||
|
return BLE_GAP_REPEAT_PAIRING_RETRY;
|
||||||
|
|
||||||
|
case BLE_GAP_EVENT_PASSKEY_ACTION:
|
||||||
|
DEBUG_MSG("PASSKEY_ACTION_EVENT started \n");
|
||||||
|
struct ble_sm_io pkey = {0};
|
||||||
|
|
||||||
|
if (event->passkey.params.action == BLE_SM_IOACT_DISP) {
|
||||||
|
pkey.action = event->passkey.params.action;
|
||||||
|
pkey.passkey = 123456; // This is the passkey to be entered on peer
|
||||||
|
DEBUG_MSG("Enter passkey %d on the peer side", pkey.passkey);
|
||||||
|
rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);
|
||||||
|
DEBUG_MSG("ble_sm_inject_io result: %d\n", rc);
|
||||||
|
} else {
|
||||||
|
DEBUG_MSG("FIXME - unexpected auth type\n");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Enables advertising with the following parameters:
|
||||||
|
* o General discoverable mode.
|
||||||
|
* o Undirected connectable mode.
|
||||||
|
*/
|
||||||
|
static void advertise(void)
|
||||||
|
{
|
||||||
|
struct ble_gap_adv_params adv_params;
|
||||||
|
struct ble_hs_adv_fields fields;
|
||||||
|
const char *name;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the advertisement data included in our advertisements:
|
||||||
|
* o Flags (indicates advertisement type and other general info).
|
||||||
|
* o Advertising tx power.
|
||||||
|
* o Device name.
|
||||||
|
* o 16-bit service UUIDs (alert notifications).
|
||||||
|
*/
|
||||||
|
|
||||||
|
memset(&fields, 0, sizeof fields);
|
||||||
|
|
||||||
|
/* Advertise two flags:
|
||||||
|
* o Discoverability in forthcoming advertisement (general)
|
||||||
|
* o BLE-only (BR/EDR unsupported).
|
||||||
|
*/
|
||||||
|
fields.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP;
|
||||||
|
|
||||||
|
/* Indicate that the TX power level field should be included; have the
|
||||||
|
* stack fill this value automatically. This is done by assigning the
|
||||||
|
* special value BLE_HS_ADV_TX_PWR_LVL_AUTO.
|
||||||
|
*/
|
||||||
|
fields.tx_pwr_lvl_is_present = 1;
|
||||||
|
fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO;
|
||||||
|
|
||||||
|
name = ble_svc_gap_device_name();
|
||||||
|
fields.name = (uint8_t *)name;
|
||||||
|
fields.name_len = strlen(name);
|
||||||
|
fields.name_is_complete = 1;
|
||||||
|
|
||||||
|
// fields.uuids16 = (ble_uuid16_t[]){BLE_UUID16_INIT(GATT_SVR_SVC_ALERT_UUID)};
|
||||||
|
// fields.num_uuids16 = 1;
|
||||||
|
// fields.uuids16_is_complete = 1;
|
||||||
|
|
||||||
|
rc = ble_gap_adv_set_fields(&fields);
|
||||||
|
if (rc != 0) {
|
||||||
|
MODLOG_DFLT(ERROR, "error setting advertisement data; rc=%d\n", rc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Begin advertising. */
|
||||||
|
memset(&adv_params, 0, sizeof adv_params);
|
||||||
|
adv_params.conn_mode = BLE_GAP_CONN_MODE_UND;
|
||||||
|
adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;
|
||||||
|
// FIXME - use RPA for first parameter
|
||||||
|
rc = ble_gap_adv_start(own_addr_type, NULL, BLE_HS_FOREVER, &adv_params, bleprph_gap_event, NULL);
|
||||||
|
if (rc != 0) {
|
||||||
|
MODLOG_DFLT(ERROR, "error enabling advertisement; rc=%d\n", rc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bleprph_on_reset(int reason)
|
||||||
|
{
|
||||||
|
DEBUG_MSG("Resetting state; reason=%d\n", reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bleprph_on_sync(void)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = ble_hs_util_ensure_addr(0);
|
||||||
|
assert(rc == 0);
|
||||||
|
|
||||||
|
/* Figure out address to use while advertising (no privacy for now) */
|
||||||
|
rc = ble_hs_id_infer_auto(0, &own_addr_type);
|
||||||
|
if (rc != 0) {
|
||||||
|
DEBUG_MSG("error determining address type; rc=%d\n", rc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Printing ADDR */
|
||||||
|
uint8_t addr_val[6] = {0};
|
||||||
|
rc = ble_hs_id_copy_addr(own_addr_type, addr_val, NULL);
|
||||||
|
|
||||||
|
DEBUG_MSG("Device Address: ");
|
||||||
|
print_addr(addr_val);
|
||||||
|
DEBUG_MSG("\n");
|
||||||
|
/* Begin advertising. */
|
||||||
|
advertise();
|
||||||
|
}
|
||||||
|
|
||||||
static void ble_host_task(void *param)
|
static void ble_host_task(void *param)
|
||||||
{
|
{
|
||||||
|
DEBUG_MSG("BLE task running\n");
|
||||||
nimble_port_run(); // This function will return only when nimble_port_stop() is executed.
|
nimble_port_run(); // This function will return only when nimble_port_stop() is executed.
|
||||||
// nimble_port_freertos_deinit();
|
|
||||||
|
nimble_port_deinit(); // teardown nimble datastructures
|
||||||
|
nimble_port_freertos_deinit(); // delete the task
|
||||||
|
|
||||||
|
auto ret = esp_nimble_hci_and_controller_deinit();
|
||||||
|
assert(ret == ESP_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg)
|
||||||
|
{
|
||||||
|
char buf[BLE_UUID_STR_LEN];
|
||||||
|
|
||||||
|
switch (ctxt->op) {
|
||||||
|
case BLE_GATT_REGISTER_OP_SVC:
|
||||||
|
DEBUG_MSG("registered service %s with handle=%d\n", ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf), ctxt->svc.handle);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BLE_GATT_REGISTER_OP_CHR:
|
||||||
|
DEBUG_MSG("registering characteristic %s with "
|
||||||
|
"def_handle=%d val_handle=%d\n",
|
||||||
|
ble_uuid_to_str(ctxt->chr.chr_def->uuid, buf), ctxt->chr.def_handle, ctxt->chr.val_handle);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BLE_GATT_REGISTER_OP_DSC:
|
||||||
|
DEBUG_MSG("registering descriptor %s with handle=%d\n", ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf), ctxt->dsc.handle);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This routine is called multiple times, once each time we come back from sleep
|
// This routine is called multiple times, once each time we come back from sleep
|
||||||
@ -394,13 +681,51 @@ void reinitBluetooth()
|
|||||||
// FIXME - why didn't this version work?
|
// FIXME - why didn't this version work?
|
||||||
// auto res = esp_nimble_hci_and_controller_init();
|
// auto res = esp_nimble_hci_and_controller_init();
|
||||||
auto res = esp_nimble_hci_init();
|
auto res = esp_nimble_hci_init();
|
||||||
DEBUG_MSG("BLE result %d\n", res);
|
// DEBUG_MSG("BLE result %d\n", res);
|
||||||
assert(res == ESP_OK);
|
assert(res == ESP_OK);
|
||||||
|
|
||||||
nimble_port_init();
|
nimble_port_init();
|
||||||
|
|
||||||
// FIXME Initialize the required NimBLE host configuration parameters and callbacks
|
/* Initialize the NimBLE host configuration. */
|
||||||
// Perform application specific tasks / initialization
|
ble_hs_cfg.reset_cb = bleprph_on_reset;
|
||||||
|
ble_hs_cfg.sync_cb = bleprph_on_sync;
|
||||||
|
ble_hs_cfg.gatts_register_cb = gatt_svr_register_cb;
|
||||||
|
ble_hs_cfg.store_status_cb = ble_store_util_status_rr;
|
||||||
|
|
||||||
|
ble_hs_cfg.sm_io_cap = BLE_SM_IO_CAP_DISP_ONLY;
|
||||||
|
#ifdef CONFIG_EXAMPLE_BONDING
|
||||||
|
ble_hs_cfg.sm_bonding = 1;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_EXAMPLE_MITM
|
||||||
|
ble_hs_cfg.sm_mitm = 1;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_EXAMPLE_USE_SC
|
||||||
|
ble_hs_cfg.sm_sc = 1;
|
||||||
|
#else
|
||||||
|
ble_hs_cfg.sm_sc = 0;
|
||||||
|
#ifdef CONFIG_EXAMPLE_BONDING
|
||||||
|
ble_hs_cfg.sm_our_key_dist = 1;
|
||||||
|
ble_hs_cfg.sm_their_key_dist = 1;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// add standard GAP services
|
||||||
|
ble_svc_gap_init();
|
||||||
|
ble_svc_gatt_init();
|
||||||
|
|
||||||
|
res = ble_gatts_count_cfg(
|
||||||
|
gatt_svr_svcs); // assigns handles? see docstring for note about clearing the handle list before calling SLEEP SUPPORT
|
||||||
|
assert(res == 0);
|
||||||
|
|
||||||
|
res = ble_gatts_add_svcs(gatt_svr_svcs);
|
||||||
|
assert(res == 0);
|
||||||
|
|
||||||
|
/* Set the default device name. */
|
||||||
|
res = ble_svc_gap_device_name_set("nimble-bleprph");
|
||||||
|
assert(res == 0);
|
||||||
|
|
||||||
|
/* XXX Need to have template for store */
|
||||||
|
ble_store_config_init();
|
||||||
|
|
||||||
nimble_port_freertos_init(ble_host_task);
|
nimble_port_freertos_init(ble_host_task);
|
||||||
}
|
}
|
||||||
|
44
src/nimble/NimbleDefs.c
Normal file
44
src/nimble/NimbleDefs.c
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#include "NimbleDefs.h"
|
||||||
|
|
||||||
|
// A C++ version of BLE_UUID128_INIT
|
||||||
|
#define BLE_UUID128_INIT_CPP(uuid128...) \
|
||||||
|
{ \
|
||||||
|
u : { \
|
||||||
|
type: \
|
||||||
|
BLE_UUID_TYPE_128 \
|
||||||
|
} \
|
||||||
|
, value: { uuid128 } \
|
||||||
|
}
|
||||||
|
|
||||||
|
static const ble_uuid128_t mesh_service_uuid =
|
||||||
|
BLE_UUID128_INIT(0xfd, 0xea, 0x73, 0xe2, 0xca, 0x5d, 0xa8, 0x9f, 0x1f, 0x46, 0xa8, 0x15, 0x18, 0xb2, 0xa1, 0x6b);
|
||||||
|
|
||||||
|
static const ble_uuid128_t toradio_uuid =
|
||||||
|
BLE_UUID128_INIT(0xe7, 0x01, 0x44, 0x12, 0x66, 0x78, 0xdd, 0xa1, 0xad, 0x4d, 0x9e, 0x12, 0xd2, 0x76, 0x5c, 0xf7);
|
||||||
|
|
||||||
|
static const ble_uuid128_t fromradio_uuid =
|
||||||
|
BLE_UUID128_INIT(0xd5, 0x54, 0xe4, 0xc5, 0x25, 0xc5, 0x31, 0xa5, 0x55, 0x4a, 0x02, 0xee, 0xc2, 0xbc, 0xa2, 0x8b);
|
||||||
|
|
||||||
|
static const ble_uuid128_t fromnum_uuid =
|
||||||
|
BLE_UUID128_INIT(0x53, 0x44, 0xe3, 0x47, 0x75, 0xaa, 0x70, 0xa6, 0x66, 0x4f, 0x00, 0xa8, 0x8c, 0xa1, 0x9d, 0xed);
|
||||||
|
|
||||||
|
const struct ble_gatt_svc_def gatt_svr_svcs[] = {
|
||||||
|
{
|
||||||
|
/*** Service: Security test. */
|
||||||
|
.type = BLE_GATT_SVC_TYPE_PRIMARY,
|
||||||
|
.uuid = &mesh_service_uuid.u,
|
||||||
|
.characteristics = (struct ble_gatt_chr_def[]){{
|
||||||
|
/*** Characteristic: Random number generator. */
|
||||||
|
.uuid = &toradio_uuid.u,
|
||||||
|
.access_cb = toradio_callback,
|
||||||
|
.flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0, /* No more characteristics in this service. */
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
0, /* No more services. */
|
||||||
|
},
|
||||||
|
};
|
23
src/nimble/NimbleDefs.h
Normal file
23
src/nimble/NimbleDefs.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esp_nimble_hci.h"
|
||||||
|
#include "host/ble_hs.h"
|
||||||
|
#include "host/ble_uuid.h"
|
||||||
|
#include "nimble/nimble_port.h"
|
||||||
|
#include "nimble/nimble_port_freertos.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int toradio_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg);
|
||||||
|
|
||||||
|
int fromradio_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg);
|
||||||
|
|
||||||
|
int fromnum_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg);
|
||||||
|
|
||||||
|
extern const struct ble_gatt_svc_def gatt_svr_svcs[];
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
};
|
||||||
|
#endif
|
@ -4,16 +4,7 @@
|
|||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include <bluefruit.h>
|
#include <bluefruit.h>
|
||||||
|
|
||||||
// NRF52 wants these constants as byte arrays
|
|
||||||
// Generated here https://yupana-engineering.com/online-uuid-to-c-array-converter - but in REVERSE BYTE ORDER
|
|
||||||
const uint8_t MESH_SERVICE_UUID_16[16u] = {0xfd, 0xea, 0x73, 0xe2, 0xca, 0x5d, 0xa8, 0x9f,
|
|
||||||
0x1f, 0x46, 0xa8, 0x15, 0x18, 0xb2, 0xa1, 0x6b};
|
|
||||||
const uint8_t TORADIO_UUID_16[16u] = {0xe7, 0x01, 0x44, 0x12, 0x66, 0x78, 0xdd, 0xa1,
|
|
||||||
0xad, 0x4d, 0x9e, 0x12, 0xd2, 0x76, 0x5c, 0xf7};
|
|
||||||
const uint8_t FROMRADIO_UUID_16[16u] = {0xd5, 0x54, 0xe4, 0xc5, 0x25, 0xc5, 0x31, 0xa5,
|
|
||||||
0x55, 0x4a, 0x02, 0xee, 0xc2, 0xbc, 0xa2, 0x8b};
|
|
||||||
const uint8_t FROMNUM_UUID_16[16u] = {0x53, 0x44, 0xe3, 0x47, 0x75, 0xaa, 0x70, 0xa6,
|
|
||||||
0x66, 0x4f, 0x00, 0xa8, 0x8c, 0xa1, 0x9d, 0xed};
|
|
||||||
|
|
||||||
static BLEService meshBleService = BLEService(BLEUuid(MESH_SERVICE_UUID_16));
|
static BLEService meshBleService = BLEService(BLEUuid(MESH_SERVICE_UUID_16));
|
||||||
static BLECharacteristic fromNum = BLECharacteristic(BLEUuid(FROMNUM_UUID_16));
|
static BLECharacteristic fromNum = BLECharacteristic(BLEUuid(FROMNUM_UUID_16));
|
||||||
|
Loading…
Reference in New Issue
Block a user