first test
This commit is contained in:
parent
ae4d5baac2
commit
87ceb9b5a4
|
|
@ -518,13 +518,44 @@
|
|||
>Enable bluetooth</label
|
||||
>
|
||||
</div>
|
||||
<div class="col-6 mt-1">
|
||||
<label for="bluetooth.type" class="form-label">Bluetooth Type</label>
|
||||
<select name="bluetooth.type" id="bluetooth.type" class="form-control">
|
||||
<option value="0">BLE for iPhone</option>
|
||||
<option value="1">BT Classic</option>
|
||||
<option value="2">BLE for Android</option>
|
||||
</select>
|
||||
<div class="col-12">
|
||||
<label
|
||||
for="bluetooth.deviceName"
|
||||
class="form-label"
|
||||
>Password</label>
|
||||
<input
|
||||
name="bluetooth.deviceName"
|
||||
id="bluetooth.deviceName"
|
||||
class="form-control"
|
||||
placeholder="LoRaTracker"
|
||||
value="LoRaTracker"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-check form-switch">
|
||||
<input
|
||||
type="checkbox"
|
||||
name="bluetooth.useBLE"
|
||||
id="bluetooth.useBLE"
|
||||
class="form-check-input"
|
||||
/>
|
||||
<label
|
||||
for="bluetooth.useBLE"
|
||||
class="form-label"
|
||||
>Enable = BLE / Disable = BT Classic</label
|
||||
>
|
||||
</div>
|
||||
<div class="form-check form-switch">
|
||||
<input
|
||||
type="checkbox"
|
||||
name="bluetooth.useKISS"
|
||||
id="bluetooth.useKISS"
|
||||
class="form-check-input"
|
||||
/>
|
||||
<label
|
||||
for="bluetooth.useKISS"
|
||||
class="form-label"
|
||||
>Enable = KISS / Disable = TNC2</label
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -246,7 +246,9 @@ function loadSettings(settings) {
|
|||
|
||||
// BLUETOOTH
|
||||
document.getElementById("bluetooth.active").checked = settings.bluetooth.active;
|
||||
document.getElementById("bluetooth.type").value = settings.bluetooth.type;
|
||||
document.getElementById("bluetooth.deviceName").value = settings.bluetooth.deviceName;
|
||||
document.getElementById("bluetooth.useBLE").checked = settings.bluetooth.useBLE;
|
||||
document.getElementById("bluetooth.useKISS").checked = settings.bluetooth.useKISS;
|
||||
|
||||
// PTT Trigger
|
||||
document.getElementById("ptt.active").checked = settings.pttTrigger.active;
|
||||
|
|
|
|||
|
|
@ -91,8 +91,10 @@ public:
|
|||
|
||||
class BLUETOOTH {
|
||||
public:
|
||||
byte type;
|
||||
bool active;
|
||||
String deviceName;
|
||||
bool useBLE;
|
||||
bool useKISS;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ TinyGPSPlus gps;
|
|||
BluetoothSerial SerialBT;
|
||||
#endif
|
||||
|
||||
String versionDate = "2025.01.11";
|
||||
String versionDate = "2025.01.22";
|
||||
|
||||
uint8_t myBeaconsIndex = 0;
|
||||
int myBeaconsSize = Config.beacons.size();
|
||||
|
|
@ -76,6 +76,7 @@ uint32_t refreshDisplayTime = millis();
|
|||
|
||||
bool sendUpdate = true;
|
||||
|
||||
bool bluetoothActive = Config.bluetooth.active;
|
||||
bool bluetoothConnected = false;
|
||||
|
||||
uint32_t lastTx = 0.0;
|
||||
|
|
@ -136,13 +137,15 @@ void setup() {
|
|||
WiFi.mode(WIFI_OFF);
|
||||
logger.log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, "Main", "WiFi controller stopped");
|
||||
|
||||
if (Config.bluetooth.type == 0 || Config.bluetooth.type == 2) {
|
||||
if (bluetoothActive) {
|
||||
if (Config.bluetooth.useBLE) {
|
||||
BLE_Utils::setup();
|
||||
} else {
|
||||
#ifdef HAS_BT_CLASSIC
|
||||
BLUETOOTH_Utils::setup();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (!Config.simplifiedTrackerMode) {
|
||||
#ifdef BUTTON_PIN
|
||||
|
|
@ -200,7 +203,8 @@ void loop() {
|
|||
MSG_Utils::processOutputBuffer();
|
||||
MSG_Utils::clean15SegBuffer();
|
||||
|
||||
if (Config.bluetooth.type == 0 || Config.bluetooth.type == 2) {
|
||||
if (bluetoothActive) {
|
||||
if (Config.bluetooth.useBLE) {
|
||||
BLE_Utils::sendToPhone(packet.text.substring(3));
|
||||
BLE_Utils::sendToLoRa();
|
||||
} else {
|
||||
|
|
@ -209,6 +213,7 @@ void loop() {
|
|||
BLUETOOTH_Utils::sendToLoRa();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
MSG_Utils::ledNotification();
|
||||
Utils::checkFlashlight();
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@
|
|||
#define CHARACTERISTIC_UUID_RX_0 "00000002-ba2a-46c9-ae49-01b0961f68bb"
|
||||
|
||||
// ANDROID - BLE Terminal app (Serial Bluetooth Terminal from Playstore)
|
||||
#define SERVICE_UUID_2 "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"
|
||||
#define CHARACTERISTIC_UUID_TX_2 "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
|
||||
#define CHARACTERISTIC_UUID_RX_2 "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
|
||||
#define SERVICE_UUID_1 "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"
|
||||
#define CHARACTERISTIC_UUID_TX_1 "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
|
||||
#define CHARACTERISTIC_UUID_RX_1 "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
|
||||
|
||||
BLEServer *pServer;
|
||||
BLECharacteristic *pCharacteristicTx;
|
||||
|
|
@ -27,10 +27,10 @@ extern Configuration Config;
|
|||
extern Beacon *currentBeacon;
|
||||
extern logging::Logger logger;
|
||||
extern bool bluetoothConnected;
|
||||
extern bool bluetoothActive;
|
||||
|
||||
bool shouldSendBLEtoLoRa = false;
|
||||
String BLEToLoRaPacket = "";
|
||||
|
||||
String kissSerialBuffer = "";
|
||||
|
||||
|
||||
|
|
@ -52,7 +52,7 @@ class MyServerCallbacks : public NimBLEServerCallbacks {
|
|||
|
||||
class MyCallbacks : public NimBLECharacteristicCallbacks {
|
||||
void onWrite(NimBLECharacteristic *pCharacteristic) {
|
||||
if (Config.bluetooth.type == 0) { // AX25 KISS
|
||||
if (Config.bluetooth.useKISS) { // KISS (AX.25)
|
||||
std::string receivedData = pCharacteristic->getValue();
|
||||
delay(100);
|
||||
for (int i = 0; i < receivedData.length(); i++) {
|
||||
|
|
@ -72,7 +72,7 @@ class MyCallbacks : public NimBLECharacteristicCallbacks {
|
|||
}
|
||||
}
|
||||
}
|
||||
} else if (Config.bluetooth.type == 2) { // TNC2
|
||||
} else { // TNC2
|
||||
std::string receivedData = pCharacteristic->getValue();
|
||||
String receivedString = "";
|
||||
for (int i = 0; i < receivedData.length(); i++) receivedString += receivedData[i];
|
||||
|
|
@ -90,22 +90,21 @@ namespace BLE_Utils {
|
|||
}
|
||||
|
||||
void setup() {
|
||||
String id = currentBeacon->callsign;
|
||||
String BLEid = id.substring(0, id.indexOf("-")) + "-BLE";
|
||||
String BLEid = Config.bluetooth.deviceName;
|
||||
BLEDevice::init(BLEid.c_str());
|
||||
pServer = BLEDevice::createServer();
|
||||
pServer->setCallbacks(new MyServerCallbacks());
|
||||
|
||||
BLEService *pService = nullptr;
|
||||
|
||||
if (Config.bluetooth.type == 0) {
|
||||
if (Config.bluetooth.useKISS) { // KISS (AX.25)
|
||||
pService = pServer->createService(SERVICE_UUID_0);
|
||||
pCharacteristicTx = pService->createCharacteristic(CHARACTERISTIC_UUID_TX_0, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);
|
||||
pCharacteristicRx = pService->createCharacteristic(CHARACTERISTIC_UUID_RX_0, NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_NR);
|
||||
} else if (Config.bluetooth.type == 2) {
|
||||
pService = pServer->createService(SERVICE_UUID_2);
|
||||
pCharacteristicTx = pService->createCharacteristic(CHARACTERISTIC_UUID_TX_2, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);
|
||||
pCharacteristicRx = pService->createCharacteristic(CHARACTERISTIC_UUID_RX_2, NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_NR);
|
||||
} else { // TNC2
|
||||
pService = pServer->createService(SERVICE_UUID_1);
|
||||
pCharacteristicTx = pService->createCharacteristic(CHARACTERISTIC_UUID_TX_1, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);
|
||||
pCharacteristicRx = pService->createCharacteristic(CHARACTERISTIC_UUID_RX_1, NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_NR);
|
||||
}
|
||||
|
||||
if (pService != nullptr) {
|
||||
|
|
@ -114,10 +113,10 @@ namespace BLE_Utils {
|
|||
|
||||
BLEAdvertising* pAdvertising = BLEDevice::getAdvertising();
|
||||
|
||||
if (Config.bluetooth.type == 0) {
|
||||
if (Config.bluetooth.useKISS) {
|
||||
pAdvertising->addServiceUUID(SERVICE_UUID_0);
|
||||
} else if (Config.bluetooth.type == 2) {
|
||||
pAdvertising->addServiceUUID(SERVICE_UUID_2);
|
||||
} else {
|
||||
pAdvertising->addServiceUUID(SERVICE_UUID_1);
|
||||
}
|
||||
pServer->getAdvertising()->setScanResponse(true);
|
||||
pServer->getAdvertising()->setMinPreferred(0x06);
|
||||
|
|
@ -125,7 +124,7 @@ namespace BLE_Utils {
|
|||
pAdvertising->start();
|
||||
logger.log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, "BLE", "%s", "Waiting for BLE central to connect...");
|
||||
} else {
|
||||
logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "BLE", "Failed to create BLE service. Invalid bluetoothType: %d", Config.bluetooth.type);
|
||||
logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "BLE", "Failed to create BLE service");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -155,7 +154,7 @@ namespace BLE_Utils {
|
|||
}
|
||||
|
||||
void txToPhoneOverBLE(const String& frame) {
|
||||
if (Config.bluetooth.type == 0) { // AX25 KISS
|
||||
if (Config.bluetooth.useKISS) { // KISS (AX.25)
|
||||
const String kissEncodedFrame = KISS_Utils::encodeKISS(frame);
|
||||
|
||||
const char* t = kissEncodedFrame.c_str();
|
||||
|
|
|
|||
|
|
@ -14,16 +14,14 @@ extern BluetoothSerial SerialBT;
|
|||
extern logging::Logger logger;
|
||||
extern TinyGPSPlus gps;
|
||||
extern bool bluetoothConnected;
|
||||
|
||||
bool bluetoothActive;
|
||||
extern bool bluetoothActive;
|
||||
|
||||
namespace BLUETOOTH_Utils {
|
||||
String serialReceived;
|
||||
bool shouldSendToLoRa = false;
|
||||
bool useKiss = false;
|
||||
bool useKiss = Config.bluetooth.useKISS? true : false;
|
||||
|
||||
void setup() {
|
||||
bluetoothActive = Config.bluetooth.active;
|
||||
if (!bluetoothActive) {
|
||||
btStop();
|
||||
esp_bt_controller_disable();
|
||||
|
|
@ -36,8 +34,7 @@ namespace BLUETOOTH_Utils {
|
|||
SerialBT.register_callback(BLUETOOTH_Utils::bluetoothCallback);
|
||||
SerialBT.onData(BLUETOOTH_Utils::getData); // callback instead of while to avoid RX buffer limit when NMEA data received
|
||||
|
||||
String id = currentBeacon->callsign;
|
||||
String BTid = id.substring(0, id.indexOf("-")) + "-BT";
|
||||
String BTid = Config.bluetooth.deviceName;
|
||||
|
||||
if (!SerialBT.begin(String(BTid))) {
|
||||
logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "Bluetooth", "Starting Bluetooth failed!");
|
||||
|
|
@ -53,7 +50,6 @@ namespace BLUETOOTH_Utils {
|
|||
if (event == ESP_SPP_SRV_OPEN_EVT) {
|
||||
logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "Bluetooth", "Client connected !");
|
||||
bluetoothConnected = true;
|
||||
useKiss = false;
|
||||
} else if (event == ESP_SPP_CLOSE_EVT) {
|
||||
logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "Bluetooth", "Client disconnected !");
|
||||
bluetoothConnected = false;
|
||||
|
|
@ -63,9 +59,7 @@ namespace BLUETOOTH_Utils {
|
|||
}
|
||||
|
||||
void getData(const uint8_t *buffer, size_t size) {
|
||||
if (size == 0) {
|
||||
return;
|
||||
}
|
||||
if (size == 0) return;
|
||||
shouldSendToLoRa = false;
|
||||
serialReceived.clear();
|
||||
bool isNmea = buffer[0] == '$';
|
||||
|
|
@ -111,7 +105,7 @@ namespace BLUETOOTH_Utils {
|
|||
}
|
||||
|
||||
void sendToPhone(const String& packet) {
|
||||
if (!packet.isEmpty() && bluetoothActive) {
|
||||
if (!packet.isEmpty()) {
|
||||
if (useKiss) {
|
||||
logger.log(logging::LoggerLevel::LOGGER_LEVEL_DEBUG, "BT RX Kiss", "%s", serialReceived.c_str());
|
||||
SerialBT.println(KISS_Utils::encodeKISS(packet));
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include <ArduinoJson.h>
|
||||
#include <SPIFFS.h>
|
||||
#include "configuration.h"
|
||||
#include "board_pinout.h"
|
||||
#include "display.h"
|
||||
#include "logger.h"
|
||||
|
||||
|
|
@ -75,8 +76,14 @@ void Configuration::writeFile() {
|
|||
data["pttTrigger"]["postDelay"] = ptt.postDelay;
|
||||
data["pttTrigger"]["reverse"] = ptt.reverse;
|
||||
|
||||
data["bluetooth"]["type"] = bluetooth.type;
|
||||
data["bluetooth"]["active"] = bluetooth.active;
|
||||
data["bluetooth"]["deviceName"] = bluetooth.deviceName;
|
||||
#ifdef HAS_BT_CLASSIC
|
||||
data["bluetooth"]["useBLE"] = bluetooth.useBLE;
|
||||
#else
|
||||
data["bluetooth"]["useBLE"] = true; // fixed as BLE
|
||||
#endif
|
||||
data["bluetooth"]["useKISS"] = bluetooth.useKISS;
|
||||
|
||||
data["other"]["simplifiedTrackerMode"] = simplifiedTrackerMode;
|
||||
data["other"]["sendCommentAfterXBeacons"] = sendCommentAfterXBeacons;
|
||||
|
|
@ -175,8 +182,15 @@ bool Configuration::readFile() {
|
|||
ptt.postDelay = data["pttTrigger"]["postDelay"] | 0;
|
||||
ptt.reverse = data["pttTrigger"]["reverse"] | false;
|
||||
|
||||
bluetooth.type = data["bluetooth"]["type"] | 1;
|
||||
bluetooth.active = data["bluetooth"]["active"] | false;
|
||||
bluetooth.deviceName = data["bluetooth"]["deviceName"] | "LoRaTracker";
|
||||
#ifdef HAS_BT_CLASSIC
|
||||
bluetooth.useBLE = data["bluetooth"]["useBLE"] | false;
|
||||
bluetooth.useKISS = data["bluetooth"]["useKISS"] | false;
|
||||
#else
|
||||
bluetooth.useBLE = true; // fixed as BLE
|
||||
bluetooth.useKISS = data["bluetooth"]["useKISS"] | true; // true=KISS, false=TNC2
|
||||
#endif
|
||||
|
||||
simplifiedTrackerMode = data["other"]["simplifiedTrackerMode"] | false;
|
||||
sendCommentAfterXBeacons = data["other"]["sendCommentAfterXBeacons"] | 10;
|
||||
|
|
@ -299,8 +313,15 @@ void Configuration::init() {
|
|||
ptt.postDelay = 0;
|
||||
ptt.reverse = false;
|
||||
|
||||
bluetooth.type = 1;
|
||||
bluetooth.active = false;
|
||||
bluetooth.deviceName = "LoRaTracker";
|
||||
#ifdef HAS_BT_CLASSIC
|
||||
bluetooth.useBLE = false;
|
||||
bluetooth.useKISS = false;
|
||||
#else
|
||||
bluetooth.useBLE = true; // fixed as BLE
|
||||
bluetooth.useKISS = true;
|
||||
#endif
|
||||
|
||||
simplifiedTrackerMode = false;
|
||||
sendCommentAfterXBeacons = 10;
|
||||
|
|
|
|||
|
|
@ -179,7 +179,9 @@ namespace WEB_Utils {
|
|||
|
||||
// Bluetooth
|
||||
Config.bluetooth.active = request->hasParam("bluetooth.active", true);
|
||||
Config.bluetooth.type = request->getParam("bluetooth.type", true)->value().toInt();
|
||||
Config.bluetooth.deviceName = request->getParam("bluetooth.deviceName", true)->value();
|
||||
Config.bluetooth.useBLE = request->hasParam("bluetooth.useBLE", true);
|
||||
Config.bluetooth.useKISS = request->hasParam("bluetooth.useKISS", true);
|
||||
|
||||
// PTT Trigger
|
||||
Config.ptt.active = request->hasParam("ptt.active", true);
|
||||
|
|
@ -190,7 +192,10 @@ namespace WEB_Utils {
|
|||
|
||||
// WiFi AP
|
||||
Config.wifiAP.password = request->getParam("wifiAP.password", true)->value();
|
||||
Config.wifiAP.active = false; // when Configuration is finished Tracker returns to normal mode.
|
||||
|
||||
//
|
||||
Config.wifiAP.active = true;
|
||||
//Config.wifiAP.active = false; // when Configuration is finished Tracker returns to normal mode.
|
||||
|
||||
Config.writeFile();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue