/// <summary> /// Erstellt aufgrund von pStatus eine versandfertige byteFolge mit der entsprechenden Kommandorückmeldung (siehe <see cref="m3sExecutionError">m3sExecutionError</see>) im ersten Nutzdatenbyte und zusätzlichen Informationen (nachfolgende Nutzdatenbytes) /// </summary> /// <param name="pStatus">Ausführungsstatus des Kommandos (siehe <see cref="m3sExecutionError">m3sExecutionError</see>)</param> /// <param name="pCommandFrame">Frame, aufgrunddessen das Kommando ausgeführt wurde</param> /// <param name="pInfo">Informationsdatenbytes (max. 255) als byte[], auch null kann übergeben werden.</param> /// <returns> /// <list type="table"> /// <item><term>versandfertiges ByteArray</term><description>bei fehlerfreier Ausführung</description></item> /// <item><term>Exception</term><description>im Fehlerfall</description></item> /// </list> /// </returns> /// <remarks> /// Die Funktion kann zusätzliche als Parameter übergebene Informationsbytes an den Kommandosender zurückliefern. Diese werden als byte[] übergeben und hinten an das ExecutionStatus-Byte angehängt. /// <para> /// <para>Interne <see cref="EDOLL">EDOLL-Behandlung</see> ist implementiert. Das heißt im Fehlerfall (siehe Rückgabewert) kann mit einer Codezeile der Fehler ausgegeben werden:</para> /// <para><c>string EDOLLHandler.GetLastError();</c></para> /// </para> /// Liste möglicherweise auftretenden EDOLL-Fehler: /// <list type="table"> /// <listheader><term><see cref="EDOLLHandler">(interne) Fehlernummer</see></term><description>Beschreibung</description></listheader> /// <item><term>-19</term><description>Ungültiges Datenframe; Länge, Frameaufbau oder Prüfsumme inkorrekt</description></item> /// <item><term>-612</term><description>Es wurden zu viele Informationsbyte (>255) übergeben.</description></item> /// </list> /// (siehe <see cref="EDOLLHandler.GetLastError">EDOLLHANDLER.GetLastError()</see>) /// </remarks> /// <exception cref="TBL.Exceptions.FrameError">Ungültiges Frame versucht zu verarbeiten</exception> public byte[] GetCommandExecutionStateFrame(m3sExecutionError pStatus, byte[] pCommandFrame, byte[] pInfo) { if(pInfo == null) { return(this.GetCommandExecutionStateFrame(pStatus,pCommandFrame)); // Version ohne Info aufrufen.. } if(!this.IsFrame(pCommandFrame)) { EDOLLHandler.Error(-19); // Frameerror Exceptions.FrameError ex = new TBL.Exceptions.FrameError("Ungültiges Frame versucht zu verarbeiten"); throw ex; } if(pInfo.Length > 255) { EDOLLHandler.Error(-612); Exceptions.ConversionException ex2 = new TBL.Exceptions.ConversionException("Es wurden zu viele Informationsbytes (" + pInfo.Length.ToString() + ") übergeben an: TBL.Communication.Protocol.m3sHandler.GetCommandExecutionStateFrame(). max 255 erlaubt!"); throw ex2; } byte[] data = new byte[1 + pInfo.Length]; data[0] = Convert.ToByte(pStatus); // Kommando ins Frame einfügen for(int i=0; i<pInfo.Length; i++) // Informationsbytes einfügen { data[i+1] = pInfo[i]; } IM3S_Dataframe toReturn = this.CreateFrame(Convert.ToInt32(pCommandFrame[1]), M3SProtocol.CommandResponse,this.ExtractMasterAddress(pCommandFrame), data, true, false); return(toReturn.GetDataframe()); }
/// <summary> /// Erstellt ein Acknowledgeframe auf einen bestimmten Datenrahmen (Argument 2) /// </summary> /// <param name="pAck">Acknowledge ja / nein (true / false)</param> /// <param name="pFrame">Datenrahmen, der acknowledged werden soll</param> /// <returns> /// Versandbereites Acknowledgeframe /// </returns> /// <exception cref="Exceptions.FrameError">Ungültiges Datenframe übergeben</exception> /// <exception cref="Exceptions.ConversionException">Aus übergebenem Datenframe kann kein Acknowledgeframe erstellt werden.</exception> public IM3S_Dataframe GetAcknowledgeFrame(bool pAck, byte[] pFrame) { if(!this.IsFrame(pFrame)) { Exceptions.FrameError ex = new TBL.Exceptions.FrameError("In Argument 2 übergebenes Dataframe ist ungültig: " + TBLConvert.BytesToHexString(pFrame)); throw ex; } M3S_V2_Dataframe ackFrame = new M3S_V2_Dataframe(Convert.ToInt32(pFrame[1]), M3SProtocol.Acknowledge, this.ExtractMasterAddress(pFrame), null, false, pAck); if(ackFrame == null) { Exceptions.ConversionException ex = new Exceptions.ConversionException("Aus dem übergebenen Dataframe kann kein Acknowledgeframe erstellt werden." + Environment.NewLine + TBLConvert.BytesToHexString(pFrame)); throw ex; } return ackFrame; }
/// <summary> /// Erstellt aufgrund von pStatus eine versandfertige byteFolge mit der entsprechenden Kommandorückmeldung (siehe <see cref="m3sExecutionError">m3sExecutionError</see>) im einzigen Nutzdatenbyte. /// </summary> /// <param name="pStatus">Ausführungsstatus des Kommandos (<see cref="m3sExecutionError">m3sExecutionError</see>)</param> /// <param name="pCommandFrame">Frame, aufgrund dessen ein Kommando ausgeführt wurde</param> /// <returns> /// <list type="table"> /// <item><term>versandfertiges ByteArray</term><description>bei fehlerfreier Ausführung</description></item> /// <item><term>Exception</term><description>im Fehlerfall</description></item> /// </list> /// </returns> /// <remarks> /// <para> /// <para>Interne <see cref="EDOLL">EDOLL-Behandlung</see> ist implementiert. Das heißt im Fehlerfall (siehe Rückgabewert) kann mit einer Codezeile der Fehler ausgegeben werden:</para> /// <para><c>string EDOLLHandler.GetLastError();</c></para> /// </para> /// Liste möglicherweise auftretenden EDOLL-Fehler: /// <list type="table"> /// <listheader><term><see cref="EDOLLHandler">(interne) Fehlernummer</see></term><description>Beschreibung</description></listheader> /// <item><term>-19</term><description>Ungültiges Datenframe; Länge, Frameaufbau oder Prüfsumme inkorrekt</description></item> /// </list> /// (siehe <see cref="EDOLLHandler.GetLastError">EDOLLHANDLER.GetLastError()</see>) /// </remarks> /// <exception cref="TBL.Exceptions.FrameError">Ungültiges Frame versucht zu verarbeiten</exception> public byte[] GetCommandExecutionStateFrame(m3sExecutionError pStatus, byte[] pCommandFrame) { byte[] data = new byte[1]; if(!this.IsFrame(pCommandFrame)) { EDOLLHandler.Error(-19); // Frameerror Exceptions.FrameError ex = new TBL.Exceptions.FrameError("Ungültiges Frame versucht zu verarbeiten"); throw ex; } data[0] = Convert.ToByte(pStatus); IM3S_Dataframe toReturn = this.CreateFrame(Convert.ToInt32(pCommandFrame[1]), M3SProtocol.CommandResponse,this.ExtractMasterAddress(pCommandFrame), data, true, false); return(toReturn.GetDataframe()); }
/// <summary> /// Extrahiert das Protokoll aus einem Datenframe /// </summary> /// <param name="pFrame">Gültiges M3S-Datenframe</param> /// <returns> /// <list type="table"> /// <item><term><see cref="M3SProtocol">M3SProtocol</see></term><description>Bei gültiger Konversion</description></item> /// <item><term><see cref="M3SProtocol.Invalid">M3SProtocol.Invalid</see></term><description>im Fehlerfall</description></item> /// </list> /// </returns> /// <remarks> /// Das Protokoll wird aus dem higher Nibble des Controlbytes extrahiert und in die Enumeration <see cref="M3SProtocol">M3SProtocol</see> gecastet. /// /// <para> /// <para>Interne <see cref="EDOLL">EDOLL-Behandlung</see> ist implementiert. Das heißt im Fehlerfall (siehe Rückgabewert) kann mit einer Codezeile der Fehler ausgegeben werden:</para> /// <para><c>string EDOLLHandler.GetLastError();</c></para> /// (siehe <see cref="EDOLLHandler.GetLastError">EDOLLHANDLER.GetLastError()</see>) /// </para> /// Liste möglicherweise auftretenden EDOLL-Fehler: /// <list type="table"> /// <listheader><term><see cref="EDOLLHandler">(interne) Fehlernummer</see></term><description>Beschreibung</description></listheader> /// <item><term>-19</term><description>Ungültiges Datenframe; Länge, Frameaufbau oder Prüfsumme inkorrekt</description></item> /// </list> /// (siehe <see cref="EDOLLHandler.GetLastError">EDOLLHANDLER.GetLastError()</see>) /// </remarks> /// <example> Extrahieren aus byte[] packedFrame = IM3S_Dataframe.getDataframe(); /// <c>Console.WriteLine("Protokoll des Pakets: " + m3sHandler.ExtractProtocol(packedFrame).ToString());</c> /// </example> /// <exception cref="TBL.Exceptions.FrameError">Ungültiges Frame versucht zu verarbeiten</exception> public M3SProtocol ExtractProtocol(byte[] pFrame) { if(!this.IsFrame(pFrame)) { EDOLLHandler.Error(-19); // Frameerror Exceptions.FrameError ex = new TBL.Exceptions.FrameError("Ungültiges Frame versucht zu verarbeiten"); throw ex; } M3SProtocol toReturn; try { toReturn = (M3SProtocol)(Convert.ToInt32(pFrame[0]) >> 4); } catch { toReturn = M3SProtocol.Invalid; } return(toReturn); }
/// <summary> /// Extrahiert die Nutzdatenbytes aus einem M3S-Rahmen /// </summary> /// <param name="pFrame">Gültiges M3S-Datenframe</param> /// <returns> /// <list type="table"> /// <item><term>NutzdatenbyteArray</term><description>Bei gültiger Konversion</description></item> /// <item><term>null</term><description>Bei Acknowledgeframes</description></item> /// <item><term>null</term><description>im Fehlerfall</description></item> /// </list> /// </returns> /// <remarks> /// Das übergebene Datenframe wird erst auf Gültigkeit überprüft, anschließend werden die Rahmendaten weggeschnitten (vorne und hinten je 3 Byte) und das Nutzdatenpaket zurückgegeben. /// <para> /// <para>Interne <see cref="EDOLL">EDOLL-Behandlung</see> ist implementiert. Das heißt im Fehlerfall (siehe Rückgabewert) kann mit einer Codezeile der Fehler ausgegeben werden:</para> /// <para><c>string EDOLLHandler.GetLastError();</c></para> /// </para> /// Liste möglicherweise auftretenden EDOLL-Fehler: /// <list type="table"> /// <listheader><term><see cref="EDOLLHandler">(interne) Fehlernummer</see></term><description>Beschreibung</description></listheader> /// <item><term>-19</term><description>Ungültiges Datenframe; Länge, Frameaufbau oder Prüfsumme inkorrekt</description></item> /// </list> /// (siehe <see cref="EDOLLHandler.GetLastError">EDOLLHANDLER.GetLastError()</see>) /// </remarks> /// <example> Extrahieren aus byte[] packedFrame = IM3S_Dataframe.getDataframe(); und zweites Nutzdatenbyte ausgeben /// <c>Console.WriteLine("Zweites Nutzdatenbyte in packedFrame: " + string.Format("0x{0:x02}", m3sHandler.ExtractPayload(packedFrame)[1])); </c> /// </example> /// <exception cref="TBL.Exceptions.FrameError">Ungültiges Frame versucht zu verarbeiten</exception> public byte[] ExtractPayload(byte[] pFrame) { if(!this.IsFrame(pFrame)) { EDOLLHandler.Error(-19); // Frameerror Exceptions.FrameError ex = new TBL.Exceptions.FrameError("Ungültiges Frame versucht zu verarbeiten"); throw ex; } if(pFrame.Length == AcknowledgeFrameLength) { // ack return(null); } byte[] toReturn = new byte[pFrame.Length - Overhead]; for(int i=M3S_V2_Dataframe.HeaderLength; i<pFrame.Length - M3S_V2_Dataframe.CrcLength; i++) { toReturn[i-M3S_V2_Dataframe.HeaderLength] = pFrame[i]; } return(toReturn); }
/// <summary> /// Extrahiert die Masteradresse aus einem Datenframe /// </summary> /// <param name="pFrame">Gültiges M3S-Datenframe</param> /// <returns> /// <list type="table"> /// <item><term>0...3</term><description>Regulär</description></item> /// <item><term>-1</term><description>im Fehlerfall</description></item> /// </list> /// </returns> /// <remarks> /// <para> /// <para>Interne <see cref="EDOLL">EDOLL-Behandlung</see> ist implementiert. Das heißt im Fehlerfall (siehe Rückgabewert) kann mit einer Codezeile der Fehler ausgegeben werden:</para> /// <para><c>string EDOLLHandler.GetLastError();</c></para> /// (siehe <see cref="EDOLLHandler.GetLastError">EDOLLHANDLER.GetLastError()</see>) /// </para> /// Liste möglicherweise auftretenden EDOLL-Fehler: /// <list type="table"> /// <listheader><term><see cref="EDOLLHandler">(interne) Fehlernummer</see></term><description>Beschreibung</description></listheader> /// <item><term>-19</term><description>Ungültiges Datenframe; Länge, Frameaufbau oder Prüfsumme inkorrekt</description></item> /// </list> /// </remarks> /// <example> Extrahieren aus byte[] packedFrame = IM3S_Dataframe.getDataframe(); /// <c>Console.WriteLine("Masteradresse im Paket: " + m3sHandler.ExtractMasterAddress(packedFrame).ToString());</c> /// </example> /// <exception cref="TBL.Exceptions.FrameError">Ungültiges Frame versucht zu verarbeiten</exception> public int ExtractMasterAddress(byte[] pFrame) { if(!this.IsFrame(pFrame)) { EDOLLHandler.Error(-19); // Frameerror Exceptions.FrameError ex = new TBL.Exceptions.FrameError("Ungültiges Frame versucht zu verarbeiten"); throw ex; } return (pFrame[0] >> 2) & 0x03; // muss sich eh immer zwischen 0 und 3 befinden... }
/// <summary> /// Extrahiert die Nutzdatenbytes aus einem M3S-Rahmen /// </summary> /// <param name="pFrame">Gültiges M3S-Datenframe</param> /// <returns> /// <list type="table"> /// <item><term>NutzdatenbyteArray</term><description>Bei gültiger Konversion</description></item> /// <item><term>null</term><description>Bei Acknowledgeframes</description></item> /// <item><term>null</term><description>im Fehlerfall</description></item> /// </list> /// </returns> /// <remarks> /// Das übergebene Datenframe wird erst auf Gültigkeit überprüft, anschließend werden die Rahmendaten weggeschnitten (vorne und hinten je 3 Byte) und das Nutzdatenpaket zurückgegeben. /// <para> /// <para>Interne <see cref="EDOLL">EDOLL-Behandlung</see> ist implementiert. Das heißt im Fehlerfall (siehe Rückgabewert) kann mit einer Codezeile der Fehler ausgegeben werden:</para> /// <para><c>string EDOLLHandler.GetLastError();</c></para> /// </para> /// Liste möglicherweise auftretenden EDOLL-Fehler: /// <list type="table"> /// <listheader><term><see cref="EDOLLHandler">(interne) Fehlernummer</see></term><description>Beschreibung</description></listheader> /// <item><term>-19</term><description>Ungültiges Datenframe; Länge, Frameaufbau oder Prüfsumme inkorrekt</description></item> /// </list> /// (siehe <see cref="EDOLLHandler.GetLastError">EDOLLHANDLER.GetLastError()</see>) /// </remarks> /// <example> Extrahieren aus byte[] packedFrame = IM3S_Dataframe.getDataframe(); und zweites Nutzdatenbyte ausgeben /// <c>Console.WriteLine("Zweites Nutzdatenbyte in packedFrame: " + string.Format("0x{0:x02}", m3sHandler.ExtractPayload(packedFrame)[1])); </c> /// </example> /// <exception cref="TBL.Exceptions.FrameError">Ungültiges Frame versucht zu verarbeiten</exception> public byte[] ExtractPayload(byte[] pFrame) { if(!this.IsFrame(pFrame)) { EDOLLHandler.Error(-19); // Frameerror Exceptions.FrameError ex = new TBL.Exceptions.FrameError("Ungültiges Frame versucht zu verarbeiten"); throw ex; } if(pFrame.Length == 5) { // ack return(null); } byte[] toReturn = new byte[pFrame.Length -6]; for(int i=3; i<pFrame.Length - 3; i++) { toReturn[i-3] = pFrame[i]; } return(toReturn); }
/// <summary> /// Prüft, ob es sich um ein Acknowledgeframe für das übergebene gesendete Frame handelt und wenn ja, ob es Acknowledge oder Not Acknowledge bedeutet /// </summary> /// <param name="rSent">Gesendetes Frame, das acknowledged werden soll</param> /// <param name="rRec">Vermutetes Acknowledgeframe (muss <see cref="AcknowledgeFrameLength">AcknowledgeFrameLength</see> haben)</param> /// <param name="oErrorCode">Ausgabeparameter: <see cref="EDOLLHandler">EDOLL-Fehlercode</see>, 0 bei fehlerfreier Übertragung</param> /// <returns> /// <list type="table"> /// <listheader><term>Rückgabewert</term><description>Beschreibung</description></listheader> /// <item><term>true</term><description>Daten erfolgreich gesendet, Acknowledge erhalten</description></item> /// <item><term>false</term><description>Daten konnten nicht übermittelt werden. Details über den Rückgabeparameter oErrorCode auswertbar</description></item> /// </list> /// </returns> /// <exception cref="Exceptions.FrameError">Ungültiges Datensatzformat, übergebenes rRec-Frame hat nicht die Länge eines Acknowledgeframes.</exception> /// <remarks>Rücgabewert False und oErrorCode==-36 indizieren ein expliztes Not-Acknowledge</remarks> public static bool IsAcknowledge(byte[] rSent, byte[] rRec, out int oErrorCode) { Exceptions.FrameError ex = new TBL.Exceptions.FrameError("Beim Überprüfen des Acknowledgeframes ist ein Fehler aufgetreten. Frame: " + TBLConvert.BytesToHexString(rRec)); if(rRec.Length != AcknowledgeFrameLength) { throw ex; } int chkSum = Convert.ToInt32(rRec[0] + rRec[1]); // calc int chkSumRec = Convert.ToInt32(rRec[2] <<16) | Convert.ToInt32(rRec[3] << 8) | Convert.ToInt32(rRec[4]); // received chkSumRec ^= CheckSumCode; if(chkSum != chkSumRec) { oErrorCode = -35; return(false); // Prüfsummenfehler } // Ok, Frame ist gültig... check obs das richtige Acknowledge is.. if(rSent[1] != rRec[1]) { oErrorCode = (-21); // Paket kommt von anderem Slave... return(false); } if((rRec[0] & 0xF0) != ((Convert.ToInt32(M3SProtocol.Acknowledge) << 4) & 0xF0)) { oErrorCode = (-22); // Es handelt sich um kein Acknowledgeframe... return(false); } if(((rRec[0] | 0x02) & 0x0F) != ((rSent[0] | 0x02) & 0x0F)) // Masteradresse, Datenrichtung und Acknowledgebit stimmt nicht... { oErrorCode = -23; return(false); } if((rRec[0] & 0x02) == 0x02) // Wenn Acknowledgebit gesetzt { oErrorCode = 0; return(true); } else { oErrorCode = -36; // NAK return(false); } }