3 This file is part of libmspnet
4 Copyright © 2009 Mikkosoft Productions, Mikko Rasa
5 Distributed under the LGPL
9 #include "communicator.h"
13 using namespace Msp::Net;
21 class HandshakeProtocol: public Protocol
27 HandshakeProtocol::HandshakeProtocol():
30 add<Handshake>()(&Handshake::hash);
34 class HandshakeReceiver: public PacketReceiver<Handshake>
41 unsigned get_hash() const { return hash; }
42 virtual void receive(const Handshake &);
45 HandshakeReceiver::HandshakeReceiver():
49 void HandshakeReceiver::receive(const Handshake &shake)
60 Communicator::Communicator(StreamSocket &s, const Protocol &p, ReceiverBase &r):
66 in_buf(new char[buf_size]),
69 out_buf(new char[buf_size])
71 socket.signal_data_available.connect(sigc::mem_fun(this, &Communicator::data_available));
74 Communicator::~Communicator()
80 void Communicator::initiate_handshake()
82 if(handshake_status!=0)
83 throw InvalidState("Handshaking is already underway or done");
89 void Communicator::data_available()
91 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)
112 signal_handshake_done.emit();
127 bool Communicator::receive_packet(const Protocol &proto, ReceiverBase &recv)
129 int psz=proto.get_packet_size(in_begin, in_end-in_begin);
130 if(psz && psz<=in_end-in_begin)
134 proto.disassemble(recv, pkt, psz);
139 if(in_end==in_buf+buf_size)
141 unsigned used=in_end-in_begin;
142 memmove(in_buf, in_begin, used);
144 in_end=in_begin+used;
150 void Communicator::send_handshake()
153 shake.hash=protocol.get_hash();
155 HandshakeProtocol hsproto;
156 unsigned size=hsproto.assemble(shake, out_buf, buf_size);
157 socket.write(out_buf, size);