#pragma once #include "Task.hpp" #include "esp_log.h" #include "esp_netif.h" #include #include #include #include #include #include #include #include using namespace std; namespace spit { /** Returns an guid */ string createGUID(); /** Returns the name of the client's host computer*/ string getClientHostName(); class ISocket { public: /** * IpAddress class is used to fetch all available IP addresses of the computer * This is for internal usage */ struct IpAddress { public: IpAddress(const string &iPAddress, const string &subnetMask) : mIpAddress(iPAddress), mSubnetMask(subnetMask) {} const string mIpAddress; const string mSubnetMask; /** * Calculates the broadcast address from a ip4 address * @param iPAddress the ip4 address * @return returns the broadcast address */ string getBroadcastIP4() const { struct in_addr broadcast; unsigned long ipAddress; unsigned long subnetMask; ipAddress = inet_addr(mIpAddress.data()); subnetMask = inet_addr(mSubnetMask.data()); broadcast.s_addr = ipAddress | ~subnetMask; return inet_ntoa(broadcast); } }; const IpAddress mOwnIp; ISocket(IpAddress ip) : mOwnIp(ip) {} virtual int sendMessage(const char *message, int length) = 0; virtual int receiveMessage(char *bu1ffer, int bufferLength, string *serverIp) const =0; virtual void setConnectionParams(const string &serverIp, const string &serverPort, const string &clientIp, const string &clientPort) =0; virtual int bindSocket(string clientIp, string clientPort) =0; virtual int setBroadcast(bool broadcast) const =0; virtual int sendMessageTo(const string &ip, const string &port, const char *message, int msgLength) =0; bool getIsBound() const { return mIsBound; } protected: bool mIsBound{}; }; class Socket : public ISocket { public: static const int FAMILY_IP4 = AF_INET; static IpAddress getAdaptersInfo(); bool createSocketUdp(); static const int INVALID_SOCKET = -1; private: int mUdpSocketIp4; public: //-------- class -------------- Socket(IpAddress ip) : ISocket(ip) { mUdpSocketIp4 = INVALID_SOCKET; createSocketUdp(); } virtual ~Socket() { ESP_LOGD("UDP", "Shutting down ..."); if (mUdpSocketIp4 != INVALID_SOCKET) { shutdown(mUdpSocketIp4, 2); close(mUdpSocketIp4); mUdpSocketIp4 = INVALID_SOCKET; } fos::Task::delayMs(100); mIsBound = false; } private: string mServerIP{}; string mServerPort{}; string mClientIp{}; string mClientPort{}; // port given by the user maybe "0" string mBoundClientPort{}; // port set after bind public: // Sets the ip address and port for server and client. void setConnectionParams(const string &serverIp, const string &serverPort, const string &clientIp, const string &clientPort) override { mServerIP = serverIp; mServerPort = serverPort; mClientIp = clientIp; mClientPort = clientPort; } /** * Send a message to the server as set by setConnectionParams * @param message byte buffer containing the message * @param length length of the message * @return */ int sendMessage(const char *message, int length) override { if (mServerPort.length() <= 0) { return -1; } if (mIsBound == false) { return -1; } int intResult = sendMessageTo(mServerIP, mServerPort, message, length); return intResult; } int receiveMessage(char *bu1ffer, int bufferLength, string *serverIp) const override; int setBroadcast(bool broadcast) const override; int bindSocket(string clientIp, string clientPort) override; int sendMessageTo(const string &ip, const string &port, const char *message, int msgLength) override; string getServerIP() const { return mServerIP; } string getServerPort() const { return mServerPort; } string getClientIP() const { return mClientIp; } string getClientPort() const { return mClientPort; } string getBoundClientPort() const { return mBoundClientPort; } void setBoundClientPort(const string &port) { mBoundClientPort = port; } void setIsBound(bool isBound) { mIsBound = isBound; } private: }; }