2020-04-21 01:03:13 +00:00
|
|
|
#pragma once
|
|
|
|
|
2020-04-22 21:55:36 +00:00
|
|
|
#include "Observer.h"
|
2020-04-21 01:03:13 +00:00
|
|
|
#include "mesh-pb-constants.h"
|
|
|
|
#include <string>
|
|
|
|
|
2020-04-27 15:10:17 +00:00
|
|
|
// Make sure that we never let our packets grow too large for one BLE packet
|
|
|
|
#define MAX_TO_FROM_RADIO_SIZE 512
|
|
|
|
|
2020-04-21 01:03:13 +00:00
|
|
|
/**
|
|
|
|
* Provides our protobuf based API which phone/PC clients can use to talk to our device
|
|
|
|
* over UDP, bluetooth or serial.
|
|
|
|
*
|
2020-04-22 21:55:36 +00:00
|
|
|
* Subclass to customize behavior for particular type of transport (BLE, UDP, TCP, serial)
|
|
|
|
*
|
2020-04-21 01:03:13 +00:00
|
|
|
* 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
|
2020-04-22 21:55:36 +00:00
|
|
|
: public Observer<uint32_t> // FIXME, we shouldn't be inheriting from Observer, instead use CallbackObserver as a member
|
2020-04-21 01:03:13 +00:00
|
|
|
{
|
|
|
|
enum State {
|
2020-12-27 08:58:32 +00:00
|
|
|
STATE_LEGACY, // (no longer used) old default state - until Android apps are all updated, uses the old BLE API
|
2020-04-22 23:03:54 +00:00
|
|
|
STATE_SEND_NOTHING, // (Eventual) Initial state, don't send anything until the client starts asking for config
|
|
|
|
STATE_SEND_MY_INFO, // send our my info record
|
2020-04-21 01:03:13 +00:00
|
|
|
STATE_SEND_RADIO,
|
2020-04-23 17:30:14 +00:00
|
|
|
// STATE_SEND_OWNER, no need to send Owner specially, it is just part of the nodedb
|
2020-04-22 23:03:54 +00:00
|
|
|
STATE_SEND_NODEINFO, // states progress in this order as the device sends to to the client
|
2020-04-21 01:03:13 +00:00
|
|
|
STATE_SEND_COMPLETE_ID,
|
|
|
|
STATE_SEND_PACKETS // send packets or debug strings
|
|
|
|
};
|
|
|
|
|
2020-12-27 08:58:32 +00:00
|
|
|
State state = STATE_SEND_NOTHING;
|
2020-04-21 01:03:13 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Each packet sent to the phone has an incrementing count
|
|
|
|
*/
|
2020-04-22 21:55:36 +00:00
|
|
|
uint32_t fromRadioNum = 0;
|
|
|
|
|
2020-04-23 17:30:14 +00:00
|
|
|
/// We temporarily keep the packet here between the call to available and getFromRadio. We will free it after the phone
|
|
|
|
/// downloads it
|
2020-04-22 21:55:36 +00:00
|
|
|
MeshPacket *packetForPhone = NULL;
|
|
|
|
|
2020-04-23 17:30:14 +00:00
|
|
|
/// We temporarily keep the nodeInfo here between the call to available and getFromRadio
|
|
|
|
const NodeInfo *nodeInfoForPhone = NULL;
|
|
|
|
|
2020-04-22 21:55:36 +00:00
|
|
|
ToRadio toRadioScratch; // this is a static scratch object, any data must be copied elsewhere before returning
|
2020-04-21 01:03:13 +00:00
|
|
|
|
2020-04-22 22:13:05 +00:00
|
|
|
/// Use to ensure that clients don't get confused about old messages from the radio
|
|
|
|
uint32_t config_nonce = 0;
|
|
|
|
|
2020-06-08 23:06:59 +00:00
|
|
|
/** the last msec we heard from the client on the other side of this link */
|
|
|
|
uint32_t lastContactMsec = 0;
|
|
|
|
|
2020-04-21 01:03:13 +00:00
|
|
|
public:
|
|
|
|
PhoneAPI();
|
|
|
|
|
2020-12-31 01:52:08 +00:00
|
|
|
/// Destructor - calls close()
|
|
|
|
virtual ~PhoneAPI();
|
|
|
|
|
2020-04-22 21:55:36 +00:00
|
|
|
/// Do late init that can't happen at constructor time
|
2020-04-27 16:36:39 +00:00
|
|
|
virtual void init();
|
2020-04-22 21:55:36 +00:00
|
|
|
|
2020-12-27 08:58:32 +00:00
|
|
|
// Call this when the client drops the connection, resets the state to STATE_SEND_NOTHING
|
2020-12-31 01:52:08 +00:00
|
|
|
// Unregisters our observer. A closed connection **can** be reopened by calling init again.
|
|
|
|
virtual void close();
|
2020-12-27 08:58:32 +00:00
|
|
|
|
2020-04-21 01:03:13 +00:00
|
|
|
/**
|
|
|
|
* Handle a ToRadio protobuf
|
|
|
|
*/
|
2020-04-27 16:36:39 +00:00
|
|
|
virtual void handleToRadio(const uint8_t *buf, size_t len);
|
2020-04-21 01:03:13 +00:00
|
|
|
|
|
|
|
/**
|
2020-04-22 21:55:36 +00:00
|
|
|
* Get the next packet we want to send to the phone
|
2020-04-21 01:03:13 +00:00
|
|
|
*
|
|
|
|
* We assume buf is at least FromRadio_size bytes long.
|
2020-04-22 21:55:36 +00:00
|
|
|
* Returns number of bytes in the FromRadio packet (or 0 if no packet available)
|
2020-04-21 01:03:13 +00:00
|
|
|
*/
|
2020-04-22 21:55:36 +00:00
|
|
|
size_t getFromRadio(uint8_t *buf);
|
2020-04-21 01:03:13 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Return true if we have data available to send to the phone
|
|
|
|
*/
|
|
|
|
bool available();
|
|
|
|
|
|
|
|
//
|
|
|
|
// The following routines are only public for now - until the rev1 bluetooth API is removed
|
|
|
|
//
|
|
|
|
|
|
|
|
void handleSetOwner(const User &o);
|
|
|
|
void handleSetRadio(const RadioConfig &r);
|
|
|
|
|
|
|
|
protected:
|
2020-12-27 08:58:32 +00:00
|
|
|
/// Are we currently connected to a client?
|
|
|
|
bool isConnected = false;
|
|
|
|
|
2020-04-29 00:43:16 +00:00
|
|
|
/// Our fromradio packet while it is being assembled
|
|
|
|
FromRadio fromRadioScratch;
|
|
|
|
|
2020-06-08 23:06:59 +00:00
|
|
|
/// 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();
|
|
|
|
|
2020-04-21 01:03:13 +00:00
|
|
|
/**
|
|
|
|
* Subclasses can use this as a hook to provide custom notifications for their transport (i.e. bluetooth notifies)
|
|
|
|
*/
|
2020-05-06 01:40:17 +00:00
|
|
|
virtual void onNowHasData(uint32_t fromRadioNum) {}
|
2020-04-21 01:03:13 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
/**
|
|
|
|
* Handle a packet that the phone wants us to send. It is our responsibility to free the packet to the pool
|
|
|
|
*/
|
|
|
|
void handleToRadioPacket(MeshPacket *p);
|
2020-04-22 21:55:36 +00:00
|
|
|
|
|
|
|
/// If the mesh service tells us fromNum has changed, tell the phone
|
|
|
|
virtual int onNotify(uint32_t newValue);
|
2020-04-21 01:03:13 +00:00
|
|
|
};
|