nimble WIP - writes kinda work now

This commit is contained in:
geeksville 2020-07-22 12:08:54 -07:00
parent 531f488fe8
commit b6a3deb341
8 changed files with 96 additions and 39 deletions

View File

@ -15,6 +15,7 @@ Nimble tasks:
- check BLE handle stability
- apply nimble RPA patches
- start RPA long test
- use a random pairing key rather than 123456
- implement nimble software update api
* update protocol description per cyclomies email thread

View File

@ -1,17 +1,19 @@
#include <Arduino.h>
#ifdef CONFIG_BLUEDROID_ENABLED
#include "../concurrency/LockGuard.h"
#include "../timing.h"
#include "BluetoothSoftwareUpdate.h"
#include "BluetoothUtil.h"
#include "RadioLibInterface.h"
#include "configuration.h"
#include "../concurrency/LockGuard.h"
#include "../timing.h"
#include <Arduino.h>
#include <BLE2902.h>
#include <CRC32.h>
#include <Update.h>
#include <esp_gatt_defs.h>
#ifdef CONFIG_BLUEDROID_ENABLED
#include "CallbackCharacteristic.h"
CRC32 crc;

View File

@ -1,9 +1,9 @@
#include "BluetoothUtil.h"
#include "MeshBluetoothService.h"
#include "PowerFSM.h"
#include "configuration.h"
#include "esp_task_wdt.h"
#include "main.h"
#include "nimble/BluetoothUtil.h"
#include "sleep.h"
#include "target_specific.h"
#include "utils.h"

View File

@ -43,8 +43,8 @@
// #include <driver/rtc_io.h>
#ifndef NO_ESP32
#include "BluetoothUtil.h"
#include "WiFi.h"
#include "nimble/BluetoothUtil.h"
#endif
#include "RF95Interface.h"

View File

@ -345,37 +345,75 @@ void reinitBluetooth()
#else
#include "PhoneAPI.h"
#include "host/util/util.h"
#include "main.h"
#include "nimble/NimbleDefs.h"
#include "services/gap/ble_svc_gap.h"
#include "services/gatt/ble_svc_gatt.h"
static uint8_t own_addr_type;
// This scratch buffer is used for various bluetooth reads/writes - but it is safe because only one bt operation can be in
// proccess at once
static uint8_t trBytes[max(FromRadio_size, ToRadio_size)];
class BluetoothPhoneAPI : public PhoneAPI
{
/**
* Subclasses can use this as a hook to provide custom notifications for their transport (i.e. bluetooth notifies)
*/
virtual void onNowHasData(uint32_t fromRadioNum)
{
PhoneAPI::onNowHasData(fromRadioNum);
DEBUG_MSG("BLE notify fromNum\n");
// fromNum.notify32(fromRadioNum);
}
};
static BluetoothPhoneAPI *bluetoothPhoneAPI;
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
auto om = ctxt->om;
uint16_t len = 0;
auto rc = ble_hs_mbuf_to_flat(om, trBytes, sizeof(trBytes), &len);
if (rc != 0) {
return BLE_ATT_ERR_UNLIKELY;
}
DEBUG_MSG("toRadioWriteCb data %p, len %u\n", trBytes, len);
bluetoothPhoneAPI->handleToRadio(trBytes, len);
return 0;
}
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
DEBUG_MSG("BLE fromRadio called\n");
size_t numBytes = bluetoothPhoneAPI->getFromRadio(trBytes);
// Someone is going to read our value as soon as this callback returns. So fill it with the next message in the queue
// or make empty if the queue is empty
auto rc = os_mbuf_append(ctxt->om, trBytes, numBytes);
assert(rc == 0);
return 0; // success
}
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
}
static uint32_t fromNum = 0;
// A C++ version of BLE_UUID128_INIT
#define BLE_UUID128_INIT_CPP(uuid128...) \
{ \
u : { \
type: \
BLE_UUID_TYPE_128 \
} \
, value: { uuid128 } \
}
DEBUG_MSG("BLE fromNum called\n");
auto rc = os_mbuf_append(ctxt->om, &fromNum,
sizeof(fromNum)); // FIXME - once we report real numbers we will need to consider endianness
assert(rc == 0);
return 0; // success
}
// Force arduino to keep ble data around
extern "C" bool btInUse()
@ -679,6 +717,11 @@ void reinitBluetooth()
DEBUG_MSG("Starting bluetooth\n");
esp_log_level_set("BTDM_INIT", ESP_LOG_VERBOSE);
if (!bluetoothPhoneAPI) {
bluetoothPhoneAPI = new BluetoothPhoneAPI();
bluetoothPhoneAPI->init();
}
// FIXME - if waking from light sleep, only esp_nimble_hci_init
// FIXME - why didn't this version work?
auto res = esp_nimble_hci_and_controller_init();
@ -723,7 +766,7 @@ void reinitBluetooth()
assert(res == 0);
/* Set the default device name. */
res = ble_svc_gap_device_name_set("nimble-bleprph");
res = ble_svc_gap_device_name_set(getDeviceName());
assert(res == 0);
/* XXX Need to have template for store */

View File

@ -27,15 +27,26 @@ 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. */
}},
.characteristics =
(struct ble_gatt_chr_def[]){{
// FIXME - remove non ENC access
.uuid = &toradio_uuid.u,
.access_cb = toradio_callback,
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_WRITE_ENC,
},
{
.uuid = &fromradio_uuid.u,
.access_cb = fromradio_callback,
.flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC,
},
{
.uuid = &fromnum_uuid.u,
.access_cb = fromnum_callback,
.flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC | BLE_GATT_CHR_F_NOTIFY,
},
{
0, /* No more characteristics in this service. */
}},
},
{

View File

@ -5,9 +5,9 @@
#include "NodeDB.h"
#include "configuration.h"
#include "error.h"
#include "timing.h"
#include "main.h"
#include "target_specific.h"
#include "timing.h"
#ifndef NO_ESP32
#include "esp32/pm.h"
@ -16,7 +16,7 @@
#include <driver/rtc_io.h>
#include <driver/uart.h>
#include "BluetoothUtil.h"
#include "nimble/BluetoothUtil.h"
esp_sleep_source_t wakeCause; // the reason we booted this time
#endif
@ -294,18 +294,18 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r
/**
* enable modem sleep mode as needed and available. Should lower our CPU current draw to an average of about 20mA.
*
*
* per https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/system/power_management.html
*
*
* supposedly according to https://github.com/espressif/arduino-esp32/issues/475 this is already done in arduino
*/
void enableModemSleep()
{
static esp_pm_config_esp32_t config; // filled with zeros because bss
static esp_pm_config_esp32_t config; // filled with zeros because bss
config.max_freq_mhz = CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ;
config.min_freq_mhz = 20; // 10Mhz is minimum recommended
config.light_sleep_enable = false;
DEBUG_MSG("Sleep request result %x\n", esp_pm_configure(&config));
config.max_freq_mhz = CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ;
config.min_freq_mhz = 20; // 10Mhz is minimum recommended
config.light_sleep_enable = false;
DEBUG_MSG("Sleep request result %x\n", esp_pm_configure(&config));
}
#endif