/// <summary> /// Client has send data. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void OnReceived(object sender, Gurux.Common.ReceiveEventArgs e) { try { lock (this) { //Show trace only for connected meters. if (Trace > TraceLevel.Info && this.ConnectionState != ConnectionState.None) { Console.WriteLine("RX:\t" + Gurux.Common.GXCommon.ToHex((byte[])e.Data, true)); } GXServerReply sr = new GXServerReply((byte[])e.Data); do { 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)); } Media.Send(sr.Reply, e.SenderInfo); sr.Data = null; } }while (sr.IsStreaming); } } catch (Exception ex) { if (!(ex is SocketException)) { Console.WriteLine(ex.Message); } } }
/// <summary> /// Read DLMS Data from the device. /// </summary> /// <remarks> /// If access is denied return null. /// </remarks> /// <param name="data">Data to send.</param> /// <returns>Received data.</returns> public byte[] ReadDLMSPacket(byte[] data, int tryCount) { if (data == null) { return(null); } object eop = (byte)0x7E; //In network connection terminator is not used. if (m_Cosem.InterfaceType == InterfaceType.Net && Media is GXNet && !Parent.UseRemoteSerial) { eop = null; } int pos = 0; bool succeeded = false; ReceiveParameters <byte[]> p = new ReceiveParameters <byte[]>() { AllData = false, Eop = eop, Count = 5, WaitTime = Parent.WaitTime * 1000, }; lock (Media.Synchronous) { if (data != null) { Media.Send(data, null); } while (!succeeded && pos != 3) { succeeded = Media.Receive(p); if (!succeeded) { //Try to read again... if (++pos != tryCount) { //If Eop is not set read one byte at time. if (p.Eop == null) { p.Count = 1; } System.Diagnostics.Debug.WriteLine("Data send failed. Try to resend " + pos.ToString() + "/3"); Media.Send(data, null); continue; } string err = "Failed to receive reply from the device in given time."; GXLogWriter.WriteLog(err, p.Reply); throw new Exception(err); } } //Loop until whole COSEM packet is received. while (!m_Cosem.IsDLMSPacketComplete(p.Reply)) { //If Eop is not set read one byte at time. if (p.Eop == null) { p.Count = 1; } if (!Media.Receive(p)) { //Try to read again... if (++pos != tryCount) { System.Diagnostics.Debug.WriteLine("Data send failed. Try to resend " + pos.ToString() + "/3"); continue; } string err = "Failed to receive reply from the device in given time."; GXLogWriter.WriteLog(err, p.Reply); throw new Exception(err); } } } GXLogWriter.WriteLog("Received data", p.Reply); object errors = m_Cosem.CheckReplyErrors(data, p.Reply); if (errors != null) { object[,] arr = (object[, ])errors; int error = (int)arr[0, 0]; if (error == -1) { //If data is reply to the previous packet sent. //This might happens sometimes. if (m_Cosem.IsPreviousPacket(data, p.Reply)) { return(ReadDLMSPacket(null)); } else { throw new Exception(arr[0, 1].ToString()); } } throw new GXDLMSException(error); } return(p.Reply); }
/// <summary> /// Read DLMS Data from the device. /// </summary> /// <remarks> /// If access is denied return null. /// </remarks> /// <param name="data">Data to send.</param> /// <returns>Received data.</returns> public void ReadDLMSPacket(byte[] data, int tryCount, GXReplyData reply) { if (data == null) { return; } object eop = (byte)0x7E; //In network connection terminator is not used. if (client.InterfaceType == InterfaceType.WRAPPER && media is GXNet && !parent.UseRemoteSerial) { eop = null; } if (parent.OnTrace != null) { parent.OnTrace(parent, "<- " + DateTime.Now.ToLongTimeString() + " " + GXCommon.ToHex(data, true)); //if (data[data.Length - 1] == 0x7E && data[data.Length - 2] == 0xC5 && data[data.Length - 3] == 0x13) // data[data.Length - 1] = 0x7E; } int pos = 0; bool succeeded = false; ReceiveParameters <byte[]> p = new ReceiveParameters <byte[]>() { AllData = false, Eop = eop, Count = 5, WaitTime = parent.WaitTime * 1000, }; lock (media.Synchronous) { if (data != null) { media.Send(data, null); } while (!succeeded && pos != 3) { succeeded = media.Receive(p); if (!succeeded) { //Try to read again... if (++pos != tryCount) { //If Eop is not set read one byte at time. if (p.Eop == null) { p.Count = 1; } System.Diagnostics.Debug.WriteLine("Data send failed. Try to resend " + pos.ToString() + "/3"); media.Send(data, null); continue; } string err = "Failed to receive reply from the device in given time."; GXLogWriter.WriteLog(err, p.Reply); throw new Exception(err); } } try { //Loop until whole COSEM packet is received. while (!client.GetData(p.Reply, reply)) { //If Eop is not set read one byte at time. if (p.Eop == null) { p.Count = 1; } if (!media.Receive(p)) { //Try to read again... if (++pos != tryCount) { System.Diagnostics.Debug.WriteLine("Data send failed. Try to resend " + pos.ToString() + "/3"); continue; } string err = "Failed to receive reply from the device in given time."; GXLogWriter.WriteLog(err, p.Reply); throw new Exception(err); } } } catch (Exception ex) { GXLogWriter.WriteLog("Received data", p.Reply); throw ex; } } if (parent.OnTrace != null) { parent.OnTrace(parent, "-> " + DateTime.Now.ToLongTimeString() + " " + GXCommon.ToHex(p.Reply, true)); } GXLogWriter.WriteLog("Received data", p.Reply); cnt++; System.Diagnostics.Debug.Write(cnt.ToString()); System.Diagnostics.Debug.Write(" Received data "); System.Diagnostics.Debug.WriteLine(BitConverter.ToString(p.Reply)); if (reply.Error != 0) { if (reply.Error == (int)ErrorCode.Rejected) { Thread.Sleep(1000); ReadDLMSPacket(data, tryCount, reply); } else { throw new GXDLMSException(reply.Error); } } }