Dictionary <string, object> AnalysisData(string MessageType, byte[] bytes) { string fieldName = ""; string customType = ""; int fieldType = 0; int repeatType = 0; try { Dictionary <string, object> data = HeapObjectPool.GetSODict(); ByteArray ba = HeapObjectPoolTool <ByteArray> .GetHeapObject(); ba.clear(); ba.Add(bytes); string messageTypeTemp = "m_" + MessageType + "_c"; if (!m_protocolInfo.ContainsKey(messageTypeTemp)) { throw new Exception("ProtocolInfo NOT Exist ->" + messageTypeTemp + "<-"); } List <Dictionary <string, object> > tableInfo = m_protocolInfo["m_" + MessageType + "_c"]; for (int i = 0; i < tableInfo.Count; i++) { fieldType = (int)tableInfo[i]["type"]; repeatType = (int)tableInfo[i]["spl"]; fieldName = (string)tableInfo[i]["name"]; if (fieldType == TYPE_string) { if (repeatType == RT_repeated) { data[fieldName] = ReadStringList(ba); } else { data[fieldName] = ReadString(ba); } } else if (fieldType == TYPE_bool) { if (repeatType == RT_repeated) { data[fieldName] = ReadBoolList(ba); } else { data[fieldName] = ReadBool(ba); } } else if (fieldType == TYPE_double) { if (repeatType == RT_repeated) { data[fieldName] = ReadDoubleList(ba); } else { data[fieldName] = ReadDouble(ba); } } else if (fieldType == TYPE_int32) { if (repeatType == RT_repeated) { data[fieldName] = ReadIntList(ba); } else { data[fieldName] = ReadInt(ba); } } else { customType = (string)tableInfo[i]["vp"]; if (repeatType == RT_repeated) { data[fieldName] = ReadDictionaryList(customType, ba); } else { data[fieldName] = ReadDictionary(customType, ba); } } } return(data); } catch (Exception e) { throw new Exception(@"ProtocolService AnalysisData Excepiton : MessageType is ->" + MessageType + "<-\n" + e.ToString()); } }
private void WriteBitWithASingleRequest(DataType dataType, int db, int startByteAdr, int bitAdr, bool bitValue) { int varCount = 0; try { var value = new[] { bitValue ? (byte)1 : (byte)0 }; varCount = value.Length; // first create the header int packageSize = 35 + value.Length; ByteArray package = new ByteArray(packageSize); package.Add(new byte[] { 3, 0, 0 }); package.Add((byte)packageSize); package.Add(new byte[] { 2, 0xf0, 0x80, 0x32, 1, 0, 0 }); package.Add(Word.ToByteArray((ushort)(varCount - 1))); package.Add(new byte[] { 0, 0x0e }); package.Add(Word.ToByteArray((ushort)(varCount + 4))); package.Add(new byte[] { 0x05, 0x01, 0x12, 0x0a, 0x10, 0x01 }); //ending 0x01 is used for writing a sinlge bit package.Add(Word.ToByteArray((ushort)varCount)); package.Add(Word.ToByteArray((ushort)(db))); package.Add((byte)dataType); int overflow = (int)(startByteAdr * 8 / 0xffffU); // handles words with address bigger than 8191 package.Add((byte)overflow); package.Add(Word.ToByteArray((ushort)(startByteAdr * 8 + bitAdr))); package.Add(new byte[] { 0, 0x03 }); //ending 0x03 is used for writing a sinlge bit package.Add(Word.ToByteArray((ushort)(varCount))); // now join the header and the data package.Add(value); stream.Write(package.Array, 0, package.Array.Length); Thread.Sleep(100); var s7data = COTP.TSDU.Read(stream); if (s7data == null || s7data[14] != 0xff) { Logger.E($"WrongNumberReceivedBytes if (s7data({s7data}) == null || s7data[14]({s7data[14]}) != 0xff)"); //throw new PlcException(ErrorCode.WrongNumberReceivedBytes); } } catch (Exception exc) { Logger.E(exc); //throw new PlcException(ErrorCode.WriteData, exc); } }
private void WriteBytesWithASingleRequest(DataType dataType, int db, int startByteAdr, byte[] value) { int varCount = 0; try { varCount = value.Length; // first create the header int packageSize = 35 + value.Length; ByteArray package = new ByteArray(packageSize); package.Add(new byte[] { 3, 0, 0 }); package.Add((byte)packageSize); package.Add(new byte[] { 2, 0xf0, 0x80, 0x32, 1, 0, 0 }); package.Add(Word.ToByteArray((ushort)(varCount - 1))); package.Add(new byte[] { 0, 0x0e }); package.Add(Word.ToByteArray((ushort)(varCount + 4))); package.Add(new byte[] { 0x05, 0x01, 0x12, 0x0a, 0x10, 0x02 }); package.Add(Word.ToByteArray((ushort)varCount)); package.Add(Word.ToByteArray((ushort)(db))); package.Add((byte)dataType); var overflow = (int)(startByteAdr * 8 / 0xffffU); // handles words with address bigger than 8191 package.Add((byte)overflow); package.Add(Word.ToByteArray((ushort)(startByteAdr * 8))); package.Add(new byte[] { 0, 4 }); package.Add(Word.ToByteArray((ushort)(varCount * 8))); // now join the header and the data package.Add(value); stream.Write(package.Array, 0, package.Array.Length); var s7data = COTP.TSDU.Read(stream); if (s7data == null || s7data[14] != 0xff) { throw new PlcException(ErrorCode.WrongNumberReceivedBytes); } } catch (Exception exc) { throw new PlcException(ErrorCode.WriteData, exc); } }
/// <summary> /// Writes up to 200 bytes to the PLC and returns NoError if successful. You must specify the memory area type, memory are address, byte start address and bytes count. /// If the write was not successful, check LastErrorCode or LastErrorString. /// </summary> /// <param name="dataType">Data type of the memory area, can be DB, Timer, Counter, Merker(Memory), Input, Output.</param> /// <param name="db">Address of the memory area (if you want to read DB1, this is set to 1). This must be set also for other memory area types: counters, timers,etc.</param> /// <param name="startByteAdr">Start byte address. If you want to read DB1.DBW200, this is 200.</param> /// <param name="value">Bytes to write. The lenght of this parameter can't be higher than 200. If you need more, use recursion.</param> /// <returns>NoError if it was successful, or the error is specified</returns> private async Task <ErrorCode> WriteBytesWithASingleRequestAsync(DataType dataType, int db, int startByteAdr, byte[] value) { byte[] bReceive = new byte[513]; int varCount = 0; try { varCount = value.Length; // first create the header int packageSize = 35 + value.Length; ByteArray package = new ByteArray(packageSize); package.Add(new byte[] { 3, 0, 0 }); package.Add((byte)packageSize); package.Add(new byte[] { 2, 0xf0, 0x80, 0x32, 1, 0, 0 }); package.Add(Word.ToByteArray((ushort)(varCount - 1))); package.Add(new byte[] { 0, 0x0e }); package.Add(Word.ToByteArray((ushort)(varCount + 4))); package.Add(new byte[] { 0x05, 0x01, 0x12, 0x0a, 0x10, 0x02 }); package.Add(Word.ToByteArray((ushort)varCount)); package.Add(Word.ToByteArray((ushort)(db))); package.Add((byte)dataType); var overflow = (int)(startByteAdr * 8 / 0xffffU); // handles words with address bigger than 8191 package.Add((byte)overflow); package.Add(Word.ToByteArray((ushort)(startByteAdr * 8))); package.Add(new byte[] { 0, 4 }); package.Add(Word.ToByteArray((ushort)(varCount * 8))); // now join the header and the data package.Add(value); await stream.WriteAsync(package.Array, 0, package.Array.Length); var s7data = await COTP.TSDU.ReadAsync(stream); if (s7data == null || s7data[14] != 0xff) { throw new Exception(ErrorCode.WrongNumberReceivedBytes.ToString()); } return(ErrorCode.NoError); } catch (Exception exc) { LastErrorCode = ErrorCode.WriteData; LastErrorString = exc.Message; return(LastErrorCode); } }
Dictionary <string, object> AnalysisData(string MessageType, byte[] bytes) { //Debug.Log("MessageType:" + MessageType + "AnalysisData: " + BitConverter.ToString(bytes)); string fieldName = ""; string customType = ""; int fieldType = 0; int repeatType = 0; try { Dictionary <string, object> data = new Dictionary <string, object>(); ByteArray ba = new ByteArray(); ba.clear(); ba.Add(bytes); string messageTypeTemp = "m_" + MessageType + "_c"; if (!m_protocolInfo.ContainsKey(messageTypeTemp)) { throw new Exception("ProtocolInfo NOT Exist ->" + messageTypeTemp + "<-"); } List <Dictionary <string, object> > tableInfo = m_protocolInfo["m_" + MessageType + "_c"]; for (int i = 0; i < tableInfo.Count; i++) { fieldType = (int)tableInfo[i]["type"]; repeatType = (int)tableInfo[i]["spl"]; fieldName = (string)tableInfo[i]["name"]; if (fieldType == TYPE_string) { if (repeatType == RT_repeated) { data[fieldName] = ReadStringList(ba); } else { data[fieldName] = ReadString(ba); } } else if (fieldType == TYPE_bool) { if (repeatType == RT_repeated) { data[fieldName] = ReadBoolList(ba); } else { data[fieldName] = ReadBool(ba); } } else if (fieldType == TYPE_double) { if (repeatType == RT_repeated) { data[fieldName] = ReadDoubleList(ba); } else { data[fieldName] = ReadDouble(ba); } } else if (fieldType == TYPE_int32) { if (repeatType == RT_repeated) { data[fieldName] = ReadIntList(ba); } else { data[fieldName] = ReadInt32(ba); } } else if (fieldType == TYPE_int16) { if (repeatType == RT_repeated) { data[fieldName] = ReadShortList(ba); } else { data[fieldName] = ReadInt16(ba); } } else if (fieldType == TYPE_int8) { if (repeatType == RT_repeated) { data[fieldName] = ReadInt8List(ba); } else { data[fieldName] = ReadInt8(ba); } } else { customType = (string)tableInfo[i]["vp"]; if (repeatType == RT_repeated) { data[fieldName] = ReadDictionaryList(customType, ba); } else { data[fieldName] = ReadDictionary(customType, ba); } } } return(data); } catch (Exception e) { throw new Exception(@"AnalysisData Excepiton Data is ->" + MessageType + "<-\nFieldName:->" + fieldName + "<-\nFieldType:->" + GetFieldType(fieldType) + "<-\nRepeatType:->" + GetRepeatType(repeatType) + "<-\nCustomType:->" + customType + "<-\n" + e.ToString()); } }
public static int CreateRequest(ByteArray message, DataItem[] dataItems) { message.Add(Header.Template); message[Header.Offsets.ParameterCount] = (byte)dataItems.Length; var paramSize = dataItems.Length * Parameter.Template.Length; Serialization.SetWordAt(message, Header.Offsets.ParameterSize, (ushort)(2 + paramSize)); var paramOffset = Header.Template.Length; var dataOffset = paramOffset + paramSize; var data = new ByteArray(); var itemCount = 0; foreach (var item in dataItems) { itemCount++; message.Add(Parameter.Template); var value = Serialization.SerializeDataItem(item); var wordLen = item.Value is bool? 1 : 2; message[paramOffset + Parameter.Offsets.WordLength] = (byte)wordLen; Serialization.SetWordAt(message, paramOffset + Parameter.Offsets.Amount, (ushort)value.Length); Serialization.SetWordAt(message, paramOffset + Parameter.Offsets.DbNumber, (ushort)item.DB); message[paramOffset + Parameter.Offsets.Area] = (byte)item.DataType; data.Add(0x00); if (item.Value is bool b) { if (item.BitAdr > 7) { throw new ArgumentException( $"Cannot read bit with invalid {nameof(item.BitAdr)} '{item.BitAdr}'.", nameof(dataItems)); } Serialization.SetAddressAt(message, paramOffset + Parameter.Offsets.Address, item.StartByteAdr, item.BitAdr); data.Add(0x03); data.AddWord(1); data.Add(b ? (byte)1 : (byte)0); if (itemCount != dataItems.Length) { data.Add(0); } } else { Serialization.SetAddressAt(message, paramOffset + Parameter.Offsets.Address, item.StartByteAdr, 0); var len = value.Length; data.Add(0x04); data.AddWord((ushort)(len << 3)); data.Add(value); if ((len & 0b1) == 1 && itemCount != dataItems.Length) { data.Add(0); } } paramOffset += Parameter.Template.Length; } message.Add(data.Array); Serialization.SetWordAt(message, Header.Offsets.MessageLength, (ushort)message.Length); Serialization.SetWordAt(message, Header.Offsets.DataLength, (ushort)(message.Length - paramOffset)); return(message.Length); }
// 将机内格式记录构造为ISO2709格式记录。 // parameters: // baMARC [in]机内格式记录。已经通过适当Encoding对象转换为ByteArray了 // baResult [out]ISO2709格式记录。 // return: // -1 error // 0 succeed public static int BuildISO2709Record(byte[] baMARC, out byte[] baResult) { int nLen; byte[] baMuci = null; // 目次区 byte[] baBody = null; // 数据区 byte[] baFldName = null; string strFldLen; string strFldStart; byte[] baFldContent = null; int nStartPos; int nFldLen; int nFldStart; bool bEnd = false; int nPos; int nRecLen = 0; baResult = null; if (baMARC == null) { return(-1); } if (baMARC.Length < 24) { return(-1); } // 2018/3/8 if (baMARC[0] == 0 || baMARC[1] == 0) { throw new Exception("ISO2709 格式无法使用编码方式 UCS-2 (UTF-16)"); } MarcHeaderStruct header = new MarcHeaderStruct(baMARC); /* * ISO2709ANSIHEADER header; * memcpy(&header, * (LPCSTR)advstrMARC, * sizeof(header)); */ nLen = baMARC.Length; for (nStartPos = 24, nFldStart = 0; ;) { nPos = ByteArray.IndexOf(baMARC, (byte)FLDEND, nStartPos); // nPos = FindCharInStringA((LPCSTR)advstrMARC, FLDEND, nStartPos); if (nPos == -1) { nFldLen = nLen - nStartPos; bEnd = true; } else { nFldLen = nPos - nStartPos + 1; } if (nFldLen < 3) { goto SKIP; } // strFldName = advstrMARC.MidA(nStartPos, 3); baFldName = new byte[3]; Array.Copy(baMARC, nStartPos, baFldName, 0, 3); // advstrFldContent = advstrMARC.MidA(nStartPos + 3, nFldLen - 3); baFldContent = new byte[nFldLen - 3]; Array.Copy(baMARC, nStartPos + 3, baFldContent, 0, nFldLen - 3); //advstrFldLen.Format("%04d", nFldLen - 3); strFldLen = Convert.ToString(nFldLen - 3); strFldLen = strFldLen.PadLeft(4, '0'); // advstrFldStart.Format("%05d", nFldStart); strFldStart = Convert.ToString(nFldStart); strFldStart = strFldStart.PadLeft(5, '0'); nFldStart += nFldLen - 3; // advstrMuci += (LPCSTR)advstrFldName; baMuci = ByteArray.Add(baMuci, baFldName); // advstrMuci += (LPCSTR)advstrFldLen; baMuci = ByteArray.Add(baMuci, Encoding.UTF8.GetBytes(strFldLen)); // advstrMuci += (LPCSTR)advstrFldStart; baMuci = ByteArray.Add(baMuci, Encoding.UTF8.GetBytes(strFldStart)); baBody = ByteArray.Add(baBody, baFldContent); SKIP: if (bEnd) { break; } nStartPos = nPos + 1; } nRecLen = baMuci.Length + 1 + baBody.Length + 1 + 24; /* * advstrText.Format( * "%05d", * nRecLen); * * memcpy(header.reclen, * (LPCSTR)advstrText, * advstrText.GetLengthA()); */ header.RecLength = nRecLen; /* * advstrText.Format( * "%05d", * sizeof(header) + advstrMuci.GetLengthA() + 1); * memcpy(header.baseaddr, * (LPCSTR)advstrText, * advstrText.GetLengthA()); */ header.BaseAddress = 24 + baMuci.Length + 1; // ForceUNIMARCHeader(&header); /* * In USMARC format, leader postion 09, one character indicate the character coding scheme: * * 09 - Character coding scheme * Identifies the character coding scheme used in the record. # - MARC-8 # a - UCS/Unicode # (http://lcweb.loc.gov/marc/bibliographic/ecbdldrd.html) */ //baTarget.SetSize(nRecLen); /* * memcpy(baTarget.GetData(), * (char *)&header, * sizeof(header)); */ baResult = ByteArray.Add(baResult, header.GetBytes()); /* * memcpy((char *)baTarget.GetData() + sizeof(header), * (LPCSTR)advstrMuci, * advstrMuci.GetLengthA()); */ baResult = ByteArray.Add(baResult, baMuci); /* *((char *)baTarget.GetData() + sizeof(header) + advstrMuci.GetLengthA()) * = FLDEND; */ baResult = ByteArray.Add(baResult, (byte)FLDEND); /* * memcpy((char *)baTarget.GetData() + sizeof(header)+ advstrMuci.GetLengthA() + 1, * (LPCSTR)advstrBody, * advstrBody.GetLengthA()); */ baResult = ByteArray.Add(baResult, baBody); /* *((char *)baTarget.GetData() + nRecLen - 1) * = RECEND; */ baResult = ByteArray.Add(baResult, (byte)RECEND); return(0); }