/// <summary> /// Client has send data for the meters that are using the same port. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public static void OnExclusiveReceived(object sender, Gurux.Common.ReceiveEventArgs e) { try { lock (buffers) { GXByteBuffer bb; if (!buffers.ContainsKey(e.SenderInfo)) { bb = new GXByteBuffer(); buffers[e.SenderInfo] = bb; } else { bb = buffers[e.SenderInfo]; } bb.Set((byte[])e.Data); int target, source; //All simulated meters are using the same interface type. GXDLMSTranslator.GetAddressInfo(interfaceType, bb, out target, out source); if (target != 0 && meters.ContainsKey(target)) { GXDLMSMeter m = meters[target]; if (Trace > TraceLevel.Info) { Console.WriteLine("RX:\t" + Gurux.Common.GXCommon.ToHex((byte[])e.Data, true)); } GXServerReply sr = new GXServerReply(bb.Data); do { m.HandleRequest(sr); //Reply is null if we do not want to send any data to the client. //This is done if client try to make connection with wrong device ID. if (sr.Reply != null) { if (Trace > TraceLevel.Info) { Console.WriteLine("TX:\t" + Gurux.Common.GXCommon.ToHex(sr.Reply, true)); } bb.Clear(); m.Media.Send(sr.Reply, e.SenderInfo); sr.Data = null; } }while (sr.IsStreaming); } } } catch (Exception ex) { if (!(ex is SocketException)) { Console.WriteLine(ex.Message); } } }
/// <summary> /// Client has send data for for the gateway. /// </summary> /// <remarks> /// GW finds the correct client and sends data for it. /// </remarks> /// <param name="sender"></param> /// <param name="e"></param> public static void OnGatewayReceived(object sender, Gurux.Common.ReceiveEventArgs e) { try { lock (buffers) { GXByteBuffer bb; if (!buffers.ContainsKey(e.SenderInfo)) { bb = new GXByteBuffer(); buffers[e.SenderInfo] = bb; } else { bb = buffers[e.SenderInfo]; } bb.Set((byte[])e.Data); GXServerReply sr = new GXServerReply(bb.Data); GatewayServer.Reset(); try { GatewayServer.HandleRequest(sr); if (sr.Reply != null) { if (Trace > TraceLevel.Info) { Console.WriteLine("TX:\t" + Gurux.Common.GXCommon.ToHex(sr.Reply, true)); } ((IGXMedia)sender).Send(sr.Reply, e.SenderInfo); return; } } catch (Exception) { //Return error. sr.Reply = GatewayServer.ReportError(sr.Command, ErrorCode.HardwareFault); } if (sr.Gateway != null && sr.Data != null) { GXByteBuffer pdu = new GXByteBuffer(sr.Data); InterfaceType type = (InterfaceType)sr.Gateway.NetworkId; GXByteBuffer address = new GXByteBuffer(); address.Set(sr.Gateway.PhysicalDeviceAddress); int addr = address.GetUInt8(); //Find correct meter using GW information. if (meters.ContainsKey(addr)) { //Find client for the server or create a new one. GXDLMSClient cl; if (!clients.ContainsKey(addr)) { //Set client address if data is send without framing. if (GatewayServer.Settings.ClientAddress == 0) { GatewayServer.Settings.ClientAddress = 0x10; } cl = new GXDLMSClient(true, GatewayServer.Settings.ClientAddress, addr, GatewayServer.Authentication, null, type); clients.Add(addr, cl); } else { cl = clients[addr]; } GXReplyData data = new GXReplyData(); GXReplyData notify = new GXReplyData(); GXDLMSMeter m = meters[addr]; //Send SNRM if needed. if (sr.Command == Command.Aarq && (type == InterfaceType.HDLC || type == InterfaceType.HdlcWithModeE)) { GXServerReply sr2 = new GXServerReply(cl.SNRMRequest()); m.HandleRequest(sr2); if (cl.GetData(sr2.Reply, data, notify)) { data.Clear(); notify.Clear(); } else { //If the meter doesn't reply. bb.Clear(); return; } } byte[][] frames = cl.CustomFrameRequest(Command.None, pdu); foreach (byte[] it in frames) { sr.Data = it; m.HandleRequest(sr); if (Trace > TraceLevel.Info) { Console.WriteLine("RX:\t" + Gurux.Common.GXCommon.ToHex(sr.Reply, true)); } data.RawPdu = true; if (cl.GetData(sr.Reply, data, notify)) { while (data.IsMoreData) { sr.Data = cl.ReceiverReady(data); m.HandleRequest(sr); if (Trace > TraceLevel.Info) { Console.WriteLine("RX:\t" + Gurux.Common.GXCommon.ToHex(sr.Reply, true)); } cl.GetData(sr.Reply, data, notify); } byte[] reply = sr.Reply; try { GXByteBuffer tmp = new GXByteBuffer(); tmp.Set(data.Data); GatewayServer.Gateway = sr.Gateway; reply = GatewayServer.CustomFrameRequest(Command.None, tmp); } finally { GatewayServer.Gateway = null; } if (Trace > TraceLevel.Info) { Console.WriteLine("TX:\t" + Gurux.Common.GXCommon.ToHex(reply, true)); } ((IGXMedia)sender).Send(reply, e.SenderInfo); } } } bb.Clear(); } } } catch (Exception ex) { if (!(ex is SocketException)) { Console.WriteLine(ex.Message); } } }