/// <summary> /// Sollte nur vom Konstruktor aufgerufen werden, versucht übergebenes Objekt in M3S-Datenframe oder Interference zu konvertieren /// </summary> /// <param name="rToStore">m3sDataframe oder Bytestream</param> private void analyseAndStore(object rToStore) { // Differenziere was es ist... logTime = DateTime.Now; dgv = new DataGridView(); if (rToStore.GetType() == typeof(IM3S_Dataframe)) { validFrame = rToStore as IM3S_Dataframe; } else if (rToStore.GetType() == typeof(byte[])) { // Konvertierung war nicht erfolgreich, probiere es in einen Bytestream zu verwandeln byte[] tempStream = rToStore as byte[]; try { int errCode = -555; validFrame = protocol.CreateFrameByBytestream(tempStream, out errCode); if (errCode == 0) // Konvertierung war erfolgreich { isValidFrame = true; interference = null; } else // Konvertierung war nicht erfolgreich { validFrame = null; interference = tempStream; // Ablegen isValidFrame = false; } } catch { // Nothing, war einfach nicht konvertierbar... Muss also Störung sein validFrame = null; interference = tempStream; // Ablegen isValidFrame = false; } } else if (rToStore.GetType() == typeof(byte)) { } else { // War auch kein Bytearray, also Exception TBL.Exceptions.ConversionException ex = new TBL.Exceptions.ConversionException("Das bei der Instanzierung an M3sLogFrame übergebene hat keinen gültigen Typ (erlaubt: m3sDataframe und byte[])"); throw ex; } if (this.isValidFrame) { if (this.validFrame.Protocol == M3SProtocol.Reset) { resetCounter++; } } }
/// <summary> /// Delegates Frames to appropriate processing Methods /// </summary> /// <param name="rDataframe">Frame that should be processed</param> /// <returns>true, if frame was successfully processed, false otherwise</returns> private bool processFrame(IM3S_Dataframe rDataframe, out int oErrorCode) { oErrorCode = -555; if (rDataframe.Protocol == M3SProtocol.Command || rDataframe.Protocol == M3SProtocol.CommandBroadcast) { return(processCommand(rDataframe, out oErrorCode)); } return(false); }
public M3SCommandReceivedEventArgs(IM3S_Dataframe rReceivedFrame) { frame = rReceivedFrame; byte[] frameBytes = frame.GetDataframe(); int upperBound = frameBytes[2]; // M3s-Upperbound cmd = frameBytes[3]; paramBytes = new byte[upperBound]; for (int i = 0; i < upperBound; i++) { paramBytes[i] = frameBytes[i + 4]; } }
private int sendSlaveInfo(IM3S_Dataframe requestFrame) { byte[] payload = { protocol_version, protocol_subv, protocol_revision, implementation, (byte)(slaveAddr), (byte)(mcAddr), (byte)(deviceID >> 8), (byte)(deviceID & 0xff), (byte)(dataUpperBound), }; IM3S_Dataframe frameToSend = protocol.CreateFrame(slaveAddr, M3SProtocol.CommandResponse, requestFrame.MasterAddress, payload, false, true); return(writeToHardware(frameToSend)); }
public bool SendCommandResponse(IM3S_Dataframe rCommandFrame, byte[] rResponseBytes, out int oErrorCode) { oErrorCode = 0; if (rCommandFrame.Protocol == M3SProtocol.Command) { IM3S_Dataframe toSend = protocol.CreateFrame(rCommandFrame.SlaveAddress, M3SProtocol.CommandResponse, rCommandFrame.MasterAddress, rResponseBytes, false, true); oErrorCode = writeToHardware(toSend); if (oErrorCode == 0) { return(true); } else { return(false); } } else { throw new TBL.Exceptions.FrameError("In DevComSlave.SendCommandResponse: passed rCommandFrame has a wrong protocol, only Command-Protocol allowed here..."); } }
private bool processCommand(IM3S_Dataframe rDataFrame, out int oErrorCode) { oErrorCode = -555; byte[] payload = protocol.ExtractPayload(rDataFrame.GetDataframe()); byte cmd = payload[0]; switch (cmd) { case (byte)M3SCommand.GetInformation: oErrorCode = sendSlaveInfo(rDataFrame); break; case (byte)M3SCommand.Ping: oErrorCode = 0; // no error, ack is sent outside... cnt++; break; default: if (delegateCommand != null) { return(delegateCommand(this, new M3SCommandReceivedEventArgs(rDataFrame))); } return(false); } if (oErrorCode == 0) { return(true); } else { return(false); } }
/// <summary> /// Sollte nur vom Konstruktor aufgerufen werden, versucht übergebenes Objekt in M3S-Datenframe oder Interference zu konvertieren /// </summary> /// <param name="rToStore">m3sDataframe oder Bytestream</param> private void analyseAndStore(object rToStore) { // Differenziere was es ist... logTime = DateTime.Now; dgv = new DataGridView(); if(rToStore.GetType() == typeof(IM3S_Dataframe)) { validFrame = rToStore as IM3S_Dataframe; } else if(rToStore.GetType() == typeof(byte[])) { // Konvertierung war nicht erfolgreich, probiere es in einen Bytestream zu verwandeln byte[] tempStream = rToStore as byte[]; try { int errCode = -555; validFrame = protocol.CreateFrameByBytestream(tempStream, out errCode); if(errCode == 0) // Konvertierung war erfolgreich { isValidFrame = true; interference = null; } else // Konvertierung war nicht erfolgreich { validFrame = null; interference = tempStream; // Ablegen isValidFrame = false; } } catch { // Nothing, war einfach nicht konvertierbar... Muss also Störung sein validFrame = null; interference = tempStream; // Ablegen isValidFrame = false; } } else if(rToStore.GetType() == typeof(byte)) { } else { // War auch kein Bytearray, also Exception TBL.Exceptions.ConversionException ex = new TBL.Exceptions.ConversionException("Das bei der Instanzierung an M3sLogFrame übergebene hat keinen gültigen Typ (erlaubt: m3sDataframe und byte[])"); throw ex; } if(this.isValidFrame) { if(this.validFrame.Protocol == M3SProtocol.Reset) { resetCounter++; } } }
public M3sLogFrame(IM3S_Dataframe rValidFrame) { analyseAndStore(rValidFrame); }
private bool processCommand(IM3S_Dataframe rDataFrame, out int oErrorCode) { oErrorCode = -555; byte[] payload = protocol.ExtractPayload(rDataFrame.GetDataframe()); byte cmd = payload[0]; switch(cmd) { case (byte)M3SCommand.GetInformation: oErrorCode = sendSlaveInfo(rDataFrame); break; case (byte)M3SCommand.Ping: oErrorCode = 0; // no error, ack is sent outside... cnt++; break; default: if(delegateCommand !=null) { return delegateCommand(this, new M3SCommandReceivedEventArgs(rDataFrame)); } return(false); } if(oErrorCode==0) { return(true); } else { return(false); } }
private void recBuffer_ByteReceived(object sender, EventArgs e) { int err; while (recBuffer.DataPtr > protocol.MinimumFrameLength) // während im Buffer entsprechen dda { somethingToSend = false; bool ackResult = false; // immer von vorne her anschaun if (state == DevComSlaveState.NotReady) { for (int i = 0; i < resetFrame.Length && i < recBuffer.DataPtr; i++) { if (recBuffer.ReadByte(i) != resetFrame[i]) // If it doesnt match frame { recBuffer.FreeBytes(0, i); // Remove Bytes incl. faulty byte recBuffer.Flush(); break; } if (i == resetFrame.GetUpperBound(0)) // got here without error => reset gotten { recBuffer.FreeBytes(0, i); recBuffer.Flush(); reset(); } } } else { for (int bufferIdx = protocol.MinimumFrameLength - 1; bufferIdx < recBuffer.DataPtr; bufferIdx++) { byte[] possFrame = recBuffer.readBytes(0, bufferIdx); if (protocol.IsFrame(possFrame)) { // Do something with the frame IM3S_Dataframe frame = protocol.CreateFrameByBytestream(possFrame, out err); if (err != 0) { if (debugmode) { stdOut.Error("Could not convert Bytestream to valid M3S-Dataframe: " + TBLConvert.BytesToHexString(possFrame)); } } else { switch (frame.Protocol) { case M3SProtocol.CommandBroadcast: if (frame.MulticastAddress == 0 || frame.MulticastAddress == mcAddr) { ackResult = processFrame(frame, out err); } break; case M3SProtocol.DataTransfer: if (frame.SlaveAddress == slaveAddr) { ackResult = processFrame(frame, out err); } break; case M3SProtocol.Command: if (frame.SlaveAddress == slaveAddr) { ackResult = processFrame(frame, out err); } break; case M3SProtocol.BroadCast: if (frame.MulticastAddress == 0 || frame.MulticastAddress == mcAddr) { ackResult = processFrame(frame, out err); } break; } if (frame.NeedsAcknowledgement && !ackAlreadySent) { hwInterface.WriteData(protocol.GetAcknowledgeFrame(ackResult, possFrame).GetDataframe()); somethingToSend = true; } } // remove the frame recBuffer.FreeBytes(0, bufferIdx); recBuffer.Flush(); } } } if (!somethingToSend) { // Only for TCP clients try { DevComTcpServer serv = hwInterface as DevComTcpServer; // if castable, its a server serv.RemainListening(); } catch { // do nothing instead } } } }
public M3SCommandReceivedEventArgs(IM3S_Dataframe rReceivedFrame) { frame = rReceivedFrame; byte[] frameBytes = frame.GetDataframe(); int upperBound = frameBytes[2]; // M3s-Upperbound cmd = frameBytes[3]; paramBytes = new byte[upperBound]; for(int i=0; i<upperBound; i++) { paramBytes[i] = frameBytes[i+4]; } }
private int writeToHardware(IM3S_Dataframe frameToWrite) { ackAlreadySent = true; somethingToSend = true; return(hwInterface.WriteData(frameToWrite.GetDataframe())); }
private int sendSlaveInfo(IM3S_Dataframe requestFrame) { byte[] payload = { protocol_version, protocol_subv, protocol_revision, implementation, (byte)(slaveAddr), (byte)(mcAddr), (byte)(deviceID >> 8), (byte)(deviceID & 0xff), (byte)(dataUpperBound), }; IM3S_Dataframe frameToSend = protocol.CreateFrame(slaveAddr, M3SProtocol.CommandResponse, requestFrame.MasterAddress, payload, false, true); return writeToHardware(frameToSend); }
/// <summary> /// Delegates Frames to appropriate processing Methods /// </summary> /// <param name="rDataframe">Frame that should be processed</param> /// <returns>true, if frame was successfully processed, false otherwise</returns> private bool processFrame(IM3S_Dataframe rDataframe, out int oErrorCode) { oErrorCode = -555; if(rDataframe.Protocol == M3SProtocol.Command || rDataframe.Protocol == M3SProtocol.CommandBroadcast) { return(processCommand(rDataframe, out oErrorCode)); } return(false); }
private bool sendCommandReadAnswer(IM3S_Dataframe pCmdFrame, out byte[] oAnswer, out int oErrorCode) { oErrorCode=-555; oAnswer = null; bool acknowledged = !pCmdFrame.NeedsAcknowledgement; // wenn kein acknowledge benötigt wird, von vornherein acknowledged.. int ptrBefore = recBuffer.DataPtr; if(available) { if(interferenceHandling) { recBuffer.HandleGarbage(); } for(int i= 0; (i < tryXTimes); i++) { oErrorCode = sendToHardware(pCmdFrame.GetDataframe()); if( oErrorCode == 0) // wenn erfolgreich gesendet wurde { // stdOut.Debug("Data Sent: " + TBLConvert.BytesToHexString(pData)); // Ausgabe zum Bibliotheksdebuggen readTimeoutReached = false; watchDog.Enabled = true; // Starte für Timeout // hier komm ich her... while(!readTimeoutReached) // wait until dataptr points to Place BEHIND last Databyte { if(recBuffer.DataPtr >= (ptrBefore+protocol.MinimumFrameLength)) { byte[] received = recBuffer.readBytes(ptrBefore, recBuffer.DataPtr-1); // read Frame that is supposed to be Acknowledge frame.. if(received.Length == protocol.AcknowledgeFrameLength) { if(protocol.IsAcknowledge(pCmdFrame.GetDataframe(),received, out oErrorCode)) { acknowledged = true; watchDog.Enabled = false; watchDog.Enabled = true; acknowledged = true; ptrBefore += protocol.AcknowledgeFrameLength; // offset erhöhen } else { if(oErrorCode == -36) { // Explizites NAK return(false); } } } else { if(protocol.IsFrame(received)) { if(acknowledged || protocol.IsImplicitAcknowledge(pCmdFrame.GetDataframe(), received, out oErrorCode)) { oAnswer = received; oErrorCode = 0; recBuffer.FreeBytes(ptrBefore, recBuffer.DataPtr-1); recBuffer.Flush(); return(true); // FOUND!! } else { if(oErrorCode == -37) { // Explizites NAKimplizit return(false); } } } } } } watchDog.Enabled = false; // watchdog aus... if(readTimeoutReached) { if(debugMode) { stdOut.Debug("Readtimeout reached @ " + watchDog.Interval.ToString() + " ms!! Buffer contains: " + recBuffer.ToString()); } recBuffer.FreeBytes(ptrBefore, recBuffer.DataPtr-1); recBuffer.Flush(); Reset(out oErrorCode); if(oErrorCode != 0) // RESET ist schiefgegangen { return(false); } } else { throw new Exception("internal sendCommandReadAnswer: This case should not be reached... Please contact Author of Library"); } } } if(oErrorCode == 0) { ptrBefore += protocol.AcknowledgeFrameLength; if(debugMode) { stdOut.Debug("Command successfully sent, got acknowledged by slave @ internal sendCommandReadAnswer(byte[]) .. waiting for response..."); } readTimeoutReached = false; watchDog.Enabled = true; while(!readTimeoutReached) { int bufferEnd = recBuffer.DataPtr; int possFrameStart = ptrBefore; if((bufferEnd - ptrBefore) >= protocol.MinimumFrameLength) { //starte suche# int possUpperBound; int possFrameEnd; while(possFrameStart + protocol.MinimumFrameLength <= recBuffer.DataPtr) { possUpperBound = recBuffer.ReadByte(possFrameStart + protocol.UpperBoundPosition); possFrameEnd = possFrameStart+protocol.Overhead + possUpperBound; byte[] possFrame = recBuffer.readBytes(possFrameStart, possFrameEnd); if(protocol.IsFrame(possFrame)) { watchDog.Enabled = false; if(debugMode) { stdOut.Debug("Response frame ("+(possFrameEnd-possFrameStart).ToString() +" bytes) found in receive buffer (holding " + recBuffer.DataPtr.ToString() + " bytes); Byte " + possFrameStart.ToString() + " to " + (possFrameEnd).ToString() + " .. Removing them from ReceiveBuffer (Free and Flush)"); } recBuffer.FreeBytes(possFrameStart,possFrameEnd); recBuffer.Flush(); // Buffer leeren oErrorCode =0; oAnswer = possFrame; return(true); } // else possFrameStart++; // eines weiter hinten starten } } } // Watchdog hat gezogen readTimeoutReached = false; // rücksetzen oErrorCode=-217; // Watchdog gezogen... oAnswer = null; return(false); } } else { oErrorCode=-34;//not available oAnswer = null; } return(false); }
// Schreibt Frame und stellt fest, ob ein Acknowledge benötigt wird oder nicht. Wenn ja, wird auf Acknowledge gewartet, sonst nur versendet private int writeFrame(IM3S_Dataframe vFrame) { bool sendSuccesful = false; int ptrBefore; int error=0; // TODO: Derive acknowledge from data.. if(available) { if(interferenceHandling) { recBuffer.HandleGarbage(); } if(!vFrame.NeedsAcknowledgement) // Wenn kein Acknowledge gefordert wird { return(this.sendToHardware(vFrame.GetDataframe())); } // ELSE for(int i= 0; (i < tryXTimes) && !(sendSuccesful); i++) { ptrBefore = recBuffer.DataPtr; //stdOut.Debug("PtrBefore now (before sending..): " + ptrBefore.ToString()); // Ausgabe zum Bibliotheksdebuggen if(sendToHardware(vFrame.GetDataframe()) == 0) // wenn erfolgreich gesendet wurde { // stdOut.Debug("Data Sent: " + TBLConvert.BytesToHexString(pData)); // Ausgabe zum Bibliotheksdebuggen readTimeoutReached = false; watchDog.Enabled = true; // Starte für Timeout // hier komm ich her... while(recBuffer.DataPtr < (ptrBefore+protocol.MinimumFrameLength) && !readTimeoutReached) // wait until dataptr points to Place BEHIND last Databyte { // wait } watchDog.Enabled = false; // watchdog aus... if(!readTimeoutReached) { byte[] received = recBuffer.readBytes(ptrBefore, ptrBefore + (protocol.AcknowledgeFrameLength -1)); // read Frame that is supposed to be Acknowledge frame.. // Check if Acknowledge try { if(protocol.IsAcknowledge(vFrame.GetDataframe(), received, out error)) { sendSuccesful = true; recBuffer.FreeBytes(ptrBefore, ptrBefore + received.Length-1); recBuffer.Flush(); } else { if(error == -36) { return(error); // Explizites NAK erhalten... } sendSuccesful = false; int err; if(!Reset(out err)) { return(err); } // send again, probably log error?! // ERROR: not Acknowledge, Log? } } catch(Exception e) // Frame error in irgend einer Weise... { // getLastError hat die FEhlernummer der Exception inna.. if(debugMode) { stdOut.Error("Intern TBL.Communication.devCom.writeFrame(byte[]), Acknowledge auswerten: " + Environment.NewLine + EDOLLHandler.GetLastError(), e.ToString()); } } } else { // Error: readtimeout reached if(debugMode) { stdOut.Debug("Readtimeout reached @ " + watchDog.Interval.ToString() + " ms!! Buffer contains: " + recBuffer.ToString()); } } } } if(!sendSuccesful) { if(error == 0) { error = -203; // Timeout } return(error); } else { return(0); } } else { // TODO: Fehlernummer "unavailable" return(-555); // ruhig weiterlaufen lassen, sonst werden dauernd fehler ausgegeben... Da wird getäuscht!! } }
public bool SendCommandResponse(IM3S_Dataframe rCommandFrame, byte[] rResponseBytes, out int oErrorCode) { oErrorCode = 0; if(rCommandFrame.Protocol == M3SProtocol.Command) { IM3S_Dataframe toSend = protocol.CreateFrame(rCommandFrame.SlaveAddress, M3SProtocol.CommandResponse,rCommandFrame.MasterAddress,rResponseBytes,false,true); oErrorCode = writeToHardware(toSend); if(oErrorCode == 0) { return(true); } else { return(false); } } else { throw new TBL.Exceptions.FrameError("In DevComSlave.SendCommandResponse: passed rCommandFrame has a wrong protocol, only Command-Protocol allowed here..."); } }