2 #include "communicator.h"
8 using namespace Msp::Net;
16 class HandshakeProtocol: public Protocol
22 HandshakeProtocol::HandshakeProtocol():
25 add<Handshake>()(&Handshake::hash);
29 class HandshakeReceiver: public PacketReceiver<Handshake>
36 unsigned get_hash() const { return hash; }
37 virtual void receive(const Handshake &);
40 HandshakeReceiver::HandshakeReceiver():
44 void HandshakeReceiver::receive(const Handshake &shake)
55 Communicator::Communicator(StreamSocket &s, const Protocol &p, ReceiverBase &r):
61 in_buf(new char[buf_size]),
64 out_buf(new char[buf_size]),
67 socket.signal_data_available.connect(sigc::mem_fun(this, &Communicator::data_available));
70 Communicator::~Communicator()
76 void Communicator::initiate_handshake()
78 if(handshake_status!=0)
79 throw sequence_error("handshaking already done");
85 void Communicator::data_available()
92 in_end += socket.read(in_end, in_buf+buf_size-in_end);
97 if(handshake_status==2)
99 more = receive_packet(protocol, receiver);
103 HandshakeProtocol hsproto;
104 HandshakeReceiver hsrecv;
105 if((more = receive_packet(hsproto, hsrecv)))
107 if(hsrecv.get_hash()==protocol.get_hash())
109 if(handshake_status==0)
111 handshake_status = 2;
112 signal_handshake_done.emit();
120 catch(const exception &e)
123 if(signal_error.empty())
125 signal_error.emit(e);
129 bool Communicator::receive_packet(const Protocol &proto, ReceiverBase &recv)
131 int psz = proto.get_packet_size(in_begin, in_end-in_begin);
132 if(psz && psz<=in_end-in_begin)
134 char *pkt = in_begin;
136 proto.disassemble(recv, pkt, psz);
141 if(in_end==in_buf+buf_size)
143 unsigned used = in_end-in_begin;
144 memmove(in_buf, in_begin, used);
146 in_end = in_begin+used;
152 void Communicator::send_handshake()
155 shake.hash = protocol.get_hash();
157 HandshakeProtocol hsproto;
158 unsigned size = hsproto.assemble(shake, out_buf, buf_size);
159 socket.write(out_buf, size);