/// <summary> /// Disconnects at the HDLC level </summary> /// <param name="phy"> the PhyLayer to transmit and receive bytes </param> public void disconnect(PhyLayer phy) { initFrame(DISC_CONTROL, 0); phy.sendData(getFrame()); readData(phy); if (connection.receivedControl != UA_CONTROL) { throw new LinkLayerException(LinkLayerExceptionReason.RECEIVED_INVALID_FRAME_FORMAT); } }
public byte[] read(PhyLayer phy) { byte[] data = readData(phy); if (data.Length < 3) { throw new LinkLayerException(LinkLayerExceptionReason.RECEIVED_INVALID_LLC_BYTES); } if (data[0] != ((byte)0xE6) || data[1] != ((byte)0xE7) || data[2] != 0x00) { throw new LinkLayerException(LinkLayerExceptionReason.RECEIVED_INVALID_LLC_BYTES); } return(helper.extensions.copyOfRange(data, 3, data.Length)); }
/// <summary> /// Encapsulates data inside a HDLC frame and sends it </summary> /// <param name="phy"> the PhyLayer to transmit and receive bytes </param> /// <param name="data"> the array of bytes to be encapsulated and transmitted </param> public void send(PhyLayer phy, byte[] data) { int control = I_CONTROL; connection.insReceivedSss(); control |= this.connection.receivedSss << 5; control |= this.connection.sss << 1; connection.incSss(); initFrame(control, data.Length + 3); updateFrame(new byte[] { (byte)0xE6, (byte)0xE6, (byte)0x00 }); updateFrame(data); phy.sendData(getFrame()); }
/// <summary> /// Connects at the HDLC level </summary> /// <param name="phy"> the PhyLayer to transmit and receive bytes </param> /// public void connect(PhyLayer phy) { try { connection.reset(); phy.sendData(snrmRequest()); parseSnrmReply(readData(phy)); } catch (IOException) { throw new LinkLayerException(LinkLayerExceptionReason.INTERNAL_ERROR); } }
private byte[] readData(PhyLayer phy) { byte[] data = phy.readData(parameters.timeoutMillis, new PhyParserIsFrameComplete()); int offset = 0; while (data[offset] != HDLC_FLAG) { offset++; } if (offset > 0) { data = helper.extensions.copyOfRange(data, offset, data.Length); } verifyReceivedData(data); return(connection.receivedData); }
/// <summary> /// Encapsulates data inside a Wrapper frame and sends it </summary> /// <param name="phy"> the PhyLayer to transmit and receive bytes </param> /// <param name="data"> the array of bytes to be encapsulated and transmitted </param> public void send(PhyLayer phy, byte[] data) { System.IO.MemoryStream stream = new System.IO.MemoryStream(); stream.WriteByte((byte)(WRAPPER_VERSION >> 8)); stream.WriteByte((byte)WRAPPER_VERSION); stream.WriteByte((byte)(parameters.wPortSource >> 8)); stream.WriteByte((byte)parameters.wPortSource); stream.WriteByte((byte)(parameters.wPortDestination >> 8)); stream.WriteByte((byte)parameters.wPortDestination); stream.WriteByte((byte)data.Length); foreach (byte b in data) { stream.WriteByte(b); } phy.sendData(stream.ToArray()); }
/// <summary> /// Performs the steps necessary for a connection in the MODE-E </summary> /// <param name="com"> PhyLayer object to be used for data tx/rx </param> /// <exception cref="PhyLayerException"> </exception> public static void connect(PhyLayer com) { //PhyParserIsFrameComplete phyLayerPaser = new PhyParserIsFrameComplete(); try { com.sendData(Encoding.ASCII.GetBytes("/?!\r\n")); byte[] rxBuff = com.readData(1000, new PhyParserIsFrameComplete()); byte baud = ((byte)rxBuff[4] & (byte)0xFF) > (byte)0x35 ? (byte)0x35 : (byte)rxBuff[4]; com.sendData(new byte[] { 0x06, 0x32, baud, 0x32, 0x0D, 0x0A }); Thread.Sleep(550); } catch (Exception e) { Console.WriteLine(e.ToString()); Console.Write(e.StackTrace); } }
/// <summary> /// Retrieves the data encapsulated inside a Wrapper frame </summary> /// <param name="phy"> the PhyLayer to receive bytes </param> /// <returns> array of bytes with the application data unit contents inside the Wrapper frame </returns> public byte[] read(PhyLayer phy) { byte[] data = phy.readData(parameters.timeoutMillis, new PhyParserIsFrameComplete()); short version = BitConverter.ToInt16(new byte[2] { data[1], data[0] }, 0); short wPortSource = BitConverter.ToInt16(new byte[2] { data[3], data[2] }, 0); short wPortDestination = BitConverter.ToInt16(new byte[2] { data[5], data[4] }, 0); if (version != WRAPPER_VERSION) { throw new LinkLayerException(LinkLayerExceptionReason.RECEIVED_INVALID_FRAME_FORMAT); } if (wPortSource != parameters.wPortDestination || wPortDestination != parameters.wPortSource) { throw new LinkLayerException(LinkLayerExceptionReason.RECEIVED_INVALID_ADDRESS); } return(helper.extensions.copyOfRange(data, 8, data.Length)); }
/// <summary> /// Wrapper doesn't have a disconnection procedure, this function doesn't need to be called when /// using the Wrapper protocol as link layer for the COSEM APDU's. </summary> /// <param name="phy"> the PhyLayer to transmit and receive bytes </param> public void disconnect(PhyLayer phy) { //no disconnection necessary }
/// <summary> /// Wrapper doesn't have a connection procedure, this function doesn't need to be called when /// using the Wrapper protocol as link layer for the COSEM APDU's. </summary> /// <param name="phy"> the PhyLayer to transmit and receive bytes </param> public void connect(PhyLayer phy) { //no connection necessary }