private dynamic Send(byte[] data) { dynamic answer = new ExpandoObject(); answer.success = false; answer.error = string.Empty; answer.errorcode = DeviceError.NO_ERROR; byte[] buffer = null; var attempts_total = SEND_ATTEMPTS_COUNT; for (var attempts = 0; (attempts < attempts_total) && (answer.success == false); attempts++) { var timeout = TIMEOUT_TIME_MIN * (attempts + 1); buffer = SendSimple(data, timeout); if (buffer.Length == 0) { answer.error = "Нет ответа"; answer.errorcode = DeviceError.NO_ANSWER; } else { if (buffer.Length < 5) { answer.errorcode = DeviceError.TOO_SHORT_ANSWER; answer.error = "в кадре ответа не может содержаться менее 5 байт"; } else if (!Crc.Check(buffer, new Crc16Modbus())) { answer.errorcode = DeviceError.CRC_ERROR; answer.error = "контрольная сумма кадра не сошлась"; } else { packagesSent++; answer.success = true; answer.error = string.Empty; answer.errorcode = DeviceError.NO_ERROR; } } } if (answer.success) { var offset = 0; answer.NetworkAddress = buffer[0]; if (answer.NetworkAddress == 251) { offset = 12; } answer.Function = buffer.Skip(offset + 1).FirstOrDefault(); answer.Body = buffer.Skip(offset + 2).Take(buffer.Length - (offset + 2 + 2)).ToArray(); } return(answer); }
public Response(byte[] data) { if (data.Length <= 4) { throw new Exception("слишком короткий ответ"); } if (!Crc.Check(data.ToArray(), new Crc16Modbus())) { throw new Exception("не сошлась контрольная сумма"); } NetworkAddress = data[0]; Function = data[1]; }
private void DataProcess(IEnumerable <byte> bytes, Action <byte[]> frameProcess) { if (bytes.Count() < 3) { return; // 1+ byte(s) and CRC 2 bytes } if (!Crc.Check(bytes.ToArray(), new Crc16Modbus())) { return; //CRC mismatch } //MESSAGE if (frameProcess != null) { frameProcess(bytes.ToArray()); } }
public Response(byte[] data, byte networkaddress) { data = data.SkipWhile(b => b == 0xff).ToArray(); if (data[0] != networkaddress) { throw new Exception("Несовпадение адреса"); } Body = data.Skip(1).Take(data.Count() - 3).ToArray(); if (data.Length < 4) { throw new Exception("в кадре ответа не может содежаться менее 4 байт"); } if (!Crc.Check(data, new Crc16Modbus())) { throw new Exception("контрольная сумма кадра не сошлась"); } NetworkAddress = data[0]; //modbus error if (data.Length == 4) { switch (data[1]) { case 0x00: ErrorMessage = "все нормально"; break; case 0x01: throw new Exception("недопустимая команда или параметр"); case 0x02: throw new Exception("внутренняя ошибка счетчика"); case 0x03: throw new Exception("не достаточен уровень доступа для удовлетворения запроса"); case 0x04: throw new Exception("внутренние часы счетчика уже корректировались в течении текущих суток"); case 0x05: throw new Exception("не открыт канал связи"); default: throw new Exception("неизвестная ошибка"); } } }
public Response(byte[] data) { if (!Crc.Check(data, 1, data.Length - 1, new BccCalculator())) { throw new Exception("Не сошлась контрольная сумма"); } var rawString = Encoding.ASCII.GetString(data, 1, data.Length - 3); Raw = rawString; rawString = rawString.Replace("\r\n", "").Replace(")(", "\n").Replace("(", "\n").Replace(")", "\n"); var elements = rawString.Split('\n'); Parameter = elements.FirstOrDefault(); Values = elements.Skip(1).Take(elements.Count() - 2).ToList(); }
dynamic ParseModbusDateResponse(byte[] data) { dynamic answer = new ExpandoObject(); answer.success = false; answer.error = ""; if (data.Length < 5) { answer.error = "в кадре ответа не может содежаться менее 5 байт"; return(answer); } if (!Crc.Check(data, new Crc16Modbus())) { answer.error = "контрольная сумма кадра не сошлась"; return(answer); } answer.NetworkAddress = data[0]; answer.Function = data[1]; //modbus error if (answer.Function > 0x80) { var exceptionCode = (ModbusExceptionCode)data[2]; answer.error = string.Format("устройство вернуло ошибку: {0}", exceptionCode); return(answer); } answer.success = true; answer.Body = data.Skip(2).Take(2 + 2).ToArray(); var year1 = ToBCD(answer.Body[1]); var year2 = ToBCD(answer.Body[2]); var year = year1 * 100 + year2; var month = ToBCD(answer.Body[3]); var day = ToBCD(answer.Body[4]); var hour = ToBCD(answer.Body[5]); var minute = ToBCD(answer.Body[6]); answer.Date = new DateTime(year, month, day, hour, 0, 0); return(answer); }
private dynamic Send(byte[] data) { dynamic answer = new ExpandoObject(); answer.success = false; answer.error = string.Empty; byte[] buffer = null; for (var attempt = 0; attempt < 3 && answer.success == false; attempt++) { buffer = SendSimple(data, attempt); if (buffer.Length == 0) { answer.error = "Нет ответа"; } else { if (buffer.Length <= 4) { answer.error = "Слишком короткий ответ"; } else if (!Crc.Check(buffer.ToArray(), new Crc16Modbus())) { answer.error = "Не сошлась контрольная сумма"; } else { answer.success = true; answer.error = string.Empty; } } } if (answer.success) { answer.code = 0; answer.NetworkAddress = buffer[0]; answer.Function = buffer[1]; answer.data = buffer; answer.Body = buffer.Skip(2).Take(buffer.Length - 4).ToArray(); } return(answer); }
public Response(byte[] data) { if (data.Length < 5) { throw new Exception("в кадре ответа не может содежаться менее 5 байт"); } if (!Crc.Check(data, new Crc16Modbus())) { throw new Exception("контрольная сумма кадра не сошлась"); } NetworkAddress = data[0]; Function = data[1]; //modbus error if (Function > 0x80) { var exceptionCode = (ModbusExceptionCode)data[2]; throw new Exception(string.Format("устройство вернуло ошибку: {0}", exceptionCode)); } }
public dynamic xOAxOD(byte[] buffer) { dynamic answer = new ExpandoObject(); answer.success = false; answer.error = string.Empty; answer.errorcode = DeviceError.NO_ERROR; if ((buffer[0] == 0x0A && buffer[1] == 0x0D) || (buffer[buffer.Length - 2] == 0x0A && buffer[buffer.Length - 1] == 0x0D)) { List <byte> bufferTmp = buffer.ToList(); while (bufferTmp.Count > 5 && (bufferTmp[0] == 0x0A && bufferTmp[1] == 0x0D)) { bufferTmp.RemoveRange(0, 2); } while (bufferTmp.Count > 5 && (bufferTmp[bufferTmp.Count - 2] == 0x0A && bufferTmp[bufferTmp.Count - 1] == 0x0D)) { bufferTmp.RemoveRange(bufferTmp.Count - 2, 2); } buffer = null; buffer = bufferTmp.ToArray(); log(string.Format("---{0}", string.Join(",", buffer.Select(b => b.ToString("X2")))), level: 3); if (!Crc.Check(buffer, new Crc16Modbus())) { answer.errorcode = DeviceError.CRC_ERROR; answer.error = "контрольная сумма кадра не сошлась"; } else { answer.success = true; answer.error = string.Empty; answer.errorcode = DeviceError.NO_ERROR; answer.buffer = buffer; } } return(answer); }
private dynamic Send(byte[] dataSend) { dynamic answer = new ExpandoObject(); answer.success = false; answer.error = string.Empty; answer.errorcode = DeviceError.NO_ERROR; byte[] data = null; for (var attempts = 0; (attempts < 2) && (answer.success == false); attempts++) { //if (attempts == 0) //{ // data = SendSimple(dataSend, 750, 1); //} //if (attempts < 2) //{ data = SendSimple(dataSend);//, 15000, 6); //} //else //{ // data = SendSimple(dataSend, 10000, 6); //} if (data.Length == 0) { answer.error = "Нет ответа"; answer.errorcode = DeviceError.NO_ANSWER; } else { if (data.Length < 5) { answer.error = "в кадре ответа не может содежаться менее 5 байт"; answer.errorcode = DeviceError.TOO_SHORT_ANSWER; } else if (!Crc.Check(data, new Crc16Modbus())) { answer.error = "контрольная сумма кадра не сошлась"; answer.errorcode = DeviceError.CRC_ERROR; } else { answer.success = true; } } } if (answer.success) { answer.NetworkAddress = data[0]; answer.Function = data[1]; answer.Length = data[3]; answer.Body = data.Skip(3).Take(data.Length - 5).ToArray(); answer.data = data; //modbus error if (answer.Function > 0x80) { var exceptionCode = (ModbusExceptionCode)data[2]; answer.success = false; answer.error = string.Format("устройство вернуло ошибку: {0}", exceptionCode); answer.errorcode = DeviceError.DEVICE_EXCEPTION; } } return(answer); }
private dynamic Send(byte[] data) { dynamic answer = new ExpandoObject(); answer.success = false; answer.error = string.Empty; answer.errorcode = DeviceError.NO_ERROR; answer.code = 0; byte[] buffer = null; for (var attempt = 0; attempt < 3 && answer.success == false; attempt++) { buffer = SendSimple(data, attempt); if (buffer.Length == 0) { answer.error = "Нет ответа"; answer.errorcode = DeviceError.NO_ANSWER; } else { if (buffer.Length <= 4) { answer.error = "Слишком короткий ответ"; answer.errorcode = DeviceError.TOO_SHORT_ANSWER; } else if (!Crc.Check(buffer.ToArray(), new Crc16Modbus())) { answer.error = "Не сошлась контрольная сумма"; answer.errorcode = DeviceError.CRC_ERROR; } else if (buffer[1] >= 0x80) { var code = buffer[2]; answer.errorcode = DeviceError.DEVICE_EXCEPTION; switch (code) { case 2: answer.error = "Несуществующий тип значений"; break; case 3: answer.error = "В архиве отсутствуют данные за эту дату"; break; case 5: answer.error = "Зафиксировано изменение схемы измерения"; break; } answer.code = code; } else { answer.success = true; answer.error = string.Empty; } } } if (answer.success) { answer.code = 0; answer.NetworkAddress = buffer[0]; answer.Function = buffer[1]; answer.data = buffer; answer.Body = buffer.Skip(2).Take(buffer.Length - 4).ToArray(); } return(answer); }
//public Guid GetObjectId(byte[] bytesObjectId, string imei, UInt32 networkAddress) //{ // Guid nullGuid = new Guid(); // Guid objectId = new Guid(bytesObjectId); // if (objectId == nullGuid || (bytesObjectId[0] == 0xFF && bytesObjectId[1] == 0xFF)) // { // objectId = GetObjectId(imei, networkAddress); // } // return objectId; //} private void Idle() { try { while (true) { var buffer = new byte[BUFFER_SIZE]; var readed = socket.Receive(buffer); if (readed == 0) { throw new Exception("пришло 0 байт"); //log.Debug(string.Format("[{0}] пришло 0 байт", GetImei())); } else { byte[] bytes = buffer.Take(readed).ToArray(); subscriber?.Invoke(bytes); if (subscriber == null) // 12.03.2019 { if (bytes.Length < 5) { if (bytes.Length == 2 && (bytes[0] + bytes[1] == 0xFF)) { SendDataToSocket(bytes); } else if (bytes.Length == 3 && ((byte)((bytes[1] >> 4) | (bytes[1] << 4)) == bytes[2])) { try { Guid objectId = GetObjectId <byte>(GetImei(), bytes[0]); ModbusControl.Instance.Request(new Guid[] { objectId }, bytes[1].ToString(), GetImei(), "Abnormal"); } catch (Exception ex) { } log.Error("событие"); } log.Error($"количество байтов пришло {bytes.Length} < 5"); } else if (Crc.Check(bytes, new Crc16Modbus())) { if (bytes[0] == 0xFB) //вместо СА используется CID { //if (bytes[13] == 0x60) // не работает еще //{ // byte[] byteConfig = bytes.Skip(1).Take(bytes.Length - 4).ToArray(); // //tsConfig conf = setBytes(byteConfig); // EditNode(BitConverter.ToString(byteConfig)); //} if (bytes[13] == 0x4D) //длинный СА { DateTime dt1970 = new DateTime(1970, 1, 1, 0, 0, 0, 0); byte[] bytesCId = bytes.Skip(1).Take(12).ToArray(); string strCId = BitConverter.ToString(bytesCId).Replace("-", ""); byte func = bytes[13]; byte[] bytesObjectId = bytes.Skip(14).Take(16).ToArray(); UInt32 networkAddress = Helper.ToUInt32(bytes, 30); //byte networkAddress = bytes[30]; Guid objectId = GetObjectId <UInt32>(bytesObjectId, GetImei(), networkAddress); byte[] byteTime = bytes.Skip(34).Take(4).ToArray(); //31 UInt32 uInt32Time = (UInt32)(byteTime[3] << 24) | (UInt32)(byteTime[2] << 16) | (UInt32)(byteTime[1] << 8) | byteTime[0]; DateTime dtContollers = dt1970.AddSeconds(uInt32Time); UInt16 code = Helper.ToUInt16(bytes, 38); DateTime[] dtEvent = new DateTime[16]; for (int i = 0; i < 16; i++) { if (i == 7) { byte[] byteTime1 = bytes.Skip(40 + i * 4).Take(4).ToArray(); //31 UInt32 uInt32Time1 = (UInt32)(byteTime1[3] << 24) | (UInt32)(byteTime1[2] << 16) | (UInt32)(byteTime1[1] << 8) | byteTime1[0]; dtEvent[i] = dt1970.AddSeconds(uInt32Time1); } else { dtEvent[i] = u32ToBytes(bytes.Skip(40 + i * 4).Take(4).ToArray()); } //byte[] byteTime1 = bytes.Skip(37 + i*4 ).Take(4).ToArray(); //UInt32 uInt32Time1 = (UInt32)(byteTime1[3] << 24) | (UInt32)(byteTime1[2] << 16) | (UInt32)(byteTime1[1] << 8) | byteTime1[0]; //dtEvent[i] = dt1970.AddSeconds(uInt32Time1); } byte[] arrParams = new byte[] { 0x01, 0x02, 0x07, 0x08, 0x0A, 0x12, 0x13, 0x00 }; List <dynamic> records = new List <dynamic>(); for (int i = 0; i < arrParams.Length; i++) { if (((byte)(code >> i) & 1) == 1 && dtEvent[i] != DateTime.MinValue) { records.Add(MakeAbnormalRecord(objectId, ParamName(arrParams[i]), MessageParam(arrParams[i]), dtEvent[i], 1)); } } if (records.Any()) { RecordsAcceptor.Instance.Save(records); } } } else { if (bytes[1] == 0x60) { byte[] byteConfig = bytes.Skip(2).Take(bytes.Length - 4).ToArray(); EditNode(BitConverter.ToString(byteConfig)); } } //tsConfig conf = setBytes(bytes); //SendDataToSocket(ModbusControl.Instance.TeleofisWrx(bytes, GetImei())); } else { if ((bytes[0] == 0x0A && bytes[1] == 0x0D) || (bytes[bytes.Length - 2] == 0x0A && bytes[bytes.Length - 1] == 0x0D)) { List <byte> bufferTmp = bytes.ToList(); while (bufferTmp.Count > 5 && (bufferTmp[0] == 0x0A && bufferTmp[1] == 0x0D)) { bufferTmp.RemoveRange(0, 2); } while (bufferTmp.Count > 5 && (bufferTmp[bufferTmp.Count - 2] == 0x0A && bufferTmp[bufferTmp.Count - 1] == 0x0D)) { bufferTmp.RemoveRange(bufferTmp.Count - 2, 2); } bytes = null; bytes = bufferTmp.ToArray(); if (!Crc.Check(bytes, new Crc16Modbus())) { log.Error("контрольная сумма кадра не сошлась"); } else { SendDataToSocket(ModbusControl.Instance.TeleofisWrx(bytes, GetImei())); } } } } } } } catch (Exception oex) { log.Error(string.Format("[{0}] поток слушающий сокет остановлен", GetImei()), oex); CloseSocket(); } }
private void Idle() { try { while (true) { var buffer = new byte[BUFFER_SIZE]; var readed = socket.Receive(buffer); if (readed == 0) { throw new Exception("пришло 0 байт"); //log.Debug(string.Format("[{0}] пришло 0 байт", GetImei())); } else { byte[] bytes = buffer.Take(readed).ToArray(); subscriber?.Invoke(bytes); if (subscriber == null) // 12.03.2019 { if (bytes.Length < 5) { if (bytes.Length == 2) { byte[] answerPing = Encoding.ASCII.GetBytes("OK"); SendDataToSocket(answerPing); } else if (bytes.Length == 3 && ((byte)((bytes[1] >> 4) | (bytes[1] << 4)) == bytes[2])) { try { Guid objectId = GetObjectId(GetImei(), bytes[0]); ModbusControl.Instance.Request(new Guid[] { objectId }, bytes[1].ToString(), GetImei(), "Abnormal"); } catch (Exception ex) { } log.Error("событие"); } log.Error($"количество байтов пришло {bytes.Length} < 5"); } else if (Crc.Check(bytes, new Crc16Modbus())) { SendDataToSocket(ModbusControl.Instance.TeleofisWrx(bytes, GetImei())); } else { if ((bytes[0] == 0x0A && bytes[1] == 0x0D) || (bytes[bytes.Length - 2] == 0x0A && bytes[bytes.Length - 1] == 0x0D)) { List <byte> bufferTmp = bytes.ToList(); while (bufferTmp.Count > 5 && (bufferTmp[0] == 0x0A && bufferTmp[1] == 0x0D)) { bufferTmp.RemoveRange(0, 2); } while (bufferTmp.Count > 5 && (bufferTmp[bufferTmp.Count - 2] == 0x0A && bufferTmp[bufferTmp.Count - 1] == 0x0D)) { bufferTmp.RemoveRange(bufferTmp.Count - 2, 2); } bytes = null; bytes = bufferTmp.ToArray(); if (!Crc.Check(bytes, new Crc16Modbus())) { log.Error("контрольная сумма кадра не сошлась"); } else { SendDataToSocket(ModbusControl.Instance.TeleofisWrx(bytes, GetImei())); } } } } } } } catch (Exception oex) { log.Error(string.Format("[{0}] поток слушающий сокет остановлен", GetImei()), oex); CloseSocket(); } }
private dynamic Send(byte[] data, byte cmd, int attempts = 3) { dynamic answer = new ExpandoObject(); answer.success = false; answer.error = string.Empty; answer.errorcode = DeviceError.NO_ERROR; byte[] buffer = null; for (var attempt = 0; (attempt < attempts) && (answer.success == false); attempt++) { buffer = SendSimple(data); if (buffer.Length == 0) { answer.error = "Нет ответа"; answer.errorcode = DeviceError.NO_ANSWER; } else { //buffer = buffer.SkipWhile(b => b == 0xff).ToArray(); var na = GetNaPacket(); if (buffer.Length < 6) { answer.error = "в кадре ответа не может содежаться менее 6 байт"; answer.errorcode = DeviceError.TOO_SHORT_ANSWER; } else if ((buffer[0] != data[0]) || (buffer[1] != data[1]) || (buffer[2] != data[2]) || (buffer[3] != data[3])) { log("Несовпадение сетевого адреса", level: 1); answer.error = "Несовпадение сетевого адреса"; answer.errorcode = DeviceError.ADDRESS_ERROR; } else if (cmd != data[4]) { answer.error = "Несовпадение команды"; answer.errorcode = DeviceError.ADDRESS_ERROR; } else { do { if (Crc.Check(buffer, new Crc16Modbus())) { break; } buffer = buffer.Take(buffer.Length - 1).ToArray(); }while (buffer.Length > 6); if (!Crc.Check(buffer, new Crc16Modbus())) { answer.error = "контрольная сумма кадра не сошлась"; answer.errorcode = DeviceError.CRC_ERROR; } else { answer.success = true; answer.error = string.Empty; answer.errorcode = DeviceError.NO_ERROR; } } } } if (answer.success) { answer.Body = buffer.Take(buffer.Length - 2).Skip(5).ToArray(); } return(answer); }
private dynamic Send(byte[] data, int attempts_total = 8) //4 { if (gate228) { dynamic answer = new ExpandoObject(); answer.success = false; answer.error = string.Empty; answer.errorcode = DeviceError.NO_ERROR; byte[] buffer = null; if (firstStart == 0) { byte[] extraBytes1 = new byte[] { 0xDE, 0x65, 0x71, 0x01, 0x00, 0x00, 0x80, 0x7F, 0x20, 0x3F }; byte[] extraBytes2 = new byte[] { 0x27, 0xB7, 0xFC, 0x01, 0x00, 0x04, 0x00, 0x00, 0x01, 0x16, 0x22, 0x04, 0x3C }; SendSimple(extraBytes1); SendSimple(extraBytes2); firstStart++; } List <byte> dataGate228 = new List <byte>(); dataGate228.Add(01); dataGate228.Add(00); if (data.Length > 255) { dataGate228.AddRange(BitConverter.GetBytes(data.Length)); } else { dataGate228.Add((byte)(data.Length)); //dataGate228.Add(4); dataGate228.Add(0); } // dataGate228.Add(0); dataGate228.Add(1); UInt32 crc24 = Crc24.Compute(dataGate228.ToArray()); dataGate228.InsertRange(0, BitConverter.GetBytes(crc24).Take(3)); byte csLast = (byte)(data.Sum(d => d) - 1); dataGate228.AddRange(data); dataGate228.Add(csLast); for (var attempts = 0; attempts < attempts_total && answer.success == false; attempts++) { buffer = SendSimple(dataGate228.ToArray()); buffer = buffer.Skip(8).Take(buffer[5]).ToArray(); log(string.Format("< {0}", string.Join(",", buffer.Select(b => b.ToString("X2")))), level: 3); if (buffer.Length == 0) { answer.error = "Нет ответа"; answer.errorcode = DeviceError.NO_ANSWER; } else { buffer = buffer.SkipWhile(b => b == 0xff).ToArray(); if (buffer.Length < 4) { answer.error = "в кадре ответа не может содежаться менее 4 байт"; answer.errorcode = DeviceError.TOO_SHORT_ANSWER; } else { UInt32 crc24forcheck = BitConverter.ToUInt32(new byte[] { buffer[0], buffer[1], buffer[2], 0x00 }, 0); byte cs = (byte)(buffer.Skip(8).Take(buffer.Length - 9).Sum(b => b) - 1); //if (crc24forcheck != Crc24.Compute(buffer, 3, 5)) //{ // answer.error = "контрольная сумма заголовка не сошлась"; // answer.errorcode = DeviceError.CRC_ERROR; //} //else if (cs != buffer[buffer.Length - 1]) //{ // answer.error = "контрольная сумма данных не сошлась"; // answer.errorcode = DeviceError.CRC_ERROR; //} answer.success = true; answer.error = string.Empty; answer.errorcode = DeviceError.NO_ERROR; //else //{ //} } } } if (answer.success) { answer.Body = buffer.Skip(1).ToArray(); //answer.Payload = buffer.Skip(8).Take(buffer.Length - 9).ToArray(); //modbus error if (buffer.Length == 4) { answer.errorcode = DeviceError.DEVICE_EXCEPTION; answer.exceptioncode = buffer[1]; answer.success = false; switch (buffer[1]) { case 0x00: answer.errorcode = DeviceError.NO_ERROR; answer.success = true; answer.error = "все нормально"; break; case 0x01: answer.error = "недопустимая команда или параметр"; break; case 0x02: answer.error = "внутренняя ошибка счетчика"; break; case 0x03: answer.error = "не достаточен уровень доступа для удовлетворения запроса"; break; case 0x04: answer.error = "внутренние часы счетчика уже корректировались в течении текущих суток"; break; case 0x05: answer.error = "не открыт канал связи"; break; default: answer.error = "неизвестная ошибка"; break; } } } return(answer); } else { dynamic answer = new ExpandoObject(); answer.success = false; answer.error = string.Empty; answer.errorcode = DeviceError.NO_ERROR; byte[] buffer = null; for (var attempts = 0; attempts < attempts_total && answer.success == false; attempts++) { buffer = SendSimple(data); if (buffer.Length == 0) { answer.error = "Нет ответа"; answer.errorcode = DeviceError.NO_ANSWER; } else { buffer = buffer.SkipWhile(b => b == 0xff).ToArray(); if (buffer.Length < 4) { answer.error = "в кадре ответа не может содежаться менее 4 байт"; answer.errorcode = DeviceError.TOO_SHORT_ANSWER; } else if (buffer[0] != NetworkAddress) { answer.error = "Несовпадение сетевого адреса"; answer.errorcode = DeviceError.ADDRESS_ERROR; } else if (buffer.Length == 4 && buffer[1] == 0x05) { answer.error = "Закрыт канал связи"; answer.errorcode = DeviceError.CHANNEL_CLOSED; } else if (!Crc.Check(buffer, new Crc16Modbus())) { answer.error = "контрольная сумма кадра не сошлась"; answer.errorcode = DeviceError.CRC_ERROR; for (int i = 0; i < buffer.Length - 1; i++) { if ((buffer[i] == 0x0d) && (buffer[i + 1] == 0x0a)) { for (int j = i + 2; j < buffer.Length - 1; j++) { if ((buffer[j] == 0x0d) && (buffer[j + 1] == 0x0a)) { //var tmp = buffer.Take(i); //buffer = null; //buffer = tmp.ToArray(); buffer = buffer.Take(i).ToArray(); if (Crc.Check(buffer, new Crc16Modbus())) { answer.success = true; answer.error = string.Empty; answer.errorcode = DeviceError.NO_ERROR; } } } } } } else { answer.success = true; answer.error = string.Empty; answer.errorcode = DeviceError.NO_ERROR; } } } if (answer.success) { answer.Body = buffer.Skip(1).Take(buffer.Count() - 3).ToArray(); answer.NetworkAddress = buffer[0]; //modbus error if (buffer.Length == 4) { answer.errorcode = DeviceError.DEVICE_EXCEPTION; answer.exceptioncode = buffer[1]; answer.success = false; switch (buffer[1]) { case 0x00: answer.errorcode = DeviceError.NO_ERROR; answer.success = true; answer.error = "все нормально"; break; case 0x01: answer.error = "недопустимая команда или параметр"; break; case 0x02: answer.error = "внутренняя ошибка счетчика"; break; case 0x03: answer.error = "не достаточен уровень доступа для удовлетворения запроса"; break; case 0x04: answer.error = "внутренние часы счетчика уже корректировались в течении текущих суток"; break; case 0x05: answer.error = "не открыт канал связи"; break; default: answer.error = "неизвестная ошибка"; break; } } } return(answer); } }
private dynamic Send(byte[] datasend, int attempts_total = SEND_ATTEMPTS) { dynamic answer = new ExpandoObject(); answer.success = false; answer.error = string.Empty; answer.errorcode = DeviceError.NO_ERROR; byte[] buffer = null; for (var attempts = 0; attempts < attempts_total && answer.success == false; attempts++) { buffer = SendSimple(datasend); if (buffer.Length == 0) { answer.error = "Нет ответа"; answer.errorcode = DeviceError.NO_ANSWER; } else { if (buffer.Length < 4) { answer.error = "в кадре ответа не может содержаться менее 4 байт"; answer.errorcode = DeviceError.TOO_SHORT_ANSWER; } else if (!Crc.Check(buffer, new Crc16Modbus())) { answer.error = "контрольная сумма кадра не сошлась"; answer.errorcode = DeviceError.CRC_ERROR; } else { answer.success = true; answer.error = string.Empty; answer.errorcode = DeviceError.NO_ERROR; } } } if (answer.success) { answer.NetworkAddress = buffer[0]; answer.Body = buffer.Skip(1).Take(buffer.Length - 3).ToArray(); var tmp = buffer.Skip(1).Take(buffer.Length - 3); /* * log($"buffer, {string.Join(",", buffer.Select(b => b.ToString("X2")))}"); * log($"Body, {string.Join(",", tmp.Select(b => b.ToString("X2")))}"); * * List<byte> tmpByte = (tmp.Select(b => b)).ToList(); * log($"tmpByte до удаления, {string.Join(",", tmpByte.Select(b => b.ToString("X2")))}"); * try * { * int firstIndexFF = tmpByte.IndexOf(0xFF); * log($"Индекс1: {firstIndexFF}"); * if (firstIndexFF > 40) * { * tmpByte.RemoveAt(firstIndexFF); * } * } * catch * { * } * log($"tmpByte после удаления, {string.Join(",", tmpByte.Select(b => b.ToString("X2")))}"); */ //answer.Body = tmpByte.ToArray(); //modbus error if (buffer.Length == 4) { answer.success = false; answer.errorcode = DeviceError.DEVICE_EXCEPTION; switch (buffer[1] & 0x0F) { case 0x00: answer.success = true; answer.errorcode = DeviceError.NO_ERROR; answer.error = "все нормально"; break; case 0x01: answer.error = "недопустимая команда или параметр"; break; case 0x02: answer.error = "внутренняя ошибка счетчика"; break; case 0x03: answer.error = "не достаточен уровень доступа для удовлетворения запроса"; break; case 0x04: answer.error = "внутренние часы счетчика уже корректировались в течении текущих суток"; break; case 0x05: answer.error = "не открыт канал связи"; break; case 0x0F: answer.error = "счётчик не отвечает (коммуникатор)"; break; default: answer.error = "неизвестная ошибка"; break; } } } return(answer); }
private dynamic Send(byte[] dataSend) { dynamic answer = new ExpandoObject(); answer.success = false; answer.error = string.Empty; byte[] data = null; for (var attempts = 0; attempts < 3 && answer.success == false; attempts++) { if (attempts == 0) { data = SendSimple(dataSend, 10000, 3); } else if (attempts == 1) { data = SendSimple(dataSend, 10000, 6); } else { data = SendSimple(dataSend, 10000, 6); } if (data.Length == 0) { answer.error = "Нет ответа"; } else { if (data.Length < 5) { answer.error = "в кадре ответа не может содежаться менее 5 байт"; } else if (!Crc.Check(data, new Crc16Modbus())) { answer.error = "контрольная сумма кадра не сошлась"; } else if ((data[1] < 0x80) && (data[1] != dataSend[1])) { answer.error = "пришёл ответ на другой запрос"; } else { answer.success = true; } } } if (answer.success) { answer.NetworkAddress = data[0]; answer.Function = data[1]; answer.Length = data[2]; answer.Body = data.Skip(3).Take(data.Length - 5).ToArray(); answer.data = data; //modbus error if (answer.Function > 0x80) { answer.exceptionCode = (ModbusExceptionCode)data[2]; answer.success = false; answer.error = string.Format("устройство вернуло ошибку: {0}", answer.exceptionCode); } } return(answer); }