diff options
Diffstat (limited to 'SDL_Core/src/thirdPartyLibs/MessageBroker/include')
12 files changed, 1659 insertions, 0 deletions
diff --git a/SDL_Core/src/thirdPartyLibs/MessageBroker/include/CMessageBroker.hpp b/SDL_Core/src/thirdPartyLibs/MessageBroker/include/CMessageBroker.hpp new file mode 100644 index 000000000..7d6d8d86a --- /dev/null +++ b/SDL_Core/src/thirdPartyLibs/MessageBroker/include/CMessageBroker.hpp @@ -0,0 +1,101 @@ +/** + * \file CMessageBroker.hpp + * \brief CMessageBroker singletone class header. + * \author AKara + */ + +#ifndef CMESSAGEBROKER_H +#define CMESSAGEBROKER_H + +#include <string> + +#include "CSender.hpp" + +/** + * \namespace NsMessageBroker + * \brief MessageBroker related functions. + */ +namespace NsMessageBroker +{ + /** + * \enum ErrorCode + * \brief MessageBroker error codes. + * \note Value from -32099 to -32000 are reserved for implementation-defined server-errors. + */ + enum ErrorCode + { + CONTROLLER_EXISTS = -32000, /**< Controller has been already registered. */ + SUBSCRIBTION_EXISTS = -32001, /**< Property has been already subscribed by this controller. */ + PARSING_ERROR = -32700, /**< Invalid JSON. An error occurred on the server while parsing the JSON text. */ + INVALID_REQUEST = -32600, /**< The received JSON not a valid MessageBroker Request. */ + METHOD_NOT_FOUND = -32601, /**< The requested remote-procedure does not exist / is not available. */ + INVALID_PARAMS = -32602, /**< Invalid method parameters. */ + INTERNAL_ERROR = -32603 /**< Internal MessageBroker error. */ + }; + + /** + * \brief Forward declaration of the private class. + */ + class CMessageBroker_Private; + + /** + * \class CMessageBroker + * \brief Singletone CMessageBroker class implementation. + */ + class CMessageBroker + { + public: + /** + * \brief Singletone instantiator. + * \return pointer to CMessageBroker instance. + */ + static CMessageBroker* getInstance(); + + /** + * \brief Destructor. + */ + ~CMessageBroker(); + + /** + * \brief Receive data from TCP server (from client). + * \param fd FileDescriptor of socket. + * \param aJSONData JSON string. + */ + void onMessageReceived(int fd, std::string& aJSONData); + + /** + * \brief Test of buffer parsing. + */ + void Test(); + + + /** + * \brief Starts MessageBroker. + */ + void startMessageBroker(CSender* pSender); + + /** + * \brief Stops MessageBroker. + */ + void stopMessageBroker(); + + /** + * \brief Method for thread with que processing. + */ + void* MethodForThread(void * arg); + + private: + /** + * \brief Private constructor. + */ + CMessageBroker(); + + /** + * \brief The PIMPL of the class. + */ + CMessageBroker_Private *p; + }; +} /* namespace NsMessageBroker */ + +#endif // CMESSAGEBROKER_H + diff --git a/SDL_Core/src/thirdPartyLibs/MessageBroker/include/CMessageBrokerRegistry.hpp b/SDL_Core/src/thirdPartyLibs/MessageBroker/include/CMessageBrokerRegistry.hpp new file mode 100644 index 000000000..81d7f79c7 --- /dev/null +++ b/SDL_Core/src/thirdPartyLibs/MessageBroker/include/CMessageBrokerRegistry.hpp @@ -0,0 +1,98 @@ +#ifndef CMESSAGEBROKERREGISTRY_H +#define CMESSAGEBROKERREGISTRY_H + +#include <map> +#include <vector> +#include <iostream> +#include <string> + +/** + * \namespace NsMessageBroker + * \brief MessageBroker related functions. + */ +namespace NsMessageBroker +{ + + /** + * \class CMessageBrokerRegistry + * \brief Singletone CMessageBrokerRegistry class implementation. + */ + class CMessageBrokerRegistry + { + public: + /** + * \brief Singletone instantiator. + * \return pointer to CMessageBroker instance + */ + static CMessageBrokerRegistry* getInstance(); + + /** + * \brief Destructor. + */ + ~CMessageBrokerRegistry(); + + /** + * \brief adds controller to the registry. + * \param fd file descriptor of controller. + * \param name name of controller. + * \return false if already exist. + */ + bool addController(int fd, std::string name); + + /** + * \brief deletes controller from the registry. + * \param name name of controller. + */ + void deleteController(std::string name); + + /** + * \brief adds notification subscriber to the registry. + * \param fd file descriptor of controller. + * \param name name of property which should be observed. + * \return false if already exist. + */ + bool addSubscriber(int fd, std::string name); + + /** + * \brief deletes notification subscriber from the registry. + * \param fd file descriptor of controller. + * \param name name of property which should be observed. + */ + void deleteSubscriber(int fd, std::string name); + + /** + * \brief gets controller fd from the registry by name. + * \param name name of controller. + * \return file descriptor of controller. + */ + int getDestinationFd(std::string name); + + /** + * \brief gets subscribers fd's. + * \param name name of property. + * \param result vector for results. + * \return count of subscribers. + */ + int getSubscribersFd(std::string name, std::vector<int>& result); + private: + /** + * \brief Constructor. + */ + CMessageBrokerRegistry(); + + /** + * \brief Map to store controllers information like ComponentName:socketFd. + * For example PhoneController:1080 + */ + std::map <std::string, int> mControllersList; + + /** + * \brief Map to store subscribers information like ComponentName.PropertyName:socketFd:. + * For example PhoneController.onPhoneBookChanged:1080 + */ + std::multimap <std::string, int> mSubscribersList; + }; +} /* namespace NsMessageBroker */ + +#endif // CMESSAGEBROKERREGISTRY_H + diff --git a/SDL_Core/src/thirdPartyLibs/MessageBroker/include/CSender.hpp b/SDL_Core/src/thirdPartyLibs/MessageBroker/include/CSender.hpp new file mode 100644 index 000000000..78faf7dad --- /dev/null +++ b/SDL_Core/src/thirdPartyLibs/MessageBroker/include/CSender.hpp @@ -0,0 +1,53 @@ +/** + * \file CSender.hpp + * \brief CSender class header. + * \author AKara + */ + +#ifndef CSENDER_H +#define CSENDER_H + +#if _MSC_VER >= 1400 // VC++ 8.0 +typedef int ssize_t; +#endif + +/** + * \namespace NsMessageBroker + * \brief MessageBroker related functions. + */ +namespace NsMessageBroker +{ + /** + * \class CSender + * \brief CSender interface class implementation. + */ + class CSender + { + public: + /** + * \brief Constructor. + */ + CSender() + { + } + + /** + * \brief Destructor. + */ + ~CSender() + { + } + + /** + * \brief Send data. + * \param fd file descriptor of the client TCP socket + * \param data data to send + * \return number of bytes sent or -1 if error + */ + virtual ssize_t Send(int fd, const std::string& data)=0; + }; +} /* namespace NsMessageBroker */ + +#endif // CSENDER_H + + diff --git a/SDL_Core/src/thirdPartyLibs/MessageBroker/include/MBDebugHelper.h b/SDL_Core/src/thirdPartyLibs/MessageBroker/include/MBDebugHelper.h new file mode 100644 index 000000000..a22de3774 --- /dev/null +++ b/SDL_Core/src/thirdPartyLibs/MessageBroker/include/MBDebugHelper.h @@ -0,0 +1,40 @@ +/** + * \file MBDebugHelper.h + * \brief DebugHelper. + * \author AKara + */ + +#ifndef MB_DEBUG_HELPER_H +#define MB_DEBUG_HELPER_H + +#include <cstdio> + +/** +* \def DEBUG_ON +* \brief Switches on debug messages. +*/ +//#define DEBUG_ON + +#ifdef DEBUG_ON +/** +* \def DBG_MSG +* \brief Debug message output with file name and line number. +* \param x formatted debug message. +* \return printf construction. +*/ +#define DBG_MSG(x) printf("%s:%d ", __FILE__, __LINE__);\ + printf x +#else +#define DBG_MSG(x) +#endif + +/** +* \def DBG_MSG_ERROR +* \brief Debug ERROR message output with file name and line number. +* \param x formatted debug message. +* \return printf construction. +*/ +#define DBG_MSG_ERROR(x) printf("ERROR!!! %s:%d ", __FILE__, __LINE__);\ + printf x + +#endif /*MB_DEBUG_HELPER_H*/ diff --git a/SDL_Core/src/thirdPartyLibs/MessageBroker/include/mb_client.hpp b/SDL_Core/src/thirdPartyLibs/MessageBroker/include/mb_client.hpp new file mode 100644 index 000000000..cd70a31cd --- /dev/null +++ b/SDL_Core/src/thirdPartyLibs/MessageBroker/include/mb_client.hpp @@ -0,0 +1,135 @@ +/** + * \file mb_client.hpp + * \brief MessageBroker client. + * \author AKara + */ + +#ifndef MB_CLIENT_H +#define MB_CLIENT_H + +#if _MSC_VER >= 1400 // VC++ 8.0 +typedef int ssize_t; +#endif + +#include "networking.h" + +/** + * \namespace NsMessageBroker + * \brief MessageBroker related functions. + */ +namespace NsMessageBroker +{ + + /** + * \class Client + * \brief Abstract MessageBroker client. + */ + class Client + { + public: + /** + * \brief Constructor. + * \param address remote network address or FQDN to contact + * \param port remote local port to contact + */ + Client(const std::string& address, uint16_t port); + + /** + * \brief Destructor. + */ + virtual ~Client(); + + /** + * \brief Get socket descriptor. + * \return socket descriptor. + */ + int GetSocket() const; + + /** + * \brief Get the address. + * \return address or FQDN + */ + std::string GetAddress() const; + + /** + * \brief Get the port. + * \return local port + */ + uint16_t GetPort() const; + + /** + * \brief Connect to the remote machine + * \return true if success, false otherwise + * \note on connectionless protocol like UDP, this function + * always returns true even if remote peer is not reachable. + */ + virtual bool Connect(); + + /** + * \brief Receive data from the network. + * \param data if data is received it will put in this reference + * \return number of bytes received or -1 if error + * \note This method will blocked until data comes. + */ + virtual ssize_t Recv(std::string& data) = 0; + + /** + * \brief Close socket. + */ + virtual void Close(); + + protected: + /** + * \brief Socket descriptor. + */ + int m_sock; + + /** + * \brief Transport protocol of the socket. + */ + enum networking::TransportProtocol m_protocol; + + /** + * \brief Remote socket address. + */ + struct sockaddr_storage m_sockaddr; + + /** + * \brief Remote socket address length. + */ + socklen_t m_sockaddrlen; + + /** + * \brief Protected constructor so our inherited classes + * don't need to call the default constructor + */ + Client(); + + /** + * \brief Protected SetAddress so out inherited classes + * don't need to call the default constructor + */ + void SetAddress(const std::string& address); + + /** + * \brief Protected SetPort so out inherited classes + * don't need to call the default constructor + */ + void SetPort(uint16_t port); + + private: + + /** + * \brief Network address or FQDN. + */ + std::string m_address; + + /** + * \brief Local port. + */ + uint16_t m_port; + }; + +} /* namespace NsMessageBroker */ + +#endif /* MB_CLIENT_H */ diff --git a/SDL_Core/src/thirdPartyLibs/MessageBroker/include/mb_controller.hpp b/SDL_Core/src/thirdPartyLibs/MessageBroker/include/mb_controller.hpp new file mode 100644 index 000000000..d3dd305d9 --- /dev/null +++ b/SDL_Core/src/thirdPartyLibs/MessageBroker/include/mb_controller.hpp @@ -0,0 +1,236 @@ +/** + * \file mb_controller.hpp + * \brief MessageBroker Controller. + * \author AKara + */ + +#ifndef MB_CONTROLLER_H +#define MB_CONTROLLER_H + +#include <iostream> + +#include "json/json.h" + +#include "mb_tcpclient.hpp" + +#include <cstring> + +/** + * \namespace NsMessageBroker + * \brief MessageBroker related functions. + */ +namespace NsMessageBroker +{ + + /** + * \class CMessageBrokerController + * \brief MessageBroker Controller. + */ + class CMessageBrokerController : public TcpClient + { + public: + /** + * \brief Constructor. + * \param address remote network address or FQDN + * \param port remote local port + * \param name name of component + */ + CMessageBrokerController(const std::string& address, uint16_t port, std::string name); + + /** + * \brief Destructor. + */ + ~CMessageBrokerController(); + + /** + * \brief Receive data from the network. + * \param data if data is received it will put in this reference + * \return number of bytes received or -1 if error + * \note This method will blocked until data comes. + */ + virtual ssize_t Recv(std::string& data); + + /** + * \brief Send data. + * \param data data to send + * \return number of bytes sent or -1 if error + */ + ssize_t Send(const std::string& data); + + /** + * \brief send Json message. + * \param message JSON message. + */ + void sendJsonMessage(Json::Value& message); + + /** + * \brief generates new message id from diapason mControllersIdStart - (mControllersIdStart+999). + * \return next id for message + */ + int getNextMessageId(); + + /** + * \brief generates new message with id, jsonrpc version. + * \param root container for prepared message + */ + void prepareMessage(Json::Value& root); + + /** + * \brief generates new message with id, jsonrpc version. + * \note Doesn't change/add fields id and jsonrpc + * \param errCode error code + * \param errMessage string of message + * \param error container for prepared error message + */ + void prepareErrorMessage(int errCode, std::string errMessage, Json::Value& error); + + /** + * \brief gets destination component name. + * \param root JSON message. + * \return string destination component name. + */ + std::string getDestinationComponentName(Json::Value& root); + + /** + * \brief gets method name. + * \param root JSON message. + * \return string method name. + */ + std::string getMethodName(Json::Value& root); + + /** + * \brief checks is message notification or not. + * \param root JSON message. + * \return true if notification. + */ + bool isNotification(Json::Value& root); + + /** + * \brief checks is message response or not. + * \param root JSON message. + * \return true if response. + */ + bool isResponse(Json::Value& root); + + /** + * \brief searches Method by id in mWaitResponseQueue. + * \param id id of incoming JSON message. + * \return string method name or "" in case not found. + */ + std::string findMethodById(std::string id); + + /** + * \brief register controller on the server. + * \param id message id for JSON message due the id diapason hasn't been received. + */ + void registerController(int id = 0); + + /** + * \brief unregister controller on the server. + */ + void unregisterController(); + + /** + * \brief subscribes controller to the property changing. + * \param property property name in format ComponentName.PropertyName. + */ + void subscribeTo(std::string property); + + /** + * \brief unsubscribes controller from the property changing. + * \param property property name in format ComponentName.PropertyName. + */ + void unsubscribeFrom(std::string property); + + /** + * \brief pure virtual method to process response. + * \param method method name which has been called. + * \param root JSON message. + */ + virtual void processResponse(std::string method, Json::Value& root) = 0; + + /** + * \brief pure virtual method to process request. + * \param root JSON message. + */ + virtual void processRequest(Json::Value& root) = 0; + + /** + * \brief Process notification message. + * \brief Notify subscribers about property change. + * expected notification format example: + * \code + * {"jsonrpc": "2.0", "method": "<ComponentName>.<NotificationName>", "params": <list of params>} + * \endcode + * \param root JSON message. + */ + virtual void processNotification(Json::Value& root) = 0; + + /** + * \brief Checks message. + * \param root JSON message. + * \param error JSON message to fill in case of any errors. + * \return true if message is good. + */ + bool checkMessage(Json::Value& root, Json::Value& error); + + /** + * \brief Returns name of Controller. + * \return name of controller. + */ + std::string getControllersName(); + + /** + * \brief Method for receiving thread. + */ + void* MethodForReceiverThread(void * arg); + private: + /** + * \brief Method for receiving messages without tcp packeting. + * \param message received data + */ + void onMessageReceived(Json::Value message); + private: + /** + * \brief Start value of id's diapason. + */ + std::string m_receivingBuffer; + + /** + * \brief Start value of id's diapason. + */ + int mControllersIdStart; + + /** + * \brief Current id's value. + */ + int mControllersIdCurrent; + + /** + * \brief Already sent messages Methods to recognize esponses: MessageId:MethodName. + */ + std::map<std::string, std::string> mWaitResponseQueue; + + /** + * \brief Name of component. + */ + std::string mControllersName; + + /** + * \brief JSON reader. + */ + Json::Reader m_reader; + + /** + * \brief JSON writer. + */ + Json::FastWriter m_writer; + + /** + * \brief JSON writer. + */ + Json::FastWriter m_receiverWriter; + + }; +} /* namespace NsMessageBroker */ +#endif /* MB_CONTROLLER_H */ diff --git a/SDL_Core/src/thirdPartyLibs/MessageBroker/include/mb_server.hpp b/SDL_Core/src/thirdPartyLibs/MessageBroker/include/mb_server.hpp new file mode 100644 index 000000000..684a89055 --- /dev/null +++ b/SDL_Core/src/thirdPartyLibs/MessageBroker/include/mb_server.hpp @@ -0,0 +1,121 @@ +/** + * \file mb_server.hpp + * \brief MessageBroker server. + * \author AKara + */ + +#ifndef MB_SERVER_H +#define MB_SERVER_H + +#include "networking.h" + +/** + * \namespace NsMessageBroker + * \brief MessageBroker related functions. + */ +namespace NsMessageBroker +{ + + /** + * \class Server + * \brief Abstract MessageBroker server. + */ + class Server + { + public: + /** + * \brief Constructor. + * \param address network address or FQDN to bind + * \param port local port to bind + */ + Server(const std::string& address, uint16_t port); + + /** + * \brief Destructor. + */ + virtual ~Server(); + + /** + * \brief Wait message. + * + * This function do a select() on the socket and Process() immediately + * the message. + * \param ms millisecond to wait (0 means infinite) + */ + virtual void WaitMessage(uint32_t ms) = 0; + + /** + * \brief Get socket descriptor. + * \return socket descriptor. + */ + int GetSocket() const; + + /** + * \brief Get the address. + * \return address or FQDN + */ + std::string GetAddress() const; + + /** + * \brief Get the port. + * \return local port + */ + uint16_t GetPort() const; + + /** + * \brief Bind the socket. + * \return true if success, false otherwise + */ + bool Bind(); + + /** + * \brief Receive data from the network and process it. + * \param fd file descriptor on which receive + * \return true if message has been correctly received, processed and + * response sent, false otherwise (mainly send/receive error) + * \note This method will blocked until data comes. + */ + virtual bool Recv(int fd) = 0; + + /** + * \brief Close socket. + * \note It should be overriden for connection-oriented protocol + * like TCP to properly close all client sockets. + */ + virtual void Close(); + + protected: + /** + * \brief Socket descriptor. + */ + int m_sock; + + /** + * \brief Transport protocol of the socket. + */ + enum networking::TransportProtocol m_protocol; + + /** + * \brief Transport protocol of the socket. + */ + + private: + /** + * \brief Network address or FQDN. + */ + std::string m_address; + + /** + * \brief Local port. + */ + uint16_t m_port; + + /** + * \brief Encapsulated format. + */ + }; + +} /* namespace NsMessageBroker */ + +#endif /* MB_SERVER_H */ + diff --git a/SDL_Core/src/thirdPartyLibs/MessageBroker/include/mb_tcpclient.hpp b/SDL_Core/src/thirdPartyLibs/MessageBroker/include/mb_tcpclient.hpp new file mode 100644 index 000000000..07697dbde --- /dev/null +++ b/SDL_Core/src/thirdPartyLibs/MessageBroker/include/mb_tcpclient.hpp @@ -0,0 +1,58 @@ +/** + * \file mb_tcpclient.hpp + * \brief MessageBroker TCP client. + * \author AKara + */ + +#ifndef MB_TCPCLIENT_H +#define MB_TCPCLIENT_H + +#include <iostream> + +#include "mb_client.hpp" + +/** + * \namespace NsMessageBroker + * \brief MessageBroker related functions. + */ +namespace NsMessageBroker +{ + + /** + *Â \class TcpClient + * \brief MessageBroker TCP client. + */ + class TcpClient : public Client + { + public: + /** + * \brief Constructor. + * \param address remote network address or FQDN + * \param port remote local port + */ + TcpClient(const std::string& address, uint16_t port); + + /** + * \brief Destructor. + */ + virtual ~TcpClient(); + + /** + * \brief Receive data from the network. + * \param data if data is received it will put in this reference + * \return number of bytes received or -1 if error + * \note This method will blocked until data comes. + */ + virtual ssize_t Recv(std::string& data); + + /** + * \brief Send data. + * \param data data to send + * \return number of bytes sent or -1 if error + */ + ssize_t Send(const std::string& data); + }; + +} /* namespace NsMessageBroker */ + +#endif /* MB_TCPCLIENT_H */ diff --git a/SDL_Core/src/thirdPartyLibs/MessageBroker/include/mb_tcpserver.hpp b/SDL_Core/src/thirdPartyLibs/MessageBroker/include/mb_tcpserver.hpp new file mode 100644 index 000000000..73034027e --- /dev/null +++ b/SDL_Core/src/thirdPartyLibs/MessageBroker/include/mb_tcpserver.hpp @@ -0,0 +1,149 @@ +/** + * \file mb_tcpserver.hpp + * \brief MessageBroker TCP server. + * \author AKara + */ + +#ifndef MB_TCPSERVER_H +#define MB_TCPSERVER_H + +#include <list> +#include <map> + +#include "mb_server.hpp" +#include "CMessageBroker.hpp" +#include "CSender.hpp" +#include "websocket_handler.hpp" + +#define RECV_BUFFER_LENGTH 2200 +#define MAX_RECV_DATA 2048 + +/** + * \namespace NsMessageBroker + * \brief MessageBroker related functions. + */ +namespace NsMessageBroker +{ + /** + * \class TcpServer + * \brief MessageBroker TCP server implementation. + */ + class TcpServer : public Server, public CSender + { + public: + /** + * \brief Constructor. + * \param address network address or FQDN to bind + * \param port local port to bind + * \param pMessageBroker pointer to MessageBroker + */ + TcpServer(const std::string& address, uint16_t port, NsMessageBroker::CMessageBroker* pMessageBroker); + + /** + * \brief Destructor. + */ + virtual ~TcpServer(); + + /** + * \brief Receive data from the network and process it. + * \param fd socket descriptor to receive data + * \return true if message has been correctly received, processed and + * response sent, false otherwise (mainly send/recv error) + * \note This method will blocked until data comes. + */ + virtual bool Recv(int fd); + + /** + * \brief Send data. + * \param fd file descriptor of the client TCP socket + * \param data data to send + * \return number of bytes sent or -1 if error + */ + virtual ssize_t Send(int fd, const std::string& data); + + /** + * \brief Wait message. + * + * This function do a select() on the socket and Process() immediately + * the message. + * \param ms millisecond to wait (0 means infinite) + */ + virtual void WaitMessage(uint32_t ms); + + /** + * \brief Put the TCP socket in LISTEN state. + */ + bool Listen() const; + + /** + * \brief Accept a new client socket. + * \return -1 if error, 0 otherwise + */ + bool Accept(); + + /** + * \brief Close listen socket and all client sockets. + */ + void Close(); + + /** + * \brief Method for thread with WaitMessage. + */ + void* MethodForThread(void * arg); + + private: + /** + * \brief Checks if incoming messages are websocket request. + * \param fd + * \param pReceivingBuffer string receiving buffer pointer + * \return true if it is a websocket handshake + */ + bool checkWebSocketHandShake(int fd, std::string* pReceivingBuffer); + + /** + * \brief Checks if incoming messages are websocket request. + * \param fd file descriptor of the client TCP socket + * \return true if it is a websocket + */ + bool isWebSocket(int fd); + + /** + * \brief Gets buffer for socket which received data. + * \param fd socket file descriptor + */ + std::string* getBufferFor(int fd); + private: + /** + * \brief WebSocket clients fd's list. + */ + std::list<int> m_WebSocketClients; + + /** + * \brief Just accepted clients fd's list. + */ + std::list<int> m_AcceptedClients; + + /** + * \brief Receiving buffers map SocketFd:bufferPointer. + */ + std::map <int, std::string*> m_receivingBuffers; + + /** + * \brief List of disconnected sockets to be purged. + */ + std::list<int> m_purge; + + /** + * \brief MessageBroker pointer. + */ + NsMessageBroker::CMessageBroker* mpMessageBroker; + + /** + * \brief WebSocket handler. + */ + CWebSocketHandler mWebSocketHandler; + }; + +} /* namespace NsMessageBroker */ + +#endif /* MB_TCPSERVER_H */ diff --git a/SDL_Core/src/thirdPartyLibs/MessageBroker/include/networking.h b/SDL_Core/src/thirdPartyLibs/MessageBroker/include/networking.h new file mode 100644 index 000000000..a08853bb3 --- /dev/null +++ b/SDL_Core/src/thirdPartyLibs/MessageBroker/include/networking.h @@ -0,0 +1,139 @@ +/* + * JsonRpc-Cpp - JSON-RPC implementation. + * Copyright (C) 2008-2011 Sebastien Vincent <sebastien.vincent@cppextrem.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * \file networking.h + * \brief Networking utils. + * \author Sebastien Vincent + */ + +#ifndef NETWORKING_H +#define NETWORKING_H + +#ifdef _WIN32 + +#ifndef _MSC_VER +#include <stdint.h> +#endif //_MSC_VER + +#include <winsock2.h> +#include <windows.h> + +#if _MSC_VER >= 1400 // VC++ 8.0 +typedef unsigned short uint16_t; +typedef unsigned long uint32_t; +#define snprintf _snprintf +#endif //_MSC_VER >= 1400 + +/* to use getaddrinfo, _WIN32_WINNT have to + * equal at least 0x0501 + */ +#define OLD_WIN32_WINNT _WIN32_WINNT + +#if (_WIN32_WINNT < 0x0501) +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x501 +#endif //(_WIN32_WINNT < 0x0501) + +#include <ws2tcpip.h> + +#if (_WIN32_WINNT != OLD_WIN32_WINNT) +#undef _WIN32_WINNT +#define _WIN32_WINNT OLD_WIN32_WINNT +#endif //(_WIN32_WINNT != OLD_WIN32_WINNT) + +typedef int socklen_t; +#define close closesocket + +#else //_WIN32 + +#include <stdint.h> + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/time.h> + +#include <unistd.h> + +#include <netinet/in.h> + +#include <netdb.h> + +#endif //_WIN32 + +#include <string> + +/** + * \namespace networking + * \brief Networking related functions. + */ +namespace networking +{ + /** + * \enum TransportProtocol + * \brief Transport protocol. + */ + enum TransportProtocol + { + UDP = IPPROTO_UDP, /**< UDP protocol. */ + TCP = IPPROTO_TCP /**< TCP protocol. */ + }; + + /** + * \brief Initialize networking. + * \return true if network is correctly initialized, false otherwise + * \note On MS Windows, this step is mandatory to use + * socket API (socket(), bind(), recvfrom(), ...). + */ + bool init(); + + /** + * \brief Cleanup networking. + * \note On MS Windows, after calling this function, + * it will be impossible to use socket API. + */ + void cleanup(); + + /** + * \brief Connect to remote machine. + * \param protocol transport protocol used + * \param address remote address + * \param port remote port + * \param sockaddr if function succeed, sockaddr + * representation of address/port + * \param addrlen if function succeed, length of sockaddr + * \return socket descriptor if success, -1 otherwise + */ + int connect(enum TransportProtocol protocol, const std::string& address, uint16_t port, struct sockaddr_storage* sockaddr, socklen_t* addrlen); + + /** + * \brief Bind on a local address. + * \param protocol transport protocol used + * \param address local address + * \param port local port + * \param sockaddr if function succeed, sockaddr + * representation of address/port + * \param addrlen if function succeed, length of sockaddr + * \return socket descriptor if success, -1 otherwise + */ + int bind(enum TransportProtocol protocol, const std::string& address, uint16_t port, struct sockaddr_storage* sockaddr, socklen_t* addrlen); + +} /* namespace networking */ + +#endif /* NETWORKING_H */ + diff --git a/SDL_Core/src/thirdPartyLibs/MessageBroker/include/system.h b/SDL_Core/src/thirdPartyLibs/MessageBroker/include/system.h new file mode 100644 index 000000000..a9a3197bb --- /dev/null +++ b/SDL_Core/src/thirdPartyLibs/MessageBroker/include/system.h @@ -0,0 +1,311 @@ +/** + * \file system.h + * \brief System utils. + * \author Sebastien Vincent + */ + +#ifndef SYSTEM_H +#define SYSTEM_H + +#ifdef _WIN32 + +#include <windows.h> + +#else + +#include <pthread.h> + +#endif + +/** + * \namespace System + * \brief System related class (thread, ...). + */ +namespace System +{ + + /** + * \brief Sleep for x milliseconds + * \param ms millisecond to sleep + */ + void msleep(unsigned long ms); + + /** + * \class ThreadArg + * \brief Abstract class to represent thread argument. + * \see ThreadArgImpl + * \see Thread + */ + class ThreadArg + { + public: + /** + * \brief Destructor. + */ + virtual ~ThreadArg(); + + /** + * \brief Call the method. + * \note Have to be implemented by subclasses + */ + virtual void* Call() = 0; + }; + + /** + * \class ThreadArgImpl + * \brief Template class that represent thread argument. + * + * This class is used to provide callback function within + * an object. The method which will be called during thread + * execution must be of the form <code>void* MyMethod(void* arg)</code>. + * Inside this method you are free to called any method of the object. + * + * \warning As class keep pointer of object reference, you should take + * care at the lifetime of object you pass in ThreadArgImpl constructor, + * else it could lead to crash your program.\n See Thread class documentation + * for an example of how to use ThreadArgImpl class. + * \see Thread + */ + template<class T> class ThreadArgImpl : public ThreadArg + { + public: + /** + * \typedef Method + * \brief T method signature. + */ + typedef void* (T::*Method)(void*); + + /** + * \brief Constructor. + * \param obj object + * \param method class method + * \param arg argument to method + */ + ThreadArgImpl(T& obj, Method method, void* arg) + { + m_obj = &obj; + m_method = method; + m_arg = arg; + } + + /** + * \brief Call the method. + */ + virtual void* Call() + { + return (m_obj->*m_method)(m_arg); + } + + private: + /** + * \brief Object pointer. + */ + T* m_obj; + + /** + * \brief Method of T class. + */ + Method m_method; + + /** + * \brief Argument of method. + */ + void* m_arg; + }; + + /** + * \class Thread + * \brief Thread implementation. + * + * Preferred use of this class is to construct ThreadArgImpl inside + * another class and pass <code>*this</code> as obj parameter:\n + * \n + * \code + * class MyClass + * { + * public: + * void MyMethod() + * { + * ThreadArg* arg = new ThreadArgImpl<MyClass>(*this, &MyClass::MethodForThread, NULL); + * Thread th(arg); + * th.Start(); + * } + * + * void* MethodForThread(void * arg) + * { + * // do stuff + * } + * }; + * \endcode + * + */ + class Thread + { + public: + /** + * \brief Constructor. + * \param arg thread argument (MUST be dynamically allocated using new) + * \note System::Thread object takes care of freeing method memory.\n + * The way of calling constructor is: + * <code> + * Thread thread(new ThreadArgImpl<MyClass>(instanceOfMyClass, &MyClass::Method)); + * </code> + * \warning You should take care of the object (instanceOfMyClass) lifetime pass + * into ThreadArgImpl constructor, else it could lead to a crash because ThreadArgImpl + * keep pointer of the reference. + * \warning The "arg" parameter MUST be dynamically allocated (using new). + * \see ThreadArgImpl + */ + Thread(ThreadArg* arg); + + /** + * \brief Destructor. + */ + virtual ~Thread(); + + /** + * \brief Start thread. + * \param detach if set to true, the thread will be in detach state so + * you do not have to call join on this type of thread. + * \return true if success, false otherwise + * \warning Do NOT <code>Join</code> a detached thread. + */ + bool Start(bool detach); + + /** + * \brief Stop thread. + * \return true if success, false otherwise + * \warning Calling this method could lead callback object to an + * incoherent state. You should call it really in desperate situations when + * you really want to stop thread and do not care about the rest. + * \warning With POSIX thread implementation, calling Stop (one or more times) + * will leak 28 bytes of memory. + */ + bool Stop(); + + /** + * \brief Join thread. + * \param ret pointer to return code of the joined thread + * \return true if success, false otherwise + * \warning Do NOT <code>Join</code> a detached thread. + */ + bool Join(void** ret = NULL); + + private: + /** + * \brief Entry point of thread before calling specific + * callback. + * \param arg thread argument + * \return result of ThreadArg callback + */ +#ifdef _WIN32 + static DWORD WINAPI Call(LPVOID arg); +#else + static void* Call(void* arg); +#endif + /** + * \brief Thread identifier. + */ +#ifdef _WIN32 /* Win32 thread */ + HANDLE m_id; +#else /* POSIX thread */ + pthread_t m_id; +#endif + + /** + * \brief Thread argument. + */ + ThreadArg* m_arg; + }; + + /** + * \class Mutex + * \brief Mutex implementation. + */ + class Mutex + { + public: + /** + * \brief Constructor. + */ + Mutex(); + + /** + * \brief Destructor. + */ + ~Mutex(); + + /** + * \brief Lock the mutex. + * \return true if mutex is locked, false if error + */ + bool Lock(); + + /** + * \brief Unlock the mutex. + * \return true if mutex is unlocked, false if error + */ + bool Unlock(); + + private: + /** + * \brief The mutex. + */ +#ifdef _WIN32 + HANDLE m_mutex; +#else + pthread_mutex_t m_mutex; +#endif + }; + +#ifdef _WIN32 +#warning "BinarySemaphore is implemented for POSIX systems only" +#else + /** + * \class BinarySemaphore + * \brief Binary semaphore implementation. + */ + class BinarySemaphore { + public: + /** + * \brief Constructor. + */ + BinarySemaphore(); + + /** + * \brief Destructor. + */ + ~BinarySemaphore(); + + /** + * \brief Wait until the semaphore is unlocked. + */ + void Wait(); + + /** + * \brief Notify the semaphore. + */ + void Notify(); + + private: + /** + * \brief Mutex to prevent concurrent access to the flag. + */ + pthread_mutex_t m_mutex; + + /** + * \brief Conditional variable to block threads. + */ + pthread_cond_t m_cond; + + /** + * \brief Semaphore state: false = down, true = up. + */ + bool m_isUp; + }; +#endif /* _WIN32 */ + +} /* namespace System */ + +#endif /* SYSTEM_H */ + diff --git a/SDL_Core/src/thirdPartyLibs/MessageBroker/include/websocket_handler.hpp b/SDL_Core/src/thirdPartyLibs/MessageBroker/include/websocket_handler.hpp new file mode 100644 index 000000000..2d3f06cee --- /dev/null +++ b/SDL_Core/src/thirdPartyLibs/MessageBroker/include/websocket_handler.hpp @@ -0,0 +1,218 @@ +/** + * \file websocket_handler.hpp + * \brief WebSocket Handler. + * Supports RFC6455 standard of protocol + * Protocol specification: + * http://tools.ietf.org/html/rfc6455 + * \author AKara + */ + +#ifndef WEBSOCKET_HANDLER_H +#define WEBSOCKET_HANDLER_H + +#include <cstring> +#include <iostream> +#include <vector> + +#define MAX_WEBSOCKET_04_KEY_LEN 128 /**< Max WS key length */ + +#define K(t) _K[(t) / 20] /**< K(t) */ +#define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d))) /**< F0(b, c, d) */ +#define F1(b, c, d) (((b) ^ (c)) ^ (d)) /**< F1(b, c, d) */ +#define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d))) /**< F2(b, c, d) */ +#define F3(b, c, d) (((b) ^ (c)) ^ (d)) /**< F3(b, c, d) */ + +#define S(n, x) (((x) << (n)) | ((x) >> (32 - n))) /**< S(n, x) */ +#define H(n) (ctxt->h.b32[(n)]) /**< H(n) */ +#define COUNT (ctxt->count) /**< COUNT */ +#define W(n) (ctxt->m.b32[(n)]) /**< W(n) */ + +#define PUTPAD(x) { \ + ctxt->m.b8[(COUNT % 64)] = (x); \ + COUNT++; \ + COUNT %= 64; \ + if (COUNT % 64 == 0) \ + sha1_step(ctxt); \ + } /**< PUTPAD(x) */ + +/** + * \namespace NsMessageBroker + * \brief MessageBroker related functions. + */ +namespace NsMessageBroker +{ + /** + * \brief sha1_ctxt txt structure. + */ + struct sha1_ctxt + { + union { + unsigned char b8[20]; + unsigned long b32[5]; + } h; /**< h */ + union { + unsigned char b8[8]; + unsigned long long b64[1]; + } c; /**< c */ + union { + unsigned char b8[64]; + unsigned long b32[16]; + } m; /**< m */ + unsigned char count; /**< count */ + }; + + + /** + * \brief Constant table. + */ + const unsigned long _K[] = { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 }; + + /** + * \brief Constant table. + */ + const char encode[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz0123456789+/"; + + /** + * \brief Constant table. + */ + const char decode[] = "|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW" + "$$$$$$XYZ[\\]^_`abcdefghijklmnopq"; + + /** + * \brief Type to present raw bytes. + */ + typedef std::vector<char> rawBytes; + + + /** + * \class CWebSocketHandler + * \brief WebSocket messages handler. + */ + class CWebSocketHandler + { + public: + /** + * \brief Constructor. + */ + CWebSocketHandler() + { + } + + /** + * \brief Destructor. + */ + ~CWebSocketHandler() + { + } + + /** + * \brief Generates Sec-WebSocket-Accept key + * \param key Sec-WebSocket-Key from client + */ + void handshake_0405(std::string &key); + + /** + * \brief Generates accept key for older (hybi-00) WebSocket protocol version. + * \param key1 The first key of the client's handshake (a string) + * \param key2 The second key of the client's handshake (a string) + * \param key3 The third key of the client's handshake (raw bytes), must be 8 bytes long + * \return Raw bytes of the generated accept key, or no bytes if error + */ + rawBytes handshake_hybi00(const std::string &key1, const std::string &key2, const rawBytes &key3); + + /** + * \brief Parses WebSocket data + * \param Buffer input buffer + * \param b_size buffer size + * \return -1 in case of issues, data length in case of success + */ + int parseWebSocketData(char* Buffer, unsigned int& b_size); + + /** + * \brief Prepares WebSocket data + * \param Buffer input buffer + * \param b_size buffer size + * \return -1 in case of issues, data length in case of success + */ + int prepareWebSocketDataHeader(char* Buffer, unsigned long b_size); + private: + /** + * \brief SHA1 hash calculator. + * \param d input buffer + * \param n size of buffer + * \param md mask buffer + * \return pointer to result + */ + unsigned char * SHA1(const unsigned char *d, size_t n, unsigned char *md); + + /** + * \brief base 64 encode string. + * \param in input buffer + * \param in_len size of buffer + * \param out output buffer + * \param out_size size of buffer + * \return -1 in case of errors + */ + int lws_b64_encode_string(const char *in, int in_len, char *out, int out_size); + + /** + * \brief base 64 decode string. + * \param in input buffer + * \param out output buffer + * \param out_size size of buffer + * \return -1 in case of errors + */ + int lws_b64_decode_string(const char *in, char *out, int out_size); + + /** + * \brief one step of SHA1. + * \param ctxt input txt structure + */ + void sha1_step(struct sha1_ctxt *ctxt); + + /** + * \brief init step of SHA1. + * \param ctxt input txt structure + */ + void sha1_init(struct sha1_ctxt *ctxt); + + /** + * \brief pad step of SHA1. + * \param ctxt input txt structure + */ + void sha1_pad(struct sha1_ctxt *ctxt); + + /** + * \brief loop step of SHA1. + * \param ctxt input txt structure + * \param input input buffer buffer + * \param len length of input buffer + */ + void sha1_loop(struct sha1_ctxt *ctxt, const unsigned char *input, size_t len); + + /** + * \brief result step of SHA1. + * \param ctxt input txt structure + * \param digest0 buffer + */ + void sha1_result(struct sha1_ctxt *ctxt, unsigned char* digest0); + + /** + * \brief base 64 test. + * \return -1 in case of errors + */ + int lws_b64_selftest(void); + + /** + * \brief Extracts and processes the number from key, + * according to the WebSocket hybi-00 specification. + * \param key Key to extract the number from + * \return The number, or 0 if error + */ + unsigned long extractNumber(const std::string &key) const; + }; + +} /* namespace NsMessageBroker */ + +#endif /* WEBSOCKET_HANDLER_H */ |