/* ZNetPeer.cpp Author: Patrick Baggett Created: 7/18/2013 Purpose: ZNet peer class, representing a remote host License: Copyright 2013, 762 Studios */ /*************************************************************************/ #include #include #include #include "ZNetPrivate.hpp" #include #include /*************************************************************************/ ZNetPeer::ZNetPeer() { lastValidIncoming = 0; lastOutgoingAck = 0; socketCopy = 0; channels = NULL; userdata = NULL; nrChannels = 0; ping = -1; state = STATE_UNCONNECTED; } /*************************************************************************/ bool ZNetPeer::Initialize(ZNetHost* _host, const SST_NetAddress* newAddr, SST_Socket s, uint32_t _nrChannels) { SST_OS_DebugAssert(_host != NULL, "Host may not be NULL"); SST_OS_DebugAssert(channels == NULL, "This should have been NULL; memory leak!"); channels = new(std::nothrow) ZNetPacketChannel[_nrChannels]; if(channels == NULL) return false; //Initialize channel ID (new[] doesn't allow non-default constructors) for(uint32_t i=0; i<_nrChannels; i++) { channels[i].SetChannelId(i); channels[i].SetHost(_host); } //Store other properties memcpy(&addr, newAddr, sizeof(SST_NetAddress)); nrChannels = _nrChannels; socketCopy = s; userdata = NULL; lastValidIncoming = SST_OS_GetMilliTime(); state = STATE_HANDSHAKE; //OK return true; } /*************************************************************************/ void ZNetPeer::Deinitialize() { for(uint32_t i=0; iGetPacketChannel(ZNET_SYSCHANNEL)->GetHost()->GetMTU(); bool unsent = true; uint64_t now = SST_OS_GetMilliTime(); //TODO: maybe not the best idea...? it will start out by sending an ACK 0...kinda silly I guess if(lastOutgoingAck == 0 || ((ping > 0) && (now > lastOutgoingAck + (uint64_t)ping) && (now - lastOutgoingAck > 50)) ) //TODO: does a minimum ack latency of 50 make any sense? in the cases where ping is realllly low (e.g. <= 1msec) don't need to spam? { lastOutgoingAck = now; } else return; ZBinaryBufferWriter writer(data, mtu, ZNET_BYTEORDER); //Write the write header ZNetPrivate::WriteWirePacketHeader(&writer); //Write an ACK point for each channel for(uint32_t i=0; i ZNetPrivate::WireSizeForSimpleCommand(ZNETCMD_ACK)) { //TODO: flags?? ZNetPrivate::WriteWireMessageHeader(&writer, i, 0, ZNETCMD_ACK, 0); writer.WriteU16(channel->GetLocalAck()); writer.WriteU16(channel->GetHighestSent()); unsent = true; } else { ZNetPrivate::SendAll(socketCopy, &addr, data, (uint32_t)writer.GetOffset()); unsent = false; //Restart writer.Rewind(); ZNetPrivate::WriteWirePacketHeader(&writer); } } if(unsent) ZNetPrivate::SendAll(socketCopy, &addr, data, (uint32_t)writer.GetOffset()); } /*************************************************************************/