Advertisement
alestane

Implementation for data layer

Apr 17th, 2012
176
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 21.64 KB | None | 0 0
  1. //
  2. //  Mediator.cpp
  3. //  Chess
  4. //
  5. //  Created by Nevin Flanagan on 4/10/12.
  6. //  Copyright (c) 2012. All rights reserved.
  7. //
  8.  
  9. #include "Mediator.h"
  10. #include <string.h>
  11. #include <sys/select.h>
  12. #include <sys/time.h>
  13.  
  14. using namespace std;
  15.  
  16. //  Transmission()
  17. //  Creates a blank transmission, usually for receiving
  18. //  Anthony Xu
  19. HostMediator::Transmission::Transmission() {
  20.     memset(data, 0, 256);
  21.     length=0;
  22. }
  23.  
  24.  
  25. //  Transmission(dataLength, someDataBuffer)
  26. //  Copies data into a transmission buffer for sending
  27. //  Anthony Xu
  28. HostMediator::Transmission::Transmission(unsigned short len, char const bytes[]) {
  29.     if (len > 256) {
  30.             throw string("package size too large!");
  31.         }
  32.     memcpy(this->data, bytes, len);
  33.     memset(this->data + len, 0, 256 - len);
  34.     // store length!
  35. }
  36.  
  37. //  HostMediator(hostName, contactPort, processor, errorRate)
  38. //  Creates a new mediator to handle reliable transmissions over a newly created connection
  39. //  Nevin Flanagan
  40. HostMediator::HostMediator(std::string const& targetAddress, int targetPort,
  41.                Acceptor& localProcessor, float errorRate): partner(*new RemoteHost(targetAddress, targetPort, *new ConnectionManager(this), errorRate)), processor(localProcessor) {
  42.  
  43. }
  44.  
  45. //  HostMediator(partnerHost, myProcessorCallback)
  46. //  Creates a new mediator to handle large, reliable transmissions using connection
  47. //  Nevin Flanagan
  48. HostMediator::HostMediator(RemoteHost& connection, HostMediator::Acceptor& localProcessor): partner(connection), processor(localProcessor) {
  49.     sendWindowSize = 2;
  50.     receiveWindowSize = 2;
  51.     for (int i = 0; i < sendWindowSize; ++i) {
  52.         sendingBuffers.push_back(new RemoteHost::Transmission());
  53.     }
  54.     receivingWindow.reset(receiveWindowSize);
  55.  
  56.     sendingID = 0;
  57.     receivingID = 0;
  58.     completedID = 0;
  59.     completedReceipt = 0;
  60. }
  61.  
  62. //  mediator.transmit(myTransmission[, false]);
  63. //  Starts sending myTransmission, dispatching an acknowledgement to the acceptor once receipt is confirmed
  64. //  reliable determines whether or not resends are done
  65. //  Nevin Flanagan
  66. HostMediator& HostMediator::transmit(HostMediator::Transmission const& data, bool reliable) throw (HostMediator::DeadConnection) {
  67.     //  add unique ID to queue
  68.     long long currentID = ++sendingID;
  69.     outgoingQueue.push_back(new SendBuffer(sendingID, data));
  70.     //  refill all empty send slots
  71.     if (!sendingID) {
  72.         list<unsigned char> openSlots = sendingWindow.missing();
  73.         for (unsigned char* e = openSlots.begin(); e != openSlots.end(); ++e) {
  74.             RemoteHost::Transmission* temporaryFrame = new RemoteHost::Transmission();
  75.             if (*outgoingQueue.begin() >> *temporaryFrame) {
  76.                 sendingWindow[*e] = temporaryFrame;
  77.                 partner << *temporaryFrame;
  78.             } else {
  79.                 delete temporaryFrame;
  80.                 break;
  81.             }
  82.         }
  83.     }
  84.     if (reliable) {
  85.         while (completedID != currentID);
  86.         completedID = 0;
  87.     }
  88.     return *this;
  89. }
  90.  
  91. //  mediator.transmit(myTransmission, interval[, false]);
  92. //  Starts sending myTransmission, dispatching an acknowledgment to the acceptor once receipt is confirmed. An exception is thrown if the operation can be complete within interval seconds.
  93. //  reliable determines whether or not resends are done
  94. //  Nevin Flanagan
  95. HostMediator& HostMediator::transmit(HostMediator::Transmission const& data, float timeout, bool reliable)
  96. throw (HostMediator::DeadConnection, HostMediator::TimeoutExpired) {
  97.    
  98. }
  99.  
  100. //  mediator.collect(blankTransmission)
  101. //  Fills blankTransmission in with the next packet waiting in the mediator.
  102. //  Blocks until a packet is available
  103. //  Anthony Xu
  104. HostMediator& HostMediator::collect(HostMediator::Transmission& storage) throw (HostMediator::DeadConnection) {
  105.     while (incomingQueue.size() == 0);
  106.     HostMediator::Transmission* packet = *incomingQueue.begin();
  107.     incomingQueue.pop_front();
  108.     memcpy(storage.data, packet->data, storage.length = packet->length);
  109.     return *this;
  110. }
  111.  
  112. //  mediator.collect(blankTransmission, interval)
  113. //  Fills blankTransmission in with the next packet waiting in the mediator.
  114. //  Blocks until a packet is available or interval passes.
  115. //  Anthony Xu
  116. HostMediator& HostMediator::collect(HostMediator::Transmission& storage, float timeout) throw (HostMediator::DeadConnection, HostMediator::TimeoutExpired) {}
  117.  
  118. //  long val = mediator.checksum(userTransmission)
  119. //  Calculates the four-byte checksum of the complete packet data using an XOR sequence
  120. //  Nevin Flanagan
  121. unsigned long HostMediator::checksum(HostMediator::Transmission const& source) {
  122.     unsigned long sum = 0;
  123.     for (unsigned short i = 0; i < source.length; ++i) {
  124.         sum ^= static_cast<unsigned long>(source.data[i]) << ((i % 4) * 8);
  125.     }
  126.     return sum;
  127. }
  128.  
  129. //  long val = mediator.checksum(internalTransmission)
  130. //  Calculates the three-byte checksum of the frame data using an XOR sequence
  131. //  Nevin Flanagan
  132. unsigned long HostMediator::checksum(RemoteHost::Transmission const& source) {
  133.     unsigned long sum = 0;
  134.     for (unsigned short i = 0; i < 128; ++i) {
  135.         if (i >= 1 && i <= 3)
  136.             continue;
  137.         sum ^= static_cast<unsigned long>(source.data[i]) << ((i % 3) * 8);
  138.     }
  139.     return sum;
  140. }
  141.  
  142. //  nack(fill, validFrame)
  143. //  Populates fill with a NACK frame based on the current state. Unless validFrame is false, fill is specified as the frame that failed.
  144. //  Nevin Flanagan
  145. RemoteHost::Transmission& HostMediator::nack(RemoteHost::Transmission& storage, bool valid) {
  146.     char sourceFrame = storage.data[18];
  147.     memset(storage.data, 0, 128);
  148.     storage.data[0] = NACK_LEADER;
  149.     packetID partial = receivingID;
  150.     for (int i = 11; i >= 4; --i) {
  151.         storage.data[i] = partial & 0xFF;
  152.         partial >>= 8;
  153.     }
  154.     char* frameList = storage.data + 12;
  155.     if (valid) {
  156.         *frameList = 0xF0 | sourceFrame >> 4;
  157.         ++frameList;
  158.     }
  159.     if (receivingID) {
  160.         *frameList = incoming->nextSequence() & 0x0F;
  161.         ++frameList;
  162.     }
  163.     list<unsigned char> missingFrames = receivingWindow.missing();
  164.     for (unsigned char* e = missingFrames.begin(); e != missingFrames.end(); ++e) {
  165.         *frameList = *e;
  166.         ++frameList;
  167.     }
  168.     *++frameList = 0;
  169.     unsigned long chk = checksum(storage);
  170.     for (int i = 3; i > 0; --i) {             //4 or 3? !!!
  171.         storage.data[i] = chk & 0xFF;
  172.         chk >>= 8;
  173.     }
  174.     return storage;
  175. }
  176.  
  177. //  ack(overwriteFrame)
  178. //  Creates a window state update based on the current receiving state
  179. //  Nevin Flanagan
  180. RemoteHost::Transmission& HostMediator::ack(RemoteHost::Transmission& complete) {
  181.     memset(complete.data, 0, 128);
  182.     complete.data[0] = ACK_LEADER;
  183.     packetID partial = receivingID;
  184.     if (!partial)
  185.         partial = completedReceipt;
  186.     for (int i = 11; i >= 4; --i) {
  187.         complete.data[i] = partial & 0xFF;
  188.         partial >>= 8;
  189.     }
  190.     char* frameList = complete.data + 12;
  191.     if (receivingID) {
  192.         list<unsigned char> missingFrames = receivingWindow.missing();
  193.         for (unsigned char* e = missingFrames.begin(); e != missingFrames.end(); ++e) {
  194.             *frameList = *e;
  195.             ++frameList;
  196.         }
  197.     }
  198.     *++frameList = 0;
  199.     unsigned long chk = checksum(complete);
  200.     for (int i = 3; i > 0; --i) {             //4 or 3? !!!
  201.         complete.data[i] = chk & 0xFF;
  202.         chk >>= 8;
  203.     }
  204.     return complete;
  205. }
  206.  
  207. //  ack(completedFrame, index)
  208. //  Creates a window state update acknowledging up through the specified index
  209. //  Nevin Flanagan
  210. RemoteHost::Transmission& HostMediator::ack(RemoteHost::Transmission& complete, unsigned char index) {
  211.     memset(complete.data, 0, 128);
  212.     complete.data[0] = ACK_LEADER;
  213.     packetID partial = receivingID;
  214.     for (int i = 11; i >= 4; --i) {
  215.         complete.data[i] = partial & 0xFF;
  216.         partial >>= 8;
  217.     }
  218.     char* frameList = complete.data + 12;
  219.     *frameList = index | 0xF0;
  220.     ++frameList;
  221.     list<unsigned char> missingFrames = receivingWindow.missing();
  222.     for (unsigned char* e = missingFrames.begin(); e != missingFrames.end(); ++e) {
  223.         *frameList = *e;
  224.         ++frameList;
  225.     }
  226.     *++frameList = 0;
  227.     unsigned long chk = checksum(complete);
  228.     for (int i = 3; i > 0; --i) {             //4 or 3? !!!
  229.         complete.data[i] = chk & 0xFF;
  230.         chk >>= 8;
  231.     }
  232.     return complete;
  233. }
  234.  
  235. //  mediator.processData(data)
  236. //  Attempts to process a new data frame into the receiving buffer
  237. //  Nevin Flanagan
  238. RemoteHost::Transmission& HostMediator::processFrame(RemoteHost::Transmission& receipt) {
  239.     packetID receivedPacket = 0;
  240.     for (int i = 5; i < 12; ++i) {
  241.         receivedPacket <<= 8;
  242.         receivedPacket |= receipt.data[i];
  243.     }
  244.     unsigned char receivedFrame = receipt.data[18] >> 4 & 0x0F;
  245.     if (!receivingID) {
  246.         if (receivedPacket == completedReceipt) {
  247.             //  ack was lost, re-acknowledge
  248.             return ack(receipt, receivedFrame);
  249.         } else {
  250.             if (!receivingWindow.includes(receivedFrame)) {
  251.                 return nack(receipt);
  252.             } else {
  253.                 receivingWindow[receivedFrame] = new RemoteHost::Transmission(128, receipt.data);
  254.                 receivingID = receivedPacket;
  255.                 unsigned short packetLength = 0;
  256.                 for (int i = 17; i >= 16; --i) {
  257.                     packetLength <<= 8;
  258.                     packetLength |= receipt.data[i];
  259.                 }
  260.                 incoming = new ReceiveBuffer(receivedPacket, packetLength);
  261.             }
  262.         }
  263.     } else {
  264.         if (receivedPacket != receivingID)
  265.             return nack(receipt);
  266.         else
  267.             if (receivingWindow.includes(receivedFrame))
  268.                 if (receivingWindow.contains(receivedFrame))
  269.                     return *reinterpret_cast<RemoteHost::Transmission*>(NULL);
  270.                 else
  271.                     receivingWindow[receivedFrame] = new RemoteHost::Transmission(128, receipt.data);
  272.             else
  273.                 return nack(receipt);
  274.     }
  275.     RemoteHost::Transmission* nextFrame;
  276.  
  277.     unsigned char lastExtracted = 0xFF;
  278.     bool completePacket = false;
  279.     while (!completePacket && receivingWindow >> nextFrame) {
  280.         *incoming << *nextFrame;
  281.         lastExtracted = nextFrame->data[18] >> 4;
  282.         completePacket = !(nextFrame->data[18] & 0x0F);
  283.         delete nextFrame;
  284.     }
  285.     receivingWindow.extend(receiveWindowSize);
  286.     if (completePacket) {
  287.         incomingQueue.push_back(new HostMediator::Transmission(incoming->length, incoming->data));
  288.         completedReceipt = receivingID;
  289.         receivingID = 0;
  290.         receivingWindow.reset(receiveWindowSize);
  291.         delete incoming;
  292.         incoming = NULL;
  293.     }
  294.     if (lastExtracted < 16)
  295.         return ack(receipt, lastExtracted);
  296.     return *reinterpret_cast<RemoteHost::Transmission*>(NULL);
  297. }
  298.  
  299. //  processACK(ackFrame)
  300. //  Updates the sending window to clear all data leading up to the acknowledged frame
  301. //  Nevin Flanagan
  302. RemoteHost::Transmission& HostMediator::processACK(RemoteHost::Transmission& ackFrame) {
  303.     packetID partial = 0;
  304.     for (int i = 5; i < 12; ++i) {
  305.         partial <<= 8;
  306.         partial |= ackFrame.data[i];
  307.     }
  308.     unsigned char acknowledgedFrame = ackFrame.data[12] & 0x0F;
  309.     while (sendingWindow.contains(acknowledgedFrame)) {
  310.         RemoteHost::Transmission* completedFrame;
  311.         sendingWindow >> completedFrame;
  312.     }
  313.     sendingWindow.extend(sendWindowSize);
  314.     list<unsigned char> openSlots = sendingWindow.missing();
  315.     for (unsigned char* e = openSlots.begin(); e != openSlots.end(); ++e) {
  316.         RemoteHost::Transmission* temporaryFrame = new RemoteHost::Transmission();
  317.         if (*outgoingQueue.begin() >> *temporaryFrame) {
  318.             sendingWindow[*e] = temporaryFrame;
  319.             partner << *temporaryFrame;
  320.         } else {
  321.             delete temporaryFrame;
  322.             break;
  323.         }
  324.     }
  325.     openSlots = sendingWindow.missing();
  326.     if (openSlots.size() >= sendWindowSize) {
  327.         SendBuffer* finished = *outgoingQueue.begin();
  328.         outgoingQueue.pop_front();
  329.         delete finished;
  330.         processor(*this, HostMediator::Acceptor::packet_acknowledged);
  331.     }
  332.     if (outgoingQueue.size() > 0) {
  333.         for (unsigned char * e = openSlots.begin(); e != openSlots.end(); ++ e) {
  334.             RemoteHost::Transmission* temporaryFrame = new RemoteHost::Transmission();
  335.             if (*outgoingQueue.begin() >> *temporaryFrame) {
  336.                 sendingWindow[*e] = temporaryFrame;
  337.                 partner << *temporaryFrame;
  338.             } else {
  339.                 delete temporaryFrame;
  340.                 break;
  341.             }
  342.         }
  343.     }
  344.     return ackFrame;
  345. }
  346.  
  347. //  processNACK(nackFrame)
  348. //  Handles retransmission when negative acknowledgments are received.
  349. //  Nevin Flanagan
  350. RemoteHost::Transmission& HostMediator::processNACK(RemoteHost::Transmission& nackFrame) {
  351.     packetID partial = 0;
  352.     for (int i = 5; i < 12; ++i) {
  353.         partial <<= 8;
  354.         partial |= nackFrame.data[i];
  355.     }
  356.     unsigned char acknowledgedFrame = nackFrame.data[12] & 0x0F;
  357.     unsigned char earliestAwaited = nackFrame.data[13];
  358.     if (sendingWindow.contains(earliestAwaited))
  359.         partner << *sendingWindow[earliestAwaited];
  360.     return nackFrame;
  361. }
  362.  
  363. //  SlidingWindow.reset(size)
  364. //  Leaves the window empty, with size slots starting from 0
  365. //  Nevin Flanagan
  366. void HostMediator::SlidingWindow::reset(unsigned char windowSize) {
  367.     clear();
  368.     while (--windowSize) {
  369.         push_back(value_type(size(), NULL));
  370.     }
  371. }
  372.  
  373. //  SlidingWindow.extend(size)
  374. //  Adds new empty slots in sequence until there are at least size
  375. //  Nevin Flanagan
  376. void HostMediator::SlidingWindow::extend(unsigned char windowSize) {
  377.     unsigned char lastIndex = rbegin()->first;
  378.     while (size() < windowSize) {
  379.         if (++lastIndex > 15) lastIndex = 1;
  380.         push_back(value_type(lastIndex, NULL));
  381.     }
  382. }
  383.  
  384. //  SlidingWIndow.includes(index)
  385. //  returns true if there is a bloc in the window with the specified index,
  386. //  whether or not it contains any content
  387. //  Nevin Flanagan
  388.  
  389. //  SlidingWindow.contains(index)
  390. //  Returns true if the window includes the specified index, and it has content.
  391. //  Nevin Flanagan
  392. bool HostMediator::SlidingWindow::contains(unsigned char index) {
  393.     for (iterator e = begin(); e != end(); ++e) {
  394.         if (e->first == index)
  395.             return e->second != NULL;
  396.     }
  397.     return false;
  398. }
  399.  
  400. //  SlidingWindow[index]
  401. //  provides easy access to the frame pointer associated with a given index
  402. //  Nevin Flanagan
  403. RemoteHost::Transmission*& HostMediator::SlidingWindow::operator [](unsigned char index) {
  404.     for (iterator e = begin(); e != end(); ++e) {
  405.         if (e->first == index)
  406.             return e->second;
  407.     }
  408.     throw string("requested element not found in window");
  409.     return NULL;
  410. }
  411.  
  412. //  SlidingWindow >> framePtr
  413. //  Removes the front of the list, if it has content, and stores the pointer in framePtr
  414. //  If the first item in the list has no content, returns fals and stores nothing.
  415. //  Nevin Flanagan
  416. bool HostMediator::SlidingWindow::operator>>(RemoteHost::Transmission*& receiver) {
  417.     RemoteHost::Transmission* next = begin()->second;
  418.     if (next) {
  419.         pop_front();
  420.         receiver = next;
  421.         return true;
  422.     }
  423.     return false;
  424. }
  425.  
  426. //  SlidingWindow.missing()
  427. //  Returns a list of spaces reserved in the window but not filled, in order
  428. //  Nevin Flanagan
  429. list<unsigned char> HostMediator::SlidingWindow::missing() {
  430.     list<unsigned char> emptySlots;
  431.     for (iterator e = begin(); e != end(); ++e) {
  432.         if (!e->second)
  433.             emptySlots.push_back(e->first);
  434.     }
  435.     return emptySlots;
  436. }
  437.  
  438. //  SendBuffer(packetID, sourceData)
  439. //  Manages fragmenting the contents of a Transmission into a size suitable for a RemoteHost
  440. //  Anthony Xu
  441. HostMediator::SendBuffer::SendBuffer(packetID sendingPacket, HostMediator::Transmission const& source): Transmission(source.length, source.data) {
  442.     data=source.data; // Use parent class constructor to copy data instead; see line above
  443.     length=source.length;
  444.     ID = sendingPacket;
  445.     sequenceNumber = 0;
  446.     buffer = this->data;  //256 // should be set to this->data, not source.data which belongs to application layer
  447. }
  448.        
  449. //  sendBuffer >> outgoingBuffer
  450. //  Extracts the next frame from the buffer
  451. //  Anthony Xu
  452. bool HostMediator::SendBuffer::operator>>(RemoteHost::Transmission& storage) {
  453.     //  this function uses fields length, data, buffer, ID, and sequence number,
  454.     //  as well as the static mediator checksum functions, to assemble a frame
  455.     //  inside storage.data. It updates the buffer and sequenceNumber fields so
  456.     //  that on the next call, it will read new data.
  457.  
  458.     //  fill in the first byte with Mediator::DATA_LEADER
  459.     //  Fill in bytes 4-11 with the packet ID
  460.     //  Fill in bytes 12-15 with the packet checksum (use existing function)
  461.     //  Fill in bytes 16-17 with the total packet length (just use the length field here)
  462.     //  Fill in byte 19 with the amount of data being put in the frame (up to 108 bytes)
  463.     //  Fill in byte 18 with the sequence information; put the current value of
  464.     //  sequenceNumber in the top four bits, then if there is no more data for another
  465.     //  frame, put 0 in the bottom four bits; or, if there is more data left, add one to
  466.     //  sequenceNumber (skip to 1 if this makes it more than 15) and store that in the
  467.     //  bottom four bits instead.
  468.     //  Fill in bytes 20-127 with data from buffer, and move buffer up.
  469.     //  Finally, use HostMediator::checksum on the frame, and store the result in bytes 1-3.
  470.  
  471.     if (!buffer)
  472.         return false;
  473.  
  474.     packetID partial = ID; //    partial is not being initialized; set to ID
  475.     bool b_moreData=false;
  476.  
  477.     storage.data[0] = HostMediator::DATA_LEADER;
  478.     for (int i = 11; i >= 4; --i) {
  479.         storage.data[i] = partial & 0xFF;
  480.         partial >>= 8;
  481.     }
  482.  
  483.     //copy current package data to make a HostMediator::Transmission
  484.     //it's used for calculate checksum
  485.     // NFF
  486.     //  Don't need a new HostMediator::Transmission; a SendBuffer inherits from it
  487.     //  Just say checksum(*this). Also, you leak memory here.
  488.     /*
  489.     HostMediator::Transmission* package0;
  490.     package0 = new HostMediator::Transmission(length, data);
  491.     unsigned long chk_pkg = checksum(package0);
  492.     */
  493.     unsigned long chk_pkg = checksum(*this);
  494.  
  495.     for (int i = 15; i > 11; --i) {
  496.         storage.data[i] = chk_pkg & 0xFF;
  497.         chk_pkg >>= 8; // variable name doesn't match
  498.     }
  499.     unsigned long len0=length;
  500.     for (int i = 17; i > 15; --i) {
  501.         storage.data[i] = len0 & 0xFF;
  502.         len0 >>= 8;
  503.     }
  504.     unsigned long len1=strlen(buffer);
  505.     if (len1>108){
  506.         b_moreData=true;
  507.         len1=108;
  508.     }
  509.     storage.data[19] = len1 & 0xFF;
  510.     unsigned long seq0 = sequenceNumber;
  511.     unsigned long seq1 = 0;
  512.     if (b_moreData)
  513.         seq1 = sequenceNumber+1;
  514.     if (seq1 > 15)
  515.         seq1 = 1;
  516.     storage.data[18] = (seq1 & 0x0F) | (seq0 & 0xF0);
  517.     memcpy(storage.data+20, buffer, len1);
  518.     unsigned long chk_frame = checksum(storage);
  519.     for (int i = 3; i > 0; --i) {             //4 or 3? !!! // frame checksum goes in bytes 1, 2, 3; this is correct
  520.         storage.data[i] = chk_frame & 0xFF;
  521.         chk_frame >>= 8; // should be chk_frame
  522.     }
  523.  
  524.     buffer+=len1;
  525.     sequenceNumber = seq1; // sequenceNumber has to go to 1 if it gets bigger than 15; save seq1 instead of incrementing
  526.     return true;
  527. }
  528.  
  529. //  ReceiveBuffer()
  530. //  Initializes a blank buffer to receive packet data into
  531. //  Anthony Xu
  532. HostMediator::ReceiveBuffer::ReceiveBuffer(packetID receivingPacket, unsigned short declaredLength) {
  533.     memset(data, 0, 256);
  534.     ID = receivingPacket;
  535.     length = declaredLength;
  536.     buffer = data;
  537.     sequenceNumber = 0;
  538.     //  sequenceNumber needs to be zero
  539. }
  540.  
  541. //  buffer << receivedData
  542. //  Adds data from a received block into the buffer.
  543. //  First verify that the buffer's desired sequence number matches the recevied frame.
  544. //  Anthony Xu
  545. bool HostMediator::ReceiveBuffer::operator<<(RemoteHost::Transmission const& source) {
  546.     //  Get data out of source.data. Make sure the sequence number (top four bits of byte 18)
  547.     //  matches the sequenceNumber field of this. If it doesn't, return false. Then, set the
  548.     //  sequenceNumber of this object to the bottom four bits of that byte. Get the frame data
  549.     //  length from byte 19, and copy that much data from bytes 20-127 into the buffer of this
  550.     //  object. Move the buffer up so that the next new frame doesn't overwrite the data we just copied.
  551.     //
  552.  
  553.     unsigned long checkbytes0, checkbytes1;
  554.     checkbytes0 = source[18] & 0xF0;
  555.     checkbytes1 = checkbytes0 >> 4 & 0x0F;
  556.     if (checkbytes1 != sequenceNumber)
  557.         return false;
  558.     else {
  559.         checkbytes1 = source[18] & 0x0F;
  560.     }
  561.     sequenceNumber = checkbytes1;
  562.     checkbytes0 = source[19] & 0xFF;
  563.     memcpy((void*) (source.data+20), (void*) buffer, checkbytes0);
  564.     buffer+=checkbytes0;
  565.     return true;
  566. }
  567.  
  568. //  ConnectionManager(deferredHandler)
  569. //  Creates a new ConnectionManager which will allocate a HostMediator if
  570. //  needed and use it to process incoming connections
  571. //  Nevin Flanagan
  572. HostMediator::ConnectionManager::ConnectionManager(HostMediator::Acceptor& handler): acceptor(handler), mediator(NULL), allocated(NULL) {}
  573.  
  574. //  ConnectionManager(linkedMediator)
  575. //  Creates a ConnectionManager to handle an existing HostMediator
  576. //  Nevin Flanagan
  577. HostMediator::ConnectionManager::ConnectionManager(HostMediator& client): mediator(&client), allocated(NULL), acceptor(*reinterpret_cast<HostMediator::Acceptor*>(NULL)) {}
  578.  
  579. //  [callback]
  580. //  Processes incoming data from the remote connection to pass ACKs and store incoming packets.
  581. //  Nevin Flanagan
  582. void HostMediator::ConnectionManager::operator()(RemoteHost& connection, event what) {
  583.     if (!mediator)
  584.         allocated = mediator = new HostMediator(connection, acceptor);
  585.     switch (what) {
  586.     case RemoteHost::Acceptor::connection_lost:
  587.         mediator->processor(*mediator, HostMediator::Acceptor::connection_lost);
  588.         if (allocated) {
  589.             delete mediator;
  590.             delete this;
  591.         }
  592.         break;
  593.     case RemoteHost::Acceptor::data_ready:
  594.         //  collect arrived frame
  595.         RemoteHost::Transmission receipt;
  596.         connection >> receipt;
  597.         //  check frame integrity
  598.         unsigned long checkval = 0;
  599.         for (int i = 1; i < 4; ++i) {
  600.             checkval <<= 8;
  601.             checkval |= receipt.data[i];
  602.         }
  603.         if (mediator->checksum(receipt) != checkval) {
  604.             mediator->nack(receipt, false);
  605.             connection << receipt;
  606.             return;
  607.         }
  608.         switch (receipt.data[0]) {
  609.         case DATA_LEADER:
  610.             RemoteHost::Transmission& result = mediator->processFrame(receipt);
  611.             if (&result != NULL)
  612.                 connection << result;
  613.             return;
  614.             break;
  615.         case ACK_LEADER:
  616.             break;
  617.         case NACK_LEADER:
  618.             break;
  619.         }
  620.         break;
  621.     }
  622. }
  623.  
  624. //  ConnectionManager::Constructor(genObject)
  625. //  Creates a manager that can be invoked to create a ConnectionManager that will use genObject as a reference to create new HostMediator::Acceptors
  626. //  Nevin Flanagan
  627. HostMediator::ConnectionManager::Generator::Generator(HostMediator::Acceptor::Generator& source): generator(source) {}
  628.  
  629. //  [callback]
  630. //  Calls a Generator to produce a new ConnectionManager object
  631. //  Nevin Flanagan
  632. RemoteHost::Acceptor& HostMediator::ConnectionManager::Generator::operator()(int socketID) {
  633.     return *new HostMediator::ConnectionManager(generator(*this));
  634. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement