teleclient.h 4.58 KB
#include "config.h"

#define EVENT_LOGIN 1
#define EVENT_LOGOUT 2
#define EVENT_SYNC 3
#define EVENT_RECONNECT 4
#define EVENT_COMMAND 5
#define EVENT_ACK 6
#define EVENT_PING 7

#define BUFFER_STATE_EMPTY 0
#define BUFFER_STATE_FILLING 1
#define BUFFER_STATE_FILLED 2
#define BUFFER_STATE_LOCKED 3

#define ELEMENT_INT 0
#define ELEMENT_UINT 1
#define ELEMENT_FLOAT 2
#define ELEMENT_FLOATX3 3

class CBuffer
{
public:
    CBuffer();
    void add(uint16_t pid, int value);
    void add(uint16_t pid, uint32_t value);
    void add(uint16_t pid, float value);
    void add(uint16_t pid, float value[]);
    void purge();
    void serialize(CStorage& store);
    uint32_t timestamp;
    int offset;
    uint16_t count;
    uint8_t state;
private:
    void setType(uint32_t dataType);
    uint8_t data[BUFFER_LENGTH];
    uint32_t types[(BUFFER_LENGTH / (sizeof(uint16_t) + sizeof(int)) + 15) / 16];
};

class CBufferManager
{
public:
    CBufferManager()
    {
        for (int n = 0; n < BUFFER_SLOTS; n++) buffers[n] = new CBuffer;
    }
    void purge()
    {
        for (int n = 0; n < BUFFER_SLOTS; n++) buffers[n]->state = BUFFER_STATE_EMPTY;
    }
    CBuffer* get(byte state = BUFFER_STATE_EMPTY)
    {
        for (int n = 0; n < BUFFER_SLOTS; n++) {
            if (buffers[n]->state == state) return buffers[n];
        }
        return 0;
    }
    CBuffer* getOldest()
    {
        uint32_t ts = 0xffffffff;
        int m = -1;
        for (int n = 0; n < BUFFER_SLOTS; n++) {
            if (buffers[n]->state == BUFFER_STATE_FILLED && buffers[n]->timestamp < ts) {
                m = n;
                ts = buffers[n]->timestamp;
            }
        }
        return m >= 0 ? buffers[m] : 0;
    }
    CBuffer* getNewest()
    {
        uint32_t ts = 0;
        int m = -1;
        for (int n = 0; n < BUFFER_SLOTS; n++) {
            if (buffers[n]->state == BUFFER_STATE_FILLED && buffers[n]->timestamp > ts) {
                m = n;
                ts = buffers[n]->timestamp;
            }
        }
        return m >= 0 ? buffers[m] : 0;
    }
    void printStats()
    {
        int bytes = 0;
        int slots = 0;
        int samples = 0;
        for (int n = 0; n < BUFFER_SLOTS; n++) {
            if (buffers[n]->state != BUFFER_STATE_FILLED) continue;
            bytes += buffers[n]->offset;
            samples += buffers[n]->count;
            slots++;
            /*
            Serial.print(n);
            Serial.print(':');
            Serial.print(buffers[n]->count);
            Serial.print(',');
            Serial.print(buffers[n]->offset);
            Serial.print(' ');
            */
        }
        if (slots) {
            Serial.print("[BUF] ");
            Serial.print(samples);
            Serial.print(" samples | ");
            Serial.print(bytes);
            Serial.print(" bytes | ");
            Serial.print(slots * 100 / BUFFER_SLOTS);
            Serial.println("%");
        }
    }
    CBuffer* buffers[BUFFER_SLOTS];
};

class TeleClient
{
public:
    virtual void reset()
    {
        txCount = 0;
        txBytes = 0;
        rxBytes = 0;
        login = false;
    }
    virtual bool notify(byte event, const char* payload = 0) { return true; }
    virtual bool connect() { return true; }
    virtual bool transmit(const char* packetBuffer, unsigned int packetSize)  { return true; }
    virtual void inbound() {}
    uint32_t txCount = 0;
    uint32_t txBytes = 0;
    uint32_t rxBytes = 0;
    uint32_t lastSyncTime = 0;
    uint16_t feedid = 0;
    uint32_t startTime = 0;
    bool login = false;
};

class TeleClientUDP : public TeleClient
{
public:
    bool notify(byte event, const char* payload = 0);
    bool connect();
    bool transmit(const char* packetBuffer, unsigned int packetSize);
    bool ping();
    void inbound();
    bool verifyChecksum(char* data);
    void shutdown();
#if NET_DEVICE == NET_WIFI
    UDPClientWIFI net;
#elif NET_DEVICE == NET_SIM800
    UDPClientSIM800 net;
#elif NET_DEVICE == NET_SIM5360
    UDPClientSIM5360 net;
#elif NET_DEVICE == NET_SIM7600
    UDPClientSIM7600 net;
#elif NET_DEVICE == NET_WIFI_MESH
    ClientWiFiMesh net;
#else
    ClientSerial net;
#endif
};

class TeleClientHTTP : public TeleClient
{
public:
    bool notify(byte event, const char* payload = 0);
    bool connect();
    bool transmit(const char* packetBuffer, unsigned int packetSize);
    bool ping();
    void shutdown();
#if NET_DEVICE == NET_WIFI
    HTTPClientWIFI net;
#elif NET_DEVICE == NET_SIM800
    HTTPClientSIM800 net;
#elif NET_DEVICE == NET_SIM5360
    HTTPClientSIM5360 net;
#elif NET_DEVICE == NET_SIM7600
    HTTPClientSIM7600 net;
#endif
private:
    bool started = false;
};