SenShaMart/demo/camera_client/dependencies/libvisiontransfer/visiontransfer/datachannelservicebase.h
2023-07-13 11:32:02 +10:00

145 lines
4.8 KiB
C++

/*******************************************************************************
* Copyright (c) 2021 Nerian Vision GmbH
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*******************************************************************************/
#include <memory>
#include <map>
#include <set>
#include <string>
#include <vector>
#include <algorithm>
#ifdef _WIN32
#include <winsock2.h>
#else
#include <arpa/inet.h>
#endif
#ifndef VISIONTRANSFER_DATACHANNELSERVICEBASE_H
#define VISIONTRANSFER_DATACHANNELSERVICEBASE_H
namespace visiontransfer {
namespace internal {
/*
* This is a header file for internal use, please use the wrappers from datachannelservice.h
*/
#pragma pack(push,1)
/**
* \brief Transport-level DataChannel header
*/
struct DataChannelMessageHeader {
uint8_t channelID;
uint8_t channelType;
uint32_t payloadSize;
};
struct DataChannelMessage {
DataChannelMessageHeader header;
unsigned char* payload;
};
#pragma pack(pop)
class DataChannelServiceBase;
/**
* \brief Base class all data channel services derive from (once on the server side, once on the API side)
*/
class DataChannel {
public:
/**
* \brief Known data channel service types, not all may be active on a specific device
*/
struct Types {
enum DataChannelTypesEnum {
CONTROL = 0x00,
BNO080 = 0x01,
UNDEFINED = 0xff
};
};
typedef unsigned char Type;
typedef unsigned char ID;
inline DataChannel(): infoString("RESERVED") { }
inline virtual ~DataChannel() {}
inline ID getChannelID() const { return channelID; }
inline std::string getInfoString() const { return infoString; }
inline void setService(std::weak_ptr<DataChannelServiceBase> serv) { service = serv; }
inline void setChannelID(ID id) { channelID = id; }
virtual Type getChannelType() const = 0;
/// \brief Channel-dependent message handlers in respective channel implementations
virtual int handleMessage(DataChannelMessage& message, sockaddr_in* sender) = 0;
/// \brief When initialize() implementations return false, the service will be deactivated
virtual bool initialize() = 0;
/// \brief startService() implementations can start devices, launch an IO-blocked worker thread etc.
virtual int startService() = 0;
/** \brief A single processing iteration; should be short and must not block.
* Actual frequency determined by the thread calling DataChannelServiceBase::process()
*/
virtual bool process() { return true; }
virtual int stopService() = 0;
protected:
std::string infoString;
int sendData(unsigned char* data, unsigned int dataSize, sockaddr_in* recipient=nullptr);
private:
ID channelID;
std::weak_ptr<DataChannelServiceBase> service;
};
/**
* \brief API-level data channel info for advertisements and subscription accounting
*/
class DataChannelInfo {
public:
inline DataChannelInfo(DataChannel::ID id, DataChannel::Type type, const std::string& info): channelID(id), channelType(type), infoString(info) { }
inline DataChannel::ID getChannelID() const { return channelID; }
inline DataChannel::Type getChannelType() const { return channelType; }
inline std::string getInfoString() const { return infoString; }
private:
DataChannel::ID channelID;
DataChannel::Type channelType;
std::string infoString;
};
/**
* \brief Base class for the data service (background sending and receiving, dispatching to channels)
*/
class DataChannelServiceBase: public std::enable_shared_from_this<DataChannelServiceBase> {
public:
DataChannelServiceBase();
~DataChannelServiceBase();
void process();
DataChannel::ID registerChannel(std::shared_ptr<DataChannel> channel);
virtual int sendDataInternal(unsigned char* compiledMessage, unsigned int messageSize, sockaddr_in* recipient);
int sendDataIsolatedPacket(DataChannel::ID id, DataChannel::Type type, unsigned char* data, unsigned int dataSize, sockaddr_in* recipient);
virtual int handleChannel0Message(DataChannelMessage& message, sockaddr_in* sender) = 0;
protected:
std::map<DataChannel::ID, std::shared_ptr<DataChannel> > channels;
#ifdef _WIN32
SOCKET dataChannelSocket;
#else
int dataChannelSocket;
#endif
DataChannelMessage message;
};
}} // namespaces
#endif