Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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];
        }
Ejemplo n.º 3
0
 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());
     }
 }
Ejemplo n.º 4
0
        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("неизвестная ошибка");
                }
            }
        }
Ejemplo n.º 5
0
        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();
        }
Ejemplo n.º 6
0
        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);
        }
Ejemplo n.º 7
0
        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);
        }
Ejemplo n.º 8
0
        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));
            }
        }
Ejemplo n.º 9
0
        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);
        }
Ejemplo n.º 10
0
        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);
        }
Ejemplo n.º 11
0
        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);
        }
Ejemplo n.º 12
0
        //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();
            }
        }
Ejemplo n.º 13
0
        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();
            }
        }
Ejemplo n.º 14
0
        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);
        }
Ejemplo n.º 15
0
        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);
            }
        }
Ejemplo n.º 16
0
        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);
        }
Ejemplo n.º 17
0
        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);
        }