Connection status admin message

This commit is contained in:
Ben Meadors 2023-02-03 08:50:10 -06:00
parent a8dd497575
commit d9031610ab
11 changed files with 149 additions and 123 deletions

View File

@ -17,4 +17,14 @@
extern const uint8_t MESH_SERVICE_UUID_16[], TORADIO_UUID_16[16u], FROMRADIO_UUID_16[], FROMNUM_UUID_16[]; 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);
class BluetoothApi
{
public:
virtual void setup();
virtual void shutdown();
virtual void clearBonds();
virtual bool isConnected();
virtual int getRssi() = 0;
};

View File

@ -33,6 +33,12 @@
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
#include "mesh/http/WebServer.h" #include "mesh/http/WebServer.h"
#include "nimble/NimbleBluetooth.h" #include "nimble/NimbleBluetooth.h"
NimbleBluetooth *nimbleBluetooth;
#endif
#ifdef ARCH_NRF52
#include "NRF52Bluetooth.h"
NRF52Bluetooth *nrf52Bluetooth;
#endif #endif
#if HAS_WIFI #if HAS_WIFI

View File

@ -9,6 +9,14 @@
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
#include <SparkFun_ATECCX08a_Arduino_Library.h> #include <SparkFun_ATECCX08a_Arduino_Library.h>
#endif #endif
#if defined(ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32S2)
#include "nimble/NimbleBluetooth.h"
extern NimbleBluetooth *nimbleBluetooth;
#endif
#ifdef ARCH_NRF52
#include "NRF52Bluetooth.h"
extern NRF52Bluetooth *nrf52Bluetooth;
#endif
extern uint8_t screen_found; extern uint8_t screen_found;
extern uint8_t screen_model; extern uint8_t screen_model;

View File

@ -2,13 +2,16 @@
#include "Channels.h" #include "Channels.h"
#include "MeshService.h" #include "MeshService.h"
#include "NodeDB.h" #include "NodeDB.h"
#include "PowerFSM.h"
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
#include "BleOta.h" #include "BleOta.h"
#endif #endif
#include "Router.h" #include "Router.h"
#include "configuration.h" #include "configuration.h"
#include "main.h" #include "main.h"
#ifdef ARCH_NRF52
#include "main.h"
#endif
#ifdef ARCH_PORTDUINO #ifdef ARCH_PORTDUINO
#include "unistd.h" #include "unistd.h"
#endif #endif
@ -30,8 +33,7 @@ static const char *secretReserved = "sekrit";
/// If buf is the reserved secret word, replace the buffer with currentVal /// If buf is the reserved secret word, replace the buffer with currentVal
static void writeSecret(char *buf, size_t bufsz, const char *currentVal) static void writeSecret(char *buf, size_t bufsz, const char *currentVal)
{ {
if (strcmp(buf, secretReserved) == 0) if (strcmp(buf, secretReserved) == 0) {
{
strncpy(buf, currentVal, bufsz); strncpy(buf, currentVal, bufsz);
} }
} }
@ -49,8 +51,7 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
bool handled = false; bool handled = false;
assert(r); assert(r);
switch (r->which_payload_variant) switch (r->which_payload_variant) {
{
/** /**
* Getters * Getters
@ -70,8 +71,7 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
handleGetModuleConfig(mp, r->get_module_config_request); handleGetModuleConfig(mp, r->get_module_config_request);
break; break;
case meshtastic_AdminMessage_get_channel_request_tag: case meshtastic_AdminMessage_get_channel_request_tag: {
{
uint32_t i = r->get_channel_request - 1; uint32_t i = r->get_channel_request - 1;
LOG_INFO("Client is getting channel %u\n", i); LOG_INFO("Client is getting channel %u\n", i);
if (i >= MAX_NUM_CHANNELS) if (i >= MAX_NUM_CHANNELS)
@ -110,22 +110,17 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
/** /**
* Other * Other
*/ */
case meshtastic_AdminMessage_reboot_seconds_tag: case meshtastic_AdminMessage_reboot_seconds_tag: {
{
reboot(r->reboot_seconds); reboot(r->reboot_seconds);
break; break;
} }
case meshtastic_AdminMessage_reboot_ota_seconds_tag: case meshtastic_AdminMessage_reboot_ota_seconds_tag: {
{
int32_t s = r->reboot_ota_seconds; int32_t s = r->reboot_ota_seconds;
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
if (BleOta::getOtaAppVersion().isEmpty()) if (BleOta::getOtaAppVersion().isEmpty()) {
{
LOG_INFO("No OTA firmware available, scheduling regular reboot in %d seconds\n", s); LOG_INFO("No OTA firmware available, scheduling regular reboot in %d seconds\n", s);
screen->startRebootScreen(); screen->startRebootScreen();
} } else {
else
{
screen->startFirmwareUpdateScreen(); screen->startFirmwareUpdateScreen();
BleOta::switchToOtaApp(); BleOta::switchToOtaApp();
LOG_INFO("Rebooting to OTA in %d seconds\n", s); LOG_INFO("Rebooting to OTA in %d seconds\n", s);
@ -137,46 +132,45 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
rebootAtMsec = (s < 0) ? 0 : (millis() + s * 1000); rebootAtMsec = (s < 0) ? 0 : (millis() + s * 1000);
break; break;
} }
case meshtastic_AdminMessage_shutdown_seconds_tag: case meshtastic_AdminMessage_shutdown_seconds_tag: {
{
int32_t s = r->shutdown_seconds; int32_t s = r->shutdown_seconds;
LOG_INFO("Shutdown in %d seconds\n", s); LOG_INFO("Shutdown in %d seconds\n", s);
shutdownAtMsec = (s < 0) ? 0 : (millis() + s * 1000); shutdownAtMsec = (s < 0) ? 0 : (millis() + s * 1000);
break; break;
} }
case meshtastic_AdminMessage_get_device_metadata_request_tag: case meshtastic_AdminMessage_get_device_metadata_request_tag: {
{
LOG_INFO("Client is getting device metadata\n"); LOG_INFO("Client is getting device metadata\n");
handleGetDeviceMetadata(mp); handleGetDeviceMetadata(mp);
break; break;
} }
case meshtastic_AdminMessage_factory_reset_tag: case meshtastic_AdminMessage_factory_reset_tag: {
{
LOG_INFO("Initiating factory reset\n"); LOG_INFO("Initiating factory reset\n");
nodeDB.factoryReset(); nodeDB.factoryReset();
reboot(DEFAULT_REBOOT_SECONDS); reboot(DEFAULT_REBOOT_SECONDS);
break; break;
} }
case meshtastic_AdminMessage_nodedb_reset_tag: case meshtastic_AdminMessage_nodedb_reset_tag: {
{
LOG_INFO("Initiating node-db reset\n"); LOG_INFO("Initiating node-db reset\n");
nodeDB.resetNodes(); nodeDB.resetNodes();
reboot(DEFAULT_REBOOT_SECONDS); reboot(DEFAULT_REBOOT_SECONDS);
break; break;
} }
case meshtastic_AdminMessage_begin_edit_settings_tag: case meshtastic_AdminMessage_begin_edit_settings_tag: {
{
LOG_INFO("Beginning transaction for editing settings\n"); LOG_INFO("Beginning transaction for editing settings\n");
hasOpenEditTransaction = true; hasOpenEditTransaction = true;
break; break;
} }
case meshtastic_AdminMessage_commit_edit_settings_tag: case meshtastic_AdminMessage_commit_edit_settings_tag: {
{
LOG_INFO("Committing transaction for edited settings\n"); LOG_INFO("Committing transaction for edited settings\n");
hasOpenEditTransaction = false; hasOpenEditTransaction = false;
saveChanges(SEGMENT_CONFIG | SEGMENT_MODULECONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS); saveChanges(SEGMENT_CONFIG | SEGMENT_MODULECONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS);
break; break;
} }
case meshtastic_AdminMessage_get_device_connection_status_request_tag: {
LOG_INFO("Client is getting device connection status\n");
handleGetDeviceConnectionStatus(mp);
break;
}
#ifdef ARCH_PORTDUINO #ifdef ARCH_PORTDUINO
case meshtastic_AdminMessage_exit_simulator_tag: case meshtastic_AdminMessage_exit_simulator_tag:
LOG_INFO("Exiting simulator\n"); LOG_INFO("Exiting simulator\n");
@ -188,16 +182,11 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
meshtastic_AdminMessage res = meshtastic_AdminMessage_init_default; meshtastic_AdminMessage res = meshtastic_AdminMessage_init_default;
AdminMessageHandleResult handleResult = MeshModule::handleAdminMessageForAllPlugins(mp, r, &res); AdminMessageHandleResult handleResult = MeshModule::handleAdminMessageForAllPlugins(mp, r, &res);
if (handleResult == AdminMessageHandleResult::HANDLED_WITH_RESPONSE) if (handleResult == AdminMessageHandleResult::HANDLED_WITH_RESPONSE) {
{
myReply = allocDataProtobuf(res); myReply = allocDataProtobuf(res);
} } else if (mp.decoded.want_response) {
else if (mp.decoded.want_response)
{
LOG_DEBUG("We did not responded to a request that wanted a respond. req.variant=%d\n", r->which_payload_variant); LOG_DEBUG("We did not responded to a request that wanted a respond. req.variant=%d\n", r->which_payload_variant);
} } else if (handleResult != AdminMessageHandleResult::HANDLED) {
else if (handleResult != AdminMessageHandleResult::HANDLED)
{
// Probably a message sent by us or sent to our local node. FIXME, we should avoid scanning these messages // Probably a message sent by us or sent to our local node. FIXME, we should avoid scanning these messages
LOG_INFO("Ignoring nonrelevant admin %d\n", r->which_payload_variant); LOG_INFO("Ignoring nonrelevant admin %d\n", r->which_payload_variant);
} }
@ -205,8 +194,7 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
} }
// If asked for a response and it is not yet set, generate an 'ACK' response // If asked for a response and it is not yet set, generate an 'ACK' response
if (mp.decoded.want_response && !myReply) if (mp.decoded.want_response && !myReply) {
{
myReply = allocErrorResponse(meshtastic_Routing_Error_NONE, &mp); myReply = allocErrorResponse(meshtastic_Routing_Error_NONE, &mp);
} }
@ -222,31 +210,26 @@ void AdminModule::handleSetOwner(const meshtastic_User &o)
int changed = 0; int changed = 0;
bool licensed_changed = false; bool licensed_changed = false;
if (*o.long_name) if (*o.long_name) {
{
changed |= strcmp(owner.long_name, o.long_name); changed |= strcmp(owner.long_name, o.long_name);
strncpy(owner.long_name, o.long_name, sizeof(owner.long_name)); strncpy(owner.long_name, o.long_name, sizeof(owner.long_name));
} }
if (*o.short_name) if (*o.short_name) {
{
changed |= strcmp(owner.short_name, o.short_name); changed |= strcmp(owner.short_name, o.short_name);
strncpy(owner.short_name, o.short_name, sizeof(owner.short_name)); strncpy(owner.short_name, o.short_name, sizeof(owner.short_name));
} }
if (*o.id) if (*o.id) {
{
changed |= strcmp(owner.id, o.id); changed |= strcmp(owner.id, o.id);
strncpy(owner.id, o.id, sizeof(owner.id)); strncpy(owner.id, o.id, sizeof(owner.id));
} }
if (owner.is_licensed != o.is_licensed) if (owner.is_licensed != o.is_licensed) {
{
changed = 1; changed = 1;
licensed_changed = true; licensed_changed = true;
owner.is_licensed = o.is_licensed; owner.is_licensed = o.is_licensed;
config.lora.override_duty_cycle = owner.is_licensed; // override duty cycle for licensed operators config.lora.override_duty_cycle = owner.is_licensed; // override duty cycle for licensed operators
} }
if (changed) if (changed) { // If nothing really changed, don't broadcast on the network or write to flash
{ // If nothing really changed, don't broadcast on the network or write to flash
service.reloadOwner(!hasOpenEditTransaction); service.reloadOwner(!hasOpenEditTransaction);
licensed_changed ? saveChanges(SEGMENT_CONFIG | SEGMENT_DEVICESTATE) : saveChanges(SEGMENT_DEVICESTATE); licensed_changed ? saveChanges(SEGMENT_CONFIG | SEGMENT_DEVICESTATE) : saveChanges(SEGMENT_DEVICESTATE);
} }
@ -257,8 +240,7 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c)
auto existingRole = config.device.role; auto existingRole = config.device.role;
bool isRegionUnset = (config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_UNSET); bool isRegionUnset = (config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_UNSET);
switch (c.which_payload_variant) switch (c.which_payload_variant) {
{
case meshtastic_Config_device_tag: case meshtastic_Config_device_tag:
LOG_INFO("Setting config: Device\n"); LOG_INFO("Setting config: Device\n");
config.has_device = true; config.has_device = true;
@ -293,8 +275,7 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c)
LOG_INFO("Setting config: LoRa\n"); LOG_INFO("Setting config: LoRa\n");
config.has_lora = true; config.has_lora = true;
config.lora = c.payload_variant.lora; config.lora = c.payload_variant.lora;
if (isRegionUnset && config.lora.region > meshtastic_Config_LoRaConfig_RegionCode_UNSET) if (isRegionUnset && config.lora.region > meshtastic_Config_LoRaConfig_RegionCode_UNSET) {
{
config.lora.tx_enabled = true; config.lora.tx_enabled = true;
} }
break; break;
@ -310,8 +291,7 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c)
void AdminModule::handleSetModuleConfig(const meshtastic_ModuleConfig &c) void AdminModule::handleSetModuleConfig(const meshtastic_ModuleConfig &c)
{ {
switch (c.which_payload_variant) switch (c.which_payload_variant) {
{
case meshtastic_ModuleConfig_mqtt_tag: case meshtastic_ModuleConfig_mqtt_tag:
LOG_INFO("Setting module config: MQTT\n"); LOG_INFO("Setting module config: MQTT\n");
moduleConfig.has_mqtt = true; moduleConfig.has_mqtt = true;
@ -375,8 +355,7 @@ void AdminModule::handleSetChannel(const meshtastic_Channel &cc)
void AdminModule::handleGetOwner(const meshtastic_MeshPacket &req) void AdminModule::handleGetOwner(const meshtastic_MeshPacket &req)
{ {
if (req.decoded.want_response) if (req.decoded.want_response) {
{
// We create the reply here // We create the reply here
meshtastic_AdminMessage res = meshtastic_AdminMessage_init_default; meshtastic_AdminMessage res = meshtastic_AdminMessage_init_default;
res.get_owner_response = owner; res.get_owner_response = owner;
@ -390,10 +369,8 @@ void AdminModule::handleGetConfig(const meshtastic_MeshPacket &req, const uint32
{ {
meshtastic_AdminMessage res = meshtastic_AdminMessage_init_default; meshtastic_AdminMessage res = meshtastic_AdminMessage_init_default;
if (req.decoded.want_response) if (req.decoded.want_response) {
{ switch (configType) {
switch (configType)
{
case meshtastic_AdminMessage_ConfigType_DEVICE_CONFIG: case meshtastic_AdminMessage_ConfigType_DEVICE_CONFIG:
LOG_INFO("Getting config: Device\n"); LOG_INFO("Getting config: Device\n");
res.get_config_response.which_payload_variant = meshtastic_Config_device_tag; res.get_config_response.which_payload_variant = meshtastic_Config_device_tag;
@ -448,10 +425,8 @@ void AdminModule::handleGetModuleConfig(const meshtastic_MeshPacket &req, const
{ {
meshtastic_AdminMessage res = meshtastic_AdminMessage_init_default; meshtastic_AdminMessage res = meshtastic_AdminMessage_init_default;
if (req.decoded.want_response) if (req.decoded.want_response) {
{ switch (configType) {
switch (configType)
{
case meshtastic_AdminMessage_ModuleConfigType_MQTT_CONFIG: case meshtastic_AdminMessage_ModuleConfigType_MQTT_CONFIG:
LOG_INFO("Getting module config: MQTT\n"); LOG_INFO("Getting module config: MQTT\n");
res.get_module_config_response.which_payload_variant = meshtastic_ModuleConfig_mqtt_tag; res.get_module_config_response.which_payload_variant = meshtastic_ModuleConfig_mqtt_tag;
@ -541,8 +516,7 @@ void AdminModule::handleGetDeviceConnectionStatus(const meshtastic_MeshPacket &r
conn.has_wifi = true; conn.has_wifi = true;
conn.wifi.status.status.is_connected = WiFi.status() != WL_CONNECTED; conn.wifi.status.status.is_connected = WiFi.status() != WL_CONNECTED;
strncpy(conn.wifi.ssid, config.network.wifi_ssid, 33); strncpy(conn.wifi.ssid, config.network.wifi_ssid, 33);
if (conn.wifi.status.status.is_connected) if (conn.wifi.status.status.is_connected) {
{
conn.wifi.rssi = WiFi.RSSI(); conn.wifi.rssi = WiFi.RSSI();
conn.wifi.status.status.ip_address = WiFi.localIP(); conn.wifi.status.status.ip_address = WiFi.localIP();
conn.wifi.status.status.is_mqtt_connected = mqtt && mqtt->connected(); conn.wifi.status.status.is_mqtt_connected = mqtt && mqtt->connected();
@ -552,18 +526,27 @@ void AdminModule::handleGetDeviceConnectionStatus(const meshtastic_MeshPacket &r
#if HAS_ETHERNET #if HAS_ETHERNET
conn.has_ethernet = true; conn.has_ethernet = true;
// conn.ethernet. if (Ethernet.linkStatus() == LinkON) {
conn.conn.ethernet.status.is_connected = true;
conn.conn.ethernet.status.ip_address = Ethernet.localIP();
conn.wifi.status.status.is_mqtt_connected = mqtt && mqtt->connected();
conn.wifi.status.status.is_syslog_connected = false; // FIXME wire this up
}
conn.conn.ethernet.status.is_connected = false;
#endif #endif
#if HAS_BLUETOOTH #if HAS_BLUETOOTH
conn.has_bluetooth = HAS_BLUETOOTH; conn.has_bluetooth = HAS_BLUETOOTH;
// nimbleBluetooth-> conn.bluetooth.pin = config.bluetooth.fixed_pin;
// #if ARCH_ESP32 #endif
#ifdef ARCH_ESP32
// #elif conn.bluetooth.is_connected = nimbleBluetooth->isConnected();
#elif defined(ARCH_NRF52)
conn.bluetooth.is_connected = nrf52Bluetooth->isConnected();
#endif #endif
conn.has_serial = true; // No serial-less devices conn.has_serial = true; // No serial-less devices
conn.serial.is_connected = powerFSM.getState() == &stateSERIAL;
conn.serial.baud = SERIAL_BAUD;
r.get_device_connection_status_response = conn; r.get_device_connection_status_response = conn;
r.which_payload_variant = meshtastic_AdminMessage_get_device_connection_status_response_tag; r.which_payload_variant = meshtastic_AdminMessage_get_device_connection_status_response_tag;
@ -572,8 +555,7 @@ void AdminModule::handleGetDeviceConnectionStatus(const meshtastic_MeshPacket &r
void AdminModule::handleGetChannel(const meshtastic_MeshPacket &req, uint32_t channelIndex) void AdminModule::handleGetChannel(const meshtastic_MeshPacket &req, uint32_t channelIndex)
{ {
if (req.decoded.want_response) if (req.decoded.want_response) {
{
// We create the reply here // We create the reply here
meshtastic_AdminMessage r = meshtastic_AdminMessage_init_default; meshtastic_AdminMessage r = meshtastic_AdminMessage_init_default;
r.get_channel_response = channels.getByIndex(channelIndex); r.get_channel_response = channels.getByIndex(channelIndex);
@ -591,17 +573,13 @@ void AdminModule::reboot(int32_t seconds)
void AdminModule::saveChanges(int saveWhat, bool shouldReboot) void AdminModule::saveChanges(int saveWhat, bool shouldReboot)
{ {
if (!hasOpenEditTransaction) if (!hasOpenEditTransaction) {
{
LOG_INFO("Saving changes to disk\n"); LOG_INFO("Saving changes to disk\n");
service.reloadConfig(saveWhat); // Calls saveToDisk among other things service.reloadConfig(saveWhat); // Calls saveToDisk among other things
} } else {
else
{
LOG_INFO("Delaying save of changes to disk until the open transaction is committed\n"); LOG_INFO("Delaying save of changes to disk until the open transaction is committed\n");
} }
if (shouldReboot) if (shouldReboot) {
{
reboot(DEFAULT_REBOOT_SECONDS); reboot(DEFAULT_REBOOT_SECONDS);
} }
} }

View File

@ -9,41 +9,41 @@
*/ */
class AdminModule : public ProtobufModule<meshtastic_AdminMessage> class AdminModule : public ProtobufModule<meshtastic_AdminMessage>
{ {
public: public:
/** Constructor /** Constructor
* name is for debugging output * name is for debugging output
*/ */
AdminModule(); AdminModule();
protected: protected:
/** Called to handle a particular incoming message /** Called to handle a particular incoming message
@return true if you've guaranteed you've handled this message and no other handlers should be considered for it @return true if you've guaranteed you've handled this message and no other handlers should be considered for it
*/ */
virtual bool handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_AdminMessage *p) override; virtual bool handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_AdminMessage *p) override;
private: private:
bool hasOpenEditTransaction = false; bool hasOpenEditTransaction = false;
void saveChanges(int saveWhat, bool shouldReboot = true); void saveChanges(int saveWhat, bool shouldReboot = true);
/** /**
* Getters * Getters
*/ */
void handleGetOwner(const meshtastic_MeshPacket &req); void handleGetOwner(const meshtastic_MeshPacket &req);
void handleGetConfig(const meshtastic_MeshPacket &req, uint32_t configType); void handleGetConfig(const meshtastic_MeshPacket &req, uint32_t configType);
void handleGetModuleConfig(const meshtastic_MeshPacket &req, uint32_t configType); void handleGetModuleConfig(const meshtastic_MeshPacket &req, uint32_t configType);
void handleGetChannel(const meshtastic_MeshPacket &req, uint32_t channelIndex); void handleGetChannel(const meshtastic_MeshPacket &req, uint32_t channelIndex);
void handleGetDeviceMetadata(const meshtastic_MeshPacket &req); void handleGetDeviceMetadata(const meshtastic_MeshPacket &req);
void handleGetDeviceConnectionStatus(const meshtastic_MeshPacket &req); void handleGetDeviceConnectionStatus(const meshtastic_MeshPacket &req);
/** /**
* Setters * Setters
*/ */
void handleSetOwner(const meshtastic_User &o); void handleSetOwner(const meshtastic_User &o);
void handleSetChannel(const meshtastic_Channel &cc); void handleSetChannel(const meshtastic_Channel &cc);
void handleSetConfig(const meshtastic_Config &c); void handleSetConfig(const meshtastic_Config &c);
void handleSetModuleConfig(const meshtastic_ModuleConfig &c); void handleSetModuleConfig(const meshtastic_ModuleConfig &c);
void handleSetChannel(); void handleSetChannel();
void reboot(int32_t seconds); void reboot(int32_t seconds);
}; };
extern AdminModule *adminModule; extern AdminModule *adminModule;

View File

@ -93,7 +93,6 @@ class NimbleBluetoothServerCallback : public NimBLEServerCallbacks
passkeyShowing = false; passkeyShowing = false;
screen->stopBluetoothPinScreen(); screen->stopBluetoothPinScreen();
} }
// bluetoothPhoneAPI->setInitialState();
} }
virtual void onDisconnect(NimBLEServer *pServer, ble_gap_conn_desc *desc) { LOG_INFO("BLE disconnect\n"); } virtual void onDisconnect(NimBLEServer *pServer, ble_gap_conn_desc *desc) { LOG_INFO("BLE disconnect\n"); }
@ -117,6 +116,21 @@ bool NimbleBluetooth::isActive()
return bleServer; return bleServer;
} }
bool NimbleBluetooth::isConnected()
{
return bleServer->getConnectedCount() > 0;
}
int NimbleBluetooth::getRssi()
{
if (bleServer && isConnected()) {
auto service = bleServer->getServiceByUUID(MESH_SERVICE_UUID);
uint16_t handle = service->getHandle();
return NimBLEDevice::getClientByID(handle)->getRssi();
}
return 0; // FIXME figure out where to source this
}
void NimbleBluetooth::setup() void NimbleBluetooth::setup()
{ {
// Uncomment for testing // Uncomment for testing
@ -135,7 +149,6 @@ void NimbleBluetooth::setup()
NimbleBluetoothServerCallback *serverCallbacks = new NimbleBluetoothServerCallback(); NimbleBluetoothServerCallback *serverCallbacks = new NimbleBluetoothServerCallback();
bleServer->setCallbacks(serverCallbacks, true); bleServer->setCallbacks(serverCallbacks, true);
setupService(); setupService();
startAdvertising(); startAdvertising();
} }

View File

@ -1,12 +1,15 @@
#pragma once #pragma once
#include "BluetoothCommon.h"
class NimbleBluetooth class NimbleBluetooth : BluetoothApi
{ {
public: public:
void setup(); void setup();
void shutdown(); void shutdown();
void clearBonds(); void clearBonds();
bool isActive(); bool isActive();
bool isConnected();
int getRssi();
private: private:
void setupService(); void setupService();

View File

@ -19,11 +19,9 @@
#include <nvs_flash.h> #include <nvs_flash.h>
#if !defined(CONFIG_IDF_TARGET_ESP32S2) #if !defined(CONFIG_IDF_TARGET_ESP32S2)
NimbleBluetooth *nimbleBluetooth;
void setBluetoothEnable(bool on) void setBluetoothEnable(bool on)
{ {
if (!isWifiAvailable() && config.bluetooth.enabled == true) { if (!isWifiAvailable() && config.bluetooth.enabled == true) {
if (!nimbleBluetooth) { if (!nimbleBluetooth) {
nimbleBluetooth = new NimbleBluetooth(); nimbleBluetooth = new NimbleBluetooth();

View File

@ -213,6 +213,16 @@ void NRF52Bluetooth::shutdown()
Bluefruit.Advertising.stop(); Bluefruit.Advertising.stop();
} }
bool NRF52Bluetooth::isConnected()
{
return Bluefruit.connected(connectionHandle);
}
int NRF52Bluetooth::getRssi()
{
return 0; // FIXME figure out where to source this
}
void NRF52Bluetooth::setup() void NRF52Bluetooth::setup()
{ {
// Initialise the Bluefruit module // Initialise the Bluefruit module

View File

@ -1,13 +1,16 @@
#pragma once #pragma once
#include "BluetoothCommon.h"
#include <Arduino.h> #include <Arduino.h>
class NRF52Bluetooth class NRF52Bluetooth : BluetoothApi
{ {
public: public:
void setup(); void setup();
void shutdown(); void shutdown();
void clearBonds(); void clearBonds();
bool isConnected();
int getRssi();
private: private:
static void onConnectionSecured(uint16_t conn_handle); static void onConnectionSecured(uint16_t conn_handle);

View File

@ -8,9 +8,8 @@
#include <stdio.h> #include <stdio.h>
// #include <Adafruit_USBD_Device.h> // #include <Adafruit_USBD_Device.h>
#include "NodeDB.h" #include "NodeDB.h"
#include "NRF52Bluetooth.h"
#include "error.h" #include "error.h"
#include "main.h"
#ifdef BQ25703A_ADDR #ifdef BQ25703A_ADDR
#include "BQ25713.h" #include "BQ25713.h"
@ -63,8 +62,6 @@ static void initBrownout()
// We don't bother with setting up brownout if soft device is disabled - because during production we always use softdevice // We don't bother with setting up brownout if soft device is disabled - because during production we always use softdevice
} }
NRF52Bluetooth *nrf52Bluetooth;
static bool bleOn = false; static bool bleOn = false;
static const bool useSoftDevice = true; // Set to false for easier debugging static const bool useSoftDevice = true; // Set to false for easier debugging