mirror of
https://github.com/meshtastic/firmware.git
synced 2025-02-09 06:01:32 +00:00
![Ben Meadors](/assets/img/avatar_default.png)
* Implement override_console_serial_port * It's opposite day in Logictown * Try to use native serial types for platforms * Fix for s3 * Trunk * Screw it... just declare as Print and handle init * Alright, chatty kathy * Missed a spot * I'll take "Kill that FIXME" for 800, Alex * Badunkadunk * Refactor out a lot of duplicated code * Boogers * Okay I probably should stop changing everything
141 lines
4.8 KiB
C++
141 lines
4.8 KiB
C++
#pragma once
|
|
|
|
#include "Observer.h"
|
|
#include "mesh-pb-constants.h"
|
|
#include <string>
|
|
|
|
// Make sure that we never let our packets grow too large for one BLE packet
|
|
#define MAX_TO_FROM_RADIO_SIZE 512
|
|
|
|
/**
|
|
* Provides our protobuf based API which phone/PC clients can use to talk to our device
|
|
* over UDP, bluetooth or serial.
|
|
*
|
|
* Subclass to customize behavior for particular type of transport (BLE, UDP, TCP, serial)
|
|
*
|
|
* Eventually there should be once instance of this class for each live connection (because it has a bit of state
|
|
* for that connection)
|
|
*/
|
|
class PhoneAPI
|
|
: public Observer<uint32_t> // FIXME, we shouldn't be inheriting from Observer, instead use CallbackObserver as a member
|
|
{
|
|
enum State {
|
|
STATE_SEND_NOTHING, // Initial state, don't send anything until the client starts asking for config
|
|
STATE_SEND_MY_INFO, // send our my info record
|
|
STATE_SEND_NODEINFO, // states progress in this order as the device sends to to the client
|
|
STATE_SEND_CHANNELS, // Send all channels
|
|
STATE_SEND_CONFIG, // Replacement for the old Radioconfig
|
|
STATE_SEND_MODULECONFIG, // Send Module specific config
|
|
STATE_SEND_METADATA,
|
|
STATE_SEND_COMPLETE_ID,
|
|
STATE_SEND_PACKETS // send packets or debug strings
|
|
};
|
|
|
|
State state = STATE_SEND_NOTHING;
|
|
|
|
uint8_t config_state = 0;
|
|
|
|
/**
|
|
* Each packet sent to the phone has an incrementing count
|
|
*/
|
|
uint32_t fromRadioNum = 0;
|
|
|
|
/// We temporarily keep the packet here between the call to available and getFromRadio. We will free it after the phone
|
|
/// downloads it
|
|
meshtastic_MeshPacket *packetForPhone = NULL;
|
|
|
|
// file transfer packets destined for phone. Push it to the queue then free it.
|
|
meshtastic_XModem xmodemPacketForPhone = meshtastic_XModem_init_zero;
|
|
|
|
// Keep QueueStatus packet just as packetForPhone
|
|
meshtastic_QueueStatus *queueStatusPacketForPhone = NULL;
|
|
|
|
/// We temporarily keep the nodeInfo here between the call to available and getFromRadio
|
|
const meshtastic_NodeInfo *nodeInfoForPhone = NULL;
|
|
|
|
meshtastic_ToRadio toRadioScratch = {
|
|
0}; // this is a static scratch object, any data must be copied elsewhere before returning
|
|
|
|
/// Use to ensure that clients don't get confused about old messages from the radio
|
|
uint32_t config_nonce = 0;
|
|
uint32_t readIndex = 0;
|
|
|
|
void resetReadIndex() { readIndex = 0; }
|
|
|
|
public:
|
|
PhoneAPI();
|
|
|
|
/// Destructor - calls close()
|
|
virtual ~PhoneAPI();
|
|
|
|
// Call this when the client drops the connection, resets the state to STATE_SEND_NOTHING
|
|
// Unregisters our observer. A closed connection **can** be reopened by calling init again.
|
|
virtual void close();
|
|
|
|
/**
|
|
* Handle a ToRadio protobuf
|
|
* @return true true if a packet was queued for sending (so that caller can yield)
|
|
*/
|
|
virtual bool handleToRadio(const uint8_t *buf, size_t len);
|
|
|
|
/**
|
|
* Get the next packet we want to send to the phone
|
|
*
|
|
* We assume buf is at least FromRadio_size bytes long.
|
|
* Returns number of bytes in the FromRadio packet (or 0 if no packet available)
|
|
*/
|
|
size_t getFromRadio(uint8_t *buf);
|
|
|
|
/**
|
|
* Return true if we have data available to send to the phone
|
|
*/
|
|
bool available();
|
|
|
|
bool isConnected() { return state != STATE_SEND_NOTHING; }
|
|
|
|
void setInitialState() { state = STATE_SEND_MY_INFO; }
|
|
|
|
protected:
|
|
/// Our fromradio packet while it is being assembled
|
|
meshtastic_FromRadio fromRadioScratch = {};
|
|
|
|
/** the last msec we heard from the client on the other side of this link */
|
|
uint32_t lastContactMsec = 0;
|
|
|
|
/// Hookable to find out when connection changes
|
|
virtual void onConnectionChanged(bool connected) {}
|
|
|
|
/// If we haven't heard from the other side in a while then say not connected
|
|
void checkConnectionTimeout();
|
|
|
|
/// Check the current underlying physical link to see if the client is currently connected
|
|
virtual bool checkIsConnected() = 0;
|
|
|
|
/**
|
|
* Subclasses can use this as a hook to provide custom notifications for their transport (i.e. bluetooth notifies)
|
|
*/
|
|
virtual void onNowHasData(uint32_t fromRadioNum) {}
|
|
|
|
/**
|
|
* Subclasses can use this to find out when a client drops the link
|
|
*/
|
|
virtual void handleDisconnect();
|
|
|
|
private:
|
|
void releasePhonePacket();
|
|
|
|
void releaseQueueStatusPhonePacket();
|
|
|
|
/// begin a new connection
|
|
void handleStartConfig();
|
|
|
|
/**
|
|
* Handle a packet that the phone wants us to send. We can write to it but can not keep a reference to it
|
|
* @return true true if a packet was queued for sending
|
|
*/
|
|
bool handleToRadioPacket(meshtastic_MeshPacket &p);
|
|
|
|
/// If the mesh service tells us fromNum has changed, tell the phone
|
|
virtual int onNotify(uint32_t newValue) override;
|
|
};
|