コード例 #1
0
        public async Task <StatusReadResult> TryReadStatusAsync(DeviceOperationScope scope, AsyncOperationInfo cancellation)
        {
            await ThreadingUtils.ContinueAtThreadPull(cancellation);

            using (Logger.Indent)
            {
                Logger.LogInfo(null, $"Чтение статуса прибора \"{Name}\"...");

                var result = await ReadAsync(Command.STATUS, scope, cancellation);

                if (result.Status == ReadStatus.OK)
                {
                    var flagsEntity     = result.Entities.ElementAt(0);
                    var numOfStatusBits = flagsEntity.Descriptor.Length.Length * 8;
                    var flags           = (uint)(dynamic)flagsEntity.Value;
                    var serial          = (ushort)result.Entities.ElementAt(1).Value;
                    var status          = new DeviceStatusInfo.StatusInfo(numOfStatusBits, flags);

                    Logger.LogInfo(null, $"Статус: {status.ToBinString()}");

                    return(new StatusReadResult(result, new DeviceStatusInfo(Id, serial, status)));
                }
                else
                {
                    return(new StatusReadResult(result, null));
                }
            }
        }
コード例 #2
0
 public override async Task DeactivateDeviceAsync(DeviceOperationScope scope, AsyncOperationInfo cancellation)
 {
     using (await _connectionInterface.LockAsync(cancellation))
     {
         await _base.DeactivateDeviceAsync(scope, cancellation);
     }
 }
コード例 #3
0
 public override async Task <StatusReadResult> TryReadStatusAsync(DeviceOperationScope scope, AsyncOperationInfo cancellation)
 {
     using (await _connectionInterface.LockAsync(cancellation))
     {
         return(await _base.TryReadStatusAsync(scope, cancellation));
     }
 }
コード例 #4
0
 public override async Task <ReadResult> ReadAsync(Command request, DeviceOperationScope scope, AsyncOperationInfo cancellation)
 {
     using (await _connectionInterface.LockAsync(cancellation))
     {
         return(await _base.ReadAsync(request, scope, cancellation));
     }
 }
コード例 #5
0
        public async Task DeactivateDeviceAsync(DeviceOperationScope scope, AsyncOperationInfo cancellation)
        {
            Logger.LogInfo(null, $"Деактивация устройства \"{Name}\"...");

            using (Logger.Indent)
            {
                await deactivateDeviceAsync(scope, cancellation);

                Logger.LogOK(null, $"Устройство \"{Name}\" деактивировано");
            }
        }
コード例 #6
0
        public override async Task <StatusReadResult> TryReadStatusAsync(DeviceOperationScope scope, AsyncOperationInfo cancellation)
        {
            var result = await base.TryReadStatusAsync(scope, cancellation);

            if (result.StatusInfo != null)
            {
                _feature.FireStatusAcquired(result.StatusInfo);
            }

            return(result);
        }
コード例 #7
0
 public override async Task <ReadResult> ReadAsync(Command request, DeviceOperationScope scope, AsyncOperationInfo cancellation)
 {
     if (SupportedCommands.Contains(request))
     {
         return(await _base.ReadAsync(request, scope, cancellation));
     }
     else
     {
         return(new ReadResult(ReadStatus.NOT_SUPPORTED_BY_INTERFACE, Enumerable.Empty <IDataEntity>(), ResponseData.NONE));
     }
 }
コード例 #8
0
        public override async Task <ReadResult> ReadAsync(Command request, DeviceOperationScope scope, AsyncOperationInfo cancellation)
        {
            var result = await _base.ReadAsync(request, scope, cancellation);

            if (request == Command.DATA &&
                result.Status == ReadStatus.OK)
            {
                DataRowAquired?.Invoke(result.Entities.GetViewEntities());
            }

            return(result);
        }
コード例 #9
0
 public override async Task DeactivateDeviceAsync(DeviceOperationScope scope, AsyncOperationInfo cancellation)
 {
     try
     {
         await _base.DeactivateDeviceAsync(scope, cancellation);
     }
     catch (OperationCanceledException) { throw; }
     catch (Exception ex)
     {
         Logger.LogErrorEverywhere("Ошибка деактивации устройства", ex);
     }
 }
コード例 #10
0
        public override async Task <ReadResult> ReadAsync(Command request, DeviceOperationScope scope, AsyncOperationInfo cancellation)
        {
            try
            {
                return(await _base.ReadAsync(request, scope, cancellation));
            }
            catch (OperationCanceledException) { throw; }
            catch (Exception ex)
            {
                Logger.LogErrorEverywhere("Ошибка запроса чтения", ex);

                return(new ReadResult(ReadStatus.UNKNOWN_ERROR, Enumerable.Empty <IDataEntity>(), ResponseData.NONE));
            }
        }
コード例 #11
0
        public override async Task <StatusReadResult> TryReadStatusAsync(DeviceOperationScope scope, AsyncOperationInfo cancellation)
        {
            try
            {
                return(await _base.TryReadStatusAsync(scope, cancellation));
            }
            catch (OperationCanceledException) { throw; }
            catch (Exception ex)
            {
                Logger.LogErrorEverywhere("Ошибка чтения статуса", ex);

                return(StatusReadResult.UNKNOWN_ERROR);
            }
        }
コード例 #12
0
        public override async Task <IRequest> handleOrMutateAsync(IRequest request, DeviceOperationScope scope, AsyncOperationInfo operationInfo)
        {
            if (request is SalachovRequest salachovRequest &&
                salachovRequest.DeviceId != _parrentId &&
                !salachovRequest.IsBroadcast)
            {
                _handled = true;

                return(SalachovRequest.CreateWriteRequest(_parrentId,
                                                          Devices.Command.RETRANSLATE_PACKET,
                                                          Requests.GetRequestDescription(_parrentId, Devices.Command.RETRANSLATE_PACKET)
                                                          .Descriptors
                                                          .Single()
                                                          .InstantiateEntity(request.Serialized).ToSequence(),
                                                          scope));
            }
コード例 #13
0
 FlashStreamReader(
     DeviceOperationScope flashReadOperationScope,
     RUSDeviceId device,
     IDictionary <RUSDeviceId, IEnumerable <IDataEntity> > rowDescriptors,
     Task <IFlashDumpDataParser> parserFuture,
     StreamPartsProviderSupplier partsProviderSupplier,
     Stream rawDumpStream,
     string rawDumpPath)
 {
     FlashReadOperationScope = flashReadOperationScope ?? throw new ArgumentNullException(nameof(flashReadOperationScope));
     _device                = device;
     _rowDescriptors        = rowDescriptors ?? throw new ArgumentNullException(nameof(rowDescriptors));
     _parserFuture          = parserFuture ?? throw new ArgumentNullException(nameof(parserFuture));
     _partsProviderSupplier = partsProviderSupplier ?? throw new ArgumentNullException(nameof(partsProviderSupplier));
     _rawDumpStream         = rawDumpStream;
     _rawDumpPath           = rawDumpPath ?? throw new ArgumentNullException(nameof(rawDumpPath));
 }
コード例 #14
0
        public virtual async Task <ReadResult> ReadAsync(Command requestAddress, DeviceOperationScope scope, AsyncOperationInfo cancellation)
        {
            Logger.LogInfo(null, $"Выполнение запроса чтения по адресу {requestAddress} для устройства \"{Name}\"...");
            var        request   = SalachovRequest.CreateReadRequest(Id, requestAddress, scope);
            ReadResult result    = null;
            var        rawResult = await _pipe.RequestAsync(request, scope, cancellation);

            if (rawResult.Status == RequestStatus.OK)
            {
                var entities = CommonUtils.TryOrDefault
                                   (() => getDataEntities(requestAddress, rawResult.To <SalachovResponse>(), _dataPacketDescriptors).ToArray(), null, out Exception ex);
                if (entities == null)
                {
                    Logger.LogError($"Не удалось разобрать данные в ответе", $"Произошла ошибка при десериализации полей ответа", ex);
                    result = new ReadResult(
                        ReadStatus.DESERIALIZATION_FAILURE,
                        null,
                        rawResult.Data,
                        rawResult.DataSections);
                }
                else
                {
                    result = new ReadResult(
                        mapRStatusToRRStatus(rawResult.Status),
                        entities,
                        rawResult.Data,
                        rawResult.DataSections);
                    if (requestAddress == Command.DATA_PACKET_CONFIGURATION_FILE)
                    {
                        _dataPacketDescriptors = EntitiesDeserializer.ExtractDataPacketDescriptors(result.Entities);
                    }
                }
            }
            else
            {
                Logger.LogError($"Не удалось выполнить запрос. Код ошибки: {rawResult.Status}", $"Произошла ошибка {rawResult.Status}. {rawResult.Status.GetEnumValueDescription()}");
                result = new ReadResult(
                    mapRStatusToRRStatus(rawResult.Status),
                    null,
                    rawResult.Data,
                    rawResult.DataSections);
            }

            return(result);
        }
コード例 #15
0
        async Task <bool> trySetCOMPortModeAsync(DeviceOperationScope scope, CancellationToken cancellation)
        {
            if (_pipe.InterfaceDevice == InterfaceDevice.RUS_TECHNOLOGICAL_MODULE_FTDI_BOX)
            {
                if (!await tryInitializeFTDIInterfaceIfRequiredAsync(scope, cancellation))
                {
                    return(false);
                }
                else if (!await _ftdiInterface.TrySwitchToRegularModeAsync(scope, cancellation))
                {
                    Logger.LogErrorEverywhere("Не удалось установить режим передачи");

                    return(false);
                }
            }

            return(true);
        }
コード例 #16
0
        public override async Task <IRequest> handleOrMutateAsync(IRequest request, DeviceOperationScope scope, AsyncOperationInfo operationInfo)
        {
            var salachovRequest = request.As <SalachovRequest>();
            var ftdiBoxRequest  = request.As <FTDIBoxRequest>();

            if (_connectionInterface.InterfaceDevice == InterfaceDevice.RUS_TECHNOLOGICAL_MODULE_FTDI_BOX && salachovRequest != null)
            {
                return(FTDIBoxRequest.CreateDeviceRequest(request, scope));
            }
            else if (_connectionInterface.InterfaceDevice == InterfaceDevice.COM && ftdiBoxRequest != null)
            {
                throw new NotSupportedException();
            }
            else
            {
                return(request);
            }
        }
コード例 #17
0
        public async static Task <FlashStreamReader> CreateAsync(RUSDeviceId device,
                                                                 IDictionary <RUSDeviceId, IEnumerable <IDataEntity> > formats,
                                                                 IFlashDumpDataParserFactory parserFactory,
                                                                 AsyncOperationInfo operationInfo)
        {
            var flashDumpPath         = Storaging.GetTempFilePath();
            var baseStream            = new FileStream(flashDumpPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read);
            var flashDumpWriteStream  = new FillNotifiableWriteOnlyStreamDecorator(CHUNK_SIZE, baseStream);
            var partsProvider         = new DumpParserPartsProvider(flashDumpPath);
            var partsProviderSupplier = new StreamPartsProviderSupplier(flashDumpWriteStream, partsProvider);
            var scope    = new DeviceOperationScope(new FlashDumpStreamParameter(flashDumpWriteStream));
            var sections = formats.Select(f =>
                                          new SectionedDataPacketParser.Section(
                                              f.Key,
                                              new DataPacketParser(EntitiesDeserializer.ExtractDataPacketDescriptors(f.Value))))
                           .ToArray();
            var dataParser   = new SectionedDataPacketParser(sections);
            var parserFuture = parserFactory.CreateFromRawPartsAsync(partsProvider.RawDumpParts(), dataParser, operationInfo);

            return(new FlashStreamReader(scope, device, formats, parserFuture, partsProviderSupplier, flashDumpWriteStream, flashDumpPath));
        }
コード例 #18
0
        async Task <bool> tryInitializeFTDIInterfaceIfRequiredAsync(DeviceOperationScope scope, CancellationToken cancellation)
        {
            if (_pipe.InterfaceDevice == InterfaceDevice.RUS_TECHNOLOGICAL_MODULE_FTDI_BOX)
            {
                if (_ftdiInterface == null)
                {
                    _ftdiInterface = await FTDIBoxFeatures.CreateAsync(_pipe, scope, cancellation);
                }

                if (_ftdiInterface == null)
                {
                    Logger.LogErrorEverywhere("Не удалось инициализировать");
                }

                return(_ftdiInterface != null);
            }
            else
            {
                return(true);
            }
        }
コード例 #19
0
        public override async Task <ReadResult> ReadAsync(Command request, DeviceOperationScope scope, AsyncOperationInfo cancellation)
        {
            var result = await base.ReadAsync(request, scope, cancellation);

            if (result.Status == ReadStatus.OK)
            {
                var statusField = result.Entities
                                  ?.Where(e => e.Descriptor.Name == STATUS_MNEMONIC)
                                  ?.FirstOrDefault()
                                  ?.Value;
                if (statusField != null && statusField.GetType().IsOneOf(typeof(ushort), typeof(uint)))
                {
                    var size           = Marshal.SizeOf(statusField) * 8;
                    var bits           = Convert.ChangeType(statusField, TypeCode.UInt32).To <uint>();
                    var statusBitsInfo = new DeviceStatusInfo.StatusInfo(size, bits);
                    var statusInfo     = new DeviceStatusInfo(Id, null, statusBitsInfo);
                    _feature.FireStatusAcquired(statusInfo);
                }
            }

            return(result);
        }
コード例 #20
0
 public override async Task <BurnResult> BurnAsync(Command request, IEnumerable <IDataEntity> entities, DeviceOperationScope scope, AsyncOperationInfo cancellation)
 {
     using (await _connectionInterface.LockAsync(cancellation))
     {
         return(await _base.BurnAsync(request, entities, scope, cancellation));
     }
 }
コード例 #21
0
 protected virtual Task deactivateDeviceAsync(DeviceOperationScope scope, AsyncOperationInfo cancellation) => Task.CompletedTask;
コード例 #22
0
        protected virtual async Task <BurnResult> burnAsync(Command requestAddress, IEnumerable <IDataEntity> entities, bool broadcast, DeviceOperationScope scope, AsyncOperationInfo cancellation)
        {
            Logger.LogInfo(null, $"Выполнение {broadcast.Ternar("широковещательного ", " ")}запроса записи по адресу {requestAddress} для устройства \"{Name}\"...");

            if (!await validateBurnOperationBySerial())
            {
                return(new BurnResult(BurnStatus.FORBIDDEN_SERIAL, null));
            }
            var targetId = broadcast ? RUSDeviceId.ALL : Id;
            var request  = SalachovRequest.CreateWriteRequest(targetId, requestAddress, entities, scope);
            var result   = await _pipe.RequestAsync(request, scope, cancellation);

            var status = map <BurnStatus>(result.Status);

            if (result.Status == RequestStatus.OK)
            {
                var requestInfo = requestAddress.GetInfo();
                if (requestInfo.IsFileRequest) // If file burn request
                {
                    await Task.Delay(DELAY_BEFORE_FILE_BURN_VERIFICATION, cancellation);

                    var isVerified = await verifyBurnAsync();

                    if (!isVerified)
                    {
                        status = BurnStatus.VERIFICATION_ERROR;
                    }
                }
            }
            else
            {
                Logger.LogErrorEverywhere($"Не удалось выполнить запись. Код ошибки: {result.Status}");
            }

            return(new BurnResult(status, result.Data, result.DataSections));

            async Task <bool> validateBurnOperationBySerial()
            {
                if (requestAddress.IsFileRequest())
                {
                    var fileSerial = Files.GetFileEntity(entities, FileEntityType.SERIAL_NUMBER).Value;
                    if (Equals(fileSerial, Files.DEFAULT_SERIAL))
                    {
                        Logger.LogError("Серийный номер не установлен", "Серийный номер не установлен");

                        return(false);
                    }

                    var readResult = await ReadAsync(requestAddress, scope, cancellation);

                    if (readResult.Status == ReadStatus.OK)
                    {
                        var deviceSerial = Files.GetFileEntity(readResult.Entities, FileEntityType.SERIAL_NUMBER).Value;

                        if (!Equals(fileSerial, deviceSerial) &&
                            !Equals(deviceSerial, Files.DEFAULT_SERIAL))
                        {
                            Logger.LogError("Серийные номера не совпадают", $"Серийный номер файла устройства не совпадает с серийным номером записываемого файла, {deviceSerial} != {fileSerial}");

                            return(false);
                        }
                    }
                }

                return(true);
            }

            async Task <bool> verifyBurnAsync()
            {
                var isVerified = false;

                using (Logger.Indent)
                {
                    Logger.LogInfo(null, $"Верификация записи...");

                    var actual = (await ReadAsync(requestAddress, scope, cancellation));
                    if (actual.Status == ReadStatus.OK)
                    {
                        var actualEntities   = actual.Entities;
                        var expectedEntities = entities;
                        if (requestAddress.GetFileType() == FileType.DATA_PACKET_CONFIGURATION)
                        {
                            actualEntities   = actual.Entities.Where(isTemplateEntity);
                            expectedEntities = entities.Where(isTemplateEntity);

                            bool isTemplateEntity(IDataEntity entity)
                            => Files.BaseFileTemplate.Any(ed => ed.Name == entity.Descriptor.Name);
                        }
                        var expectedData = expectedEntities.Select(e => e.RawValue).Flatten().ToArray();
                        var actualData   = actualEntities.Select(e => e.RawValue).Flatten().ToArray();
                        isVerified = actualData.SequenceEqual(expectedData);
                        if (isVerified)
                        {
                            Logger.LogOKEverywhere($"Файл \"{requestAddress.GetFileType().GetInfo().FileName}\" записан", $"Верификация записи успешно завершена");
                        }
                        else
                        {
                            Logger.LogWarningEverywhere($"Считанный файл не совпадает с записанным");
                        }
                    }
                    else
                    {
                        Logger.LogWarningEverywhere($"Не удалось выполнить верификацию записи. Код ошибки: {actual.Status}");
                    }
                }

                return(isVerified);
            }
        }
コード例 #23
0
 public async Task <BurnResult> BurnAsync
     (Command requestAddress, IEnumerable <IDataEntity> entities, DeviceOperationScope scope, AsyncOperationInfo cancellation)
 {
     return(await burnAsync(requestAddress, entities, false, scope, cancellation));
 }
コード例 #24
0
        protected override async Task activateDeviceAsync(DeviceOperationScope scope, AsyncOperationInfo cancellation)
        {
            await base.activateDeviceAsync(scope, cancellation);

            await tryInitializeFTDIInterfaceIfRequiredAsync(scope, cancellation);
        }
コード例 #25
0
        protected override async Task <BurnResult> burnAsync(Command requestAddress, IEnumerable <IDataEntity> entities, bool broadcast, DeviceOperationScope scope, AsyncOperationInfo cancellation)
        {
            if (!await trySetCOMPortModeAsync(scope, cancellation))
            {
                return(new BurnResult(BurnStatus.COULD_NOT_INITIALIZE, null));
            }

            return(await base.burnAsync(requestAddress, entities, broadcast, scope, cancellation));
        }
コード例 #26
0
        public override sealed async Task <ReadResult> ReadAsync(Command requestAddress, DeviceOperationScope scope, AsyncOperationInfo cancellation)
        {
            if (!await tryInitializeFTDIInterfaceIfRequiredAsync(scope, cancellation))
            {
                return(new ReadResult(ReadStatus.COULD_NOT_INITIALIZE, null, null));
            }

            if (requestAddress == Command.DOWNLOAD_FLASH)
            {
                var modeSetResult = await BurnAsync(Command.SET_DATA_UNLOAD_MODE, new IDataEntity[0], scope, cancellation);

                var file = modeSetResult.Status == BurnStatus.OK
                    ? await _ftdiInterface.ReadFileAsync(scope, cancellation)
                    : null;

                var modeUnsetResult = modeSetResult.Status == BurnStatus.OK
                    ? await BurnAsync(Command.SET_FLASH_WORK_MODE, new IDataEntity[0], scope, cancellation)
                    : null;

                if (modeSetResult.Status != BurnStatus.OK)
                {
                    Logger.LogErrorEverywhere("Не удалось перевести флеш в режим выгрузки");

                    return(new ReadResult(ReadStatus.COULD_NOT_INITIALIZE, null, null));
                }
                if (file == null)
                {
                    Logger.LogErrorEverywhere("Не удалось считать данные из флеш");

                    return(new ReadResult(ReadStatus.REQUEST_ERROR, null, null));
                }
                if (modeUnsetResult.Status != BurnStatus.OK)
                {
                    Logger.LogErrorEverywhere("Не удалось перевести флеш в режим работы");

                    return(new ReadResult(ReadStatus.OK, null, file));
                }

                if (file != null)
                {
                    return(new ReadResult(ReadStatus.OK, null, file));
                }
                else
                {
                    return(new ReadResult(ReadStatus.REQUEST_ERROR, null, file));
                }
            }
            else
            {
                if (!await trySetCOMPortModeAsync(scope, cancellation))
                {
                    return(new ReadResult(ReadStatus.COULD_NOT_INITIALIZE, null, null));
                }
                else
                {
                    return(await base.ReadAsync(requestAddress, scope, cancellation));
                }
            }
        }
コード例 #27
0
        public async Task <IResponse> RequestAsync(IRequest request, DeviceOperationScope scope, AsyncOperationInfo operationInfo)
        {
            IResponse result = null;

            await clearUnreadBytesAsync();

            var requestData   = request.Serialized.ToArray();
            var sendRequestOk = await tryWriteToPort(requestData, operationInfo);

            if (!sendRequestOk)
            {
                result = request.BuildErrorResponse(RequestStatus.CONNECTION_INTERFACE_ERROR);
            }
            else
            {
                await Logger.LogRequestAsync(requestData);

                try
                {
                    using (var future = new ResponseFuture(_port.Pipe, request.Timeout, operationInfo))
                    {
                        result = await request.DeserializeResponseAsync(future, operationInfo);
                    }
                }
                catch (TimeoutException)
                {
                    result = request.BuildErrorResponse(RequestStatus.READ_TIMEOUT);
                }
                catch (IOException)
                {
                    result = request.BuildErrorResponse(RequestStatus.CONNECTION_INTERFACE_ERROR);
                }
                catch (OperationCanceledException)
                {
                    result = request.BuildErrorResponse(RequestStatus.CONNECTION_INTERFACE_ERROR);
                }
                catch
                {
                    result = request.BuildErrorResponse(RequestStatus.UNKNOWN_ERROR);
                }
            }

            return(result);

            async Task clearUnreadBytesAsync()
            {
                var clearOperation = await CommonUtils.TryAsync(async() => await _port.Pipe.ClearReadBufferAsync(operationInfo));

                if (clearOperation.Ok)
                {
                    if (clearOperation.Result.BytesRead != 0)
                    {
                        Logger.LogWarning(null, $"Обнаружены несчитанные данные в буфере приема! Это означает, что устройство отправило больше данных чем предполагалось. -NLДлина: {clearOperation.Result.Data.Count()} -NLДанные={clearOperation.Result.Data.Take(1000).Select(b => b.ToString("X2")).AsString(" ")}");
                    }
                }
                else
                {
                    Logger.LogError(null, $"Ошибка очистки буфера чтения порта. Порт был закрыт?");
                }
            }
        }
コード例 #28
0
        protected override async Task deactivateDeviceAsync(DeviceOperationScope scope, AsyncOperationInfo cancellation)
        {
            await base.deactivateDeviceAsync(scope, cancellation);

            _ftdiInterface = null;
        }
コード例 #29
0
 public override async Task <IResponse> handleOrMutateAsync(IResponse response, DeviceOperationScope scope, AsyncOperationInfo operationInfo)
 {
     if (_connectionInterface.InterfaceDevice == InterfaceDevice.RUS_TECHNOLOGICAL_MODULE_FTDI_BOX &&
         InitialRequest is SalachovRequest &&
         response is FTDIBoxResponse ftdiBoxResponse &&
         ftdiBoxResponse.Status == RequestStatus.OK)
     {
         return(await InitialRequest.DeserializeResponseAsync(new ResponseDataToResponseFutureAdapter(ftdiBoxResponse.Body), operationInfo)); // Will return SalachovResponse
     }
コード例 #30
0
        public override async Task <BurnResult> BurnAsync(Command request, IEnumerable <IDataEntity> entities, DeviceOperationScope scope, AsyncOperationInfo cancellation)
        {
            try
            {
                return(await _base.BurnAsync(request, entities, scope, cancellation));
            }
            catch (OperationCanceledException) { throw; }
            catch (Exception ex)
            {
                Logger.LogErrorEverywhere("Ошибка запроса записи", ex);

                return(new BurnResult(BurnStatus.UNKNOWN_ERROR, ResponseData.NONE));
            }
        }