示例#1
0
        /// <summary>
        /// Enqueue a message in the current priority queue.  If you have not
        /// set the priority of the message it is enqueued according to its
        /// creation status.
        /// </summary>
        /// <param name="enqueue"></param>
        public void commPriorityQueueEnqueue(CNCRMessage enqueue)
        {
            bool threadLocked = _commPriorityQLock.WaitOne(100);

            if (threadLocked)
            {
                _commPriorityQueue.Enqueue(enqueue);
                _commPriorityQLock.Release();
            }
            else
            {
                throw new Exception("Failed to lock thread");
            }
        }
示例#2
0
        // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
        // @@@@@ IComparable  Functions @@@@@
        public int CompareTo(object obj)
        {
            CNCRMessage msg = (CNCRMessage)obj;

            if (msg != null)
            {
                int compare = getPriority().CompareTo(msg.getPriority());
                switch (compare)
                {
                case 0:
                    return(_msgID.CompareTo(msg.getMsgID()));

                default:
                    return(compare);
                }
            }
            else
            {
                throw new ArgumentException("Object is not a message");
            }
        }
示例#3
0
        public void SendMsg(CNCRMessage msg)
        {
            //TODO: SendMsg: Should this function really be doing this check?  Shouldnt the function errorhandler do this?
            if (getDiscardingData() &&                   // If we are discarding data.
                msg.getMessageType() == CNCRMSG_TYPE.CMD_ACKNOWLEDGE && // and sending an acknowledge
                ((CNCRMsgCmdAck)msg).getError() == true) // and that acknowledge is saying we have an error.
            {
                setDiscardingData(false);                // Then clear the discard data bit so we can see the response.
                byte[] serialStuff = msg.toSerial();
                string toDisplay   = "Ack Sent: " + CNCRTools.BytesToHex(msg.toSerial());
                toDisplay += "\n";

                DisplayData(toDisplay);
            }
            if (msg.getMessageType() != CNCRMSG_TYPE.CMD_ACKNOWLEDGE)
            {
                setWaitingOnAck(true);
            }
            setLastMessage(msg);
            DisplayData("Sending: " + msg.ToString() + "\n");
            SendBytes(msg.toSerial());
        }
示例#4
0
        private void btnSndMsg_Click(object sender, EventArgs e)
        {
            /*
             * int discarded = 0;
             * byte[] bytes = CNCRTools.GetBytes(txtHex.Text, out discarded);
             * lblDbgOut.Text = "";
             * for (int i = 0; i < bytes.Length; i++)
             * {
             *  lblDbgOut.Text += bytes[i].ToString() + " ";
             * }//*/

            byte[]      sendBytes = { 0 };
            CNCRMessage sendMsg   = null;

            switch (cmbMsgs.SelectedIndex)
            {
            case 0:
                int discarded = 0;
                sendBytes = CNCRTools.GetBytes(txtHex.Text, out discarded);
                break;

            case 1:
                sendMsg   = new CNCRMsgPing();
                sendBytes = sendMsg.toSerial();
                break;

            case 2:
                sendMsg   = new CNCRMsgCmdAck(false, 127);
                sendBytes = sendMsg.toSerial();
                break;

            case 3:
                sendMsg   = new CNCRMsgEStop();
                sendBytes = sendMsg.toSerial();
                break;

            case 4:
                sendMsg   = new CNCRMsgRequestCommands(128);
                sendBytes = sendMsg.toSerial();
                break;

            case 5:
                sendMsg   = new CNCRMsgStartQueue(false);
                sendBytes = sendMsg.toSerial();
                break;

            case 6:
                sendMsg   = new CNCRMsgSetSpeed(true, true, false, 40000);
                sendBytes = sendMsg.toSerial();
                break;

            case 7:
                sendMsg   = new CNCRMsgMove(Int16.MinValue, Int16.MaxValue, 0);
                sendBytes = sendMsg.toSerial();
                break;

            case 8:
                sendMsg   = new CNCRMsgToolCmd(true);
                sendBytes = sendMsg.toSerial();
                break;
            }
            rtbTraffic.AppendText(CNCRTools.BytesToHex(sendBytes) + "\n");
            if (sendMsg == null)
            {
                commCmd.SendBytes(sendBytes);
            }
            else
            {
                commCmd.SendMsg(sendMsg);
            }
        }
示例#5
0
 private void setLastMessage(CNCRMessage lastMessage)
 {
     _lastMessageLock.WaitOne();
     _lastMessage = lastMessage;
     _lastMessageLock.Release();
 }
示例#6
0
        public void SendMsg(CNCRMessage msg)
        {
            //TODO: SendMsg: Should this function really be doing this check?  Shouldnt the function errorhandler do this?
            if (getDiscardingData()                                     // If we are discarding data.
                && msg.getMessageType() == CNCRMSG_TYPE.CMD_ACKNOWLEDGE // and sending an acknowledge
                && ((CNCRMsgCmdAck)msg).getError() == true)             // and that acknowledge is saying we have an error.
            {
                setDiscardingData(false);   // Then clear the discard data bit so we can see the response.
                byte[] serialStuff = msg.toSerial();
                string toDisplay = "Ack Sent: " + CNCRTools.BytesToHex(msg.toSerial());
                toDisplay += "\n";

                DisplayData(toDisplay);
            }
            if (msg.getMessageType() != CNCRMSG_TYPE.CMD_ACKNOWLEDGE)
            {
                setWaitingOnAck(true);
            }
            setLastMessage(msg);
            DisplayData("Sending: " + msg.ToString() + "\n");
            SendBytes(msg.toSerial());
        }
示例#7
0
 /// <summary>
 /// Enqueue a message in the current priority queue.  If you have not
 /// set the priority of the message it is enqueued according to its
 /// creation status.
 /// </summary>
 /// <param name="enqueue"></param>
 public void commPriorityQueueEnqueue(CNCRMessage enqueue)
 {
     bool threadLocked = _commPriorityQLock.WaitOne(100);
     if (threadLocked)
     {
         _commPriorityQueue.Enqueue(enqueue);
         _commPriorityQLock.Release();
     }
     else
         throw new Exception("Failed to lock thread");
 }
示例#8
0
        private void processQueues()
        {
            DateTime lastMsg = DateTime.Now;
            TimeSpan timeout = new TimeSpan(CNCRConstants.TIMEOUT_MS * TimeSpan.TicksPerMillisecond);

            while (!getEStopActive() && // While eStop is not active.
                   ((commPriorityQueueCount() > 0) || (commCommandQueueCount() > 0 && getNumCmdsToSend() > 0)) && // And this stuff
                   ((DateTime.Now - lastMsg) < timeout))  // TODO; Log a timeout error.
            {
                // If waiting for Ack or EStopped, exit thread, we cant send any commands.
                if (!getWaitingOnAck() && !getEStopActive())
                {
                    // reset the timeout
                    lastMsg = DateTime.Now;

                    int numCmdsToSend = getNumCmdsToSend();

                    // Check the priority queue first, it has priority.
                    if (commPriorityQueueCount() > 0)
                    {
                        CNCRMessage commMsg = commPriorityQueueDequeue();
                        if (commMsg.getMessageType() == CNCRMSG_TYPE.E_STOP)
                        {
                            setEStopActive(true);
                        }

                        SendMsg(commMsg);
                    }
                    // Check to see if the router is requesting commands and then
                    // Check to ensure we actually have commands to send.
                    else if (numCmdsToSend > 0 && commCommandQueueCount() > 0)
                    {
                        // Grab the next router command in the queue.
                        SendMsg(commCommandQueueDequeue());

                        // Check if we are out of commands, if so set the numCmdsToSend to 0
                        // and send StartQueue(true)
                        if (commCommandQueueCount() == 0)
                        {
                            numCmdsToSend = 0;
                            commPriorityQueueEnqueue(new CNCRMsgStartQueue(true));
                        }
                        else // Decrement the command counter
                        {
                            numCmdsToSend--;
                        }

                        // Set the new numCmdsToSend safely.
                        setNumCmdsToSend(numCmdsToSend);
                    }
                }
                // TODO: Check to see if we timed out, what do we do in this event?
                // TODO: Check to see if the router is requesting more commands than we have.
                //       if so, send them a "StartQueue(true)" message to stop them.
                //      - Possibly do this when sending messages? what about when I receive this message?
                //      - I should be able to check on receipt if requested is > than received.
                //      - Or when emptying the queue, as soon as I hit 0 I can append a "stop message"
                //   (following message saved for posterity, moved from above last }
                //  - Well currently I do not even reach this level if there
                //   is a discrepency between commCommandQueueCount and
                //   getNumCmdsToSend due to the while loop.  Figure this out.
                Thread.Sleep(10);
            }
        }
示例#9
0
        /// <summary>
        /// Takes the passed in message and performs the nessessary actions
        /// required by that message.
        /// </summary>
        /// <param name="msg">Message to act on.</param>
        public void actOnMessage(object msgObj)
        {
            CNCRMessage msg = (CNCRMessage)msgObj;

            if (msg == null)
            {
                throw new ArgumentNullException();
            }

            switch (msg.getMessageType())
            {
            case CNCRMSG_TYPE.CMD_ACKNOWLEDGE:
                if (((CNCRMsgCmdAck)msg).getError())
                {
                    // if error, resend last message
                    CNCRMessage lastMsg = getLastMessage();
                    lastMsg.setPriority(CNCRMSG_PRIORITY.HIGH);
                    commPriorityQueueEnqueue(lastMsg);
                }
                else
                {
                    // if not error, clear "Waiting for Ack"
                    setWaitingOnAck(false);
                }
                launchProcessQueues();
                break;

            case CNCRMSG_TYPE.E_STOP:
                // Send Ack.
                CNCRMessage ack = new CNCRMsgCmdAck(false, 0);
                ack.setPriority(CNCRMSG_PRIORITY.MEDIUM);     // TODO: what about the E-stop Ack.
                commPriorityQueueEnqueue(ack);

                // Set the "Stop Sending Messages variable"
                setEStopActive(true);
                break;

            case CNCRMSG_TYPE.REQUEST_COMMAND:
                // Send Ack.
                CNCRMessage ack2 = new CNCRMsgCmdAck(false, 0);
                ack2.setPriority(CNCRMSG_PRIORITY.MEDIUM);
                commPriorityQueueEnqueue(ack2);

                // Set the "Send Commands" variable to the # of messages.
                CNCRMsgRequestCommands msgRC = (CNCRMsgRequestCommands)msg;
                setNumCmdsToSend(msgRC.getCommandCount() + getNumCmdsToSend());

                // If it is not already started, kick off the "SendMessages" method.
                launchProcessQueues();
                break;

            case CNCRMSG_TYPE.MOVE:
            case CNCRMSG_TYPE.PING:
            case CNCRMSG_TYPE.SET_SPEED:
            case CNCRMSG_TYPE.START_QUEUE:
            case CNCRMSG_TYPE.TOOL_CMD:
                // We should not be receiving any of these messages.
                DisplayData("Received a valid message that should not have " +
                            "been sent by the router. " + msg.ToString() + "\n");
                break;

            default:
                throw new ArgumentException("CNCRMessage has an invalid type");
            }
        }
示例#10
0
        public void handleData(byte[] commBuffer)
        {
            // Are we currently in the middle of a type?
            if (_commBufferQueue.Count == 0)
            {
                // No, so grab the type in the next byte.
                setCurType((CNCRMSG_TYPE)Enum.ToObject(typeof(CNCRMSG_TYPE), (commBuffer[0] & 0xF0) >> 4));
            }

            // Get the current type, if it is not between MIN and MAX_TYPE
            CNCRMSG_TYPE currentType = getCurType();

            if (CNCRMSG_TYPE.zMIN_TYPE < currentType && currentType < CNCRMSG_TYPE.zMAX_TYPE)
            {
                // Drop all incoming bytes into the queue
                for (int i = 0; i < commBuffer.Length; i++)
                {
                    if (CNCRTools.validateParityBit(commBuffer[i]))
                    {
                        _commBufferQueue.Enqueue(commBuffer[i]);
                    }
                    else
                    {
                        // Bad Parity bit, Discard the data and log an error.
                        handleError("Invalid Parity Bit.");
                        return;
                    }
                }

                // Check how long of a message we are expecting
                int expectedLength = CNCRTools.getMsgLenFromType(getCurType());
                // Uh, Oh, what about expectedLength = 0, AKA, bad type?
                // - At this point, curType should be validated and curType
                //   should not be unknown, throw an error in getMsgLenFromType.
                if (expectedLength > 0)
                {
                    // Process the current Queue
                    while (_commBufferQueue.Count >= expectedLength)
                    {
                        // We have enough bytes, lets get the message for those bytes.
                        byte[] msgBytes = new byte[expectedLength];
                        for (int i = 0; i < msgBytes.Length; i++)
                        {
                            msgBytes[i] = _commBufferQueue.Dequeue();
                        }

                        if (CNCRTools.validateParityByte(msgBytes))
                        {
                            DisplayData("- Valid Parity\n");
                            CNCRMessage CommMsg = CNCRTools.getMsgFromBytes(msgBytes);
                            DisplayData("- Type: " + CommMsg.ToString() + "\n");
                            Thread runActOnMessage = new Thread(new ParameterizedThreadStart(actOnMessage));
                            runActOnMessage.Start(CommMsg);
                        }
                        else
                        {
                            handleError("Invalid Parity Byte.");
                            return;
                        }
                    }
                }
                else
                {
                    handleError("Expected length was 0 or less.");
                    return;
                }
            }
            else
            {
                // Bad type: log an error, discard bytes.
                handleError("Invalid message type.");
                return;
            }
        }
示例#11
0
 private void setLastMessage(CNCRMessage lastMessage)
 {
     _lastMessageLock.WaitOne();
     _lastMessage = lastMessage;
     _lastMessageLock.Release();
 }