begin new ble charateristics

1.2-legacy
geeksville 2020-02-03 11:15:17 -08:00
rodzic e7f12b62ba
commit 8f7f4d894f
11 zmienionych plików z 95 dodań i 68 usunięć

Wyświetl plik

@ -1,5 +1,6 @@
# High priority
* implement new ble characteristics
* have MeshService keep a node DB by sniffing user messages
* have meshservice send location data on mesh (if device has a GPS)
* implement getCurrentTime() - set based off gps but then updated locally
@ -29,6 +30,7 @@
* do debug logging to android over bluetooth
* break out my bluetooth OTA software as a seperate library so others can use it
* never enter deep sleep while connected to USB power (but still go to other low power modes)
* How do avalanche beacons work? Could this do that as well? possibly by using beacon mode feature of the RF95?
# Pre-beta priority

Wyświetl plik

@ -5,23 +5,30 @@
#include <Arduino.h>
#include <assert.h>
#include <pb_encode.h>
#include <pb_decode.h>
#include "mesh.pb.h"
#include "MeshService.h"
#include "mesh-pb-constants.h"
static BLECharacteristic meshFromRadioCharacteristic("8ba2bcc2-ee02-4a55-a531-c525c5e454d5", BLECharacteristic::PROPERTY_READ);
static BLECharacteristic meshToRadioCharacteristic("f75c76d2-129e-4dad-a1dd-7866124401e7", BLECharacteristic::PROPERTY_WRITE);
static BLECharacteristic meshFromNumCharacteristic("ed9da18c-a800-4f66-a670-aa7547e34453", BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY);
static BLECharacteristic
meshFromRadioCharacteristic("8ba2bcc2-ee02-4a55-a531-c525c5e454d5", BLECharacteristic::PROPERTY_READ),
meshToRadioCharacteristic("f75c76d2-129e-4dad-a1dd-7866124401e7", BLECharacteristic::PROPERTY_WRITE),
meshFromNumCharacteristic("ed9da18c-a800-4f66-a670-aa7547e34453", BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY),
meshMyNodeCharacteristic("ea9f3f82-8dc4-4733-9452-1f6da28892a2", BLECharacteristic::PROPERTY_READ),
meshNodeInfoCharacteristic("d31e02e0-c8ab-4d3f-9cc9-0b8466bdabe8", BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_READ),
meshRadioCharacteristic("b56786c8-839a-44a1-b98e-a1724c4a0262", BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_READ),
meshOwnerCharacteristic("6ff1d8b6-e2de-41e3-8c0b-8fa384f64eb6", BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_READ);
/**
* Tell any bluetooth clients that the number of rx packets has changed
*/
void bluetoothNotifyFromNum(uint32_t newValue) {
void bluetoothNotifyFromNum(uint32_t newValue)
{
meshFromNumCharacteristic.setValue(newValue);
meshFromNumCharacteristic.notify();
}
class BluetoothMeshCallbacks : public BLECharacteristicCallbacks
{
void onRead(BLECharacteristic *c)
@ -54,15 +61,8 @@ class BluetoothMeshCallbacks : public BLECharacteristicCallbacks
static uint8_t trBytes[ToRadio_size];
pb_ostream_t stream = pb_ostream_from_buffer(trBytes, sizeof(trBytes));
if (!pb_encode(&stream, FromRadio_fields, &fradio))
{
Serial.printf("Error: can't encode FromRadio %s\n", PB_GET_ERROR(&stream));
}
else
{
c->setValue(trBytes, stream.bytes_written);
}
size_t numbytes = pb_encode_to_bytes(trBytes, sizeof(trBytes), FromRadio_fields, &fradio);
c->setValue(trBytes, numbytes);
}
}
else
@ -125,6 +125,18 @@ callback was called, but before it arrives at the phone. If the phone writes to
When the esp32 advances fromnum, it will delay doing the notify by 100ms, in the hopes that the notify will never actally need to be sent if the phone is already pulling from fromradio.
Note: that if the phone ever sees this number decrease, it means the esp32 has rebooted.
meshMyNodeCharacteristic("ea9f3f82-8dc4-4733-9452-1f6da28892a2", BLECharacteristic::PROPERTY_READ)
mynode - read/write this to access a MyNodeInfo protobuf
meshNodeInfoCharacteristic("d31e02e0-c8ab-4d3f-9cc9-0b8466bdabe8", BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_READ),
mynodeinfo - read this to get a series of node infos (ending with a null empty record), write to this to restart the read statemachine that returns all the node infos
meshRadioCharacteristic("b56786c8-839a-44a1-b98e-a1724c4a0262", BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_READ),
radio - read/write this to access a RadioConfig protobuf
meshOwnerCharacteristic("6ff1d8b6-e2de-41e3-8c0b-8fa384f64eb6", BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_READ)
owner - read/write this to access a User protobuf
Re: queue management
Not all messages are kept in the fromradio queue (filtered based on SubPacket):
* only the most recent Position and User messages for a particular node are kept

Wyświetl plik

@ -9,9 +9,10 @@
#include "configuration.h"
#include "NodeDB.h"
// Change to 434.0 or other frequency, must match RX's freq!
#define RF95_FREQ 915.0
// Change to 434.0 or other frequency, must match RX's freq! FIXME, choose a better default value
#define RF95_FREQ_US 915.0f
RadioConfig radioConfig;
MeshRadio::MeshRadio(MemoryPool<MeshPacket> &_pool, PointerQueue<MeshPacket> &_rxDest)
: rf95(NSS_GPIO, DIO0_GPIO),
@ -20,6 +21,8 @@ MeshRadio::MeshRadio(MemoryPool<MeshPacket> &_pool, PointerQueue<MeshPacket> &_r
rxDest(_rxDest),
txQueue(MAX_TX_QUEUE)
{
radioConfig.tx_power = 23;
radioConfig.center_freq = RF95_FREQ_US; // FIXME, pull this config from flash
}
bool MeshRadio::init()
@ -43,14 +46,13 @@ bool MeshRadio::init()
Serial.println("LoRa radio init OK!");
// Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM
if (!rf95.setFrequency(RF95_FREQ))
if (!rf95.setFrequency(radioConfig.center_freq))
{
Serial.println("setFrequency failed");
while (1)
;
}
Serial.print("Set Freq to: ");
Serial.println(RF95_FREQ);
Serial.printf("Set Freq to: %f\n", radioConfig.center_freq);
// Defaults after init are 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on
@ -58,7 +60,7 @@ bool MeshRadio::init()
// If you are using RFM95/96/97/98 modules which uses the PA_BOOST transmitter pin, then
// you can set transmitter powers from 5 to 23 dBm:
// FIXME - can we do this? It seems to be in the Heltec board.
rf95.setTxPower(23, false);
rf95.setTxPower(radioConfig.tx_power, false);
return true;
}
@ -90,6 +92,7 @@ void MeshRadio::handleReceive(MeshPacket *mp)
assert(res == pdTRUE);
}
void MeshRadio::loop()
{
// FIXME read from radio with recvfromAckTimeout
@ -121,10 +124,8 @@ static int16_t packetnum = 0; // packet counter, we increment per xmission
mp->from = srcaddr;
mp->to = destaddr;
pb_istream_t stream = pb_istream_from_buffer(radiobuf, rxlen);
if (!pb_decode(&stream, SubPacket_fields, p))
if (!pb_decode_from_bytes(radiobuf, rxlen, SubPacket_fields, p))
{
Serial.printf("Error: can't decode SubPacket %s\n", PB_GET_ERROR(&stream));
pool.release(mp);
}
else
@ -142,16 +143,10 @@ static int16_t packetnum = 0; // packet counter, we increment per xmission
Serial.println("sending queued packet on mesh");
assert(txp->has_payload);
pb_ostream_t stream = pb_ostream_from_buffer(radiobuf, sizeof(radiobuf));
if (!pb_encode(&stream, SubPacket_fields, &txp->payload))
{
Serial.printf("Error: can't encode SubPacket %s\n", PB_GET_ERROR(&stream));
}
else
{
int res = sendTo(txp->to, radiobuf, stream.bytes_written);
assert(res == ERRNO_OK);
}
size_t numbytes = pb_encode_to_bytes(radiobuf, sizeof(radiobuf), SubPacket_fields, &txp->payload);
int res = sendTo(txp->to, radiobuf, numbytes);
assert(res == ERRNO_OK);
bool loopbackTest = false; // if true we will pretend to receive any packets we just sent
if (loopbackTest)

Wyświetl plik

@ -52,3 +52,4 @@ private:
void handleReceive(MeshPacket *p);
};
extern RadioConfig radioConfig;

Wyświetl plik

@ -2,8 +2,6 @@
#include <Arduino.h>
#include <assert.h>
#include <pb_encode.h>
#include <pb_decode.h>
#include "mesh-pb-constants.h"
#include "MeshService.h"
#include "MeshBluetoothService.h"
@ -67,12 +65,7 @@ void MeshService::handleToRadio(std::string s)
{
static ToRadio r; // this is a static scratch object, any data must be copied elsewhere before returning
pb_istream_t stream = pb_istream_from_buffer((const uint8_t *)s.c_str(), s.length());
if (!pb_decode(&stream, ToRadio_fields, &r))
{
Serial.printf("Error: can't decode ToRadio %s\n", PB_GET_ERROR(&stream));
}
else
if (pb_decode_from_bytes((const uint8_t *)s.c_str(), s.length(), ToRadio_fields, &r))
{
switch (r.which_variant)
{
@ -80,18 +73,6 @@ void MeshService::handleToRadio(std::string s)
sendToMesh(r.variant.packet);
break;
case ToRadio_want_nodes_tag:
Serial.println("FIXME: ignoring want nodes");
break;
case ToRadio_set_radio_tag:
Serial.println("FIXME: ignoring set radio");
break;
case ToRadio_set_owner_tag:
Serial.println("FIXME: ignoring set owner");
break;
default:
Serial.println("Error: unexpected ToRadio variant");
break;

Wyświetl plik

@ -7,6 +7,7 @@
#include "mesh-pb-constants.h"
#include "NodeDB.h"
MyNodeInfo myNodeInfo;
NodeDB nodeDB;
/**

Wyświetl plik

@ -50,3 +50,4 @@ private:
};
extern NodeDB nodeDB;
extern MyNodeInfo myNodeInfo;

Wyświetl plik

@ -0,0 +1,38 @@
#include <Arduino.h>
#include "mesh-pb-constants.h"
#include <pb_encode.h>
#include <pb_decode.h>
#include <assert.h>
/// helper function for encoding a record as a protobuf, any failures to encode are fatal and we will panic
/// returns the encoded packet size
size_t pb_encode_to_bytes(uint8_t *destbuf, size_t destbufsize, const pb_msgdesc_t *fields, const void *src_struct)
{
pb_ostream_t stream = pb_ostream_from_buffer(destbuf, destbufsize);
if (!pb_encode(&stream, fields, &src_struct))
{
Serial.printf("Error: can't encode protobuf %s\n", PB_GET_ERROR(&stream));
assert(0); // FIXME - panic
}
else
{
return stream.bytes_written;
}
}
/// helper function for decoding a record as a protobuf, we will return false if the decoding failed
bool pb_decode_from_bytes(const uint8_t *srcbuf, size_t srcbufsize, const pb_msgdesc_t *fields, void *dest_struct)
{
pb_istream_t stream = pb_istream_from_buffer(srcbuf, srcbufsize);
if (!pb_decode(&stream, fields, &dest_struct))
{
Serial.printf("Error: can't decode protobuf %s\n", PB_GET_ERROR(&stream));
return false;
}
else
{
return true;
}
}

Wyświetl plik

@ -12,3 +12,11 @@
/// max number of nodes allowed in the mesh
#define MAX_NUM_NODES (member_size(DeviceState, node_db) / member_size(DeviceState, node_db[0]))
/// helper function for encoding a record as a protobuf, any failures to encode are fatal and we will panic
/// returns the encoded packet size
size_t pb_encode_to_bytes(uint8_t *destbuf, size_t destbufsize, const pb_msgdesc_t *fields, const void *src_struct);
/// helper function for decoding a record as a protobuf, we will return false if the decoding failed
bool pb_decode_from_bytes(const uint8_t *srcbuf, size_t srcbufsize, const pb_msgdesc_t *fields, void *dest_struct);

Wyświetl plik

@ -45,7 +45,7 @@ PB_BIND(MyNodeInfo, MyNodeInfo, AUTO)
PB_BIND(FromRadio, FromRadio, AUTO)
PB_BIND(ToRadio, ToRadio, 2)
PB_BIND(ToRadio, ToRadio, AUTO)
PB_BIND(ToRadio_WantNodes, ToRadio_WantNodes, AUTO)

Wyświetl plik

@ -127,9 +127,6 @@ typedef struct _ToRadio {
pb_size_t which_variant;
union {
MeshPacket packet;
ToRadio_WantNodes want_nodes;
RadioConfig set_radio;
User set_owner;
} variant;
} ToRadio;
@ -219,9 +216,6 @@ typedef struct _ToRadio {
#define FromRadio_packet_tag 2
#define FromRadio_num_tag 1
#define ToRadio_packet_tag 1
#define ToRadio_want_nodes_tag 100
#define ToRadio_set_radio_tag 101
#define ToRadio_set_owner_tag 102
/* Struct field encoding specification for nanopb */
#define Position_FIELDLIST(X, a) \
@ -336,16 +330,10 @@ X(a, STATIC, ONEOF, MESSAGE, (variant,packet,variant.packet), 2)
#define FromRadio_variant_packet_MSGTYPE MeshPacket
#define ToRadio_FIELDLIST(X, a) \
X(a, STATIC, ONEOF, MESSAGE, (variant,packet,variant.packet), 1) \
X(a, STATIC, ONEOF, MESSAGE, (variant,want_nodes,variant.want_nodes), 100) \
X(a, STATIC, ONEOF, MESSAGE, (variant,set_radio,variant.set_radio), 101) \
X(a, STATIC, ONEOF, MESSAGE, (variant,set_owner,variant.set_owner), 102)
X(a, STATIC, ONEOF, MESSAGE, (variant,packet,variant.packet), 1)
#define ToRadio_CALLBACK NULL
#define ToRadio_DEFAULT NULL
#define ToRadio_variant_packet_MSGTYPE MeshPacket
#define ToRadio_variant_want_nodes_MSGTYPE ToRadio_WantNodes
#define ToRadio_variant_set_radio_MSGTYPE RadioConfig
#define ToRadio_variant_set_owner_MSGTYPE User
#define ToRadio_WantNodes_FIELDLIST(X, a) \