#ifndef __LIBBC_BC_BASICSERVICE_HPP__ #define __LIBBC_BC_BASICSERVICE_HPP__ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ /** * @file * @brief main header file for the BasicService class * @author Dominik Meyer * @date 2018-11-23 * @copyright 2018 no yet defined */ #include #include #include #include #include #include #include #include #include #include #include #include namespace BC { /** * @brief base class for all battle-com services * * This class is the interface for all battle-com services. It enforces all * the required methods and provides essential data types. */ class BasicService { private: /// the network id of the device using this service BC::DataTypes::deviceIdType id; /// The major type of the id of the device using this service BC::DataTypes::deviceMajorType majorType; /// The minor type of the device, like a string with vendor/device string std::string minorType; /// variable for holding the receive thread identifier std::thread receiveThread; /// variable indicating if the receiveThread should be stopped std::atomic stopReceiveThread; /// list holding all the subscribers of this service std::map>> subscribers; /// mutex protecting the subscrivers list in a multithread context std::mutex subscribersMutex; /// show if the service is connected or not std::atomic connected; std::mutex mutex; /// attribute identifying this service as a gateway and all packets should be forwarded bool gateway = false; /** * @brief method called by the receive thread. * * This method is called inside the receiveThread * It calls the derivedReceive method in an endless loop. */ void receive(); /** * @brief method to process basic received messages * * example messages processed in this method are * PING and Control messages. * * @param m - the message to process * * @return true - the message has been processed by the method * @return false - the message has not been processes by the method */ bool basicProcess(const BC::Message *m); protected: /** * @brief called by the connect method after basic initializing * * This method has to be implemented by every child class. It is responsible * for connecting to the underlying transport layer protocol like UDP/TCP. * */ virtual void derivedConnect()=0; /** * @brief called by the disconnect method before closing everything down * * This method has to be implemented by every child class. It is responsible * for disconnecting from the underlying transport layer protocol like UDP/TCP. * */ virtual void derivedDisconnect()=0; /** * @brief called from the receive thread to receive a message in a *neverending loop* * * This method has to be implemented by every child class. It is responsible * for receiving data from the used transport layer protocol, like UDP/TCP . * * It has to be implemented that it receives one data frame. It is called repeatedly from * the receive thread. It may block but eventually the method has to return control * to the receive thread. * * The last action of this method has to be calling the process(std::vector v) method */ virtual void derivedReceive()=0; /** * @brief process an received data vector, called from the derivedReceive method * * Method converts the vector to a CMS::PubSub::Message and calls * the basicProcess and the process(CMS::PubSub::Message *m) method * * if the message is not processed by one of these methods it searches for subscribers * to call * * @param v - the vector to process and convert to a CMS::PubSub::Message */ void process(std::vector &v); /** * @brief called from the publish method inside the child class * * In this method the transmission of the message through the * used transport layer is implemented. * * The BasicService is publishing a HOTPLUG JOIN after connecting and * a HOTPLUG LEAVE message before disconnecting. The child class is * responsible to add a CMS::PubSub::Payloads::HotPlugJoin payload to * the first and a CMS::PubSub::Payloads::HotPlugLeave payload to the * later in this method before transmitting it. * * @param m - the message to publish/transmit */ virtual void derivedPublish(BC::Message &m)=0; /** * @brief method to process certain messages inside the child class * * Method is called after converting the char vector to a CMS::PubSub::Message * and calling basicProcess. The child class can process some required * special messages in this method. * * @param m - the message to process * * @return true - the message has been processed by the method * @return false - the message has not been processes by the method */ virtual bool process(const BC::Message *m)=0; public: /** * @brief main constructor for the BasicService class * * This constructor just initializes the attributes to the given parameter values. * receiveThread is initialized to a thread but without a call function. * This is required to just initialize the class without starting a thread. */ BasicService(const BC::DataTypes::deviceIdType &myID, const BC::DataTypes::deviceMajorType &majorT, const std::string &minorT) : id(myID), majorType(majorT), minorType(minorT), receiveThread(), stopReceiveThread(false), connected(false) {} /** * @brief destructor the the BasicService. if necessary stop the receiveThread * */ virtual ~BasicService(); /** * @brief set if we are a gateay or not * */ void setGateway(const bool v){gateway=v;} /** * @brief check if we are a gateway or not * */ bool isGateway() const {return gateway;} /** * @brief check if the service is already connected * */ bool isConnected() const {return connected;} /** * @brief just return the id */ BC::DataTypes::deviceIdType getId() const {return id;} /** * @brief method to connect the service to the underlying network and start receiving * * this method also calls the derivedConnect method of the child class */ void connect(); /** * @brief method to disconnect the service from the underlying network * * this method also calls the derivedDisconnect method of the child class */ void disconnect(); /** * @brief method to publish a message through the service * * this method calls the derivedPublish method of the child class * * @param m - the message to publish */ void publish(BC::Message &m); /** * @brief subscribe a CMS::PubSub::receiveable class to the list of domains and the list of topics * * @param r - the class to subscribe * @param domains the list of domains to subscribe to * @param topics the list of topics to subscribe to */ void subscribe(BC::receiveable *r, std::list domains, std::list topics); /** * @brief subscribe a CMS::PubSub::receiveable class to the domain and the list of topics * * @param r - the class to subscribe * @param domains the domain to subscribe to * @param topics the list of topics to subscribe to */ void subscribe(BC::receiveable *r, std::string domain, std::list topics); /** * @brief subscribe a CMS::PubSub::receiveable class to the list of domains and the topic * * @param r - the class to subscribe * @param domains the list of domains to subscribe to * @param topics the topic to subscribe to */ void subscribe(BC::receiveable *r, std::string domain, std::string topic); /** * @brief Return the id of the service in the network. * */ BC::DataTypes::deviceIdType getID() const { return id;} /** * @brief Get the Major Type of the Service. * * @return BC::DataTypes::deviceMajorType */ BC::DataTypes::deviceMajorType getMajorType() const { return majorType;} /** * @brief Get the Minor Type of the Service. * * @return std::string */ std::string getMinorType() const { return minorType;} }; }; // namespace BC #endif