/// <summary> /// This function sends out a FDXDatagram /// </summary> /// <param name="datagram">the datagram that is to be send</param> /// <returns></returns> public int Send(ref FDXDatagram datagram) { //Set the current valid sequence number datagram.SetSequenceNumber(this.mNextTransmitSequenceNumber); // convert the datagram object to a byte array var outData = datagram.GenerateBuffer(); var res = this.mSocket.Send(outData, outData.Length); // Increment the sequence number for the next datagram this.mNextTransmitSequenceNumber = FDXDatagram.IncrementSequenceNumber(this.mNextTransmitSequenceNumber); return(res); }
public void DispatchDatagram(ref FDXDatagram datagram) { var lCopy = datagram.Buffer; //if the received bytes are too short, skip if (lCopy.Length < 16) { this.OnFormatError("Datagram too short"); return; } // extract datagram header information var header = DatagramHeader.DeSerialize(lCopy); //if the signature doesn't match, skip if (header.FDXSignature != FDXHelper.kFDXSignature) { this.OnFormatError("Signature mismatch"); return; } //if the major version doesn't match, skip if (header.FDXMajorVersion != FDXHelper.kFDXMajorVersion) { this.OnFormatError("Incorrect Major version"); return; } //if the minor version doesn't match, skip if (header.FDXMinorVersion != FDXHelper.kFDXMinorVersion) { this.OnFormatError("Incorrect Minor Version"); return; } //checking the sequence number if (header.SequenceNumber == FDXHelperSequenceNumber.kSequenceNumberUnused) { //we don't use sequence numbering } else { // check if the received sequence number is the expected if ((header.SequenceNumber & 0x7FFF) != this.mNextExpectedSequenceNumber) { this.OnSequenceError(this.mNextExpectedSequenceNumber, header.SequenceNumber); } // if the session end sequence number arrives, reset the expected sequence number else if ((header.SequenceNumber & FDXHelperSequenceNumber.kSequenceNumberSessionEndFlag) != 0) { this.mNextExpectedSequenceNumber = FDXHelperSequenceNumber.kSequenceNumberStart; } else { // if expected sequence number matches the received sequence number this.mNextExpectedSequenceNumber = FDXDatagram.IncrementSequenceNumber(header.SequenceNumber); } } //extract the number of commands and set the position var numOfCommands = header.NumberOfCommands; var commandPosAndLength = DatagramHeader.Size(); //create a buffer for the single commands var data = new byte[lCopy.Length - commandPosAndLength]; for (var i = 0; i < numOfCommands; ++i) { //copy command number i into the buffer Array.Copy(lCopy, commandPosAndLength, data, 0, lCopy.Length - commandPosAndLength); //extract the header information and copy the data from the buffer into the concrete command // buffer var cmdHead = CommandHeader.DeSerialize(data); var concreteCommand = new byte[cmdHead.CommandSize]; Array.Copy(data, 0, concreteCommand, 0, concreteCommand.Length); commandPosAndLength += concreteCommand.Length; // with the command code we can decide what to do with the received command switch (cmdHead.CommandCode) { case FDXHelperCommandCode.kCommandCodeDataExchange: { var cmd = DataExchangeCommand.DeSerialize(concreteCommand); this.OnDataExchange(cmd); break; } case FDXHelperCommandCode.kCommandCodeStatus: { var cmd = StatusCommand.DeSerialize(concreteCommand); this.OnStatus(cmd); break; } case FDXHelperCommandCode.kCommandCodeSequenceNumberError: { var com = SequenceNumberErrorCommand.DeSerialize(concreteCommand); this.OnSequenceError(com.ExpectedSeqNr, com.ReceivedSeqNr); break; } } } }