git-subtree-dir: libs/CommService git-subtree-split: 7ccc0fce88bbc5969df060058cf0fb57abe3bcf9
284 lines
9.1 KiB
C++
284 lines
9.1 KiB
C++
#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 <dmeyer@hsu-hh.de>
|
|
* @date 2018-11-23
|
|
* @copyright 2018 no yet defined
|
|
*/
|
|
#include <thread>
|
|
#include <iostream>
|
|
#include <string>
|
|
#include <thread>
|
|
#include <mutex>
|
|
#include <chrono>
|
|
#include <list>
|
|
#include <atomic>
|
|
#include <map>
|
|
#include <BC/BC.hpp>
|
|
#include <BC/Message.hpp>
|
|
#include <BC/receiveable.hpp>
|
|
|
|
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<bool> stopReceiveThread;
|
|
|
|
/// list holding all the subscribers of this service
|
|
std::map<std::string, std::map<std::string,std::vector<BC::receiveable *>>> subscribers;
|
|
|
|
/// mutex protecting the subscrivers list in a multithread context
|
|
std::mutex subscribersMutex;
|
|
|
|
/// show if the service is connected or not
|
|
std::atomic<bool> 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<unsigned char> 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<unsigned char> &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<std::string> domains, std::list<std::string> 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<std::string> 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
|