/// <summary> /// Sends the specified command to the Paradox PRT3 module. /// </summary> /// <param name="command">The command.</param> public void SendCommand(string command) { if (this.IsConnected) { try { // Write the command to the serial port and wait 10ms this.serialPort.WriteLine(command); Thread.Sleep(10); // Log obfuscation for PIN code if (command.StartsWith("AA") || command.StartsWith("AD")) { command = command.Substring(0, command.Length - 4) + "****"; } // Raise the MessageSent event if (this.MessageSent != null) { var message = new ParadoxMessageEventArgs() { Date = DateTime.Now, Message = command }; Delegate[] receivers = this.MessageSent.GetInvocationList(); foreach (EventHandler <ParadoxMessageEventArgs> receiver in receivers) { receiver.BeginInvoke(this, message, null, null); } } } catch (Exception ex) { if (this.InterfaceError != null) { this.InterfaceError(this, new InterfaceErrorEventArgs() { Exception = ex }); } this.IsConnected = false; } } else { throw new InvalidOperationException("The interface is not connected !"); } }
/// <summary> /// Handles when message is received from the PRT3 module. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="ParadoxMessageEventArgs"/> instance containing the raw message.</param> private void OnMessageReceived(object sender, ParadoxMessageEventArgs e) { // Find the message handler var eventToRaise = this.GetType().GetEvents() .Select(ev => new { Description = ev.GetCustomAttribute <DescriptionAttribute>(), EventInfo = ev }) .Where(ev => ev.Description != null && e.Message.StartsWith(ev.Description.Description) && ev.EventInfo != null) .Select(ev => new { EventName = ev.EventInfo.Name, EventArgsType = ev.EventInfo.EventHandlerType.GenericTypeArguments.FirstOrDefault() }) .SingleOrDefault(); // If the event exist if (eventToRaise != null && eventToRaise.EventArgsType != null) { try { // Process the message var eventArgs = (ParadoxBaseEventArgs)Activator.CreateInstance(eventToRaise.EventArgsType); eventArgs.ProcessMessage(e.Message); // Invoke handler(s) var eventDelegate = (MulticastDelegate)this.GetType().GetField(eventToRaise.EventName, BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this); if (eventDelegate != null) { foreach (var handler in eventDelegate.GetInvocationList()) { handler.Method.Invoke(handler.Target, new object[] { this, eventArgs }); } } } catch { } } }
/// <summary> /// Internal loop to read the serial port. /// </summary> private void ReadSerialPort() { while (this.IsConnected) { try { // If there is data to read if (this.serialPort.BytesToRead > 0) { // Read incoming datas to the string buffer byte[] buffer = new byte[this.serialPort.BytesToRead]; this.serialPort.Read(buffer, 0, this.serialPort.BytesToRead); this.strBuffer += ASCIIEncoding.ASCII.GetString(buffer); this.lastReceivedDatas = DateTime.Now; int nlIndex = -1; // Read each line from the string buffer while ((nlIndex = this.strBuffer.IndexOf('\r')) > 0) { // If there are subscribers if (this.MessageReceived != null) { // Extract the line and build the ParadoxMessageEventArgs var message = new ParadoxMessageEventArgs() { Date = DateTime.Now, Message = this.strBuffer.Substring(0, nlIndex) }; // Raise MessageReceived event for each subscribers Delegate[] receivers = this.MessageReceived.GetInvocationList(); foreach (EventHandler <ParadoxMessageEventArgs> receiver in receivers) { receiver.BeginInvoke(this, message, null, null); } } // Remove the message processed from the buffer this.strBuffer = this.strBuffer.Substring(nlIndex + 1); } } // Check anormal buffer content (= data without '\r' in the string buffer since 2000ms) if (this.strBuffer.Length > 0 && this.strBuffer.IndexOf('\r') < 0 && DateTime.Now.Subtract(lastReceivedDatas).TotalMilliseconds >= BUFFER_TIMEOUT) { // Raise error if (this.InterfaceError != null) { this.InterfaceError(this, new InterfaceErrorEventArgs() { Exception = new TimeoutException($"String buffer timeout. The buffer content was '{this.strBuffer}'.") }); } // Reset string buffer this.strBuffer = string.Empty; } // Pause at each iteration Thread.Sleep(10); } catch (Exception ex) { if (this.InterfaceError != null) { this.InterfaceError(this, new InterfaceErrorEventArgs() { Exception = ex }); } this.IsConnected = false; } } }