Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
didacticNet.h 3.43 KiB
/**************************************************************************
    @file     didacticNet.h
    @author   anian buehler @ letsgoING
**************************************************************************/


#ifndef _DIDACTICNET_
#define _DIDACTICNET_

#include "Arduino.h"
//callback(topic, topicLength, data, dataLength)
#define PSNET_CALLBACK_SIGNATURE void (*callback)(char*, int, char*, int)

#define MSG_PRELIMITER '<'
#define MSG_DELIMITER  '>'
#define MSG_SEPARATOR  '|'

//@ publish   → on publish check topic, then send topic-update
//? subscribe → subscribe starts update, topic filter @client
//# update    → update to specific topic Broker to client
#define MSG_PUBLISH   '@'
#define MSG_SUBSCRIBE '?'
#define MSG_UPDATE    '#'
#define MSG_TOPIC_MULTI     '*'

//<@topic|payload>
#define LEN_OVERHEAD  4

#define CSMA_CHECK_DELAY_US 400
#define CSMA_MIN_DELAY_MS    10
#define CSMA_MID_DELAY_MS    20
#define CSMA_MAX_DELAY_MS    30

#define MAX_NR_TOPICS_CLIENT   5
#define MAX_NR_TOPICS_BROKER  20
#define MAX_LEN_TOPICS 		  10
#define MAX_LEN_PAYLOAD       20

#define DN_ERROR_NOERROR      0
#define DN_ERROR_TOPIC_LEN   -1
#define DN_ERROR_PAYLOAD_LEN -2

//little helpers
#define ASCII_CR 13
#define ASCII_NL 10

int  edgeDetected(bool);
bool valueChanged(int, int);
bool timeElapsed(long);
int readSerialData(Stream&, char*, char);

class didacticPSNet
{
	protected:
		Stream* _port;

		PSNET_CALLBACK_SIGNATURE;

		char _bufferTopic[MAX_LEN_TOPICS +1] = {0};
		char _bufferPayload[MAX_LEN_PAYLOAD +1] = {0};
		char _readBufferMessage[MAX_LEN_TOPICS + MAX_LEN_PAYLOAD + LEN_OVERHEAD +1];
		char _sendBufferMessage[MAX_LEN_TOPICS + MAX_LEN_PAYLOAD + LEN_OVERHEAD +1];

		bool _dataToSend = false; // int Data to send for queue?
		unsigned long _waitingTime = 0L;
		int _currentTopicLength = 0;
		int _currentPayloadLength  = 0;

		didacticPSNet& setCallback(PSNET_CALLBACK_SIGNATURE);
		void setStream(Stream& _port);

		int checkData();
		bool recieveData();
		bool sendData();
		int extractData(int, int, char*, char);
		void writeDataToTopic(char*, char*);
		virtual int getTopicNr(char*)=0;
		virtual int getFreeTopicNr()=0;
		virtual bool getMessageFilter(char)=0;
		virtual bool savePayload(char*, int)=0;
		virtual bool handleData()=0;

	public:
		didacticPSNet();
		~didacticPSNet();

		void begin(Stream& _port);
		void begin(Stream& _port, PSNET_CALLBACK_SIGNATURE);
		bool handleNetwork();
		bool isDataToSend();

};

class didacticPSNetClient : public  didacticPSNet
{
	private:
	char _topic[MAX_NR_TOPICS_CLIENT][MAX_LEN_TOPICS+1] = { { 0 } };
	char _payload[MAX_NR_TOPICS_CLIENT][MAX_LEN_PAYLOAD+1] = { { 0 } };

	bool savePayload(char*, int);
	bool getMessageFilter(char);
	bool handleData();
	int getTopicNr(char*);
	int getFreeTopicNr();

	public:
	didacticPSNetClient();
	~didacticPSNetClient();

	int publish(char*, char*);
	int publish(char*, int, char*, int);
	int subscribe(char*);
	int subscribe(char*, int);
	bool unsubscribe(char*);
	bool unsubscribe(char*, int);
};


class didacticPSNetBroker: public  didacticPSNet
{
	private:
	char _topic[MAX_NR_TOPICS_BROKER][MAX_LEN_TOPICS+1] = { { 0 } };
	char _data[MAX_NR_TOPICS_BROKER][MAX_LEN_PAYLOAD+1] = { { 0 } };

	bool savePayload(char*, int);
	bool getMessageFilter(char);
	void writeDataToTopic(int, char*, char*);
	bool handleData();
	int getTopicNr(char*);
	int getFreeTopicNr();

	public:
	didacticPSNetBroker();
	~didacticPSNetBroker();

	bool update(char*, int, char*, int);


};
#endif