Exemplo n.º 1
0
        protected override bool BlockCompleted()
        {
            try
            {
                //CNXLog.InfoFormat("Testing block {0}", mBlockId);
                //if (mMemStream.Length == mSize && mBytesWritten >= mSize)
                //{
                //    mMemStream.Seek(0, SeekOrigin.Begin);
                //    ushort crc = CRC16.CRCStream(mMemStream);
                //    CNXLog.InfoFormat("CRC check calculated {0} should be {1}.", crc, mCRC);
                //    mCRCOk = (crc == mCRC);
                if (base.BlockCompleted() && mSize > 0)
                {
                    //CNXLog.InfoFormat("Block {0} complete.", mBlockId);
                    // transfere to permanat storage
                    CreateBlockFile();
                    mMemStream.WriteTo(mFileStream);
                    mFileStream.Flush();
                    mFileStream.Close();
                }
                //}
            }
            catch (Exception e)
            {
                CNXLog.ErrorFormat("BlockComplete {0} {1}.", (Block)mBlockId, e.Message);
            }

            return(mCRCOk);
        }
Exemplo n.º 2
0
        /// <summary>
        /// What to do when a complete block has arrived.
        /// Provided by derived class.
        /// </summary>
        /// <returns></returns>
        protected virtual bool BlockCompleted()
        {
            try
            {
                CNXLog.InfoFormat("Testing {0} length {1}", (Block)mBlockId, mMemStream.Length);
                if (mSize == 0)
                {
                    mCRCOk = true;
                }
                else if (mMemStream.Length >= mSize && mBytesWritten >= mSize)
                {
                    mMemStream.Seek(0, SeekOrigin.Begin);
                    ushort crc = CRC16.CRCStream(mMemStream, (int)mSize);
                    CNXLog.InfoFormat("CRC check calculated {0:X4} should be {1:X4}.", crc, mCRC);
                    mCRCOk = (crc == mCRC);
                }
                if (mCRCOk)
                {
                    CNXLog.InfoFormat("{0} complete.", (Block)mBlockId);
                }
                SendBlockQueryResponce();
            }
            catch (Exception e)
            {
                CNXLog.ErrorFormat("BlockComplete {0} {1}.", (Block)mBlockId, e.Message);
            }

            return(mCRCOk);
        }
Exemplo n.º 3
0
        protected override bool BlockCompleted()
        {
            bool result = false;

            try
            {
                if (base.BlockCompleted())
                {
                    mBlockData = new byte[mSize];
                    if (mSize > 0)
                    {
                        Array.Copy(mMemStream.ToArray(), mBlockData, mSize);
                    }
                    else
                    {
                        OnRaiseBlockStatusEvent(new BlockStatusEventArgs(mBlockId, BlockState.COMPLETE));
                    }

                    CNXLog.InfoFormat("TransientBlockReciever {0} Completed:\n\r{1}", (Block)mBlockId, HexDump.Dump(mBlockData));

                    result = true;
                }
            }
            catch (Exception e)
            {
                CNXLog.Error("TransientBlockReciever.BlockCompleted:", e);
            }
            return(result);
        }
        /// <summary>
        /// Creates a CAN client ready for sending and recieving CAN frames.
        /// </summary>
        /// <param name="ifaceName">The CAN interfave name to bind to.</param>
        /// <param name="bufferSize">recieve buffer size to set.</param>
        /// <remarks>This is a Linux only implementation and requires a native library.</remarks>
        public CANNativeClient(string ifaceName, uint bufferSize)
        {
            if (bufferSize == 0)
            {
                mCanFd = can_open(ifaceName);
            }
            else
            {
                mCanFd = can_buffer_open(ifaceName, bufferSize);
            }
            if (mCanFd < 0)
            {
                CNXLog.FatalFormat("CANNativeClient can_buffer_open({0}, 0x1000) returned {1}", ifaceName, mCanFd);
                throw new SocketException(mCanFd);
            }

            // organise a decent buffersize for the frames
            int buffersize = can_getbuffersize(mCanFd);

            CNXLog.InfoFormat("CAN buffer size {0}.", buffersize);
            mRxThread = new Thread(new ThreadStart(ReceiveFrame))
            {
                Priority     = ThreadPriority.AboveNormal,
                IsBackground = true
            };
            mRxThread.Start();
        }
        ///// <summary>
        ///// Event firing method.
        ///// </summary>
        ///// <param name="frame">The CAN frame just received.</param>
        //protected virtual void OnRaiseFrameReceivedEvent(FrameReceivedEventArgs frameEvent)
        //{
        //    // copy the event handler to avoid mid process subscribe/un-subscribe
        //    EventHandler<FrameReceivedEventArgs> handler = RaiseFrameReceivedEvent;

        //    // Check if there are any Subscribers
        //    if (handler != null)
        //    {
        //        // Call the Event
        //        handler(this, frameEvent);
        //    }
        //}

        private void ReceiveFrame()
        {
            byte[]   buffer = new byte[8];
            CANFrame frame  = new CANFrame();
            int      rxLen  = 0;
            byte     length = 0;
            uint     canId  = 0;

            while (mKeepReceiving)
            {
                try
                {
                    rxLen = can_recieve(mCanFd, ref canId, ref length, buffer);
                    if (rxLen > 0)
                    {
                        // populate a CAN frame
                        frame.MailboxId = canId;
                        frame.DataFromArray(buffer, 0, length);
                        base.OnRaiseFrameReceivedEvent(new FrameReceivedEventArgs(frame));
                    }
                }
                catch (Exception e)
                {
                    // stuffed.
                    mKeepReceiving = false;
                    CNXLog.Error("CANNative.ReceiveFrame", e);
                    break;
                }
            }
            Console.WriteLine("CAN native end recieve loop");
        }
        private void ReceiveFrames()
        {
            const int length = 16;

            byte[]   buffer = new byte[length];
            CANFrame frame  = new CANFrame();
            int      rxLen  = 0;

            while (mKeepReceiving)
            {
                try
                {
                    rxLen = can_read(mCanFd, buffer, length);
                    if (rxLen > 0)
                    {
                        frame.WireFormatArray = buffer;
                        base.OnRaiseFrameReceivedEvent(new FrameReceivedEventArgs(frame));
                    }
                }
                catch (Exception e)
                {
                    // stuffed.
                    mKeepReceiving = false;
                    CNXLog.Error("CANNative.ReceiveFrames", e);
                    break;
                }
            }
            Console.WriteLine("CAN native end recieve loop");
        }
 /// <summary>
 /// Sends a CAN frame across the bridge
 /// </summary>
 /// <param name="frame">The CAN frame to send.</param>
 public override int Send(CANFrame frame)
 {
     try
     {
         return(mRxSocket.SendTo(frame.WireFormatArray, mTxEndPoint));
     }
     catch
     {
         CNXLog.Debug(frame.MailboxId.ToString("X"));
         return(0);
     }
 }
Exemplo n.º 8
0
        private void CreateBlockFile()
        {
            try
            {
                mPath = String.Format("{0}blk{1}", ((Environment.OSVersion.Platform == System.PlatformID.Unix) ? LinuxBlockFilePath : MSBlockFilePath), mBlockId);
                //string path = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData

                // delete any old file from a previous instance and overwrite with a new one.
                //mFileStream = new FileStream(mPath, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite | FileShare.Delete, 8, FileOptions.RandomAccess);
                mFileStream = new FileStream(mPath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read, 8192, FileOptions.RandomAccess);
            }
            catch (Exception e)
            {
                CNXLog.ErrorFormat("Block Reciever failed for path {0}. {1}", mPath, e.Message);
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// Provides validation that the sentence is a complete and valid NMEA sentence
        /// </summary>
        /// <param name="sentence">The sentence to be validated.</param>
        /// <returns>True if the sentence is a valid NMEA formated sentence.</returns>
        /// <remarks>
        /// NMEA sentences are of the form $GPRMC,11,22,33,44,55*CC
        /// A valid sentence starts with a $.
        /// Has comma seperated data values.
        /// Has a * indicating the end of the data and position of the checksum.
        /// The two checksum characters are correct.
        /// </remarks>
        public bool ValidateNMEASentence(string sentence)
        {
            // Does it begin with a dollar sign?
            if (!sentence.StartsWith("$", StringComparison.Ordinal))
            {
                CNXLog.WarnFormat("NMEAClient Validation failed, no $.");
                return(false);
            }

            // make sure there are data fields
            if (sentence.IndexOf(",", StringComparison.Ordinal) == -1)
            {
                CNXLog.WarnFormat("NMEAClient Validation failed, no data fields.");
                return(false);
            }

            // Next, get the index of the asterisk
            int asteriskIndex = sentence.IndexOf("*", StringComparison.Ordinal);

            // Is an asterisk present?
            if (asteriskIndex == -1)
            {
                CNXLog.WarnFormat("NMEAClient Validation failed, no *.");
                return(false);
            }

            // The checksum is calculated over the command and data portion of the sentence
            byte checksum = (byte)sentence[1];

            for (int index = 2; index < asteriskIndex; ++index)
            {
                checksum ^= (byte)sentence[index];
            }

            // The checksum is the two-character hexadecimal value
            string calculatedChecksum = checksum.ToString("X2", NMEACultureInfo);
            string sentenceChecksum   = sentence.Substring(asteriskIndex + 1, 2);

            if (!calculatedChecksum.Equals(sentenceChecksum, StringComparison.Ordinal))
            {
                ++mChecksumErrors;
                CNXLog.WarnFormat("NMEAClient checksum errors {0}, sentence ratio {1}/{2}.", mChecksumErrors, mValidSentences, mSentencesRecieved);
                return(false);
            }

            return(true);
        }
        /// <summary>
        /// Creates a client connection to the CAN bridge which passes CAN frames across an IP socket as datagrams.
        /// </summary>
        /// <param name="address">Server address.</param>
        /// <param name="inPort">Port to receive frames on.</param>
        /// <param name="outPort">Port to transmit frames on.</param>
        public CANBridgeClient(string address, int inPort, int outPort)
        {
            mInPort  = inPort;
            mOutPort = outPort;
            mAddress = address;

            // associate with the CAN Bridge

            mTxEndPoint = new IPEndPoint(IPAddress.Parse(address), outPort);
            mRxEndPoint = new IPEndPoint(IPAddress.Any, inPort);
            mRxSocket   = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            mRxSocket.Bind(mRxEndPoint);
            mTxSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            // set a decent number of threads in the thread pool
            int worker, completion;

            ThreadPool.GetMinThreads(out worker, out completion);
            CNXLog.InfoFormat("Workers {0} + 16, Completion {1}", worker, completion);
            ThreadPool.SetMinThreads(worker + 16, completion);
            mRxThread = new Thread(new ThreadStart(ReceiveFrames));
            //mRxThread.IsBackground = true;
            mRxThread.Start();
        }
        /// <summary>
        /// Sends the frame on the CAN bus.
        /// </summary>
        /// <param name="frame">The frame to send.</param>
        /// <returns>Total number of bytes put onto the CAN bus.</returns>
        public override int Send(CANFrame frame)
        {
            // synchronise sends
            //int sent = 0;
            //lock (sendLock)
            //{
            //    int retries = 3;
            //    for (sent = can_send(mCanFd, frame.MailboxId, (byte)frame.DataLength, frame.Data); sent < 4 && --retries > 0; sent = can_send(mCanFd, frame.MailboxId, (byte)frame.DataLength, frame.Data))
            //        Thread.Sleep(1);
            //}

            //return sent;

            // synchronise sends
            int  sent  = -1;
            uint canId = frame.MailboxId;

            // test 11 or 29 bit addressing
            if (canId > 0x7ff)
            {
                canId |= (uint)CANFrame.IDFlags.CAN_EFF_FLAG;
            }

            lock (sendLock)
            {
                try
                {
                    sent = can_send(mCanFd, canId, (byte)frame.DataLength, frame.Data);
                }
                catch (Exception e)
                {
                    CNXLog.Error("CANNative.Send", e);
                }
            }

            return(sent);
        }
        /// <summary>
        /// Event firing method.
        /// </summary>
        /// <param name="frame">The CAN frame just received.</param>
        //protected virtual void OnRaiseFrameReceivedEvent(FrameReceivedEventArgs frameEvent)
        //{
        //    // copy the event handler to avoid mid process subscribe/un-subscribe
        //    EventHandler<FrameReceivedEventArgs> handler = RaiseFrameReceivedEvent;

        //    // Check if there are any Subscribers
        //    if (handler != null)
        //        // Call the Event
        //        handler(this, frameEvent);
        //}

        private void ReceiveFrames()
        {
            byte[]   buffer = new byte[13];
            EndPoint ep     = mRxEndPoint;
            CANFrame frame  = new CANFrame();

            while (mKeepReceiving)
            {
                try
                {
                    if (mRxSocket.ReceiveFrom(buffer, ref ep) > 0)
                    {
                        CNXLog.Debug(BitConverter.ToString(buffer));
                        // populate a CAN frame
                        frame.WireFormatArray = buffer;
                        CNXLog.Debug(BitConverter.ToString(frame.Data));
                        CNXLog.Debug(frame.MailboxId.ToString("X"));
                        OnRaiseFrameReceivedEvent(new FrameReceivedEventArgs(frame));
                    }
                }
                catch (SocketException se)
                {
                    // may be OK to continue.
                    CNXLog.WarnFormat("ReceiveFrames {0}.", se.Message);
                }
                catch (Exception e)
                {
                    // stuffed.
                    mKeepReceiving = false;
                    CNXLog.ErrorFormat("ReceiveFrames {0}.", e.Message);
                    break;
                }
            }

            mRxSocket.Close();
        }
Exemplo n.º 13
0
        private void ProcessNewSentence(string sentence)
        {
            if (sentence.Length < 6)
            {
                OnRaiseGPSStatusChangedEvent(new GPSStatusEvent(GPS_STATUS.OFFLINE));
                CNXLog.ErrorFormat("NMEAClient short sentence {0}", sentence);
                return;
            }

            try
            {
                //CNXLog.InfoFormat("NMEAClient ProcessNewSentence {0}", sentence);
                bool   updateAvailable = false;
                string sentenceType    = "";

                if (sentence.Contains("RMC"))
                {
                    sentenceType = "RMC";
                }
                else if (sentence.Contains("GGA"))
                {
                    sentenceType = "GGA";
                }
                else if (sentence.Contains("GSA"))
                {
                    sentenceType = "GSA";
                }

                // Determine the type of sentence.
                // The NMEA specification states that the first two letters of a sentence may change.
                // For example, for "$GPGSV" there may be variations such as "$__GSV" where the first two letters change.
                // As a result, we need only test the last three characters.

                // Is this a GPRMC sentence?
                if (sentenceType.Equals("RMC", StringComparison.Ordinal))
                {
                    updateAvailable = mGPSPosition.ParseRMC(sentence);
                    if (!updateAvailable)
                    {
                        OnRaiseGPSPositionChangedEvent(new GPSPositionEvent(mGPSPosition));
                    }
                }
                else if (sentenceType.Equals("GGA", StringComparison.Ordinal))
                {
                    // dont update on GGA, only augment error estimates.
                    updateAvailable = mGPSPosition.ParseGGA(sentence);
                }
                else if (sentenceType.Equals("GSA", StringComparison.Ordinal))
                {
                    updateAvailable = mGPSPosition.ParseGSA(sentence);
                }

                if (updateAvailable)
                {
                    mLastNMEASentenceType = sentenceType;

                    // report any status changes
                    GPS_STATUS status = GPS_STATUS.OFFLINE;
                    switch (mGPSPosition.NMEAMode)
                    {
                    case GPSPosition.NMEAMODE.NO_FIX:
                        status           = GPS_STATUS.Connected;
                        mTravellingState = MovingState.Unknown;
                        break;

                    case GPSPosition.NMEAMODE.NO_MODE:
                        status           = GPS_STATUS.Connected | GPS_STATUS.GPSResponding;
                        mTravellingState = MovingState.Unknown;
                        break;

                    case GPSPosition.NMEAMODE.TWO_DIMENSION:
                    case GPSPosition.NMEAMODE.THREE_DIMENSION:
                        status = GPS_STATUS.Connected | GPS_STATUS.GPSResponding | GPS_STATUS.Fix;
                        // set the travelling state
                        mAverageVelocity.Value = mGPSPosition.SpeedOverGround;

                        //lat = mG
                        mTravellingState = (mAverageVelocity.Value > mMovingThreshold) ? MovingState.Moving : MovingState.Stationary;
                        break;
                    }
                    if (status != mStatus)
                    {
                        mStatus = status;
                        OnRaiseGPSStatusChangedEvent(new GPSStatusEvent(mStatus));
                        //Console.WriteLine("Fired Status Changed.");
                    }
                    // only update from RMC sentences as other sentences dont have date & time.
                    if (sentenceType.Equals("RMC", StringComparison.Ordinal))
                    {
                        //Console.WriteLine("Firing Position Changed.");
                        //CNXLog.InfoFormat("GPS State {0}, {1}", mStatus, mGPSPosition.CurrentPosition.ToString());
                        //if (mGPSPosition.Tag.EndsWith("RMC", StringComparison.Ordinal))
                        if ((mStatus & GPS_STATUS.Fix) == GPS_STATUS.Fix)
                        {
                            //CNXLog.InfoFormat(mGPSPosition.CurrentPosition.ToString());
                            OnRaiseGPSPositionChangedEvent(new GPSPositionEvent(mGPSPosition));
                            //CNXLog.InfoFormat("OnRaiseGPSPositionChangedEvent completed.");
                            //CNXLog.InfoFormat(mGPSPosition.CurrentPosition.ToString());
                            //Console.WriteLine("Fired Position Changed.");
                        }
                    }
                }
                //CNXLog.InfoFormat("GPS State {0}, {1}", mStatus, mGPSPosition.CurrentPosition.ToString());
            }
            catch (Exception e)
            {
                CNXLog.Error(String.Format("NMEAClient ProcessNewSentence {0}", sentence), e);
            }
        }