/* ZNetHost.cpp Author: Patrick Baggett Created: 6/4/2013 Purpose: ZNet host class, represents the local system License: Copyright 2013, 762 Studios */ #include #include #include #include #include //SST_OS_Alloca() #include "ZNetPrivate.hpp" #include #include #include //HACKHACK /*************************************************************************/ ZNetHost::ZNetHost() { mtu = ZNET_MTU_IPV4SAFE; //Safe, but small MTU as a default dropChance = 0; } /*************************************************************************/ ZNetPacket* ZNetHost::CreatePacket(const void* initData, uint32_t dataSize, uint32_t flags) { ZNetPacket* packet; //Validate that ONLY legitimate bits are set if(flags != 0) return NULL; //Allocate packet structure + data packet = (ZNetPacket*)malloc(sizeof(ZNetPacket) + dataSize); if(packet == NULL) return NULL; packet->flags = flags; packet->dataSize = dataSize; packet->refCount = 1; if(initData != NULL) memcpy(packet->GetData(), initData, dataSize); return packet; } /*************************************************************************/ bool ZNetHost::GetNextEvent(ZNetEvent* eventReturn) { if(!events.Empty()) { *eventReturn = events.PopFront(); return true; } return false; } /*************************************************************************/ bool ZNetHost::SendToPeer(ZNetPeer* peer) { uint8_t* data = (uint8_t*)SST_OS_Alloca(GetMTU()); bool unsent = false; //TODO: No bandwidth allocations done here //TODO: send in round-robin fashion across channels ZBinaryBufferWriter writer(data, GetMTU(), ZNET_BYTEORDER); ZNetPrivate::WriteWirePacketHeader(&writer); //OUTER LOOP: for each channel for(uint32_t i=0; iGetNumberChannels(); i++) { ZNetPacketChannel* channel = peer->GetPacketChannel(i); bool moreInChannel = true; uint32_t index = 0; uint32_t newIndex; uint32_t nrWritten; //INNER LOOP: fill buffer with channel data do { uint32_t remain = mtu - (uint32_t)writer.GetOffset(); if(!channel->FillBuffer((uint8_t*)writer.GetBufferWriteAddress(), remain, index, &newIndex, &nrWritten))//TODO: update to make use of ZBinaryBufferWriter interface { //Buffer is full, send now index = newIndex; writer.SeekForward(nrWritten); if(!ZNetPrivate::SendAll(peer->GetSocket(), peer->GetNetAddress(), data, (uint32_t)writer.GetOffset())) { printf("SendToPeer FAILED %u bytes\n", (uint32_t)writer.GetOffset()); return false; } printf("SendToPeer -> Sent %u bytes\n", (uint32_t)writer.GetOffset()); //Restart! writer.Rewind(); ZNetPrivate::WriteWirePacketHeader(&writer); unsent = false; } else //Done with this channel { if(nrWritten > 0 && !unsent) { unsent = true; writer.SeekForward(nrWritten); } moreInChannel = false; } } while(moreInChannel); } //Any unsent data? if(unsent) { //Then send it! if(!ZNetPrivate::SendAll(peer->GetSocket(), peer->GetNetAddress(), data, (uint32_t)writer.GetOffset())) { printf("SendToPeer FAILED %u bytes\n", (uint32_t)writer.GetOffset()); return false; } printf("SendToPeer -> Sent %u bytes\n", (uint32_t)writer.GetOffset()); } return true; }