private void Channel_OnReceive(object sender, ChannelReceivedEventArgs e) { try { MbapHeader header = MbapHeader.Decode(e.Message); if (!unitId.HasValue) { unitId = header.UnitId; } if (unitId.HasValue && header.UnitId == unitId.Value) { RtuPiSystem piSystem = map.GetItem((ushort)unitId.Value); if (piSystem == null) { throw new Exception($"PI-System not found for unit id - {unitId.Value}"); } else { client.SubscribeAsync(piSystem.RtuOutputEvent, QualityOfServiceLevelType.AtLeastOnce, ReceiveOutput).GetAwaiter(); client.PublishAsync(QualityOfServiceLevelType.AtLeastOnce, piSystem.RtuInputEvent, contentType, e.Message).GetAwaiter(); } } else { throw new Exception("Unit Id missing from SCADA client message."); } } catch (Exception ex) { OnError?.Invoke(this, new AdapterErrorEventArgs(Id, ex)); } }
private void Input_OnReceive(object sender, ChannelReceivedEventArgs e) { MbapHeader header = MbapHeader.Decode(e.Message); if (header == null) { logger?.LogWarning("MBAP Header returned null"); return; //assume keep alive } if (!map.HasItem(header.UnitId)) { byte[] errorMsg = ModbusErrorMessage.Create(e.Message, ErrorCode.GatewayPathsNotAvailable); this.InputChannel.SendAsync(errorMsg).GetAwaiter(); return; } if (!map.GetItem(header.UnitId).Authorize(e.Message)) { byte[] errorMsg = ModbusErrorMessage.Create(e.Message, ErrorCode.IllegalAddress); this.InputChannel.SendAsync(errorMsg).GetAwaiter(); return; } byte[] message = e.Message; byte[] msg = null; foreach (var filter in InputFilters) { msg = filter.Execute(message); msg ??= message; } OutputChannel.SendAsync(msg).GetAwaiter(); }
public async Task SendAsync(byte[] message) { if (client == null || !client.IsConnected) { logger?.LogWarning("MQTT client is not available to forward message."); return; } try { MbapHeader header = MbapHeader.Decode(message); if (map.HasItem(header.UnitId)) { if (!subscriptions.Contains(header.UnitId)) { string resource = map.GetItem(header.UnitId).RtuOutputEvent; await client.SubscribeAsync(resource, QualityOfServiceLevelType.AtMostOnce, ModbusMessageReceived); logger?.LogInformation( $"MQTT client channel subscribed {resource} with Unit ID = {header.UnitId}"); subscriptions.Add(header.UnitId); } cache.Add(GetCacheKey(header), new Tuple <ushort, byte[]>(header.TransactionId, message), 20.0); string pisystem = map.GetItem(header.UnitId).RtuInputEvent; await client.PublishAsync(QualityOfServiceLevelType.AtMostOnce, pisystem, "application/octet-stream", message); logger?.LogDebug($"VRTU published to {pisystem}"); await diag?.PublishInput(header); } else { logger?.LogWarning($"Unit Id = {header.UnitId} in Modbus message not found in RTU map."); } } catch (Exception ex) { logger?.LogError(ex, "Fault sending MQTT client channel."); } }
private async void Channel_OnReceive(object sender, ChannelReceivedEventArgs e) { logger?.LogDebug("SCADA client channel starting receive."); try { MbapHeader header = MbapHeader.Decode(e.Message); RtuPiSystem piSystem = map.GetItem(header.UnitId); if (piSystem == null) { logger?.LogWarning("SCADA client receive cannot find RTU pi-system."); throw new InvalidOperationException("RTU pi-system was not found."); } if (!subscribed.Contains(header.UnitId)) { //subscribe to pi-system for unit id await connection.AddSubscriptionAsync(piSystem.RtuOutputEvent.ToLowerInvariant(), ReceiveOutput); subscribed.Add(header.UnitId); } byte[] msg = mapper.MapIn(e.Message); await connection.SendAsync(piSystem.RtuInputEvent.ToLowerInvariant(), CONTENT_TYPE, msg); MbapHeader mheader = MbapHeader.Decode(msg); //await connection.Monitor.SendInAsync(ModuleType.VRTU.ToString(), e.Message, mheader.TransactionId); } catch (Exception ex) { logger?.LogError($"SCADA client receive error - {ex.Message}"); OnError?.Invoke(this, new AdapterErrorEventArgs(Id, ex)); } }