static public byte[] ReadReadout(IGXMedia media, string data, int wt) { ReceiveParameters <byte[]> p = new ReceiveParameters <byte[]>() { Eop = GetEops(), WaitTime = wt }; lock (media.Synchronous) { if (data != null) { media.Send(data, null); } do { if (!media.Receive(p)) { //There is no eop or CRC. break; } }while (p.Reply[p.Reply.Length - 1] != 0x3); //Read CRC if EOP is found. if (p.Reply[p.Reply.Length - 1] == 0x3) { p.Eop = null; p.Count = 1; if (!media.Receive(p)) { throw new Exception("Failed to receive reply from the device in given time."); } } } 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, GXReplyData reply) { if ((data == null || data.Length == 0) && !reply.IsStreaming()) { return; } GXReplyData notify = new GXReplyData(); reply.Error = 0; object eop = (byte)0x7E; //In network connection terminator is not used. if (client.InterfaceType == InterfaceType.WRAPPER && !parent.UseRemoteSerial) { eop = null; } ReceiveParameters <byte[]> p = new ReceiveParameters <byte[]>() { AllData = false, Eop = eop, Count = 5, WaitTime = parent.WaitTime * 1000, }; var answer = Send(data); GXByteBuffer rd = new GXByteBuffer(answer.Body); try { //Loop until whole COSEM packet is received. while (!client.GetData(rd, reply, notify)) { p.Reply = null; if (notify.Data.Size != 0) { // Handle notify. if (!notify.IsMoreData) { rd.Trim(); notify.Clear(); p.Eop = eop; } continue; } //If Eop is not set read one byte at time. if (p.Eop == null) { p.Count = client.GetFrameSize(rd); } rd.Set(p.Reply); } } catch (Exception ex) { throw ex; } if (reply.Error != 0) { throw new GXDLMSException(reply.Error); } }
/// <inheritdoc cref="IGXMedia.Receive"/> public bool Receive <T>(ReceiveParameters <T> args) { if (!IsOpen) { throw new InvalidOperationException("Media is closed."); } return(syncBase.Receive(args)); }
/// <summary> /// Try to find client and server address from the meter. /// </summary> private void DiscoverMeters(object sender, GXAsyncWork work, object[] parameters) { GXDLMSClient cl = new GXDLMSClient(true, 16, 1, Authentication.None, null, (InterfaceType)Settings.Default.PlcInterface); byte[] data = cl.Plc.DiscoverRequest(); ReceiveParameters <byte[]> p = new ReceiveParameters <byte[]>() { AllData = false, Count = 8, WaitTime = 10000, }; DateTime start = DateTime.Now; GXByteBuffer rd = new GXByteBuffer(); lock (media.Synchronous) { if (data != null) { media.Send(data, null); start = DateTime.Now; } GXReplyData reply = new GXReplyData(); rd = new GXByteBuffer(p.Reply); try { while (!work.IsCanceled) { p.Reply = null; //If Eop is not set read one byte at time. if (p.Eop == null) { p.Count = cl.GetFrameSize(rd); } if (!media.IsOpen) { throw new InvalidOperationException("Media is closed."); } if (!media.Receive(p)) { //It's OK if there is no reply. Read again continue; } rd.Position = 0; rd.Set(p.Reply); if (cl.GetData(rd, reply)) { List <GXDLMSPlcMeterInfo> list = cl.Plc.ParseDiscover(reply.Data, (UInt16)reply.TargetAddress, (UInt16)reply.SourceAddress); BeginInvoke(new AppendMeterEventHandler(OnAppendMeter), list); } } } catch (Exception) { //Throw original exception. throw; } } }
public static async Task Receive(ReceiveParameters param) { if (param.deviceName == null) { param.deviceName = Environment.MachineName; } try { using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { using (var sd = new ServiceDiscovery()) { var endPoint = new IPEndPoint(IPAddress.Any, 0); socket.Bind(endPoint); var port = ((IPEndPoint)socket.LocalEndPoint).Port; var serviceProfile = new ServiceProfile(param.deviceName, ADropDomainName, (ushort)port); sd.Advertise(serviceProfile); socket.Listen(1); var incoming = socket.Accept(); Console.WriteLine($"{incoming.RemoteEndPoint} connect, receiving metadata."); using (var receiver = new Receiver(incoming)) { var meta = receiver.ReadMetadata(); Console.WriteLine($"MetaInfo: {meta.FileInfos.Count()} files with type:\n{meta.FileInfos}"); receiver.SendAction(Proto.Action.Types.ActionType.Accepted); for (int i = 0; i < meta.FileInfos.Count(); i++) { var mimeType = meta.FileInfos[i].FileType; var result = await receiver.ReadFile(); if (mimeType == "text/plain") { Console.WriteLine($"received text: \n{Encoding.UTF8.GetString(result)}"); } else { var extension = MimeTypes.MimeTypeMap.GetExtension(mimeType) ?? ".dat"; File.WriteAllBytes($"{i}{extension}", result); } } } } return; } } catch (SocketException e) { Console.WriteLine(e); } return; }
/// <summary> /// Read table data from the meter. /// </summary> /// <remarks> /// With commmand R6 data can be read one row at the time and it is parsed on the fly. /// With other commands all data must first read before data can be parse. /// </remarks> /// <param name="media"></param> /// <param name="wt"></param> /// <param name="name"></param> /// <param name="start"></param> /// <param name="end"></param> /// <param name="level"></param> /// <returns></returns> public static object[][] ReadTable(Gurux.Common.IGXMedia media, int wt, string name, DateTime start, DateTime end, string parameters, int level, int count, out string[] columns) { columns = null; List <byte> reply = new List <byte>(); string header, frame; //Read CRC. ReceiveParameters <byte[]> crc = new ReceiveParameters <byte[]>() { Count = 1, WaitTime = wt }; List <byte> data = new List <byte>(); data.Add(1); data.AddRange(GenerateReadTable(name, start, end, parameters, level, count)); data.Add(3); data.Add(CalculateChecksum(data, 1, data.Count - 1)); lock (media.Synchronous) { do { List <byte> tmp = new List <byte>(SendData(media, data == null ? null : data.ToArray(), '\0', wt, true, level == 6, false)); data = null; if (level != 6 && tmp[tmp.Count - 1] == 0x3) { crc.Count = 1; if (!media.Receive(crc)) { throw new Exception("Failed to receive reply from the device in given time."); } tmp.AddRange(crc.Reply); } else if (level == 6) { if (GetPacket(tmp, true, out header, out frame) == null) { throw new Exception("Failed to receive reply from the device in given time."); } if (tmp[tmp.Count - 2] == 0x4) { //Send ACK if more data is left. data = new List <byte>(); data.Add(6); System.Threading.Thread.Sleep(200); } } reply.AddRange(tmp); }while (reply[reply.Count - 2] != 0x3); } int status = 0; DateTime tm = DateTime.MinValue; int add = 0; return(ParseTableData(reply.ToArray(), ref columns, ref status, ref tm, ref add, name)); }
/// <summary> /// Send IEC disconnect message. /// </summary> void DiscIEC() { ReceiveParameters <string> p = new ReceiveParameters <string>() { AllData = false, Eop = (byte)0x0A, WaitTime = parent.WaitTime * 1000 }; string data = (char)0x01 + "B0" + (char)0x03 + "\r\n"; media.Send(data, null); p.Count = 1; media.Receive(p); }
/// <summary> /// Send IEC disconnect message. /// </summary> private static void DiscIEC(Media media) { ReceiveParameters <string> p = new ReceiveParameters <string>() { AllData = false, Eop = (byte)0x0A, WaitTime = media.WaitTime * 1000 }; string data = (char)0x01 + "B0" + (char)0x03 + "\r\n"; media.Target.Send(data, null); p.Count = 1; media.Target.Receive(p); }
/// <summary> /// Disconnect. /// </summary> /// <param name="serial"></param> /// <param name="tryCount"></param> public static void Disconnect(IGXMedia media, int tryCount) { lock (media.Synchronous) { ReceiveParameters <byte[]> p = new ReceiveParameters <byte[]>() { Eop = GetEops(), WaitTime = 1000 }; List <byte> data = new List <byte>(); data.Add(0x01); data.Add((byte)'B'); data.Add((byte)'0'); data.Add(0x03); data.Add(CalculateChecksum(data, 1, data.Count - 1)); byte[] data1 = data.ToArray(); string header, frame; media.Send(data1, null); media.Receive(p); while (--tryCount > -1) { if (media.Receive(p)) { GetPacket(new List <byte>(p.Reply), false, out header, out frame); if (header == "B0") { break; } if (p.Reply.Length > 11) { p.Reply = null; } } media.Send(data1, null); } } }
private ReceiveMessageResponse ReceiveTestMessage() { var input = new ReceiveParameters { QueueUrl = queueURL, MaxNumberOfMessages = 1 }; var options = new ReceiveOptions { DeleteMessageAfterReceiving = true, VisibilityTimeout = 30, WaitTimeSeconds = 5 }; var awsOptions = new AWSOptions { AWSCredentials = SQS.GetBasicAWSCredentials(credParams), UseDefaultCredentials = false, Region = region }; return(SQS.ReceiveMessage(input, options, awsOptions, new System.Threading.CancellationToken()).Result); }
public bool Receive <T>(ReceiveParameters <T> args) { if (args.Eop == null && args.Count == 0 && !args.AllData) { throw new ArgumentException("Either Count or Eop must be set."); } int nSize = 0; byte[] terminator = null; if (args.Eop != null) { if (args.Eop is Array) { Array arr = args.Eop as Array; terminator = GXCommon.GetAsByteArray(arr.GetValue(0)); } else { terminator = GXCommon.GetAsByteArray(args.Eop); } nSize = terminator.Length; } int nMinSize = (int)Math.Max(args.Count, nSize); if (nMinSize == 0) { nMinSize = 1; } int waitTime = args.WaitTime; if (waitTime <= 0) { waitTime = -1; } //Wait until reply occurred. int nFound = -1; int LastBuffSize = 0; DateTime StartTime = DateTime.Now; bool retValue = true; do { if (waitTime == 0) { //If we do not want to read all data. if (!args.AllData) { return(false); } retValue = false; break; } if (waitTime != -1) { waitTime -= (int)(DateTime.Now - StartTime).TotalMilliseconds; StartTime = DateTime.Now; if (waitTime < 0) { waitTime = 0; } } bool received; lock (receivedSync) { received = !(LastBuffSize == receivedSize || receivedSize < nMinSize); } //Do not wait if there is data on the buffer... if (!received) { if (waitTime == -1) { received = receivedEvent.WaitOne(); } else { received = receivedEvent.WaitOne(waitTime); } if (!received && args.Eop == null) { lock (receivedSync) { received = !(LastBuffSize == receivedSize || receivedSize < nMinSize); } } } if (this.Exception != null) { Exception ex = this.Exception; this.Exception = null; throw ex; } //If timeout occurred. if (!received) { //If we do not want to read all data. if (!args.AllData) { return(false); } retValue = false; break; } lock (receivedSync) { LastBuffSize = receivedSize; //Read more data, if not enough if (receivedSize < nMinSize) { continue; } //If only byte count matters. if (nSize == 0) { nFound = args.Count; } else { int index = lastPosition != 0 && lastPosition < receivedSize ? lastPosition : args.Count; //If terminator found. if (args.Eop is Array) { foreach (object it in args.Eop as Array) { byte[] term = GXCommon.GetAsByteArray(it); if (term.Length != 1 && receivedSize - index < term.Length) { index = receivedSize - term.Length; } nFound = GXCommon.IndexOf(m_Received, term, index, receivedSize); if (nFound != -1) { break; } } } else { if (terminator.Length != 1 && receivedSize - index < terminator.Length) { index = receivedSize - terminator.Length; } nFound = GXCommon.IndexOf(m_Received, terminator, index, receivedSize); } lastPosition = receivedSize; if (nFound != -1) { nFound += terminator.Length; } } } }while (nFound == -1); if (nSize == 0) //If terminator is not given read only bytes that are needed. { nFound = args.Count; } if (args.AllData) //If all data is copied. { nFound = receivedSize; } if (nFound == 0) { retValue = false; } //Convert bytes to object. byte[] tmp = new byte[nFound]; lock (receivedSync) { Array.Copy(m_Received, tmp, nFound); } int readBytes = 0; object data = GXCommon.ByteArrayToObject(tmp, typeof(T), out readBytes); //Remove read data. receivedSize -= nFound; //Received size can go less than zero if we have received data and we try to read more. if (receivedSize < 0) { receivedSize = 0; } if (receivedSize != 0) { lock (receivedSync) { Array.Copy(m_Received, nFound, m_Received, 0, receivedSize); } } else { lastPosition = 0; } //Reset count after read. args.Count = 0; //Append data. int oldReplySize = 0; if (args.Reply == null) { args.Reply = (T)data; } else { if (args.Reply is Array) { Array oldArray = args.Reply as Array; Array newArray = data as Array; if (newArray == null) { throw new ArgumentException(); } oldReplySize = oldArray.Length; int len = oldArray.Length + newArray.Length; Array arr = (Array)Activator.CreateInstance(typeof(T), len); //Copy old values. Array.Copy(args.Reply as Array, arr, oldArray.Length); //Copy new values. Array.Copy(newArray, 0, arr, oldArray.Length, newArray.Length); object tmp2 = arr; args.Reply = (T)tmp2; } else if (args.Reply is string) { string str = args.Reply as string; str += (string)data; data = str; args.Reply = (T)data; } } return(retValue); }
static byte[] SendData(IGXMedia media, byte[] data, char baudRate, int wt, bool useCrcSend, bool useCrcReply, bool readAllDataOnce) { ReceiveParameters<byte[]> p = new ReceiveParameters<byte[]>() { Eop = GetEops(), WaitTime = wt }; lock (media.Synchronous) { if (data != null) { media.Send(data, null); if (baudRate != '\0' && media.MediaType == "Serial") { Gurux.Serial.GXSerial serial = media as Gurux.Serial.GXSerial; while (serial.BytesToWrite != 0) { System.Threading.Thread.Sleep(100); } System.Threading.Thread.Sleep(200); switch (baudRate) { case '0': serial.BaudRate = 300; break; case '1': case 'A': serial.BaudRate = 600; break; case '2': case 'B': serial.BaudRate = 1200; break; case '3': case 'C': serial.BaudRate = 2400; break; case '4': case 'D': serial.BaudRate = 4800; break; case '5': case 'E': serial.BaudRate = 9600; break; case '6': case 'F': serial.BaudRate = 19200; break; default: throw new Exception("Unknown baud rate."); } } } if (!media.Receive(p)) { throw new Exception("Failed to receive reply from the device in given time."); } List<byte> reply2 = new List<byte>(); reply2.AddRange(p.Reply); p.Reply = null; string header, frame; byte[] packet = null; if (useCrcSend && data != null) { while ((packet = GetPacket(reply2, false, out header, out frame)) == null) { p.Eop = null; p.Count = 1; if (!media.Receive(p)) { throw new Exception("Failed to receive reply from the device in given time."); } reply2.AddRange(p.Reply); p.Reply = null; } p.Eop = GetEops(); } else { for (int pos = 0; pos != reply2.Count; ++pos) { if (reply2[pos] == 0xA) { ++pos; packet = new byte[pos]; reply2.CopyTo(0, packet, 0, pos); break; } } } //Remove echo. if (data != null && EqualBytes(data, packet)) { reply2.RemoveRange(0, data.Length); if (useCrcReply && reply2.Count != 0)// && !(data != null && data[data.Length - 1] == 0xA)) { while (GetPacket(reply2, false, out header, out frame) == null) { p.Eop = null; p.Count = 1; if (!media.Receive(p)) { throw new Exception("Failed to receive reply from the device in given time."); } reply2.AddRange(p.Reply); p.Reply = null; } } else { if (GetPacket(reply2, false, out header, out frame) == null) { reply2.AddRange(SendData(media, null, baudRate, wt, useCrcSend, useCrcReply, readAllDataOnce)); } } //If there is more data available. if (readAllDataOnce && reply2[reply2.Count - 2] == 0x4) { reply2.AddRange(SendData(media, new byte[] { 6 }, '\0', wt, useCrcSend, useCrcReply, readAllDataOnce)); } return reply2.ToArray(); } if (useCrcReply && !(data != null && data[data.Length - 1] == 0xA)) { while (GetPacket(reply2, false, out header, out frame) == null) { p.Eop = null; p.Count = 1; if (!media.Receive(p)) { throw new Exception("Failed to receive reply from the device in given time."); } reply2.AddRange(p.Reply); p.Reply = null; } } return reply2.ToArray(); } }
void InitializeIEC() { GXManufacturer manufacturer = this.Parent.Manufacturers.FindByIdentification(Parent.Manufacturer); if (manufacturer == null) { throw new Exception("Unknown manufacturer " + Parent.Manufacturer); } GXSerial serial = Media as GXSerial; byte Terminator = (byte)0x0A; if (serial != null && Parent.StartProtocol == StartProtocolType.IEC) { serial.BaudRate = 300; serial.DataBits = 7; serial.Parity = Parity.Even; serial.StopBits = StopBits.One; } Media.Open(); //Query device information. if (Media != null && Parent.StartProtocol == StartProtocolType.IEC) { string data = "/?!\r\n"; if (this.Parent.HDLCAddressing == HDLCAddressType.SerialNumber) { data = "/?" + this.Parent.PhysicalAddress + "!\r\n"; } GXLogWriter.WriteLog("HDLC sending:" + data); ReceiveParameters <string> p = new ReceiveParameters <string>() { AllData = false, Eop = Terminator, WaitTime = Parent.WaitTime * 1000 }; lock (Media.Synchronous) { Media.Send(data, null); if (!Media.Receive(p)) { //Try to move away from mode E. try { this.ReadDLMSPacket(this.DisconnectRequest(), 1); } catch (Exception ex) { } data = (char)0x01 + "B0" + (char)0x03 + "\r\n"; Media.Send(data, null); p.Count = 1; Media.Receive(p); data = "Failed to receive reply from the device in given time."; GXLogWriter.WriteLog(data); throw new Exception(data); } //If echo is used. if (p.Reply == data) { p.Reply = null; if (!Media.Receive(p)) { //Try to move away from mode E. this.ReadDLMSPacket(this.DisconnectRequest(), 1); if (serial != null) { data = (char)0x01 + "B0" + (char)0x03 + "\r\n"; Media.Send(data, null); p.Count = 1; if (!Media.Receive(p)) { } serial.DtrEnable = serial.RtsEnable = false; serial.BaudRate = 9600; serial.DtrEnable = serial.RtsEnable = true; data = (char)0x01 + "B0" + (char)0x03 + "\r\n"; Media.Send(data, null); p.Count = 1; Media.Receive(p); } data = "Failed to receive reply from the device in given time."; GXLogWriter.WriteLog(data); throw new Exception(data); } } } GXLogWriter.WriteLog("HDLC received: " + p.Reply); if (p.Reply[0] != '/') { p.WaitTime = 100; Media.Receive(p); throw new Exception("Invalid responce."); } string manufactureID = p.Reply.Substring(1, 3); UpdateManufactureSettings(manufactureID); char baudrate = p.Reply[4]; int BaudRate = 0; switch (baudrate) { case '0': BaudRate = 300; break; case '1': BaudRate = 600; break; case '2': BaudRate = 1200; break; case '3': BaudRate = 2400; break; case '4': BaudRate = 4800; break; case '5': BaudRate = 9600; break; case '6': BaudRate = 19200; break; default: throw new Exception("Unknown baud rate."); } GXLogWriter.WriteLog("BaudRate is : " + BaudRate.ToString()); //Send ACK //Send Protocol control character byte controlCharacter = (byte)'2';// "2" HDLC protocol procedure (Mode E) //Send Baud rate character //Mode control character byte ModeControlCharacter = (byte)'2';//"2" //(HDLC protocol procedure) (Binary mode) //Set mode E. byte[] arr = new byte[] { 0x06, controlCharacter, (byte)baudrate, ModeControlCharacter, 13, 10 }; GXLogWriter.WriteLog("Moving to mode E.", arr); lock (Media.Synchronous) { Media.Send(arr, null); System.Threading.Thread.Sleep(500); serial.BaudRate = BaudRate; p.Reply = null; p.WaitTime = 100; //Note! All meters do not echo this. Media.Receive(p); if (p.Reply != null) { GXLogWriter.WriteLog("Received: " + p.Reply); } serial.Close(); serial.DataBits = 8; serial.Parity = Parity.None; serial.StopBits = StopBits.One; serial.Open(); System.Threading.Thread.Sleep(500); } } }
/// <summary> /// Read DLMS Data from the device. /// </summary> /// <param name="data">Data to send.</param> /// <returns>Received data.</returns> public void ReadDLMSPacket(byte[] data, GXReplyData reply) { if (data == null && !reply.IsStreaming()) { return; } reply.Error = 0; object eop = (byte)0x7E; //In network connection terminator is not used. if (Client.InterfaceType == InterfaceType.WRAPPER && Media is GXNet) { eop = null; } int pos = 0; bool succeeded = false; ReceiveParameters <byte[]> p = new ReceiveParameters <byte[]>() { Eop = eop, Count = 5, WaitTime = WaitTime, }; GXReplyData notify = new GXReplyData(); lock (Media.Synchronous) { while (!succeeded && pos != 3) { if (!reply.IsStreaming()) { WriteTrace(true, "TX:\t" + DateTime.Now.ToString("hh:mm:ss") + "\t" + GXCommon.ToHex(data, true)); Media.Send(data, null); } succeeded = Media.Receive(p); if (!succeeded) { if (++pos >= RetryCount) { throw new Exception("Failed to receive reply from the device in given time."); } //If Eop is not set read one byte at time. if (p.Eop == null) { p.Count = 1; } //Try to read again... System.Diagnostics.Debug.WriteLine("Data send failed. Try to resend " + pos.ToString() + "/3"); } } try { pos = 0; //Loop until whole COSEM packet is received. while (!Client.GetData(p.Reply, reply, notify)) { // If all data is received. if (notify.IsComplete && !notify.IsMoreData) { /* * try * { * if (GXNotifyListener.Parser != null) * { * GXAMIClient cl = new GXAMIClient(); * GXNotifyListener.Parser.Parse(Media.ToString(), notify.Value, cl.GetData, cl.SetData); * } * } * catch (Exception ex) * { * //TODO: Save error to the database. * } */ notify.Clear(); } //If Eop is not set read one byte at time. if (p.Eop == null) { p.Count = 1; } while (!Media.Receive(p)) { if (++pos >= RetryCount) { throw new Exception("Failed to receive reply from the device in given time."); } //If echo. if (p.Reply == null || p.Reply.Length == data.Length) { Media.Send(data, null); } //Try to read again... System.Diagnostics.Debug.WriteLine("Data send failed. Try to resend " + pos.ToString() + "/3"); } } } catch (Exception ex) { WriteTrace(false, "RX:\t" + DateTime.Now.ToString("hh:mm:ss") + "\t" + GXCommon.ToHex(p.Reply, true)); throw ex; } } WriteTrace(false, "RX:\t" + DateTime.Now.ToString("hh:mm:ss") + "\t" + GXCommon.ToHex(p.Reply, true)); if (reply.Error != 0) { if (reply.Error == (short)ErrorCode.Rejected) { Thread.Sleep(1000); ReadDLMSPacket(data, reply); } else { throw new GXDLMSException(reply.Error); } } }
/// <summary> /// Read DLMS Data from the device. /// </summary> /// <param name="data">Data to send.</param> /// <returns>Received data.</returns> public byte[] ReadDLMSPacket(byte[] data) { if (data == null) { return null; } object eop = (byte)0x7E; //In network connection terminator is not used. if (Client.InterfaceType == InterfaceType.Net && Media is GXNet) { eop = null; } int pos = 0; bool succeeded = false; ReceiveParameters<byte[]> p = new ReceiveParameters<byte[]>() { AllData = true, Eop = eop, Count = 5, WaitTime = WaitTime, }; lock (Media.Synchronous) { while (!succeeded && pos != 3) { WriteTrace("<- " + DateTime.Now.ToLongTimeString() + "\t" + GXCommon.ToHex(data, true)); Media.Send(data, null); succeeded = Media.Receive(p); if (!succeeded) { //If Eop is not set read one byte at time. if (p.Eop == null) { p.Count = 1; } //Try to read again... if (++pos != 3) { System.Diagnostics.Debug.WriteLine("Data send failed. Try to resend " + pos.ToString() + "/3"); continue; } throw new Exception("Failed to receive reply from the device in given time."); } } //Loop until whole Cosem packet is received. while (!Client.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 != 3) { System.Diagnostics.Debug.WriteLine("Data send failed. Try to resend " + pos.ToString() + "/3"); continue; } throw new Exception("Failed to receive reply from the device in given time."); } } } WriteTrace("-> " + DateTime.Now.ToLongTimeString() + "\t" + GXCommon.ToHex(p.Reply, true)); object errors = Client.CheckReplyErrors(data, p.Reply); if (errors != null) { object[,] arr = (object[,])errors; int error = (int)arr[0, 0]; throw new GXDLMSException(error); } return p.Reply; }
/// <summary> /// Initialize optical head. /// </summary> void InitializeOpticalHead() { if (Client.InterfaceType != InterfaceType.HdlcWithModeE) { return; } GXSerial serial = Media as GXSerial; byte Terminator = (byte)0x0A; Media.Open(); //Some meters need a little break. Thread.Sleep(1000); //Query device information. string data = "/?!\r\n"; if (Trace > TraceLevel.Info) { Console.WriteLine("IEC Sending:" + data); } ReceiveParameters <string> p = new ReceiveParameters <string>() { AllData = false, Eop = Terminator, WaitTime = WaitTime * 1000 }; lock (Media.Synchronous) { Media.Send(data, null); if (!Media.Receive(p)) { //Try to move away from mode E. try { Disconnect(); } catch (Exception) { } DiscIEC(); string str = "Failed to receive reply from the device in given time."; if (Trace > TraceLevel.Info) { Console.WriteLine(str); } Media.Send(data, null); if (!Media.Receive(p)) { throw new Exception(str); } } //If echo is used. if (p.Reply == data) { p.Reply = null; if (!Media.Receive(p)) { //Try to move away from mode E. GXReplyData reply = new GXReplyData(); Disconnect(); if (serial != null) { DiscIEC(); serial.DtrEnable = serial.RtsEnable = false; serial.BaudRate = 9600; serial.DtrEnable = serial.RtsEnable = true; DiscIEC(); } data = "Failed to receive reply from the device in given time."; if (Trace > TraceLevel.Info) { Console.WriteLine(data); } throw new Exception(data); } } } if (Trace > TraceLevel.Info) { Console.WriteLine("HDLC received: " + p.Reply); } if (p.Reply[0] != '/') { p.WaitTime = 100; Media.Receive(p); DiscIEC(); throw new Exception("Invalid responce."); } string manufactureID = p.Reply.Substring(1, 3); char baudrate = p.Reply[4]; int BaudRate = 0; switch (baudrate) { case '0': BaudRate = 300; break; case '1': BaudRate = 600; break; case '2': BaudRate = 1200; break; case '3': BaudRate = 2400; break; case '4': BaudRate = 4800; break; case '5': BaudRate = 9600; break; case '6': BaudRate = 19200; break; default: throw new Exception("Unknown baud rate."); } if (Trace > TraceLevel.Info) { Console.WriteLine("BaudRate is : " + BaudRate.ToString()); } //Send ACK //Send Protocol control character // "2" HDLC protocol procedure (Mode E) byte controlCharacter = (byte)'2'; //Send Baud rate character //Mode control character byte ModeControlCharacter = (byte)'2'; //"2" //(HDLC protocol procedure) (Binary mode) //Set mode E. byte[] arr = new byte[] { 0x06, controlCharacter, (byte)baudrate, ModeControlCharacter, 13, 10 }; if (Trace > TraceLevel.Info) { Console.WriteLine("Moving to mode E.", arr); } lock (Media.Synchronous) { p.Reply = null; Media.Send(arr, null); //Some meters need this sleep. Do not remove. Thread.Sleep(200); p.WaitTime = 2000; //Note! All meters do not echo this. Media.Receive(p); if (p.Reply != null) { if (Trace > TraceLevel.Info) { Console.WriteLine("Received: " + p.Reply); } } serial.BaudRate = BaudRate; serial.DataBits = 8; serial.Parity = Parity.None; serial.StopBits = StopBits.One; //Some meters need this sleep. Do not remove. Thread.Sleep(800); } }
void InitSerial() { GXSerial serial = Media as GXSerial; byte Terminator = (byte)0x0A; if (serial != null && InitializeIEC) { serial.BaudRate = 300; serial.DataBits = 7; serial.Parity = Parity.Even; serial.StopBits = StopBits.One; } Media.Open(); //Query device information. if (Media != null && InitializeIEC) { string data = "/?001!\r\n"; if (Trace) { Console.WriteLine("HDLC sending:" + data); } ReceiveParameters<string> p = new ReceiveParameters<string>() { Eop = Terminator, WaitTime = WaitTime }; lock (Media.Synchronous) { Media.Send(data, null); if (!Media.Receive(p)) { //Try to move away from mode E. throw new Exception("Failed to receive reply from the device in given time."); } //If echo is used. if (p.Reply == data) { p.Reply = null; if (!Media.Receive(p)) { //Try to move away from mode E. throw new Exception("Failed to receive reply from the device in given time."); } } } if (Trace) { Console.WriteLine("HDLC received: " + p.Reply); } if (p.Reply[0] != '/') { p.WaitTime = 100; Media.Receive(p); throw new Exception("Invalid responce."); } string manufactureID = p.Reply.Substring(1, 3); //UpdateManufactureSettings(manufactureID); char baudrate = p.Reply[4]; int BaudRate = 0; switch (baudrate) { case '0': BaudRate = 300; break; case '1': BaudRate = 600; break; case '2': BaudRate = 1200; break; case '3': BaudRate = 2400; break; case '4': BaudRate = 4800; break; case '5': BaudRate = 9600; break; case '6': BaudRate = 19200; break; default: throw new Exception("Unknown baud rate."); } Console.WriteLine("BaudRate is :", BaudRate.ToString()); //Send ACK //Send Protocol control character byte controlCharacter = (byte)'2';// "2" HDLC protocol procedure (Mode E) //Send Baudrate character //Mode control character byte ModeControlCharacter = (byte)'2';//"2" //(HDLC protocol procedure) (Binary mode) //Set mode E. byte[] arr = new byte[] { 0x06, controlCharacter, (byte)baudrate, ModeControlCharacter, 13, 10 }; if (Trace) { Console.WriteLine("Moving to mode E", BitConverter.ToString(arr)); } lock (Media.Synchronous) { Media.Send(arr, null); p.Reply = null; p.WaitTime = 500; if (!Media.Receive(p)) { //Try to move away from mode E. this.ReadDLMSPacket(m_Parser.DisconnectRequest()); throw new Exception("Failed to receive reply from the device in given time."); } } if (serial != null) { serial.BaudRate = BaudRate; serial.DataBits = 8; serial.Parity = Parity.None; serial.StopBits = StopBits.One; } } }
/// <summary> /// Read DLMS Data from the device. /// </summary> /// <param name="data">Data to send.</param> /// <returns>Received data.</returns> public byte[] ReadDLMSPacket(byte[] data) { if (data == null) { return(null); } object eop = (byte)0x7E; //In network connection terminator is not used. if (Client.InterfaceType == InterfaceType.Net && Media is GXNet) { eop = null; } int pos = 0; bool succeeded = false; ReceiveParameters <byte[]> p = new ReceiveParameters <byte[]>() { AllData = true, Eop = eop, Count = 5, WaitTime = WaitTime, }; lock (Media.Synchronous) { while (!succeeded && pos != 3) { WriteTrace("<- " + DateTime.Now.ToLongTimeString() + "\t" + GXCommon.ToHex(data, true)); Media.Send(data, null); succeeded = Media.Receive(p); if (!succeeded) { //If Eop is not set read one byte at time. if (p.Eop == null) { p.Count = 1; } //Try to read again... if (++pos != 3) { System.Diagnostics.Debug.WriteLine("Data send failed. Try to resend " + pos.ToString() + "/3"); continue; } throw new Exception("Failed to receive reply from the device in given time."); } } //Loop until whole Cosem packet is received. while (!Client.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 != 3) { System.Diagnostics.Debug.WriteLine("Data send failed. Try to resend " + pos.ToString() + "/3"); continue; } throw new Exception("Failed to receive reply from the device in given time."); } } } WriteTrace("-> " + DateTime.Now.ToLongTimeString() + "\t" + GXCommon.ToHex(p.Reply, true)); object errors = Client.CheckReplyErrors(data, p.Reply); if (errors != null) { object[,] arr = (object[, ])errors; int error = (int)arr[0, 0]; throw new GXDLMSException(error); } return(p.Reply); }
public override void ImportFromDevice(Control[] addinPages, GXDevice device, IGXMedia media) { media.Open(); GXMBusDevice dev = device as GXMBusDevice; object data; //Handshake ShortFrame sf = new ShortFrame(); sf.AddressField = dev.DeviceAddress; sf.ControlField = (byte)CFieldFunctions.SendSlaveInit; sf.CountChecksum(); data = sf.ToByteArray(); ReceiveParameters<byte[]> recParams = new ReceiveParameters<byte[]>() { Count = 1, Peek = false, WaitTime = device.WaitTime }; lock (media.Synchronous) { media.Send(data, null); if (!media.Receive(recParams)) { throw new Exception("Failed to receive reply from the device in given time."); } if (recParams.Reply.Length < 1 || recParams.Reply[0] != 0xE5) { throw new Exception("Handshake failed."); } bool morePacketsAvailable = false; byte fcb = 1; List<MBusRegister> items = new List<MBusRegister>(); do { sf = new ShortFrame(); sf.AddressField = dev.DeviceAddress; if (fcb == 1) { sf.ControlField = (byte)CFieldFunctions.RequestClass2Data; } else { sf.ControlField = (byte)CFieldFunctions.RequestClass2Data | (byte)CFieldRequest.FrameCountBit; } sf.CountChecksum(); recParams.AllData = true; recParams.Count = 1; recParams.Eop = (byte)0x16; recParams.Reply = null; int cnt = 0; //Some meters can't answer right a way. do { media.Send(sf.ToByteArray(), null); if (++cnt == 6) { throw new Exception("Failed to receive reply from the device in given time."); } } while (!media.Receive(recParams)); while (!VerifyReadReplyCheckSum(recParams.Reply)) { recParams.Count = 0; recParams.Reply = null; bool gotData = media.Receive(recParams); if (!gotData) { break; } } morePacketsAvailable = recParams.Reply.Length > 5 && (recParams.Reply[4] & 0x10) != 0; items.AddRange(ParseReadReply(recParams.Reply)); } while (morePacketsAvailable); GXMBusCategory defaultCategory = null; if ((defaultCategory = (GXMBusCategory)device.Categories.Find("Default")) == null) { defaultCategory = new GXMBusCategory(); defaultCategory.Name = "Default"; device.Categories.Add(defaultCategory); } for (int pos = 0; pos < items.Count; ++pos) { MBusRegister item = items[pos]; GXMBusProperty prop = new GXMBusProperty(); prop.Ordinal = pos; if (item.IsVariableData) { string name = item.MBusType; int len = name.IndexOf('_'); if (len != -1) { name = name.Substring(0, len); } name += " " + item.Function.ToString(); if (item.Tariff != 0) { name += " Tariff " + item.Tariff.ToString(); } prop.Name = name; prop.Unit = item.Unit; prop.DataLength = item.DataLength; item.Mask.Reverse(); prop.InfoMask = item.Mask.ToArray(); prop.Type = item.Type; if (item.MBusType.ToLower().Contains("date") || item.MBusType.ToLower().Contains("timepoint")) { prop.ValueType = typeof(DateTime); } else { prop.ValueType = typeof(string); } } else { prop.Name = item.MBusType; prop.Unit = item.Unit; prop.ValueType = typeof(string); prop.DataLength = 4; } prop.InfoBytes = item.InformationBytes.Reverse().ToArray(); defaultCategory.Properties.Add(prop); } } }
/// <summary> /// Read table data from the meter. /// </summary> /// <remarks> /// With commmand R6 data can be read one row at the time and it is parsed on the fly. /// With other commands all data must first read before data can be parse. /// </remarks> /// <param name="media"></param> /// <param name="wt"></param> /// <param name="name"></param> /// <param name="start"></param> /// <param name="end"></param> /// <param name="level"></param> /// <returns></returns> public static object[][] ReadTable(Gurux.Common.IGXMedia media, int wt, string name, DateTime start, DateTime end, string parameters, int level, int count, out string[] columns) { columns = null; List<byte> reply = new List<byte>(); string header, frame; //Read CRC. ReceiveParameters<byte[]> crc = new ReceiveParameters<byte[]>() { Count = 1, WaitTime = wt }; List<byte> data = new List<byte>(); data.Add(1); data.AddRange(GenerateReadTable(name, start, end, parameters, level, count)); data.Add(3); data.Add(CalculateChecksum(data, 1, data.Count - 1)); lock (media.Synchronous) { do { List<byte> tmp = new List<byte>(SendData(media, data == null ? null : data.ToArray(), '\0', wt, true, level == 6, false)); data = null; if (level != 6 && tmp[tmp.Count - 1] == 0x3) { crc.Count = 1; if (!media.Receive(crc)) { throw new Exception("Failed to receive reply from the device in given time."); } tmp.AddRange(crc.Reply); } else if (level == 6) { if (GetPacket(tmp, true, out header, out frame) == null) { throw new Exception("Failed to receive reply from the device in given time."); } if (tmp[tmp.Count - 2] == 0x4) { //Send ACK if more data is left. data = new List<byte>(); data.Add(6); System.Threading.Thread.Sleep(200); } } reply.AddRange(tmp); } while (reply[reply.Count - 2] != 0x3); } int status = 0; DateTime tm = DateTime.MinValue; int add = 0; return ParseTableData(reply.ToArray(), ref columns, ref status, ref tm, ref add, name); }
static byte[] SendData(IGXMedia media, byte[] data, char baudRate, int wt, bool useCrcSend, bool useCrcReply, bool readAllDataOnce) { ReceiveParameters <byte[]> p = new ReceiveParameters <byte[]>() { Eop = GetEops(), WaitTime = wt }; lock (media.Synchronous) { if (data != null) { media.Send(data, null); if (baudRate != '\0' && media.MediaType == "Serial") { Gurux.Serial.GXSerial serial = media as Gurux.Serial.GXSerial; while (serial.BytesToWrite != 0) { System.Threading.Thread.Sleep(100); } System.Threading.Thread.Sleep(200); switch (baudRate) { case '0': serial.BaudRate = 300; break; case '1': case 'A': serial.BaudRate = 600; break; case '2': case 'B': serial.BaudRate = 1200; break; case '3': case 'C': serial.BaudRate = 2400; break; case '4': case 'D': serial.BaudRate = 4800; break; case '5': case 'E': serial.BaudRate = 9600; break; case '6': case 'F': serial.BaudRate = 19200; break; default: throw new Exception("Unknown baud rate."); } } } if (!media.Receive(p)) { throw new Exception("Failed to receive reply from the device in given time."); } List <byte> reply2 = new List <byte>(); reply2.AddRange(p.Reply); p.Reply = null; string header, frame; byte[] packet = null; if (useCrcSend && data != null) { while ((packet = GetPacket(reply2, false, out header, out frame)) == null) { p.Eop = null; p.Count = 1; if (!media.Receive(p)) { throw new Exception("Failed to receive reply from the device in given time."); } reply2.AddRange(p.Reply); p.Reply = null; } p.Eop = GetEops(); } else { for (int pos = 0; pos != reply2.Count; ++pos) { if (reply2[pos] == 0xA) { ++pos; packet = new byte[pos]; reply2.CopyTo(0, packet, 0, pos); break; } } } //Remove echo. if (data != null && EqualBytes(data, packet)) { reply2.RemoveRange(0, data.Length); if (useCrcReply && reply2.Count != 0)// && !(data != null && data[data.Length - 1] == 0xA)) { while (GetPacket(reply2, false, out header, out frame) == null) { p.Eop = null; p.Count = 1; if (!media.Receive(p)) { throw new Exception("Failed to receive reply from the device in given time."); } reply2.AddRange(p.Reply); p.Reply = null; } } else { if (GetPacket(reply2, false, out header, out frame) == null) { reply2.AddRange(SendData(media, null, baudRate, wt, useCrcSend, useCrcReply, readAllDataOnce)); } } //If there is more data available. if (readAllDataOnce && reply2[reply2.Count - 2] == 0x4) { reply2.AddRange(SendData(media, new byte[] { 6 }, '\0', wt, useCrcSend, useCrcReply, readAllDataOnce)); } return(reply2.ToArray()); } if (useCrcReply && !(data != null && data[data.Length - 1] == 0xA)) { while (GetPacket(reply2, false, out header, out frame) == null) { p.Eop = null; p.Count = 1; if (!media.Receive(p)) { throw new Exception("Failed to receive reply from the device in given time."); } reply2.AddRange(p.Reply); p.Reply = null; } } return(reply2.ToArray()); } }
public void InitializeConnection() { if (!string.IsNullOrEmpty(parent.Manufacturer)) { UpdateManufactureSettings(parent.Manufacturer); } if (media is GXSerial) { GXLogWriter.WriteLog("Initializing serial connection."); InitSerial(); connectionStartTime = DateTime.Now; } else if (media is GXNet) { GXLogWriter.WriteLog("Initializing Network connection."); InitNet(); //Some Electricity meters need some time before first message can be send. System.Threading.Thread.Sleep(500); } else if (media is Gurux.Terminal.GXTerminal) { GXLogWriter.WriteLog("Initializing Terminal connection."); InitTerminal(); } else { throw new Exception("Unknown media type."); } try { GXReplyData reply = new GXReplyData(); byte[] data; data = SNRMRequest(); if (data != null) { GXLogWriter.WriteLog("Send SNRM request.", data); ReadDLMSPacket(data, 1, reply); GXLogWriter.WriteLog("Parsing UA reply.\r\n" + reply.Data.ToString()); //Has server accepted client. ParseUAResponse(reply.Data); GXLogWriter.WriteLog("Parsing UA reply succeeded."); } //Generate AARQ request. //Split requests to multiple packets if needed. //If password is used all data might not fit to one packet. foreach (byte[] it in AARQRequest()) { GXLogWriter.WriteLog("Send AARQ request", it); reply.Clear(); ReadDLMSPacket(it, reply); } GXLogWriter.WriteLog("Parsing AARE reply\r\n" + reply.Data.ToString()); try { //Parse reply. ParseAAREResponse(reply.Data); } catch (Exception Ex) { reply.Clear(); ReadDLMSPacket(DisconnectRequest(), 1, reply); throw Ex; } //If authentication is required. if (client.IsAuthenticationRequired) { foreach (byte[] it in client.GetApplicationAssociationRequest()) { GXLogWriter.WriteLog("Authenticating", it); reply.Clear(); ReadDLMSPacket(it, reply); } client.ParseApplicationAssociationResponse(reply.Data); } } catch (Exception ex) { if (media is GXSerial && parent.StartProtocol == StartProtocolType.IEC) { ReceiveParameters<string> p = new ReceiveParameters<string>() { Eop = (byte) 0xA, WaitTime = parent.WaitTime * 1000 }; lock (media.Synchronous) { string data = (char)0x01 + "B0" + (char)0x03 + "\r\n"; media.Send(data, null); media.Receive(p); } } throw ex; } GXLogWriter.WriteLog("Parsing AARE reply succeeded."); parent.KeepAliveStart(); }
void InitRead(object sender, GXPacket GXPacket) { LastNotifiedTransactionProgress = 0; parser = new Gurux.DLMS.GXDLMSClient(); GXDLMSDevice device = sender as GXDLMSDevice; parser.UseLogicalNameReferencing = device.UseLogicalNameReferencing; Gurux.Common.IGXMedia media = device.GXClient.Media as Gurux.Common.IGXMedia; SupportNetworkSpecificSettings = device.SupportNetworkSpecificSettings && media is GXNet; if (SupportNetworkSpecificSettings) { parser.InterfaceType = Gurux.DLMS.InterfaceType.Net; } else { media.Eop = (byte)0x7E; } if (device.Manufacturers == null) { device.Manufacturers = new GXManufacturerCollection(); GXManufacturerCollection.ReadManufacturerSettings(device.Manufacturers); } GXManufacturer man = device.Manufacturers.FindByIdentification(device.Identification); if (man == null) { throw new Exception("Unknown DLMS manufacturer type: " + device.Identification); } if (!string.IsNullOrEmpty(man.Extension)) { Type t = Type.GetType(man.Extension); Extension = Activator.CreateInstance(t) as IGXManufacturerExtension; } if (media is GXSerial && device.StartProtocol == StartProtocolType.IEC) { byte Terminator = 0xA; GXSerial serial = media as GXSerial; serial.Eop = Terminator; ReceiveParameters<string> p = new ReceiveParameters<string>() { Eop = Terminator, WaitTime = device.WaitTime * 1000 }; lock (media.Synchronous) { //Init IEC connection. This must done first with serial connections. string data = "/?!\r\n"; if (device.HDLCAddressing == HDLCAddressType.SerialNumber) { data = "/?" + device.SerialNumber + "!\r\n"; } media.Send(data, null); if (!media.Receive(p)) { //Try to move away from mode E. //TODO: this.ReadDLMSPacket(this.DisconnectRequest()); data = "Failed to receive reply from the device in given time."; GXLogWriter.WriteLog(data); throw new Exception(data); } //If echo is used. if (p.Reply == data) { p.Reply = null; if (!media.Receive(p)) { //Try to move away from mode E. //TODO: this.ReadDLMSPacket(this.DisconnectRequest()); data = "Failed to receive reply from the device in given time."; GXLogWriter.WriteLog(data); throw new Exception(data); } } } string manufactureID = p.Reply.Substring(1, 3); char baudrate = p.Reply[4]; int bitrate = 0; switch (baudrate) { case '0': bitrate = 300; break; case '1': bitrate = 600; break; case '2': bitrate = 1200; break; case '3': bitrate = 2400; break; case '4': bitrate = 4800; break; case '5': bitrate = 9600; break; case '6': bitrate = 19200; break; default: throw new Exception("Unknown baud rate."); } //Send ACK //Send Protocol control character byte controlCharacter = (byte)'2';// "2" HDLC protocol procedure (Mode E) //Send Baudrate character //Mode control character byte ModeControlCharacter = (byte)'2';//"2" //(HDLC protocol procedure) (Binary mode) //We are not receive anything. lock (media.Synchronous) { media.Send(new byte[] { 0x06, controlCharacter, (byte)baudrate, ModeControlCharacter, 0x8D, 0x0A }, null); System.Threading.Thread.Sleep(1000); serial.BaudRate = bitrate; ReceiveParameters<byte[]> args = new ReceiveParameters<byte[]>(); args.Eop = (byte)0x0A; args.WaitTime = 500; media.Receive(args); } serial.DataBits = 8; serial.Parity = System.IO.Ports.Parity.None; serial.StopBits = System.IO.Ports.StopBits.One; serial.ResetSynchronousBuffer(); serial.Eop = (byte)0x7E; } }
/// <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; } 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; } } GXLogWriter.WriteLog(null, p.Reply); if (parent.OnTrace != null) { parent.OnTrace(parent, "-> " + DateTime.Now.ToLongTimeString(), 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); } } }
internal byte[] ReadDLMSPacket(GXDLMSClient cosem, Gurux.Common.IGXMedia media, byte[] data, int wt) { if (data == null) { return null; } ReceiveParameters<byte[]> args = new ReceiveParameters<byte[]>() { Eop = (byte)0x7E, Count = 5, WaitTime = wt }; if (cosem.InterfaceType == InterfaceType.Net) { args.Eop = null; args.Count = 8; args.AllData = true; } int pos = 0; bool succeeded = false; lock (media.Synchronous) { media.Send(data, null); while (!succeeded && pos != 3) { succeeded = media.Receive(args); if (!succeeded) { //Try to read again... if (++pos != 3) { 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, (byte[])args.Reply); throw new Exception(err); } } //Loop until whole m_Cosem packet is received. while (!(succeeded = cosem.IsDLMSPacketComplete(args.Reply))) { if (!media.Receive(args)) { //Try to read again... if (++pos != 3) { System.Diagnostics.Debug.WriteLine("Data receive failed. Try to resend " + pos.ToString() + "/3"); continue; } string err = "Failed to receive reply from the device in given time."; GXLogWriter.WriteLog(err, (byte[])args.Reply); throw new Exception(err); } } } object[,] errors = cosem.CheckReplyErrors(data, args.Reply); if (errors != null) { int error = (int)errors[0, 0]; throw new GXDLMSException(error); } return args.Reply; }
/// <summary> /// Disconnect. /// </summary> /// <param name="serial"></param> /// <param name="tryCount"></param> public static void Disconnect(IGXMedia media, int tryCount) { lock (media.Synchronous) { ReceiveParameters<byte[]> p = new ReceiveParameters<byte[]>() { Eop = GetEops(), WaitTime = 1000 }; List<byte> data = new List<byte>(); data.Add(0x01); data.Add((byte)'B'); data.Add((byte)'0'); data.Add(0x03); data.Add(CalculateChecksum(data, 1, data.Count - 1)); byte[] data1 = data.ToArray(); string header, frame; media.Send(data1, null); media.Receive(p); while (--tryCount > -1) { if (media.Receive(p)) { GetPacket(new List<byte>(p.Reply), false, out header, out frame); if (header == "B0") { break; } if (p.Reply.Length > 11) { p.Reply = null; } } media.Send(data1, null); } } }
/// <summary> /// Import properties from the device. /// </summary> /// <param name="addinPages">Addin pages.</param> /// <param name="device">The target GXDevice to put imported items.</param> /// <param name="media">A media connection to the device.</param> /// <returns>True if there were no errors, otherwise false.</returns> public override void ImportFromDevice(Control[] addinPages, GXDevice device, IGXMedia media) { media.Open(); GXDLMSDevice Device = (GXDLMSDevice)device; int wt = Device.WaitTime; GXDLMSClient cosem = null; byte[] data, reply = null; IGXManufacturerExtension Extension = null; try { //Initialize connection. cosem = new GXDLMSClient(); cosem.UseLogicalNameReferencing = Device.UseLogicalNameReferencing; if (Device.Manufacturers == null) { Device.Manufacturers = new GXManufacturerCollection(); GXManufacturerCollection.ReadManufacturerSettings(Device.Manufacturers); } GXManufacturer man = Device.Manufacturers.FindByIdentification(Device.Identification); if (!string.IsNullOrEmpty(man.Extension)) { Type t = Type.GetType(man.Extension); Extension = Activator.CreateInstance(t) as IGXManufacturerExtension; } if (!Device.UseRemoteSerial && media is GXNet) //If media is network. { if (Device.SupportNetworkSpecificSettings) { cosem.InterfaceType = Gurux.DLMS.InterfaceType.Net; } } else if (media is GXSerial) //If media is serial. { byte terminator = 0xA; if (Device.StartProtocol == StartProtocolType.IEC) { GXSerial serial = media as GXSerial; serial.Eop = terminator; serial.Eop = terminator; //Init IEC connection. This must done first with serial connections. string str = "/?" + Device.SerialNumber + "!\r\n"; ReceiveParameters<string> args = new ReceiveParameters<string>() { Eop = terminator, WaitTime = wt }; lock (media.Synchronous) { media.Send(str, null); do { args.Reply = null; if (!media.Receive(args)) { throw new Exception("Failed to receive reply from the device in given time."); } } while (str == args.Reply);//Remove echo } string answer = args.Reply.ToString(); if (answer[0] != '/') { throw new Exception("Invalid responce."); } string manufactureID = answer.Substring(1, 3); char baudrate = answer[4]; if (baudrate == ' ') { baudrate = '5'; } int baudRate = 0; switch (baudrate) { case '0': baudRate = 300; break; case '1': baudRate = 600; break; case '2': baudRate = 1200; break; case '3': baudRate = 2400; break; case '4': baudRate = 4800; break; case '5': baudRate = 9600; break; case '6': baudRate = 19200; break; default: throw new Exception("Unknown baud rate."); } //Send ACK //Send Protocol control character byte controlCharacter = (byte)'2';// "2" HDLC protocol procedure (Mode E) //Send Baudrate character //Mode control character byte ModeControlCharacter = (byte)'2';//"2" //(HDLC protocol procedure) (Binary mode) //We are not receive anything. data = new byte[] { 0x06, controlCharacter, (byte)baudrate, ModeControlCharacter, 0x0D, 0x0A }; lock (media.Synchronous) { args.Reply = null; media.Send(data, null); //This is in standard. Do not remove sleep. //Some meters work without it, but some do not. System.Threading.Thread.Sleep(500); serial.BaudRate = baudRate; ReceiveParameters<byte[]> args2 = new ReceiveParameters<byte[]>() { Eop = terminator, WaitTime = 100 }; //If this fails, just read all data. if (!media.Receive(args2)) { //Read buffer. args2.AllData = true; args2.WaitTime = 1; media.Receive(args2); } serial.DataBits = 8; serial.Parity = Parity.None; serial.StopBits = StopBits.One; serial.DiscardInBuffer(); serial.DiscardOutBuffer(); serial.ResetSynchronousBuffer(); } } } media.Eop = (byte) 0x7E; cosem.Authentication = (Gurux.DLMS.Authentication)Device.Authentication; object clientAdd = null; if (cosem.Authentication == Authentication.None) { clientAdd = Device.ClientID; } else if (cosem.Authentication == Authentication.Low) { clientAdd = Device.ClientIDLow; } else if (cosem.Authentication == Authentication.High) { clientAdd = Device.ClientIDHigh; } if (!string.IsNullOrEmpty(Device.Password)) { cosem.Password = ASCIIEncoding.ASCII.GetBytes(Device.Password); } else { cosem.Password = null; } //If network media is used check is manufacturer supporting IEC 62056-47 if (!Device.UseRemoteSerial && media is GXNet && Device.SupportNetworkSpecificSettings) { cosem.InterfaceType = InterfaceType.Net; media.Eop = null; cosem.ClientID = Convert.ToUInt16(clientAdd); cosem.ServerID = Convert.ToUInt16(Device.PhysicalAddress); } else { if (Device.HDLCAddressing == HDLCAddressType.Custom) { cosem.ClientID = clientAdd; } else { cosem.ClientID = (byte)(Convert.ToByte(clientAdd) << 1 | 0x1); } if (Device.HDLCAddressing == HDLCAddressType.SerialNumber) { cosem.ServerID = GXManufacturer.CountServerAddress(Device.HDLCAddressing, Device.SNFormula, Convert.ToUInt32(Device.SerialNumber), Device.LogicalAddress); } else { cosem.ServerID = GXManufacturer.CountServerAddress(Device.HDLCAddressing, Device.SNFormula, Device.PhysicalAddress, Device.LogicalAddress); } } byte[] allData = null; data = cosem.SNRMRequest(); //General Network connection don't need SNRMRequest. if (data != null) { Trace("--- Initialize DLMS connection\r\n"); try { reply = ReadDLMSPacket(cosem, media, data, wt); } catch (Exception Ex) { throw new Exception("DLMS Initialize failed. " + Ex.Message); } //Has server accepted client. cosem.ParseUAResponse(reply); } Trace("Connecting\r\n"); media.ResetSynchronousBuffer(); try { foreach (byte[] it in cosem.AARQRequest(null)) { reply = ReadDLMSPacket(cosem, media, it, wt); } } catch (Exception Ex) { throw new Exception("DLMS AARQRequest failed. " + Ex.Message); } cosem.ParseAAREResponse(reply); //Now 1/5 or actions is done. Progress(1, 5); Trace("Read Objects\r\n"); try { allData = ReadDataBlock(cosem, media, cosem.GetObjectsRequest(), wt, 1); } catch (Exception Ex) { throw new Exception("DLMS AARQRequest failed. " + Ex.Message); } Trace("--- Parse Objects ---\r\n"); GXDLMSObjectCollection objs = cosem.ParseObjects((byte[])allData, true); allData = null; //Now we know exact number of read registers. Update progress bar again. int max = objs.Count; Trace("--- Read scalars ---\r\n"); //Now 2/5 or actions is done. Progress(2 * max, 5 * max); GXCategory dataItems = new GXCategory(); dataItems.Name = "Data Items"; GXCategory registers = new GXCategory(); registers.Name = "Registers"; Device.Categories.Add(dataItems); Device.Categories.Add(registers); int pos = 0; foreach (GXDLMSObject it in objs) { ++pos; //Skip association views. if (it.ObjectType == ObjectType.AssociationLogicalName || it.ObjectType == ObjectType.AssociationShortName) { continue; } if (it.ObjectType != ObjectType.ProfileGeneric) { object prop = UpdateData(media, Device, wt, cosem, man, it, dataItems, registers); //Read scaler and unit if (it.ObjectType == ObjectType.Register) { try { data = cosem.Read(it.Name, it.ObjectType, 3)[0]; allData = ReadDataBlock(cosem, media, data, wt, 2); cosem.UpdateValue(allData, it, 3); Gurux.DLMS.Objects.GXDLMSRegister item = it as Gurux.DLMS.Objects.GXDLMSRegister; GXDLMSRegister r = prop as GXDLMSRegister; r.Scaler = item.Scaler; r.Unit = item.Unit.ToString(); } //Ignore HW error and read next. catch (GXDLMSException) { continue; } catch (Exception Ex) { throw new Exception("DLMS Register Scaler and Unit read failed. " + Ex.Message); } } //Read scaler and unit else if (it.ObjectType == ObjectType.ExtendedRegister) { try { data = cosem.Read(it.Name, it.ObjectType, 3)[0]; allData = ReadDataBlock(cosem, media, data, wt, 2); cosem.UpdateValue(allData, it, 3); Gurux.DLMS.Objects.GXDLMSExtendedRegister item = it as Gurux.DLMS.Objects.GXDLMSExtendedRegister; GXDLMSCategory cat = prop as GXDLMSCategory; GXDLMSRegister r = cat.Properties[0] as GXDLMSRegister; r.Scaler = item.Scaler; r.Unit = item.Unit.ToString(); cat.Properties[1].SetValue(item.Scaler.ToString() + ", " + item.Unit.ToString(), true, PropertyStates.None); } //Ignore HW error and read next. catch (GXDLMSException) { continue; } catch (Exception Ex) { throw new Exception("DLMS Register Scaler and Unit read failed. " + Ex.Message); } } //Read scaler and unit else if (it.ObjectType == ObjectType.DemandRegister) { try { data = cosem.Read(it.Name, it.ObjectType, 3)[0]; allData = ReadDataBlock(cosem, media, data, wt, 2); cosem.UpdateValue(allData, it, 3); Gurux.DLMS.Objects.GXDLMSDemandRegister item = it as Gurux.DLMS.Objects.GXDLMSDemandRegister; GXDLMSCategory cat = prop as GXDLMSCategory; cat.Properties[2].SetValue(item.Scaler.ToString() + ", " + item.Unit.ToString(), true, PropertyStates.None); GXDLMSRegister r = cat.Properties[0] as GXDLMSRegister; r.Scaler = item.Scaler; r.Unit = item.Unit.ToString(); r = cat.Properties[1] as GXDLMSRegister; r.Scaler = item.Scaler; r.Unit = item.Unit.ToString(); } //Ignore HW error and read next. catch (GXDLMSException) { continue; } catch (Exception Ex) { throw new Exception("DLMS Register Scaler and Unit read failed. " + Ex.Message); } } } //Now 3/5 actions is done. double tmp = pos * max; tmp /= max; tmp += 2 * max; Progress((int) tmp , 5 * max); } //Now 3/5 actions is done. Progress(3 * max, 5 * max); Trace("--- Read Generic profiles ---\r\n"); GXDLMSObjectCollection pg = objs.GetObjects(ObjectType.ProfileGeneric); foreach (GXDLMSProfileGeneric it in pg) { try { allData = ReadDataBlock(cosem, media, cosem.Read(it.Name, it.ObjectType, 3)[0], wt, 3); cosem.UpdateValue(allData, it, 3); UpdateData(media, Device, wt, cosem, man, it, dataItems, registers); } //Ignore HW error and read next. catch (GXDLMSException) { continue; } catch (Exception Ex) { Trace("DLMS Generic Profile read failed. " + Ex.Message + Environment.NewLine); } } //Now 4/5 actions is done. Progress(4 * max, 5 * max); //Update IEC HDLC interval if found. GXDLMSObjectCollection objects = objs.GetObjects(ObjectType.IecHdlcSetup); if (objects.Count != 0) { allData = ReadDataBlock(cosem, media, cosem.Read(objects[0].Name, objects[0].ObjectType, 8)[0], wt, 5); //Minus 10 second. Device.Keepalive.Interval = (Convert.ToInt32(cosem.GetValue(allData)) - 10) * 1000; } //Now all actions are done. Progress(max, max); Trace("--- Succeeded ---\r\n"); } finally { if (cosem != null && media != null) { Trace("--- Disconnecting ---\r\n"); byte[] allData = null; if (cosem != null) { //Network standard don't need this. if (!(media is GXNet && Device.SupportNetworkSpecificSettings)) { try { reply = ReadDLMSPacket(cosem, media, cosem.DisconnectRequest(), wt); cosem.GetDataFromPacket(reply, ref allData); } catch (Exception Ex) { Trace("DisconnectRequest failed. " + Ex.Message); } } } if (media != null) { media.Close(); media = null; } Trace("--- Disconnected ---\r\n--- Done---\r\n"); } } }
/// <summary> /// Read DLMS Data from the device. /// </summary> /// <param name="data">Data to send.</param> /// <returns>Received data.</returns> public void ReadDLMSPacket(byte[] data, GXReplyData reply) { if (data == null && !reply.IsStreaming()) { return; } GXReplyData notify = new GXReplyData(); reply.Error = 0; object eop = (byte)0x7E; //In network connection terminator is not used. if (Client.InterfaceType == InterfaceType.WRAPPER) { eop = null; } int pos = 0; bool succeeded = false; ReceiveParameters <byte[]> p = new ReceiveParameters <byte[]>() { Eop = eop, WaitTime = WaitTime, }; if (eop == null) { p.Count = 8; } else { p.Count = 5; } GXByteBuffer rd = new GXByteBuffer(); lock (Media.Synchronous) { while (!succeeded && pos != 3) { if (!reply.IsStreaming()) { WriteTrace("TX:\t" + DateTime.Now.ToLongTimeString() + "\t" + GXCommon.ToHex(data, true)); Media.Send(data, null); } succeeded = Media.Receive(p); if (!succeeded) { if (++pos >= RetryCount) { throw new Exception("Failed to receive reply from the device in given time."); } //If Eop is not set read one byte at time. if (p.Eop == null) { p.Count = 1; } //Try to read again... System.Diagnostics.Debug.WriteLine("Data send failed. Try to resend " + pos.ToString() + "/3"); } } rd = new GXByteBuffer(p.Reply); try { pos = 0; //Loop until whole COSEM packet is received. while (!Client.GetData(rd, reply, notify)) { p.Reply = null; if (notify.IsComplete && notify.Data.Data != null) { //Handle notify. if (!notify.IsMoreData) { //Show received push message as XML. string xml; GXDLMSTranslator t = new GXDLMSTranslator(TranslatorOutputType.SimpleXml); t.DataToXml(notify.Data, out xml); Console.WriteLine(xml); notify.Clear(); continue; } } if (p.Eop == null) { p.Count = Client.GetFrameSize(rd); } while (!Media.Receive(p)) { if (++pos >= RetryCount) { throw new Exception("Failed to receive reply from the device in given time."); } //If echo. if (rd == null || rd.Size == data.Length) { Media.Send(data, null); } //Try to read again... System.Diagnostics.Debug.WriteLine("Data send failed. Try to resend " + pos.ToString() + "/3"); } rd.Set(p.Reply); } } catch (Exception ex) { WriteTrace("RX:\t" + DateTime.Now.ToLongTimeString() + "\t" + rd); throw ex; } } WriteTrace("RX:\t" + DateTime.Now.ToLongTimeString() + "\t" + rd); if (reply.Error != 0) { if (reply.Error == (short)ErrorCode.Rejected) { Thread.Sleep(1000); ReadDLMSPacket(data, reply); } else { throw new GXDLMSException(reply.Error); } } }
private static void InitializeIEC(TraceLevel trace, Media media) { GXSerial serial = (GXSerial)media.Target; serial.BaudRate = 300; serial.DataBits = 7; serial.Parity = Parity.Even; serial.StopBits = StopBits.One; byte Terminator = (byte)0x0A; //Some meters need a little break. Thread.Sleep(1000); //Query device information. string data = "/?!\r\n"; WriteLog(trace, "IEC Sending:" + data); if (media.WaitTime == 0) { media.WaitTime = 5; } ReceiveParameters <string> p = new ReceiveParameters <string>() { AllData = false, Eop = Terminator, WaitTime = media.WaitTime * 1000 }; lock (media.Target.Synchronous) { media.Target.Send(data, null); if (!media.Target.Receive(p)) { DiscIEC(media); string str = "Failed to receive reply from the device in given time."; WriteLog(trace, str); media.Target.Send(data, null); if (!media.Target.Receive(p)) { throw new Exception(str); } } //If echo is used. if (p.Reply == data) { p.Reply = null; if (!media.Target.Receive(p)) { data = "Failed to receive reply from the device in given time."; WriteLog(trace, data); throw new Exception(data); } } } WriteLog(trace, "IEC received: " + p.Reply); if (p.Reply[0] != '/') { p.WaitTime = 100; media.Target.Receive(p); throw new Exception("Invalid responce."); } string manufactureID = p.Reply.Substring(1, 3); char baudrate = p.Reply[4]; int BaudRate; switch (baudrate) { case '0': BaudRate = 300; break; case '1': BaudRate = 600; break; case '2': BaudRate = 1200; break; case '3': BaudRate = 2400; break; case '4': BaudRate = 4800; break; case '5': BaudRate = 9600; break; case '6': BaudRate = 19200; break; default: throw new Exception("Unknown baud rate."); } if (media.MaximumBaudRate != 0) { BaudRate = media.MaximumBaudRate; baudrate = GetIecBaudRate(BaudRate); WriteLog(trace, "Maximum BaudRate is set to : " + BaudRate.ToString()); } WriteLog(trace, "BaudRate is : " + BaudRate.ToString()); //Send ACK //Send Protocol control character // "2" HDLC protocol procedure (Mode E) byte controlCharacter = (byte)'2'; //Send Baud rate character //Mode control character byte ModeControlCharacter = (byte)'2'; //"2" //(HDLC protocol procedure) (Binary mode) //Set mode E. byte[] arr = new byte[] { 0x06, controlCharacter, (byte)baudrate, ModeControlCharacter, 13, 10 }; WriteLog(trace, "Moving to mode E. " + GXCommon.ToHex(arr)); lock (media.Target.Synchronous) { p.Reply = null; media.Target.Send(arr, null); p.WaitTime = 2000; //Note! All meters do not echo this. media.Target.Receive(p); if (p.Reply != null) { WriteLog(trace, "Received: " + p.Reply); } media.Target.Close(); serial.BaudRate = BaudRate; serial.DataBits = 8; serial.Parity = Parity.None; serial.StopBits = StopBits.One; serial.Open(); //Some meters need this sleep. Do not remove. Thread.Sleep(1000); } }
void InitSerial() { GXSerial serial = Media as GXSerial; byte Terminator = (byte)0x0A; if (serial != null && InitializeIEC) { serial.BaudRate = 300; serial.DataBits = 7; serial.Parity = Parity.Even; serial.StopBits = StopBits.One; } Media.Open(); //Query device information. if (Media != null && InitializeIEC) { string data = "/?!\r\n"; if (Trace) { Console.WriteLine("IEC sending:" + data); } ReceiveParameters<string> p = new ReceiveParameters<string>() { Eop = Terminator, WaitTime = WaitTime }; lock (Media.Synchronous) { WriteTrace("<- " + DateTime.Now.ToLongTimeString() + "\t" + GXCommon.ToHex(ASCIIEncoding.ASCII.GetBytes(data), true)); Media.Send(data, null); if (!Media.Receive(p)) { //Try to move away from mode E. try { ReadDLMSPacket(Client.DisconnectRequest()); } catch (Exception) { } data = (char)0x01 + "B0" + (char)0x03; Media.Send(data, null); p.Count = 1; if (!Media.Receive(p)) { } data = "Failed to receive reply from the device in given time."; Console.WriteLine(data); throw new Exception(data); } WriteTrace("-> " + DateTime.Now.ToLongTimeString() + "\t" + GXCommon.ToHex(ASCIIEncoding.ASCII.GetBytes(p.Reply), true)); //If echo is used. if (p.Reply == data) { p.Reply = null; if (!Media.Receive(p)) { //Try to move away from mode E. ReadDLMSPacket(Client.DisconnectRequest()); if (serial != null) { data = (char)0x01 + "B0" + (char)0x03; Media.Send(data, null); p.Count = 1; Media.Receive(p); serial.BaudRate = 9600; data = (char)0x01 + "B0" + (char)0x03 + "\r\n"; Media.Send(data, null); p.Count = 1; Media.Receive(p); } data = "Failed to receive reply from the device in given time."; Console.WriteLine(data); throw new Exception(data); } WriteTrace("-> " + DateTime.Now.ToLongTimeString() + "\t" + GXCommon.ToHex(ASCIIEncoding.ASCII.GetBytes(p.Reply), true)); } } Console.WriteLine("IEC received: " + p.Reply); if (p.Reply[0] != '/') { p.WaitTime = 100; Media.Receive(p); throw new Exception("Invalid responce."); } string manufactureID = p.Reply.Substring(1, 3); UpdateManufactureSettings(manufactureID); char baudrate = p.Reply[4]; int BaudRate = 0; switch (baudrate) { case '0': BaudRate = 300; break; case '1': BaudRate = 600; break; case '2': BaudRate = 1200; break; case '3': BaudRate = 2400; break; case '4': BaudRate = 4800; break; case '5': BaudRate = 9600; break; case '6': BaudRate = 19200; break; default: throw new Exception("Unknown baud rate."); } Console.WriteLine("BaudRate is : " + BaudRate.ToString()); //Send ACK //Send Protocol control character byte controlCharacter = (byte)'2';// "2" HDLC protocol procedure (Mode E) //Send Baudrate character //Mode control character byte ModeControlCharacter = (byte)'2';//"2" //(HDLC protocol procedure) (Binary mode) //Set mode E. byte[] arr = new byte[] { 0x06, controlCharacter, (byte)baudrate, ModeControlCharacter, 13, 10 }; Console.WriteLine("Moving to mode E.", arr); lock (Media.Synchronous) { WriteTrace("<- " + DateTime.Now.ToLongTimeString() + "\t" + GXCommon.ToHex(arr, true)); Media.Send(arr, null); p.Reply = null; if (!Media.Receive(p)) { //Try to move away from mode E. ReadDLMSPacket(Client.DisconnectRequest()); data = "Failed to receive reply from the device in given time."; Console.WriteLine(data); throw new Exception(data); } WriteTrace("-> " + DateTime.Now.ToLongTimeString() + "\t" + GXCommon.ToHex(ASCIIEncoding.ASCII.GetBytes(p.Reply), true)); Console.WriteLine("Received: " + p.Reply); if (serial != null) { serial.BaudRate = BaudRate; serial.DataBits = 8; serial.Parity = Parity.None; serial.StopBits = StopBits.One; System.Threading.Thread.Sleep(300); serial.ResetSynchronousBuffer(); } } } }
void InitializeIEC() { GXManufacturer manufacturer = this.parent.Manufacturers.FindByIdentification(parent.Manufacturer); if (manufacturer == null) { throw new Exception("Unknown manufacturer " + parent.Manufacturer); } GXSerial serial = media as GXSerial; byte Terminator = (byte)0x0A; media.Open(); //Query device information. if (media != null && parent.StartProtocol == StartProtocolType.IEC) { string data = "/?!\r\n"; if (this.parent.HDLCAddressing == HDLCAddressType.SerialNumber) { data = "/?" + this.parent.PhysicalAddress + "!\r\n"; } GXLogWriter.WriteLog("HDLC sending:" + data); ReceiveParameters<string> p = new ReceiveParameters<string>() { AllData = false, Eop = Terminator, WaitTime = parent.WaitTime * 1000 }; lock (media.Synchronous) { media.Send(data, null); if (!media.Receive(p)) { //Try to move away from mode E. try { GXReplyData reply = new GXReplyData(); this.ReadDLMSPacket(this.DisconnectRequest(), 1, reply); } catch (Exception) { } data = (char)0x01 + "B0" + (char)0x03 + "\r\n"; media.Send(data, null); p.Count = 1; media.Receive(p); data = "Failed to receive reply from the device in given time."; GXLogWriter.WriteLog(data); throw new Exception(data); } //If echo is used. if (p.Reply == data) { p.Reply = null; if (!media.Receive(p)) { //Try to move away from mode E. GXReplyData reply = new GXReplyData(); this.ReadDLMSPacket(this.DisconnectRequest(), 1, reply); if (serial != null) { data = (char)0x01 + "B0" + (char)0x03 + "\r\n"; media.Send(data, null); p.Count = 1; if (!media.Receive(p)) { } serial.DtrEnable = serial.RtsEnable = false; serial.BaudRate = 9600; serial.DtrEnable = serial.RtsEnable = true; data = (char)0x01 + "B0" + (char)0x03 + "\r\n"; media.Send(data, null); p.Count = 1; media.Receive(p); } data = "Failed to receive reply from the device in given time."; GXLogWriter.WriteLog(data); throw new Exception(data); } } } GXLogWriter.WriteLog("HDLC received: " + p.Reply); if (p.Reply[0] != '/') { p.WaitTime = 100; media.Receive(p); throw new Exception("Invalid responce."); } string manufactureID = p.Reply.Substring(1, 3); UpdateManufactureSettings(manufactureID); char baudrate = p.Reply[4]; int BaudRate = 0; switch (baudrate) { case '0': BaudRate = 300; break; case '1': BaudRate = 600; break; case '2': BaudRate = 1200; break; case '3': BaudRate = 2400; break; case '4': BaudRate = 4800; break; case '5': BaudRate = 9600; break; case '6': BaudRate = 19200; break; default: throw new Exception("Unknown baud rate."); } if (parent.MaximumBaudRate != 0) { BaudRate = parent.MaximumBaudRate; GXLogWriter.WriteLog("Maximum BaudRate is set to : " + BaudRate.ToString()); } GXLogWriter.WriteLog("BaudRate is : " + BaudRate.ToString()); //Send ACK //Send Protocol control character byte controlCharacter = (byte)'2';// "2" HDLC protocol procedure (Mode E) //Send Baud rate character //Mode control character byte ModeControlCharacter = (byte)'2';//"2" //(HDLC protocol procedure) (Binary mode) //Set mode E. byte[] arr = new byte[] { 0x06, controlCharacter, (byte)baudrate, ModeControlCharacter, 13, 10 }; GXLogWriter.WriteLog("Moving to mode E.", arr); lock (media.Synchronous) { media.Send(arr, null); System.Threading.Thread.Sleep(500); serial.BaudRate = BaudRate; p.Reply = null; p.WaitTime = 100; //Note! All meters do not echo this. media.Receive(p); if (p.Reply != null) { GXLogWriter.WriteLog("Received: " + p.Reply); } serial.Close(); serial.DataBits = 8; serial.Parity = Parity.None; serial.StopBits = StopBits.One; serial.Open(); } } }
/// <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); }
static public byte[] ReadReadout(IGXMedia media, string data, int wt) { ReceiveParameters<byte[]> p = new ReceiveParameters<byte[]>() { Eop = GetEops(), WaitTime = wt }; lock (media.Synchronous) { if (data != null) { media.Send(data, null); } do { if (!media.Receive(p)) { //There is no eop or CRC. break; } } while (p.Reply[p.Reply.Length - 1] != 0x3); //Read CRC if EOP is found. if (p.Reply[p.Reply.Length - 1] == 0x3) { p.Eop = null; p.Count = 1; if (!media.Receive(p)) { throw new Exception("Failed to receive reply from the device in given time."); } } } return p.Reply; }
public void InitializeConnection() { if (!string.IsNullOrEmpty(Parent.Manufacturer)) { UpdateManufactureSettings(Parent.Manufacturer); } if (Media is GXSerial) { GXLogWriter.WriteLog("Initializing serial connection."); InitSerial(); ConnectionStartTime = DateTime.Now; } else if (Media is GXNet) { GXLogWriter.WriteLog("Initializing Network connection."); InitNet(); //Some Electricity meters need some time before first message can be send. System.Threading.Thread.Sleep(500); } else if (Media is Gurux.Terminal.GXTerminal) { GXLogWriter.WriteLog("Initializing Terminal connection."); InitTerminal(); } else { throw new Exception("Unknown media type."); } try { byte[] data, reply = null; data = SNRMRequest(); if (data != null) { GXLogWriter.WriteLog("Send SNRM request.", data); reply = ReadDLMSPacket(data, 1); GXLogWriter.WriteLog("Parsing UA reply.", reply); //Has server accepted client. ParseUAResponse(reply); GXLogWriter.WriteLog("Parsing UA reply succeeded."); } //Generate AARQ request. //Split requests to multiple packets if needed. //If password is used all data might not fit to one packet. foreach (byte[] it in AARQRequest()) { GXLogWriter.WriteLog("Send AARQ request", it); reply = ReadDLMSPacket(it); } GXLogWriter.WriteLog("Parsing AARE reply", (byte[])reply); try { //Parse reply. ParseAAREResponse(reply); } catch (Exception Ex) { ReadDLMSPacket(DisconnectRequest(), 1); throw Ex; } //If authentication is required. if (m_Cosem.IsAuthenticationRequired) { foreach (byte[] it in m_Cosem.GetApplicationAssociationRequest()) { GXLogWriter.WriteLog("Authenticating", it); reply = ReadDLMSPacket(it); } m_Cosem.ParseApplicationAssociationResponse(reply); } } catch (Exception ex) { if (Media is GXSerial && Parent.StartProtocol == StartProtocolType.IEC) { ReceiveParameters <string> p = new ReceiveParameters <string>() { Eop = (byte)0xA, WaitTime = Parent.WaitTime * 1000 }; lock (Media.Synchronous) { string data = (char)0x01 + "B0" + (char)0x03 + "\r\n"; Media.Send(data, null); Media.Receive(p); } } throw ex; } GXLogWriter.WriteLog("Parsing AARE reply succeeded."); Parent.KeepAliveStart(); }
/// <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; }
private void Readout(object sender, GXPacket packet) { GXMBusDevice device = (GXMBusDevice)GetDeviceFromSender(sender); IGXMedia media = (IGXMedia)device.GXClient.Media; bool isSerial = device.GXClient.MediaType == "Serial"; if (isSerial) { ((Gurux.Serial.GXSerial)media).BaudRate = 2400; ((Gurux.Serial.GXSerial)media).DataBits = 8; ((Gurux.Serial.GXSerial)media).Parity = System.IO.Ports.Parity.Even; ((Gurux.Serial.GXSerial)media).StopBits = System.IO.Ports.StopBits.One; } List<byte> buff = new List<byte>(new byte[] {0x10, 0x40, device.DeviceAddress}); buff.Add(CountShortFrameChecksum(buff.ToArray())); buff.Add(0x16); ReceiveParameters<byte[]> recParams = new ReceiveParameters<byte[]>(); lock (media.Synchronous) { recParams.AllData = true; recParams.Count = 1; recParams.Peek = false; recParams.Eop = null; recParams.Reply = null; recParams.WaitTime = device.WaitTime; media.Send(buff.ToArray(), null); if (!media.Receive(recParams)) { throw new Exception("Handshake timeout."); } } System.Threading.Thread.Sleep(2000); if (!(recParams.Reply.Length > 0 && recParams.Reply[0] == 0xE5)) { throw new Exception("Invalid handshake response."); } packet.Bop = (byte)0x10; packet.Eop = (byte)0x16; packet.ChecksumSettings.Position = -2; packet.ChecksumSettings.Type = ChecksumType.Sum8Bit; packet.ChecksumSettings.Start = 1; packet.ChecksumSettings.Count = -2; packet.AppendData((byte)0x5B); packet.AppendData(device.DeviceAddress); m_PreviousFCB = -1; }
public override void ImportFromDevice(Control[] addinPages, GXDevice device, Gurux.Common.IGXMedia media) { media.Eop = device.GXClient.Eop; GXDLT645Device dev = device as GXDLT645Device; dev.Parser.IgnoreFrame = false; Dictionary<ulong, object> items = GXDLT645Property.ReadDataID(); GXCategory cat = device.Categories.Find("Default"); if (cat == null) { cat = new GXCategory("Default"); device.Categories.Add(cat); } media.Open(); int count = 0; foreach (var it in items) { Progress(++count, items.Count); byte[] data = dev.Parser.ReadValue(it.Key); lock (media.Synchronous) { media.Send(data, null); ReceiveParameters<byte[]> p = new ReceiveParameters<byte[]>() { Eop = media.Eop, WaitTime = device.WaitTime }; bool compleate = false; try { while (!(compleate = dev.Parser.IsPacketComplete(it.Key, p.Reply))) { if (!media.Receive<byte[]>(p)) { break; } } } catch (Exception ex) { Trace(ex.Message + Environment.NewLine); } // If data is not received or error has occurred. if (!compleate || dev.Parser.IsError(p.Reply)) { continue; } GXDLT645Data d = it.Value as GXDLT645Data; if (d != null) { Trace(it.Key + " " + d.Name + Environment.NewLine); cat.Properties.Add(new GXDLT645Property(it.Key, d.Name, d.Type, d.Access)); } else { GXDLT645TableTemplate t = it.Value as GXDLT645TableTemplate; Trace(it.Key + " " + t.Name + Environment.NewLine); GXDLT645Table table = new GXDLT645Table(); table.Name = t.Name; table.DataID = it.Key; foreach (GXDLT645Data col in t.Columns) { table.Columns.Add(new GXDLT645Property(it.Key, col.Name, col.Type, col.Access)); } device.Tables.Add(table); } } } }
private void StartWithIec() { //Query device information. GXSerial serial = Media as GXSerial; if (serial == null) { return; } if (UseIec) { serial.BaudRate = 300; serial.DataBits = 7; serial.Parity = System.IO.Ports.Parity.Even; serial.StopBits = System.IO.Ports.StopBits.One; } else { serial.BaudRate = 9600; serial.DataBits = 8; serial.Parity = System.IO.Ports.Parity.None; serial.StopBits = System.IO.Ports.StopBits.One; } byte Terminator = (byte)0x0A; string data = "/?!\r\n"; if (Trace > TraceLevel.Info) { Console.WriteLine("IEC sending:" + data); } ReceiveParameters <string> p = new ReceiveParameters <string>() { Eop = Terminator, WaitTime = WaitTime }; lock (Media.Synchronous) { WriteTrace("<- " + DateTime.Now.ToLongTimeString() + "\t" + GXCommon.ToHex(ASCIIEncoding.ASCII.GetBytes(data), true)); Media.Send(data, null); if (!Media.Receive(p)) { //Try to move away from mode E. try { GXReplyData reply = new GXReplyData(); ReadDLMSPacket(Client.DisconnectRequest(), reply); } catch (Exception) { } data = (char)0x01 + "B0" + (char)0x03; Media.Send(data, null); p.Count = 1; if (!Media.Receive(p)) { } data = "Failed to receive reply from the device in given time."; Console.WriteLine(data); throw new Exception(data); } WriteTrace("-> " + DateTime.Now.ToLongTimeString() + "\t" + GXCommon.ToHex(ASCIIEncoding.ASCII.GetBytes(p.Reply), true)); //If echo is used. if (p.Reply == data) { p.Reply = null; if (!Media.Receive(p)) { //Try to move away from mode E. GXReplyData reply = new GXReplyData(); ReadDLMSPacket(Client.DisconnectRequest(), reply); if (serial != null) { data = (char)0x01 + "B0" + (char)0x03; Media.Send(data, null); p.Count = 1; Media.Receive(p); serial.BaudRate = 9600; data = (char)0x01 + "B0" + (char)0x03 + "\r\n"; Media.Send(data, null); p.Count = 1; Media.Receive(p); } data = "Failed to receive reply from the device in given time."; Console.WriteLine(data); throw new Exception(data); } WriteTrace("-> " + DateTime.Now.ToLongTimeString() + "\t" + GXCommon.ToHex(ASCIIEncoding.ASCII.GetBytes(p.Reply), true)); } } Console.WriteLine("IEC received: " + p.Reply); if (p.Reply[0] != '/') { p.WaitTime = 100; Media.Receive(p); throw new Exception("Invalid responce."); } string manufactureID = p.Reply.Substring(1, 3); char baudrate = p.Reply[4]; int BaudRate = 0; switch (baudrate) { case '0': BaudRate = 300; break; case '1': BaudRate = 600; break; case '2': BaudRate = 1200; break; case '3': BaudRate = 2400; break; case '4': BaudRate = 4800; break; case '5': BaudRate = 9600; break; case '6': BaudRate = 19200; break; default: throw new Exception("Unknown baud rate."); } Console.WriteLine("BaudRate is : " + BaudRate.ToString()); //Send ACK //Send Protocol control character byte controlCharacter = (byte)'2'; // "2" HDLC protocol procedure (Mode E) //Send Baudrate character //Mode control character byte ModeControlCharacter = (byte)'2'; //"2" //(HDLC protocol procedure) (Binary mode) //Set mode E. byte[] arr = new byte[] { 0x06, controlCharacter, (byte)baudrate, ModeControlCharacter, 13, 10 }; Console.WriteLine("Moving to mode E.", arr); lock (Media.Synchronous) { WriteTrace("<- " + DateTime.Now.ToLongTimeString() + "\t" + GXCommon.ToHex(arr, true)); Media.Send(arr, null); p.Reply = null; p.WaitTime = 2000; //Note! All meters do not echo this. Media.Receive(p); if (p.Reply != null) { WriteTrace("-> " + DateTime.Now.ToLongTimeString() + "\t" + GXCommon.ToHex(ASCIIEncoding.ASCII.GetBytes(p.Reply), true)); Console.WriteLine("Received: " + p.Reply); } if (serial != null) { Media.Close(); serial.BaudRate = BaudRate; serial.DataBits = 8; serial.Parity = Parity.None; serial.StopBits = StopBits.One; Media.Open(); //Some meters need this sleep. Do not remove. Thread.Sleep(1000); } } }
/// <summary> /// Read DLMS Data from the device. /// </summary> /// <param name="data">Data to send.</param> /// <returns>Received data.</returns> public void ReadDLMSPacket(byte[] data, GXReplyData reply) { if (data == null) { return; } reply.Error = 0; object eop = (byte)0x7E; //In network connection terminator is not used. if (Client.InterfaceType == InterfaceType.WRAPPER && Media is GXNet) { eop = null; } int pos = 0; bool succeeded = false; ReceiveParameters<byte[]> p = new ReceiveParameters<byte[]>() { Eop = eop, Count = 5, WaitTime = WaitTime, }; lock (Media.Synchronous) { while (!succeeded && pos != 3) { WriteTrace("<- " + DateTime.Now.ToLongTimeString() + "\t" + GXCommon.ToHex(data, true)); Media.Send(data, null); succeeded = Media.Receive(p); if (!succeeded) { //If Eop is not set read one byte at time. if (p.Eop == null) { p.Count = 1; } //Try to read again... if (++pos != 3) { System.Diagnostics.Debug.WriteLine("Data send failed. Try to resend " + pos.ToString() + "/3"); continue; } throw new Exception("Failed to receive reply from the device in given time."); } } 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; } while (!Media.Receive(p)) { //If echo. if (p.Reply.Length == data.Length) { Media.Send(data, null); } //Try to read again... if (++pos != 3) { System.Diagnostics.Debug.WriteLine("Data send failed. Try to resend " + pos.ToString() + "/3"); continue; } throw new Exception("Failed to receive reply from the device in given time."); } } } catch (Exception ex) { WriteTrace("-> " + DateTime.Now.ToLongTimeString() + "\t" + GXCommon.ToHex(p.Reply, true)); throw ex; } } WriteTrace("-> " + DateTime.Now.ToLongTimeString() + "\t" + GXCommon.ToHex(p.Reply, true)); if (reply.Error != 0) { if (reply.Error == (short)ErrorCode.Rejected) { Thread.Sleep(1000); ReadDLMSPacket(data, reply); } else { throw new GXDLMSException(reply.Error); } } }
/// <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; } 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; } } GXLogWriter.WriteLog("Received data", 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); } } }
public void InitializeConnection() { if (!string.IsNullOrEmpty(parent.Manufacturer)) { UpdateManufactureSettings(parent.Manufacturer); } if (media is GXSerial) { GXLogWriter.WriteLog("Initializing serial connection."); InitSerial(); connectionStartTime = DateTime.Now; } else if (media is GXNet) { GXLogWriter.WriteLog("Initializing Network connection."); InitNet(); //Some Electricity meters need some time before first message can be send. System.Threading.Thread.Sleep(500); } else if (media is Gurux.Terminal.GXTerminal) { GXLogWriter.WriteLog("Initializing Terminal connection."); InitTerminal(); } else { media.Open(); } try { GXReplyData reply = new GXReplyData(); byte[] data; client.Limits.WindowSizeRX = parent.WindowSizeRX; client.Limits.WindowSizeTX = parent.WindowSizeTX; client.Limits.MaxInfoRX = parent.MaxInfoRX; client.Limits.MaxInfoTX = parent.MaxInfoTX; client.MaxReceivePDUSize = parent.PduSize; client.Priority = parent.Priority; client.ServiceClass = parent.ServiceClass; data = SNRMRequest(); if (data != null) { ReadDataBlock(data, "Send SNRM request.", reply); GXLogWriter.WriteLog("Parsing UA reply succeeded."); //Has server accepted client. ParseUAResponse(reply.Data); } //Generate AARQ request. //Split requests to multiple packets if needed. //If password is used all data might not fit to one packet. reply.Clear(); ReadDataBlock(AARQRequest(), "Send AARQ request.", reply); try { //Parse reply. ParseAAREResponse(reply.Data); GXLogWriter.WriteLog("Parsing AARE reply succeeded."); } catch (Exception Ex) { reply.Clear(); ReadDLMSPacket(DisconnectRequest(), 1, reply); throw Ex; } //If authentication is required. if (client.Authentication > Authentication.Low) { foreach (byte[] it in client.GetApplicationAssociationRequest()) { GXLogWriter.WriteLog("Authenticating", it); reply.Clear(); ReadDLMSPacket(it, reply); } client.ParseApplicationAssociationResponse(reply.Data); } } catch (Exception ex) { if (media is GXSerial && parent.StartProtocol == StartProtocolType.IEC) { ReceiveParameters <string> p = new ReceiveParameters <string>() { Eop = (byte)0xA, WaitTime = parent.WaitTime * 1000 }; lock (media.Synchronous) { string data = (char)0x01 + "B0" + (char)0x03 + "\r\n"; media.Send(data, null); media.Receive(p); } } throw ex; } parent.KeepAliveStart(); }
/// <summary> /// Read DLMS Data from the device. /// </summary> /// <param name="data">Data to send.</param> /// <returns>Received data.</returns> public void ReadDLMSPacket(byte[] data, GXReplyData reply) { if (data == null) { return; } reply.Error = 0; object eop = (byte)0x7E; //In network connection terminator is not used. if (Client.InterfaceType == InterfaceType.WRAPPER && Media is GXNet) { eop = null; } int pos = 0; bool succeeded = false; ReceiveParameters <byte[]> p = new ReceiveParameters <byte[]>() { Eop = eop, Count = 5, WaitTime = WaitTime, }; lock (Media.Synchronous) { while (!succeeded && pos != 3) { WriteTrace("<- " + DateTime.Now.ToLongTimeString() + "\t" + GXCommon.ToHex(data, true)); Media.Send(data, null); succeeded = Media.Receive(p); if (!succeeded) { //If Eop is not set read one byte at time. if (p.Eop == null) { p.Count = 1; } //Try to read again... if (++pos != 3) { System.Diagnostics.Debug.WriteLine("Data send failed. Try to resend " + pos.ToString() + "/3"); continue; } throw new Exception("Failed to receive reply from the device in given time."); } } 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; } while (!Media.Receive(p)) { //If echo. if (p.Reply.Length == data.Length) { Media.Send(data, null); } //Try to read again... if (++pos != 3) { System.Diagnostics.Debug.WriteLine("Data send failed. Try to resend " + pos.ToString() + "/3"); continue; } throw new Exception("Failed to receive reply from the device in given time."); } } } catch (Exception ex) { WriteTrace("-> " + DateTime.Now.ToLongTimeString() + "\t" + GXCommon.ToHex(p.Reply, true)); throw ex; } } WriteTrace("-> " + DateTime.Now.ToLongTimeString() + "\t" + GXCommon.ToHex(p.Reply, true)); if (reply.Error != 0) { if (reply.Error == (short)ErrorCode.Rejected) { Thread.Sleep(1000); ReadDLMSPacket(data, reply); } else { throw new GXDLMSException(reply.Error); } } }
void InitSerial() { GXSerial serial = Media as GXSerial; byte Terminator = (byte)0x0A; if (serial != null && InitializeIEC) { serial.BaudRate = 300; serial.DataBits = 7; serial.Parity = Parity.Even; serial.StopBits = StopBits.One; } Media.Open(); //Query device information. if (Media != null && InitializeIEC) { string data = "/?001!\r\n"; if (Trace) { Console.WriteLine("HDLC sending:" + data); } ReceiveParameters <string> p = new ReceiveParameters <string>() { Eop = Terminator, WaitTime = WaitTime }; lock (Media.Synchronous) { Media.Send(data, null); if (!Media.Receive(p)) { //Try to move away from mode E. throw new Exception("Failed to receive reply from the device in given time."); } //If echo is used. if (p.Reply == data) { p.Reply = null; if (!Media.Receive(p)) { //Try to move away from mode E. throw new Exception("Failed to receive reply from the device in given time."); } } } if (Trace) { Console.WriteLine("HDLC received: " + p.Reply); } if (p.Reply[0] != '/') { p.WaitTime = 100; Media.Receive(p); throw new Exception("Invalid responce."); } string manufactureID = p.Reply.Substring(1, 3); //UpdateManufactureSettings(manufactureID); char baudrate = p.Reply[4]; int BaudRate = 0; switch (baudrate) { case '0': BaudRate = 300; break; case '1': BaudRate = 600; break; case '2': BaudRate = 1200; break; case '3': BaudRate = 2400; break; case '4': BaudRate = 4800; break; case '5': BaudRate = 9600; break; case '6': BaudRate = 19200; break; default: throw new Exception("Unknown baud rate."); } Console.WriteLine("BaudRate is :", BaudRate.ToString()); //Send ACK //Send Protocol control character byte controlCharacter = (byte)'2';// "2" HDLC protocol procedure (Mode E) //Send Baudrate character //Mode control character byte ModeControlCharacter = (byte)'2';//"2" //(HDLC protocol procedure) (Binary mode) //Set mode E. byte[] arr = new byte[] { 0x06, controlCharacter, (byte)baudrate, ModeControlCharacter, 13, 10 }; if (Trace) { Console.WriteLine("Moving to mode E", BitConverter.ToString(arr)); } lock (Media.Synchronous) { Media.Send(arr, null); p.Reply = null; p.WaitTime = 500; if (!Media.Receive(p)) { //Try to move away from mode E. this.ReadDLMSPacket(m_Parser.DisconnectRequest()); throw new Exception("Failed to receive reply from the device in given time."); } } if (serial != null) { serial.BaudRate = BaudRate; serial.DataBits = 8; serial.Parity = Parity.None; serial.StopBits = StopBits.One; } } }