2020-04-01 04:56:35 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "MemoryPool.h"
|
|
|
|
#include "MeshTypes.h"
|
|
|
|
#include "PointerQueue.h"
|
|
|
|
#include "mesh.pb.h"
|
|
|
|
#include <RH_RF95.h>
|
|
|
|
|
|
|
|
#define MAX_TX_QUEUE 16 // max number of packets which can be waiting for transmission
|
|
|
|
|
2020-04-30 16:44:16 +00:00
|
|
|
#define MAX_RHPACKETLEN 256
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This structure has to exactly match the wire layout when sent over the radio link. Used to keep compatibility
|
|
|
|
* wtih the old radiohead implementation.
|
|
|
|
*/
|
|
|
|
typedef struct {
|
|
|
|
uint8_t to, from, id, flags;
|
|
|
|
} PacketHeader;
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-04-01 04:56:35 +00:00
|
|
|
/**
|
|
|
|
* Basic operations all radio chipsets must implement.
|
|
|
|
*
|
|
|
|
* This defines the SOLE API for talking to radios (because soon we will have alternate radio implementations)
|
|
|
|
*/
|
|
|
|
class RadioInterface
|
|
|
|
{
|
|
|
|
friend class MeshRadio; // for debugging we let that class touch pool
|
2020-04-17 16:48:54 +00:00
|
|
|
PointerQueue<MeshPacket> *rxDest = NULL;
|
2020-04-01 04:56:35 +00:00
|
|
|
|
|
|
|
protected:
|
|
|
|
MeshPacket *sendingPacket = NULL; // The packet we are currently sending
|
2020-04-30 16:44:16 +00:00
|
|
|
PointerQueue<MeshPacket> txQueue;
|
|
|
|
uint32_t lastTxStart = 0L;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A temporary buffer used for sending/receving packets, sized to hold the biggest buffer we might need
|
|
|
|
* */
|
|
|
|
uint8_t radiobuf[MAX_RHPACKETLEN];
|
2020-04-17 16:48:54 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Enqueue a received packet for the registered receiver
|
|
|
|
*/
|
2020-04-18 21:22:24 +00:00
|
|
|
void deliverToReceiver(MeshPacket *p);
|
2020-04-17 16:48:54 +00:00
|
|
|
|
2020-04-01 04:56:35 +00:00
|
|
|
public:
|
2020-04-30 01:46:32 +00:00
|
|
|
float freq = 915.0; // FIXME, init all these params from user setings
|
|
|
|
int8_t power = 17;
|
|
|
|
RH_RF95::ModemConfigChoice modemConfig;
|
|
|
|
|
2020-04-01 04:56:35 +00:00
|
|
|
/** pool is the pool we will alloc our rx packets from
|
|
|
|
* rxDest is where we will send any rx packets, it becomes receivers responsibility to return packet to the pool
|
|
|
|
*/
|
2020-04-17 16:48:54 +00:00
|
|
|
RadioInterface();
|
2020-04-01 04:56:35 +00:00
|
|
|
|
|
|
|
/**
|
2020-04-17 16:48:54 +00:00
|
|
|
* Set where to deliver received packets. This method should only be used by the Router class
|
2020-04-01 04:56:35 +00:00
|
|
|
*/
|
2020-04-17 16:48:54 +00:00
|
|
|
void setReceiver(PointerQueue<MeshPacket> *_rxDest) { rxDest = _rxDest; }
|
2020-04-01 04:56:35 +00:00
|
|
|
|
2020-04-17 19:41:01 +00:00
|
|
|
virtual void loop() {} // Idle processing
|
|
|
|
|
2020-04-23 19:47:41 +00:00
|
|
|
/**
|
|
|
|
* Return true if we think the board can go to sleep (i.e. our tx queue is empty, we are not sending or receiving)
|
|
|
|
*
|
|
|
|
* This method must be used before putting the CPU into deep or light sleep.
|
|
|
|
*/
|
2020-04-30 22:50:07 +00:00
|
|
|
virtual bool canSleep() { return true; }
|
2020-04-23 19:47:41 +00:00
|
|
|
|
|
|
|
/// Prepare hardware for sleep. Call this _only_ for deep sleep, not needed for light sleep.
|
|
|
|
virtual bool sleep() { return true; }
|
|
|
|
|
2020-04-17 16:48:54 +00:00
|
|
|
/**
|
|
|
|
* Send a packet (possibly by enquing in a private fifo). This routine will
|
|
|
|
* later free() the packet to pool. This routine is not allowed to stall.
|
|
|
|
* If the txmit queue is full it might return an error
|
|
|
|
*/
|
2020-04-01 04:56:35 +00:00
|
|
|
virtual ErrorCode send(MeshPacket *p) = 0;
|
2020-04-29 21:54:03 +00:00
|
|
|
|
|
|
|
// methods from radiohead
|
|
|
|
|
|
|
|
|
|
|
|
/// Initialise the Driver transport hardware and software.
|
|
|
|
/// Make sure the Driver is properly configured before calling init().
|
|
|
|
/// \return true if initialisation succeeded.
|
|
|
|
virtual bool init() = 0;
|
|
|
|
|
2020-04-30 01:46:32 +00:00
|
|
|
/// Apply any radio provisioning changes
|
|
|
|
/// Make sure the Driver is properly configured before calling init().
|
|
|
|
/// \return true if initialisation succeeded.
|
|
|
|
virtual bool reconfigure() = 0;
|
2020-04-30 16:44:16 +00:00
|
|
|
|
|
|
|
protected:
|
|
|
|
/***
|
|
|
|
* given a packet set sendingPacket and decode the protobufs into radiobuf. Returns # of bytes to send (including the PacketHeader & payload).
|
|
|
|
*
|
|
|
|
* Used as the first step of
|
|
|
|
*/
|
|
|
|
size_t beginSending(MeshPacket *p);
|
2020-04-01 04:56:35 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class SimRadio : public RadioInterface
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
virtual ErrorCode send(MeshPacket *p);
|
|
|
|
|
|
|
|
// methods from radiohead
|
|
|
|
|
|
|
|
/// Initialise the Driver transport hardware and software.
|
|
|
|
/// Make sure the Driver is properly configured before calling init().
|
|
|
|
/// \return true if initialisation succeeded.
|
|
|
|
virtual bool init() { return true; }
|
|
|
|
|
|
|
|
/// If current mode is Rx or Tx changes it to Idle. If the transmitter or receiver is running,
|
|
|
|
/// disables them.
|
|
|
|
void setModeIdle() {}
|
|
|
|
|
|
|
|
/// If current mode is Tx or Idle, changes it to Rx.
|
|
|
|
/// Starts the receiver in the RF95/96/97/98.
|
|
|
|
void setModeRx() {}
|
|
|
|
|
|
|
|
/// Returns the operating mode of the library.
|
|
|
|
/// \return the current mode, one of RF69_MODE_*
|
|
|
|
virtual RHGenericDriver::RHMode mode() { return RHGenericDriver::RHModeIdle; }
|
|
|
|
};
|