sforkowany z mirror/meshtastic-firmware
begin adding rx from radio handling
rodzic
5dca838ba3
commit
4051bf8465
|
@ -39,6 +39,7 @@
|
|||
"streambuf": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"utility": "cpp",
|
||||
"typeinfo": "cpp"
|
||||
"typeinfo": "cpp",
|
||||
"string": "cpp"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
/**
|
||||
* A pool based allocator
|
||||
*
|
||||
* Eventually this routine will even be safe for ISR use...
|
||||
*/
|
||||
template <class T> class MemoryPool {
|
||||
TypedQueue<T *> dead;
|
||||
|
||||
T *buf; // our large raw block of memory
|
||||
|
||||
public:
|
||||
MemoryPool(int maxElements): queued(maxElements), dead(maxElements) {
|
||||
buf = new T[maxElements];
|
||||
|
||||
// prefill dead
|
||||
for(int i = 0; i < maxElements; i++)
|
||||
release(&buf[i]);
|
||||
}
|
||||
|
||||
~MemoryPool() {
|
||||
delete[] buf;
|
||||
}
|
||||
|
||||
/// Return a queable object which has been prefilled with zeros
|
||||
T *allocZeroed(TickType_t maxWait = portMAX_DELAY) {
|
||||
T *p;
|
||||
|
||||
if(dead.dequeue(&p, maxWait) != pdTRUE)
|
||||
return NULL;
|
||||
|
||||
memset(p, 0, sizeof(T));
|
||||
return p;
|
||||
}
|
||||
|
||||
/// Return a buffer for use by others
|
||||
void free(T *p) {
|
||||
int res = dead.enqueue(p, 0);
|
||||
assert(res == pdTRUE);
|
||||
}
|
||||
};
|
||||
|
|
@ -9,6 +9,8 @@
|
|||
#include <pb_decode.h>
|
||||
#include "mesh.pb.h"
|
||||
#include "MeshRadio.h"
|
||||
#include "TypedQueue.h"
|
||||
#include "MemoryPool.h"
|
||||
|
||||
/*
|
||||
receivedPacketQueue - this is a queue of messages we've received from the mesh, which we are keeping to deliver to the phone.
|
||||
|
@ -53,6 +55,9 @@ public:
|
|||
|
||||
*/
|
||||
|
||||
#define MAX_PACKETS 32 // max number of packets which can be in flight (either queued from reception or queued for sending)
|
||||
#define MAX_RX_TOPHONE 16 // max number of packets which can be waiting for delivery to android
|
||||
|
||||
/// A temporary buffer used for sending packets, sized to hold the biggest buffer we might need
|
||||
static uint8_t outbuf[MeshPacket_size];
|
||||
|
||||
|
@ -62,7 +67,45 @@ static uint8_t outbuf[MeshPacket_size];
|
|||
*/
|
||||
class MeshService
|
||||
{
|
||||
MemoryPool<MeshPacket> packetPool;
|
||||
|
||||
/// received packets waiting for the phone to process them
|
||||
/// FIXME, change to a DropOldestQueue and keep a count of the number of dropped packets to ensure
|
||||
/// we never hang because android hasn't been there in a while
|
||||
PointerQueue<MeshPacket> toPhoneQueue;
|
||||
|
||||
/// Packets which have just arrived from the radio, ready to be processed by this service and possibly
|
||||
/// forwarded to the phone. Note: not using yet - seeing if I can just handle everything asap in handleFromRadio
|
||||
// PointerQueue<MeshPacket> fromRadioQueue;
|
||||
|
||||
public:
|
||||
MeshService() : packetPool(MAX_PACKETS), toPhoneQueue(MAX_RX_TOPHONE) {
|
||||
|
||||
}
|
||||
|
||||
/// Do idle processing (mostly processing messages which have been queued from the radio)
|
||||
// void loop() { }
|
||||
|
||||
/**
|
||||
* handle an incoming MeshPacket from the radio, update DB state and queue it for the phone
|
||||
*/
|
||||
void handleFromRadio(NodeNum from, NodeNum to, const uint8_t *buf, size_t len) {
|
||||
MeshPacket *p = packetPool.allocZeroed();
|
||||
assert(p);
|
||||
|
||||
pb_istream_t stream = pb_istream_from_buffer(buf, len);
|
||||
if (!pb_decode(&stream, MeshPacket_fields, p) || !p->has_payload)
|
||||
{
|
||||
Serial.printf("Error: can't decode MeshPacket %s\n", PB_GET_ERROR(&stream));
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME - update DB state based on payload and show recevied texts
|
||||
|
||||
toPhoneQueue.enqueue(p);
|
||||
}
|
||||
}
|
||||
|
||||
/// Given a ToRadio buffer parse it and properly handle it (setup radio, owner or send packet into the mesh)
|
||||
void handleToRadio(std::string s)
|
||||
{
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
typedef int ErrorCode;
|
||||
typedef uint8_t NodeNum;
|
||||
|
||||
/// Callback for a receive packet
|
||||
typedef void (*MeshRXHandler)(NodeNum from, NodeNum to, std::string packet);
|
||||
/// Callback for a receive packet, the callee must copy/queue the payload elsewhere before returning
|
||||
typedef void (*MeshRXHandler)(NodeNum from, NodeNum to, const uint8_t *buf, size_t len);
|
||||
|
||||
/**
|
||||
* A raw low level interface to our mesh. Only understands nodenums and bytes (not protobufs or node ids)
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <assert.h>
|
||||
|
||||
/**
|
||||
* A wrapper for freertos queues. Note: each element object must be quite small, so T should be only
|
||||
* pointer types or ints
|
||||
*/
|
||||
template <class T> class TypedQueue {
|
||||
QueueHandle_t h;
|
||||
public:
|
||||
TypedQueue(int maxElements) {
|
||||
h = xQueueCreate(maxElements, sizeof(T));
|
||||
assert(h);
|
||||
}
|
||||
|
||||
~TypedQueue() {
|
||||
vQueueDelete(h);
|
||||
}
|
||||
|
||||
// pdTRUE for success else failure
|
||||
BaseType_t enqueue(T x, TickType_t maxWait = portMAX_DELAY) {
|
||||
return xQueueSendToBack(h, &x, maxWait);
|
||||
}
|
||||
|
||||
// pdTRUE for success else failure
|
||||
BaseType_t dequeue(T *p, TickType_t maxWait = portMAX_DELAY) {
|
||||
return xQueueReceive(h, p, maxWait);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A wrapper for freertos queues that assumes each element is a pointer
|
||||
*/
|
||||
template <class T> class PointerQueue: public TypedQueue<T *> {
|
||||
TypedQueue h;
|
||||
public:
|
||||
PointerQueue(int maxElements) : TypedQueue(maxElements) {
|
||||
}
|
||||
|
||||
// preturns a ptr or null if the queue was empty
|
||||
T *dequeuePtr(TickType_t maxWait = portMAX_DELAY) {
|
||||
T *p;
|
||||
|
||||
return dequeue(&p, maxWait) == pdTRUE ? p : NULL;
|
||||
}
|
||||
};
|
||||
|
|
@ -27,10 +27,7 @@ PB_BIND(DenyNodeNum, DenyNodeNum, AUTO)
|
|||
PB_BIND(SubPacket, SubPacket, AUTO)
|
||||
|
||||
|
||||
PB_BIND(MeshPayload, MeshPayload, 2)
|
||||
|
||||
|
||||
PB_BIND(MeshPacket, MeshPacket, 2)
|
||||
PB_BIND(MeshPacket, MeshPacket, AUTO)
|
||||
|
||||
|
||||
PB_BIND(RadioConfig, RadioConfig, 2)
|
||||
|
@ -39,10 +36,10 @@ PB_BIND(RadioConfig, RadioConfig, 2)
|
|||
PB_BIND(NodeInfo, NodeInfo, AUTO)
|
||||
|
||||
|
||||
PB_BIND(DeviceState, DeviceState, 4)
|
||||
PB_BIND(DeviceState, DeviceState, 2)
|
||||
|
||||
|
||||
PB_BIND(FromRadio, FromRadio, 2)
|
||||
PB_BIND(FromRadio, FromRadio, AUTO)
|
||||
|
||||
|
||||
PB_BIND(ToRadio, ToRadio, 2)
|
||||
|
|
|
@ -86,16 +86,11 @@ typedef struct _SubPacket {
|
|||
} variant;
|
||||
} SubPacket;
|
||||
|
||||
typedef struct _MeshPayload {
|
||||
pb_size_t subPackets_count;
|
||||
SubPacket subPackets[4];
|
||||
} MeshPayload;
|
||||
|
||||
typedef struct _MeshPacket {
|
||||
int32_t from;
|
||||
int32_t to;
|
||||
bool has_payload;
|
||||
MeshPayload payload;
|
||||
SubPacket payload;
|
||||
} MeshPacket;
|
||||
|
||||
typedef struct _DeviceState {
|
||||
|
@ -143,8 +138,7 @@ typedef struct _ToRadio {
|
|||
#define WantNodeNum_init_default {0, ""}
|
||||
#define DenyNodeNum_init_default {""}
|
||||
#define SubPacket_init_default {0, {Position_init_default}}
|
||||
#define MeshPayload_init_default {0, {SubPacket_init_default, SubPacket_init_default, SubPacket_init_default, SubPacket_init_default}}
|
||||
#define MeshPacket_init_default {0, 0, false, MeshPayload_init_default}
|
||||
#define MeshPacket_init_default {0, 0, false, SubPacket_init_default}
|
||||
#define RadioConfig_init_default {0, 0}
|
||||
#define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, false, Time_init_default}
|
||||
#define DeviceState_init_default {false, RadioConfig_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default}, 0}
|
||||
|
@ -158,8 +152,7 @@ typedef struct _ToRadio {
|
|||
#define WantNodeNum_init_zero {0, ""}
|
||||
#define DenyNodeNum_init_zero {""}
|
||||
#define SubPacket_init_zero {0, {Position_init_zero}}
|
||||
#define MeshPayload_init_zero {0, {SubPacket_init_zero, SubPacket_init_zero, SubPacket_init_zero, SubPacket_init_zero}}
|
||||
#define MeshPacket_init_zero {0, 0, false, MeshPayload_init_zero}
|
||||
#define MeshPacket_init_zero {0, 0, false, SubPacket_init_zero}
|
||||
#define RadioConfig_init_zero {0, 0}
|
||||
#define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, false, Time_init_zero}
|
||||
#define DeviceState_init_zero {false, RadioConfig_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero}, 0}
|
||||
|
@ -195,7 +188,6 @@ typedef struct _ToRadio {
|
|||
#define SubPacket_user_tag 4
|
||||
#define SubPacket_want_node_tag 5
|
||||
#define SubPacket_deny_node_tag 6
|
||||
#define MeshPayload_subPackets_tag 3
|
||||
#define MeshPacket_from_tag 1
|
||||
#define MeshPacket_to_tag 2
|
||||
#define MeshPacket_payload_tag 3
|
||||
|
@ -268,19 +260,13 @@ X(a, STATIC, ONEOF, MESSAGE, (variant,deny_node,variant.deny_node), 6)
|
|||
#define SubPacket_variant_want_node_MSGTYPE WantNodeNum
|
||||
#define SubPacket_variant_deny_node_MSGTYPE DenyNodeNum
|
||||
|
||||
#define MeshPayload_FIELDLIST(X, a) \
|
||||
X(a, STATIC, REPEATED, MESSAGE, subPackets, 3)
|
||||
#define MeshPayload_CALLBACK NULL
|
||||
#define MeshPayload_DEFAULT NULL
|
||||
#define MeshPayload_subPackets_MSGTYPE SubPacket
|
||||
|
||||
#define MeshPacket_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, INT32, from, 1) \
|
||||
X(a, STATIC, SINGULAR, INT32, to, 2) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, payload, 3)
|
||||
#define MeshPacket_CALLBACK NULL
|
||||
#define MeshPacket_DEFAULT NULL
|
||||
#define MeshPacket_payload_MSGTYPE MeshPayload
|
||||
#define MeshPacket_payload_MSGTYPE SubPacket
|
||||
|
||||
#define RadioConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, BOOL, keep_all_packets, 100) \
|
||||
|
@ -344,7 +330,6 @@ extern const pb_msgdesc_t User_msg;
|
|||
extern const pb_msgdesc_t WantNodeNum_msg;
|
||||
extern const pb_msgdesc_t DenyNodeNum_msg;
|
||||
extern const pb_msgdesc_t SubPacket_msg;
|
||||
extern const pb_msgdesc_t MeshPayload_msg;
|
||||
extern const pb_msgdesc_t MeshPacket_msg;
|
||||
extern const pb_msgdesc_t RadioConfig_msg;
|
||||
extern const pb_msgdesc_t NodeInfo_msg;
|
||||
|
@ -361,7 +346,6 @@ extern const pb_msgdesc_t ToRadio_WantNodes_msg;
|
|||
#define WantNodeNum_fields &WantNodeNum_msg
|
||||
#define DenyNodeNum_fields &DenyNodeNum_msg
|
||||
#define SubPacket_fields &SubPacket_msg
|
||||
#define MeshPayload_fields &MeshPayload_msg
|
||||
#define MeshPacket_fields &MeshPacket_msg
|
||||
#define RadioConfig_fields &RadioConfig_msg
|
||||
#define NodeInfo_fields &NodeInfo_msg
|
||||
|
@ -378,13 +362,12 @@ extern const pb_msgdesc_t ToRadio_WantNodes_msg;
|
|||
#define WantNodeNum_size 13
|
||||
#define DenyNodeNum_size 7
|
||||
#define SubPacket_size 106
|
||||
#define MeshPayload_size 432
|
||||
#define MeshPacket_size 457
|
||||
#define MeshPacket_size 130
|
||||
#define RadioConfig_size 6
|
||||
#define NodeInfo_size 140
|
||||
#define DeviceState_size 19310
|
||||
#define FromRadio_size 466
|
||||
#define ToRadio_size 460
|
||||
#define DeviceState_size 8846
|
||||
#define FromRadio_size 149
|
||||
#define ToRadio_size 133
|
||||
#define ToRadio_WantNodes_size 0
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
Ładowanie…
Reference in New Issue