I want to separate the communication protocol from the communication medium in a project. For example, I want to have a serial class and whatever other medium class and separately have a checksum protocol class and a crc protocol class and so forth. That way, a device class can have a member base class pointer to the medium and another to the protocol and via that device class's constructor child classes of both can be passed.
Pseudo code
class CDevice
{
public:
CDevice( CCommunicationDriver * drvr, CProtocol * protocol ) :
drvr_ ( drvr ),
protocol_ ( protocol )
{}
private:
CCommunicationDriver * drvr_;
CProtocol * protocol_;
};
class CCrcProtcol : public CProtocol
{};
class CSerial : public CCommunicationDriver
{};
CDevice a_device( new CSerial, new CCrcProtocol );
The idea is that if the difference between 2 devices is solely the medium and/or protocol a simple change can have a profound impact. The goal is minimal code rewrite for a change of this nature.
Ultimately, I envision the communication driver taking in a CPacket which is a thin wrapper around a std::vector. That way the interface for communicationdriver doesn't have to change going forward. I plan for the vector to hold unsigned char's ( bytes ) since ultimately everything going over a wire/medium is bytes.
This leads to commands that are decoupled from the medium and protocol albeit not completely decoupled. So, a command to turn on a light might have an ID 1 and a sub-ID 2. What I think I need to do is to pass child commands to the driver's transmit function [ tx( CCommand * ) ] and have that function apply the protocol's decoration ( not sure on how that'll work yet ) and then get a vector of bytes to have the child communication driver push out over the wire.
Thus, I have 2 questions I could use help with. 1. ( main question ) Since ultimately everything ends up in the std::vector< unsigned char > what's a flexible way to add data to that vector? I.e. a command has an id 2 bytes long due to one protocol but for another it's 4 bytes. How do I pass id and 2 or 4 to some function that will split it up into single bytes? Assume there's a lot sizes ( 1, 2, 3, 4, 8, etc. length ). I've thought about a template function that you specify the type with and then the value passed will be interpreted as that type's size. template< typename T > void addData( T data ) { // determine data's type, parse somehow? }
and also
template <typename T >
void addData( T data, int size )
{
// size is known but won't I have to specialize every size?
}
- Would you have the protocol class be a member of the driver class or keep them separate?
I hope this long explanation of what I'm trying to achieve is more helpful than annoying and that someone has a bright idea.
Thanks. -G-