Exemplo n.º 1
0
        public static void OnDeviceDataReceieved(object sender, FrameReceivedEventArgs e)
        {
            N2kFrame    n2kFrame = (N2kFrame)e.ReceivedFrame;
            CANStreamer stream   = sender as CANStreamer;

            CANDevice dev = UpdateAddDevice(n2kFrame, stream.Name);
        }
Exemplo n.º 2
0
        private bool SetProductInformation(N2kFrame n2kFrame)
        {
            bool changed = false;

            lock (Lock)
            {
                if (!EqualBytesLongUnrolled(PiData, n2kFrame.Data))
                {
                    // We pass here field description and use NMEA2000 definition
                    N2kVersion         = BitConverter.ToUInt16(n2kFrame.Data, 0);
                    ProductCode        = BitConverter.ToUInt16(n2kFrame.Data, 2);
                    ModelID            = N2kASCIIField.ReadString(n2kFrame.Data, 4, 32);
                    SwCode             = N2kASCIIField.ReadString(n2kFrame.Data, 36, 32);
                    ModelVersion       = N2kASCIIField.ReadString(n2kFrame.Data, 68, 32);
                    ModelSerialCode    = N2kASCIIField.ReadString(n2kFrame.Data, 100, 32);
                    CertificationLevel = n2kFrame.Data[132];
                    LoadEquivalency    = n2kFrame.Data[133];
                    PiData             = n2kFrame.Data.ToArray();

                    changed = true;
                }
            }

            return(changed);
        }
Exemplo n.º 3
0
        private bool SetDeviceInformation(N2kFrame n2kFrame)
        {
            bool changed = false;

            lock (Lock)
            {
                UInt64 _ID = BitConverter.ToUInt64(n2kFrame.Data, 0);

                if (ID != _ID)
                {
                    ID = _ID;

                    // We pass here field description and use NMEA2000 definition
                    UInt32 UnicAndMCode = BitConverter.ToUInt32(n2kFrame.Data, 0);
                    UniqueNumber     = UnicAndMCode & 0x1FFFFF;
                    ManufacturerCode = (UnicAndMCode >> 21) & 0x7ff;
                    DeviceFunction   = n2kFrame.Data[5];
                    DeviceClass      = (UInt32)((n2kFrame.Data[6] >> 1) & 0x7f);
                    IndustryGroup    = (n2kFrame.Data[7] >> 4) & 0x7;

                    changed = true;
                }
            }

            return(changed);
        }
Exemplo n.º 4
0
        private static void UpdateDevice(CANDevice dev, N2kFrame n2kFrame)
        {
            var e = DeviceListChange;

            if (dev.UpdateDevice(n2kFrame) && e != null)
            {
                e();
            }
        }
Exemplo n.º 5
0
        public override int ProcessBytes(byte[] bytes, int offset, int size)
        {
            N2kHeader n2kHeader = new N2kHeader(bytes[0], bytes[1], bytes[2], bytes[3]);

            byte[] n2kData = new byte[size - 4];
            Array.Copy(bytes, 4, n2kData, 0, size - 4);

            N2kFrame n2kFrame = new N2kFrame(n2kHeader, n2kData, DateTime.Now);

            OnFrameCreated(n2kFrame);

            return(size);
        }
Exemplo n.º 6
0
        private static CANDevice AddDevice(N2kFrame n2kFrame, string streamName)
        {
            CANDevice dev = null;
            int       Source;

            if (Int32.TryParse(n2kFrame.Header.Source, out Source))
            {
                dev = new CANDevice(Source, streamName);
                lock (Lock)
                {
                    dev.Source = Source;
                    _Devices.Add(Source, dev);
                }
                UpdateDevice(dev, n2kFrame);
            }

            return(dev);
        }
Exemplo n.º 7
0
        // Given a (possibly partially) completed PGN message,
        // described by a PGN number, and the apparent 'byte length'
        // for the message (which is only relevant if the message is a
        // multiple packet message), return the
        // PGNDefn that allows this message to be decoded
        public PGNDefn GetPGNDefn(N2kFrame msg)
        {
            uint PGN = (uint)msg.Header.PGN;
            int  pgnIndex;

            if (!PGNDictionary.TryGetValue(PGN, out pgnIndex))
            {
                // No matching PGN definition; return UnknownPGNDefn
                return(UnknownPGNDefn);
            }
            else
            {
                PGNDefn pgn = PGNDefns[pgnIndex];
                // Is this a multiple definition PGN? (If so, it must be a fast packet PGN?)
                if (!pgn.HasMultipleDefinitions)
                {
                    // Only one matching definition available; return it
//                    int iBytesTransmitted = pgn.ByteLength <= 8 ? msg.Data.Length : msg.Data[1];
                    return(PGNDefns[pgnIndex]);
                }
                else
                {
                    // Find the matching definition
                    while ((pgnIndex < PGNDefns.Length) && (PGNDefns[pgnIndex].PGN == pgn.PGN))
                    {
                        if (PGNDefns[pgnIndex].ByteLength == msg.Data[1])
                        {
                            return(PGNDefns[pgnIndex]);
                        }
                        else
                        {
                            // Find any PGN that is not too long, just on case we cannot find any with an exact match
                            if (pgn.ByteLength < msg.Data[1])
                            {
                                pgn = PGNDefns[pgnIndex];
                            }
                            pgnIndex++;
                        }
                    }
                    return(pgn);
                }
            }
        }
Exemplo n.º 8
0
        public override byte[] GetBytes(Frame frame)
        {
            N2kFrame n2kFrame = frame as N2kFrame;

            if (frame == null)
            {
                ReportHandler.LogWarning("Attempt to send non-N2k frame as N2k datagram");
                return(null);
            }

            byte[] datagram = new byte[4 + n2kFrame.Data.Length];
            datagram[0] = n2kFrame.Header.Byte0;
            datagram[1] = n2kFrame.Header.Byte1;
            datagram[2] = n2kFrame.Header.Byte2;
            datagram[3] = n2kFrame.Header.Byte3;
            Array.Copy(n2kFrame.Data, 0, datagram, 4, n2kFrame.Data.Length);

            return(datagram);
        }
Exemplo n.º 9
0
        public bool UpdateDevice(N2kFrame n2kFrame)
        {
            bool changed = false;

            switch (n2kFrame.Header.PGN)
            {
            case 60928:
                changed = SetDeviceInformation(n2kFrame);
                break;

            case 126996:
                changed = SetProductInformation(n2kFrame);
                break;

            case 126998:
                changed = SetConfigurationInformation(n2kFrame);
                break;
            }

            return(changed);
        }
Exemplo n.º 10
0
        public override byte[] GetBytes(Frame frame)
        {
            N0183Frame n0183Frame = frame as N0183Frame;

            if (n0183Frame != null)
            {
                return(Encoding.ASCII.GetBytes(n0183Frame.FullMessage + "\r\n"));
            }

            N2kFrame n2kFrame = frame as N2kFrame;

            if (n2kFrame != null)
            {
                return(Encoding.ASCII.GetBytes(FrameConversion.PackN2k(n2kFrame).FullMessage + "\r\n"));
            }

            AISFrame aisFrame = frame as AISFrame;

            if (aisFrame != null)
            {
                // TODO : Breaking up message if too long

                int    padbits = 6 * aisFrame.AISData.AISString.Length - 8 * aisFrame.AISData.AISBytes.Length; // [0, 5]
                string message = "!AIVDM,1,1,,A," + aisFrame.AISData.AISString + "," + padbits;

                // Add checksum
                byte checksum = 0;
                for (int i = 1; i < message.Length; i++)
                {
                    checksum ^= Convert.ToByte(message[i]);
                }
                message += "*" + checksum.ToString("X2");

                return(Encoding.ASCII.GetBytes(message + "\r\n"));
            }

            throw new Exception("Attempt to send unknown frame type: '" + frame.GetType().Name + "'");
        }
Exemplo n.º 11
0
        private bool SetConfigurationInformation(N2kFrame n2kFrame)
        {
            bool changed = false;

            lock (Lock)
            {
                if (!EqualBytesLongUnrolled(CiData, n2kFrame.Data))
                {
                    // We pass here field description and use NMEA2000 definition
                    int ByteOffset = 0;
                    int ByteLength = 0;
                    InstallationDescription1 = N2kStringField.ReadString(n2kFrame.Data, ByteOffset, ref ByteLength);
                    ByteOffset += ByteLength; ByteLength = 0;
                    InstallationDescription2 = N2kStringField.ReadString(n2kFrame.Data, ByteOffset, ref ByteLength);
                    ByteOffset  += ByteLength; ByteLength = 0;
                    Manufacturer = N2kStringField.ReadString(n2kFrame.Data, ByteOffset, ref ByteLength);
                    CiData       = n2kFrame.Data.ToArray();

                    changed = true;
                }
            }

            return(changed);
        }
Exemplo n.º 12
0
        // Private methods
        private void ProcessN2kMessage(ActisenseMessage msg)
        {
            /* This N2kDataReceived message goes:
             * [0] Priority
             * [1] PGN LSB=Least Significant Byte
             * [2] PGN Middle Byte
             * [3] PGN MSB=MostSignificant Byte
             * [4] Destination
             * [5] Source
             * [6,7,8,9] Time stamp, LSB...MSB
             * [10] N2k payload length
             * [11, 12, ...] N2k payload (always 8 bytes in data seen so far)
             */

            byte[] payload = msg.MessagePayload;

            byte Priority    = payload[0];
            int  PGN         = payload[1] + (payload[2] << 8) + (payload[3] << 16);
            byte Destination = payload[4];
            byte Source      = payload[5];
            uint ms          = BitConverter.ToUInt32(payload, 6);

            // TODO: Work out what the Actisense is transmitting in its time-stamp field
            //       as the number of milliseconds appears to go down as well as up (according to a user report)
            // Note that the Actisense clock appears to be reset when the unit is reset by software,

            /* as indicated by the following R(read)/W(rite) sequence of commands
             *                                              Clock 4 bytes
             *  W:	10	2	A1	1	13	4B	10	3
             *  R:	10	2	93	13	2	2	FD	1	FF	3A	66	9F	0	0	8	FF	3	3	69	0	FA	FF	FF	AC	10	3
             *  R:	10	2	A0	0E	13	1	0E	0	FA	A4	1	0	0	0	0	0	0	1	90	10	3
             *  W:	10	2	A1	3	13	0	0	49	10	3
             *  R:	10	2	A0	0E	13	1	0E	0	FA	A4	1	0	0	0	0	0	0	0	91	10	3
             *  W:	10	2	A1	1	10	10	4E	10	3
             *  R:	10	2	93	13	2	12	F1	1	FF	3A	98	9F	0	0	8	FF	0	0	FF	7F	FF	7F	FD	E4	10	3
             *  R:	10	2	A0	22	10	10	1	0E	0	FA	A4	1	0	0	0	0	0	6D	0	3C	9C	25	93	67	8	3C	9C	2A	93	67	0	BB	AF	0	0	3	0	0	0	AB	10	3
             *  W:	10	2	A1	2	4C	2	0F	10	3   <- some sort of reset?
             *  R:	10	2	A0	0D	4C	1	0E	0	FA	A4	1	0	0	0	0	0	2	57	10	3
             *  W:	10	2	A1	1	13	4B	10	3   <- some sort of reset?
             *  R:	10	2	A0	0F	F0	1	0E	0	FA	A4	1	0	0	0	0	0	67	8	0	44	10	3
             *  R:	10	2	93	13	2	12	F1	1	FF	3A	2D	0	0	0	8	FF	0	0	FF	7F	FF	7F	FD	EE	10	3
             */
            // For now, we just use the computer's clock (and so don't get millisecond accuracy)
            DateTime thisTime;

            thisTime = DateTime.Now;
            //if (firstArrived)
            //{
            //    // Check for rollover.
            //    if (ms < lastMs)
            //        baseTime = baseTime.AddMilliseconds(uint.MaxValue); // being 8.1715 years

            //    thisTime = baseTime.AddMilliseconds(ms);
            //}
            //else
            //{
            //    firstArrived = true;
            //    thisTime = DateTime.Now;
            //    baseTime = thisTime.AddMilliseconds(-ms);
            //}
            //lastMs = ms;

            int N2kDataLength = payload[10];

            byte[] N2kData = new byte[N2kDataLength];
            Array.Copy(payload, 11, N2kData, 0, N2kDataLength);

            N2kHeader Header = new N2kHeader(Priority, PGN, Destination, Source);
            N2kFrame  frame  = new N2kFrame(Header, N2kData, thisTime);

            OnFrameCreated(frame);
        }
Exemplo n.º 13
0
        // Public methods
        public static int PackFrame(N2kFrame n2kFrame, byte[] buffer)
        {
            /* [0] Message Protocol: 0x93 = N2kDataReceived
             * [1] Message body length (number of bytes 2, 3, ..., up to last byte before CRC)
             * [2] Priority
             * [3] PGN LSB=Least Significant Byte
             * [4] PGN Middle Byte
             * [5] PGN MSB=MostSignificant Byte
             * [6] Destination
             * [7] Source
             * [8,9,10,11] Time stamp, LSB...MSB
             * [12] N2k payload length
             * [13, 14, ..., 13+[12]=20 ] N2k payload (always 8 bytes in data seen so far)
             * [21] CRC byte, chosen so that the sum over all bytes is 0 (mod 256).
             */

            // TODO : Test sending
            // - confirm CRC is generated correctly

            N2kHeader n2kHeader = n2kFrame.Header;

            buffer[0] = Escape;
            buffer[1] = StartOfText;
            buffer[2] = N2kDataReceived; // TODO : What should this be ?

            int  pgn    = n2kHeader.PGN;
            byte pgnLSB = (byte)(pgn & 0xFF);

            pgn >>= 8;
            byte pgnMDB = (byte)(pgn & 0xFF);

            pgn >>= 8;
            byte pgnMSB = (byte)(pgn & 0xFF);

            buffer[4] = n2kHeader.PGNPriority;
            buffer[5] = pgnLSB;
            buffer[6] = pgnMDB;
            buffer[7] = pgnMSB;
            buffer[8] = n2kHeader.PGNDestination;
            buffer[9] = n2kHeader.PGNSource;

            // Set timestamp bytes [10, 11, 12, 13]
            Array.Copy(BitConverter.GetBytes(DateTime.Now.Millisecond), 0, buffer, 10, 4);

            // Byte 14 : Length of n2k data
            buffer[14] = (byte)n2kFrame.Data.Length; // N2k data length : Bytes [15, CRCbyte)

            byte msgIdx = 15;

            for (int i = 0; i < n2kFrame.Data.Length; i++)
            {
                if (n2kFrame.Data[i] == Escape)
                {
                    buffer[msgIdx++] = Escape;
                    buffer[msgIdx++] = Escape;
                }
                else
                {
                    buffer[msgIdx++] = n2kFrame.Data[i];
                }
            }
            int byteSum = 0;

            for (int i = 2; i < msgIdx; i++)
            {
                byteSum += buffer[i];
            }
            byteSum %= 256;

            buffer[msgIdx++] = (byte)((byteSum == 0) ? 0 : (256 - byteSum));

            buffer[3] = (byte)(msgIdx - 5); // Message length : Bytes [4, CRCbyte)

            buffer[msgIdx++] = Escape;
            buffer[msgIdx++] = EndOfText;

            return(msgIdx);
        }
Exemplo n.º 14
0
        private static CANDevice UpdateAddDevice(N2kFrame n2kFrame, string streamName)
        {
            CANDevice dev = null;
            int       Source;

            if (Int32.TryParse(n2kFrame.Header.Source, out Source))
            {
                lock (Lock)
                {
                    // First try to find device with source
                    _Devices.TryGetValue(Source, out dev);

                    if (dev != null)   // If we found device, just update it
                    {
                        UpdateDevice(dev, n2kFrame);
                    }
                    else
                    {
                        // If device does not exist, check is it on different source.
                        // Source may change due to address claiming.
                        if (n2kFrame.Header.PGN == 60928)
                        {
                            UInt64 ID  = BitConverter.ToUInt64(n2kFrame.Data, 0);
                            int    Key = FindDeviceKeyByID(ID);
                            if (Key != -1) // We found device, so register it with new key.
                            {
                                dev = _Devices[Key];
                                _Devices.Remove(Key);
                                _Devices.Remove(Source);
                                _Devices.Add(Source, dev);
                                lock (dev.Lock)
                                {
                                    dev.Source = Source;
                                }
                                // Notify that device address has been changed
                                var e = SourceChange; if (e != null)
                                {
                                    e();
                                }
                                e = DeviceListChange; if (e != null)
                                {
                                    e();
                                }
                            }
                            else
                            {
                                dev = AddDevice(n2kFrame, streamName);
                                var e = SourceChange; if (e != null)
                                {
                                    e();
                                }
                            }
                        }
                        else
                        {
                            // We did not find the device, but we can not add it, since message was
                            // not ISO Address claim PGN 60928
                        }
                    } // device was null
                }
            }
            return(dev);
        }