/** Reads params from packet and fills in S7Data. */ public bool read(byte[] data, int offset, S7Data[] outs) { func = data[offset++]; byte count = data[offset++]; for (int a = 0; a < count; a++) { S7Data outData = outs[a]; byte success = data[offset++]; if (success != (byte)0xff) { Console.WriteLine("Error:success=" + success); return(false); } if (func == READ) { byte transport_type = data[offset++]; int len = BE.getuint16(data, offset); if (isBits(transport_type)) { len = (len + 7) >> 3; //divide by 8 } offset += 2; outData.data = new byte[len]; Arrays <byte> .Copy(data, offset, outData.data, 0, len); offset += len; if (len % 2 == 1) { offset++; //fill byte } } } return(true); }
/** Create a packet to read multiple tags. */ public void makeRead(S7Data[] s7s) { func = READ; byte cnt = (byte)s7s.Length; funcData = new byte[1 + cnt * 12]; funcData[0] = cnt; //count int offset = 1; for (byte a = 0; a < cnt; a++) { S7Data s7 = s7s[a]; funcData[offset++] = 0x12; //var def funcData[offset++] = 10; //length of def funcData[offset++] = 0x10; //S7ANY funcData[offset++] = s7.data_type; //INT, BYTE, etc. BE.setuint16(funcData, offset, 1); //length (# of elements) offset += 2; BE.setuint16(funcData, offset, s7.block_number); //DBxx offset += 2; funcData[offset++] = s7.block_type; //DB, I, Q, etc. //BE.setuint24(data, 9, off); funcData[offset++] = (byte)((s7.offset & 0xff0000) >> 16); funcData[offset++] = (byte)((s7.offset & 0xff00) >> 8); funcData[offset++] = (byte)(s7.offset & 0xff); } }
/** Decodes a packet and returns any data returned. */ public static S7Data[] decodeMultiPacket(byte[] packet, int count) { try { S7Data[] data = new S7Data[count]; for (int a = 0; a < count; a++) { data[a] = new S7Data(); } int offset = 0; TPKT tpkt = new TPKT(); tpkt.read(packet, offset); offset += tpkt.size(); COTP cotp = new COTP(); cotp.read(packet, offset); if (cotp.PDU_type == COTP.type_connect) { return(data); } if (cotp.PDU_type == COTP.type_connect_ack) { return(data); } offset += cotp.size(); S7Header header = new S7Header(); header.read(packet, offset); offset += header.size(); S7Params _params = new S7Params(); _params.read(packet, offset, data); return(data); } catch (Exception e) { Console.WriteLine(e.ToString()); } return(null); }
/** Create a packet to read single tag. */ public void makeRead(S7Data s7) { func = READ; funcData = new byte[13]; funcData[0] = 1; //count funcData[1] = 0x12; //var def funcData[2] = 10; //length of def funcData[3] = 0x10; //S7ANY funcData[4] = s7.data_type; //INT, BYTE, etc. BE.setuint16(funcData, 5, s7.length); //length (# of elements) BE.setuint16(funcData, 7, s7.block_number); //DBxx funcData[9] = s7.block_type; //DB, I, Q, etc. //BE.setuint24(data, 9, off); funcData[10] = (byte)((s7.offset & 0xff0000) >> 16); funcData[11] = (byte)((s7.offset & 0xff00) >> 8); funcData[12] = (byte)(s7.offset & 0xff); }
/** Creates a packet to read data from S7. */ public static byte[] makeReadPacket(S7Data s7) { TPKT tpkt = new TPKT(); COTP cotp = new COTP(COTP.type_data); S7Header header = new S7Header(); S7Params _params = new S7Params(); byte[] data; _params.makeRead(s7); int size = tpkt.size() + cotp.size() + header.size() + _params.size(); data = new byte[size]; int dataoff = 0; tpkt.write(data, dataoff, (short)size); dataoff += tpkt.size(); cotp.write(data, dataoff); dataoff += cotp.size(); header.write(data, dataoff, (short)_params.size(), (short)0); dataoff += header.size(); _params.write(data, dataoff); return(data); }
/** Creates a packet to write data to S7. */ public static byte[] makeWritePacket(S7Data type) { TPKT tpkt = new TPKT(); COTP cotp = new COTP(COTP.type_data); S7Header header = new S7Header(); S7Params _params = new S7Params(); byte[] data; _params.makeWrite(type.block_type, type.block_number, type.data_type, type.offset, type.length, type.data); int size = tpkt.size() + cotp.size() + header.size() + _params.size(); data = new byte[size]; int dataoff = 0; tpkt.write(data, dataoff, (short)size); dataoff += tpkt.size(); cotp.write(data, dataoff); dataoff += cotp.size(); header.write(data, dataoff, (short)(_params.size() - 4 - type.length), (short)(4 + type.length)); dataoff += header.size(); _params.write(data, dataoff); return(data); }
/** Decodes S7 Address. * * Supports: DB,M,I,Q * * Does not support ranges yet. */ public static S7Data decodeAddress(String addr) { //DB##.DB?##[.#] //M[?]##[.#] //I[?]##[.#] //Q[?]##[.#] S7Data data = new S7Data(); int idx; if (addr.StartsWith("DB")) { data.block_type = S7Types.DB; idx = addr.IndexOf('.'); //.DB?##[.#] data.block_number = (short)Int32.ValueOf(addr.SubstringIdx(2, idx)); addr = addr.Substring(idx + 2); //B?##[.#] } else if (addr.StartsWith("M")) { data.block_type = S7Types.M; } else if (addr.StartsWith("I")) { data.block_type = S7Types.I; } else if (addr.StartsWith("Q")) { data.block_type = S7Types.Q; } else { return(null); } data.data_type = S7Types.getType(addr.CharAt(1)); short offset; idx = addr.IndexOf('.'); if (idx == -1) { idx = addr.IndexOf(' '); } if (idx == -1) { idx = addr.Length; } if (data.data_type == 0) { //no type present (assume bit) offset = (short)Int32.ValueOf(addr.SubstringIdx(1, idx)); data.data_type = S7Types.BIT; } else { offset = (short)Int32.ValueOf(addr.SubstringIdx(2, idx)); } data.offset = (short)(offset << 3); if (data.data_type == S7Types.BIT) { int idx2 = addr.IndexOf(' '); if (idx2 == -1) { idx2 = addr.Length; } byte bit = Byte.ValueOf(addr.SubstringIdx(idx + 1, idx2)); data.offset += bit; } idx = addr.IndexOf(" BYTE "); if (idx == -1) { //S7Types.getTypeSize(data.data_type, (short)1); data.length = 1; } else { data.length = (short)Int32.ValueOf(addr.Substring(idx + 6)); } return(data); }