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)); } } }
public override async Task DeactivateDeviceAsync(DeviceOperationScope scope, AsyncOperationInfo cancellation) { using (await _connectionInterface.LockAsync(cancellation)) { await _base.DeactivateDeviceAsync(scope, cancellation); } }
public override async Task <StatusReadResult> TryReadStatusAsync(DeviceOperationScope scope, AsyncOperationInfo cancellation) { using (await _connectionInterface.LockAsync(cancellation)) { return(await _base.TryReadStatusAsync(scope, cancellation)); } }
public override async Task <ReadResult> ReadAsync(Command request, DeviceOperationScope scope, AsyncOperationInfo cancellation) { using (await _connectionInterface.LockAsync(cancellation)) { return(await _base.ReadAsync(request, scope, cancellation)); } }
public async Task DeactivateDeviceAsync(DeviceOperationScope scope, AsyncOperationInfo cancellation) { Logger.LogInfo(null, $"Деактивация устройства \"{Name}\"..."); using (Logger.Indent) { await deactivateDeviceAsync(scope, cancellation); Logger.LogOK(null, $"Устройство \"{Name}\" деактивировано"); } }
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); }
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)); } }
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); }
public override async Task DeactivateDeviceAsync(DeviceOperationScope scope, AsyncOperationInfo cancellation) { try { await _base.DeactivateDeviceAsync(scope, cancellation); } catch (OperationCanceledException) { throw; } catch (Exception ex) { Logger.LogErrorEverywhere("Ошибка деактивации устройства", ex); } }
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)); } }
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); } }
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)); }
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)); }
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); }
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); }
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); } }
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)); }
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); } }
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); }
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)); } }
protected virtual Task deactivateDeviceAsync(DeviceOperationScope scope, AsyncOperationInfo cancellation) => Task.CompletedTask;
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); } }
public async Task <BurnResult> BurnAsync (Command requestAddress, IEnumerable <IDataEntity> entities, DeviceOperationScope scope, AsyncOperationInfo cancellation) { return(await burnAsync(requestAddress, entities, false, scope, cancellation)); }
protected override async Task activateDeviceAsync(DeviceOperationScope scope, AsyncOperationInfo cancellation) { await base.activateDeviceAsync(scope, cancellation); await tryInitializeFTDIInterfaceIfRequiredAsync(scope, cancellation); }
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)); }
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)); } } }
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, $"Ошибка очистки буфера чтения порта. Порт был закрыт?"); } } }
protected override async Task deactivateDeviceAsync(DeviceOperationScope scope, AsyncOperationInfo cancellation) { await base.deactivateDeviceAsync(scope, cancellation); _ftdiInterface = null; }
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 }
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)); } }