示例#1
0
        public static IMessage GetMessageHandler(RawMessage data)
        {
            if (data.Length < 1)
            {
                throw new IncompleteMessageException();
            }

            // FIXME XXX TODO LOL - This logic is going to end up somewhere else, but I'll leave it here for now to refactor later
            MessageType msgType = (MessageType)(data.Byte(1) & ~((byte)BitField.Bit7 | (byte)BitField.Bit8));

            // Check we have a class that we can instantiate to handle this
            MessageFactory.ReflectHandlers();
            Type handlerType;
            if (!_messageHandlers.TryGetValue(msgType, out handlerType))
            {
                throw new MessageNotHandledException();
            }

            // Instantiate and hand back
            try
            {
                IMessage handler = (IMessage)handlerType.GetConstructor(new Type[] {}).Invoke(new object[] {});
                handler.Deserialise(data);
                return handler;
            }
            catch
            {
                throw new MessageNotHandledException();
            }
        }
示例#2
0
 public static int MessageLength( RawMessage data )
 {
     if (data.Length < 2)
     {
         throw new InvalidOperationException();
     }
     return data.Byte(0);
 }
示例#3
0
        public static bool isComplete( RawMessage data )
        {
            // A valid message requires at least 4 bytes (length, number, check1, check2)
            if( data.Length < 4 )
            {
                return false;
            }

            // Check that the last charachter isn't a stuffing byte
            if( data.Byte( data.Length - 1 ) == Constants.EncodingToken )
            {
                return false;
            }

            // Check that we've read enough (length byte, [length] bytes, check1, check2)
            return (data.Length == (3 + MessageLength(data)));
        }
示例#4
0
 public void Deserialise(RawMessage input)
 {
     // XXX TODO FIXME DEBUG LOL - Remove the message type ID byte and checksums
     //this._ackRequiredFlagSet = (input.Byte(1) & (int)BitField.Bit8) == (int)BitField.Bit8;
     DeserialiseMessage(input);
 }
示例#5
0
 protected abstract void DeserialiseMessage(RawMessage input);
示例#6
0
 protected override void DeserialiseMessage(RawMessage input)
 {
     throw new NotImplementedException();
 }
示例#7
0
        protected override void DeserialiseMessage(RawMessage input)
        {
            // Remember the first byte is the message id
            ASCIIEncoding encoding = new ASCIIEncoding();
            this.firmwareVersion = encoding.GetString( input.Bytes(1, 4).ToArray() );

            for (int i = 6; i <= 11; i++)
            {
                bool[] byteFlags = Util.UnpackByte(input.Byte(i-1));

                switch (i)
                {
                    case 6:
                        this.supportsMessage[MessageType.InterfaceConfiguration] = byteFlags[1];
                        this.supportsMessage[MessageType.ZoneStatus] = byteFlags[4];
                        this.supportsMessage[MessageType.ZoneSnapshot] = byteFlags[5];
                        this.supportsMessage[MessageType.PartitionStatus] = byteFlags[6];
                        this.supportsMessage[MessageType.PartitionSnapshot] = byteFlags[7];
                        break;

                    case 7:
                        this.supportsMessage[MessageType.SystemStatus] = byteFlags[0];
                        this.supportsMessage[MessageType.X10MessageReceived] = byteFlags[1];
                        this.supportsMessage[MessageType.LogEvent] = byteFlags[2];
                        this.supportsMessage[MessageType.KeypadMessageReceived] = byteFlags[3];
                        break;

                    case 8:
                        this.supportsMessage[MessageType.InterfaceConfigurationRequest] = byteFlags[1];
                        this.supportsMessage[MessageType.ZoneNameRequest] = byteFlags[3];
                        this.supportsMessage[MessageType.ZoneStatusRequest] = byteFlags[4];
                        this.supportsMessage[MessageType.ZoneSnapshotRequest] = byteFlags[5];
                        this.supportsMessage[MessageType.PartitionStatusRequest] = byteFlags[6];
                        this.supportsMessage[MessageType.PartitionSnapshotRequest] = byteFlags[7];
                        break;

                    case 9:
                        this.supportsMessage[MessageType.SystemStatusRequest] = byteFlags[0];
                        this.supportsMessage[MessageType.SendX10Message] = byteFlags[1];
                        this.supportsMessage[MessageType.LogEventRequest] = byteFlags[2];
                        this.supportsMessage[MessageType.SendKeypadTextMessage] = byteFlags[3];
                        this.supportsMessage[MessageType.KeypadTerminalModeRequest] = byteFlags[4];
                        break;

                    case 10:
                        this.supportsMessage[MessageType.ProgramDataRequest] = byteFlags[0];
                        this.supportsMessage[MessageType.ProgramDataCommand] = byteFlags[1];
                        this.supportsMessage[MessageType.UserInformationRequestWithPIN] = byteFlags[2];
                        this.supportsMessage[MessageType.UserInformationRequestWithoutPIN] = byteFlags[3];
                        this.supportsMessage[MessageType.SetUserCodeCommandWithPIN] = byteFlags[4];
                        this.supportsMessage[MessageType.SetUserCodeCommandWithoutPIN] = byteFlags[5];
                        this.supportsMessage[MessageType.SetUserAuthorisationCommandWithPIN] = byteFlags[6];
                        this.supportsMessage[MessageType.SetUserAuthorisationCommandWithoutPIN] = byteFlags[7];
                        break;

                    case 11:
                        this.supportsMessage[MessageType.StoreCommunicationEventCommand] = byteFlags[2];
                        this.supportsMessage[MessageType.SetClockOrCalendarCommand] = byteFlags[3];
                        this.supportsMessage[MessageType.PrimaryKeypadFunctionWithPIN] = byteFlags[4];
                        this.supportsMessage[MessageType.PrimaryKeypadFunctionWithoutPIN] = byteFlags[5];
                        this.supportsMessage[MessageType.SecondaryKeypadFunction] = byteFlags[6];
                        this.supportsMessage[MessageType.ZoneBypassToggle] = byteFlags[7];
                        break;
                }
            }
        }
示例#8
0
        public void MainLoop()
        {
            // Initialise serial port
            //SerialPort serial = new SerialPort("/dev/ttyS0", 19200, Parity.None, 8, StopBits.One);
            SerialPort serial = new SerialPort("COM3", 19200, Parity.None, 8, StopBits.One);

            // Set some serial port options
            serial.Handshake = Handshake.None;
            serial.RtsEnable = false;
            serial.Encoding = Encoding.ASCII;

            // Open serial port and flush buffers
            serial.Open();
            serial.DiscardInBuffer();
            serial.DiscardOutBuffer();

            // Initialise some stuff we use
            List<byte> curDataStream = new List<byte>();
            List<RawMessage> pending = new List<RawMessage>();
            List<IMessage> messages = new List<IMessage>();

            Trace("Hurr: " + ((byte)Constants.ProtocolToken).ToString("X"));

            // Main event loop
            while (true)
            {
                // Read data from the serial device
                while (serial.BytesToRead > 0)
                {
                    byte data = (byte)serial.ReadByte();
                    Trace("Read char: " + data.ToString("X2"));
                    if (data == Constants.ProtocolToken )
                    {
                        Trace("End of message");
                        Trace(dodgefmt(curDataStream));

                        RawMessage msg = new RawMessage(curDataStream);
                        Trace("Message length: " + msg.Length);
                        if (MessageFactory.isComplete(msg))
                        {
                            pending.Add(msg);
                        }
                        else
                        {
                            Trace("Message incomplete");
                        }
                        curDataStream = new List<byte>();
                        continue;
                    }

                    curDataStream.Add(Convert.ToByte(data));
                }

                // Parse any finished messages
                foreach (RawMessage msg in pending)
                {
                    Trace("Pulling message out of pending list");
                    IMessage messageHandler = MessageFactory.GetMessageHandler(msg);
                    messageHandler.FireEvents();

                    // XXX TODO FIXME DEBUG LOL
                    System.Console.WriteLine(messageHandler.ToString());

                    if (msg.AcknowledgeRequired)
                    {
                        byte[] data = new common.Messages.PositiveAcknowledge().Serialise().WireBytes();
                        Trace("Acknowledgement required, sending: " + dodgefmt(data));
                        serial.Write(data, 0, data.Length);
                    }
                }
                pending.Clear();

                // XXX TODO FIXME DEBUG LOL - Emit any replies back onto the wire
            }

            serial.Close();
        }