2 #include "communicator.h"
6 using namespace Msp::Net;
14 class HandshakeProtocol: public Protocol
20 HandshakeProtocol::HandshakeProtocol():
23 add<Handshake>()(&Handshake::hash);
27 class HandshakeReceiver: public PacketReceiver<Handshake>
34 unsigned get_hash() const { return hash; }
35 virtual void receive(const Handshake &);
38 HandshakeReceiver::HandshakeReceiver():
42 void HandshakeReceiver::receive(const Handshake &shake)
53 Communicator::Communicator(StreamSocket &s, const Protocol &p, ReceiverBase &r):
59 in_buf(new char[buf_size]),
62 out_buf(new char[buf_size])
64 socket.signal_data_available.connect(sigc::mem_fun(this, &Communicator::data_available));
67 Communicator::~Communicator()
73 void Communicator::initiate_handshake()
75 if(handshake_status!=0)
76 throw InvalidState("Handshaking is already underway or done");
82 void Communicator::data_available()
84 in_end += socket.read(in_end, in_buf+buf_size-in_end);
90 if(handshake_status==2)
92 more = receive_packet(protocol, receiver);
96 HandshakeProtocol hsproto;
97 HandshakeReceiver hsrecv;
98 if((more = receive_packet(hsproto, hsrecv)))
100 if(hsrecv.get_hash()==protocol.get_hash())
102 if(handshake_status==0)
104 handshake_status = 2;
105 signal_handshake_done.emit();
120 bool Communicator::receive_packet(const Protocol &proto, ReceiverBase &recv)
122 int psz = proto.get_packet_size(in_begin, in_end-in_begin);
123 if(psz && psz<=in_end-in_begin)
125 char *pkt = in_begin;
127 proto.disassemble(recv, pkt, psz);
132 if(in_end==in_buf+buf_size)
134 unsigned used = in_end-in_begin;
135 memmove(in_buf, in_begin, used);
137 in_end = in_begin+used;
143 void Communicator::send_handshake()
146 shake.hash = protocol.get_hash();
148 HandshakeProtocol hsproto;
149 unsigned size = hsproto.assemble(shake, out_buf, buf_size);
150 socket.write(out_buf, size);