// The get note positions command instructs the validator to return in the second byte the number of
 // notes stored and then in the following bytes, the values/channel (see SetValueReportingType()) of the stored
 // notes. The length of the response will vary based on the number of stored notes.
 public void CheckForStoredNotes()
 {
     m_cmd.CommandData[0]    = CCommands.SSP_CMD_GET_NOTE_POSITIONS;
     m_cmd.CommandDataLength = 1;
     if (!SendCommand())
     {
         return;
     }
     if (CheckGenericResponses())
     {
         int counter = 0;
         Array.Clear(m_NotePositionValues, 0, m_NotePositionValues.Length);
         // Work backwards for a more accurate display (LIFO)
         for (int i = (m_cmd.ResponseData[1] * 4) + 1; i >= 2; i -= 4, counter++)
         {
             m_NotePositionValues[counter] = CHelpers.ConvertBytesToInt32(m_cmd.ResponseData, i - 3);
         }
     }
 }
        // The poll function is called repeatedly to poll to validator for information, it returns as
        // a response in the command structure what events are currently happening.
        public bool DoPoll()
        {
            byte i;

            m_cmd.CommandData[0]    = CCommands.SSP_CMD_POLL;
            m_cmd.CommandDataLength = 10;

            if (!SendCommand())
            {
                return(false);
            }

            // Store poll response to avoid corruption if the cmd structure is accessed whilst polling
            m_cmd.ResponseData.CopyTo(m_CurrentPollResponse, 0);
            m_CurrentPollResponseLength = m_cmd.ResponseDataLength;

            //parse poll m_CurrentPollResponse
            int noteVal = 0;

            for (i = 1; i < m_CurrentPollResponseLength; i++)
            {
                switch (m_CurrentPollResponse[i])
                {
                // This m_CurrentPollResponse indicates that the unit was reset and this is the first time a poll
                // has been called since the reset.
                case CCommands.SSP_POLL_SLAVE_RESET:
                    Log.WriteLog("Unit reset ");
                    UpdateData();
                    break;

                // A note is currently being read by the validator sensors. The second byte of this response
                // is zero until the note's type has been determined, it then changes to the channel of the
                // scanned note.
                case CCommands.SSP_POLL_READ_NOTE:
                    if (m_CurrentPollResponse[i + 1] > 0)
                    {
                        noteVal = GetChannelValue(m_CurrentPollResponse[i + 1]);
                        Log.WriteLog("Note in escrow, amount: " + CHelpers.FormatToCurrency(noteVal) + " " + GetChannelCurrency(m_CurrentPollResponse[i + 1]) + " ", "CashAcceptor");
                        noteVal = noteVal / 100;
                        if (Global.iTotalAmount < noteVal)
                        {
                            Log.WriteLog("Rs " + noteVal + " Return Fire", "CashAcceptor");
                            ReturnNote();
                        }

                        m_HoldCount = m_HoldNumber;
                    }
                    else
                    {
                        Log.WriteLog("Reading note ", "CashAcceptor");
                    }
                    i++;
                    break;

                // A credit event has been detected, this is when the validator has accepted a note as legal currency.
                case CCommands.SSP_POLL_CREDIT_NOTE:
                    noteVal = GetChannelValue(m_CurrentPollResponse[i + 1]);
                    Log.WriteLog("Credit " + CHelpers.FormatToCurrency(noteVal) + " " + GetChannelCurrency(m_CurrentPollResponse[i + 1]) + " ", "CashAcceptor");
                    Global.iTotalAmount = Global.iTotalAmount - (noteVal / 100);
                    NotesAccepted++;
                    UpdateData();
                    i++;
                    break;

                // A note is being rejected from the validator. This will carry on polling while the note is in transit.
                case CCommands.SSP_POLL_NOTE_REJECTING:
                    break;

                // A note has been rejected from the validator. This response only appears once.
                case CCommands.SSP_POLL_NOTE_REJECTED:
                    Log.WriteLog("Note rejected ", "CashAcceptor");
                    QueryRejection();
                    UpdateData();
                    EnableValidator();
                    break;

                // A note is in transit to the cashbox.
                case CCommands.SSP_POLL_NOTE_STACKING:
                    Log.WriteLog("Stacking note ", "CashAcceptor");
                    break;

                // A note has reached the cashbox.
                case CCommands.SSP_POLL_NOTE_STACKED:
                    Log.WriteLog("Note stacked ", "CashAcceptor");
                    break;

                // A safe jam has been detected. This is where the user has inserted a note and the note
                // is jammed somewhere that the user cannot reach.
                case CCommands.SSP_POLL_SAFE_NOTE_JAM:
                    Log.WriteLog("Safe jam ", "CashAcceptor");
                    break;

                // An unsafe jam has been detected. This is where a user has inserted a note and the note
                // is jammed somewhere that the user can potentially recover the note from.
                case CCommands.SSP_POLL_UNSAFE_NOTE_JAM:
                    Log.WriteLog("Unsafe jam ", "CashAcceptor");
                    break;

                // The validator is disabled, it will not execute any commands or do any actions until enabled.
                case CCommands.SSP_POLL_DISABLED:
                    Log.WriteLog("Unit disabled... ", "CashAcceptor");
                    break;

                // A fraud attempt has been detected. The second byte indicates the channel of the note that a fraud
                // has been attempted on.
                case CCommands.SSP_POLL_FRAUD_ATTEMPT:
                    Log.WriteLog("Fraud attempt, note type: " + GetChannelValue(m_CurrentPollResponse[i + 1]) + " ", "CashAcceptor");
                    i++;
                    break;

                // The stacker (cashbox) is full.
                case CCommands.SSP_POLL_STACKER_FULL:
                    Log.WriteLog("Stacker full ", "CashAcceptor");
                    break;

                // A note was detected somewhere inside the validator on startup and was rejected from the front of the
                // unit.
                case CCommands.SSP_POLL_NOTE_CLEARED_FROM_FRONT:
                    Log.WriteLog(GetChannelValue(m_CurrentPollResponse[i + 1]) + " " + GetChannelCurrency(m_CurrentPollResponse[i + 1]) + " note cleared from front at reset." + " ", "CashAcceptor");
                    i++;
                    break;

                // A note was detected somewhere inside the validator on startup and was cleared into the cashbox.
                case CCommands.SSP_POLL_NOTE_CLEARED_TO_CASHBOX:
                    Log.WriteLog(GetChannelValue(m_CurrentPollResponse[i + 1]) + " " + GetChannelCurrency(m_CurrentPollResponse[i + 1]) + " note cleared to stacker at reset." + " ", "CashAcceptor");
                    i++;
                    break;

                // The cashbox has been removed from the unit. This will continue to poll until the cashbox is replaced.
                case CCommands.SSP_POLL_CASHBOX_REMOVED:
                    Log.WriteLog("Cashbox removed ", "CashAcceptor");
                    break;

                // The cashbox has been replaced, this will only display on a poll once.
                case CCommands.SSP_POLL_CASHBOX_REPLACED:
                    Log.WriteLog("Cashbox replaced ", "CashAcceptor");
                    break;

                // A note has been stored in the payout device to be paid out instead of going into the cashbox.
                case CCommands.SSP_POLL_NOTE_STORED_IN_PAYOUT:
                    Log.WriteLog("Note stored ", "CashAcceptor");
                    i += (byte)((m_CurrentPollResponse[i + 1] * 7) + 1);
                    UpdateData();
                    break;

                // The validator is in the process of paying out a note, this will continue to poll until the note has
                // been fully dispensed and removed from the front of the validator by the user.
                case CCommands.SSP_POLL_DISPENSING:
                    Log.WriteLog("Dispensing note ", "CashAcceptor");
                    i += (byte)((m_CurrentPollResponse[i + 1] * 7) + 1);
                    break;

                // The note has been dispensed and removed from the bezel by the user.
                case CCommands.SSP_POLL_DISPENSED:
                    for (int j = 0; j < m_CurrentPollResponse[i + 1]; j += 7)
                    {
                        Log.WriteLog("Dispensed " + (CHelpers.ConvertBytesToInt32(m_CurrentPollResponse, j + i + 2) / 100).ToString() +
                                     " " + (char)m_CurrentPollResponse[j + i + 6] + (char)m_CurrentPollResponse[j + i + 7] +
                                     (char)m_CurrentPollResponse[j + i + 8] + " ", "CashAcceptor");
                    }
                    i += (byte)((m_CurrentPollResponse[i + 1] * 7) + 1);
                    NotesDispensed++;
                    UpdateData();
                    EnableValidator();
                    break;

                // A note has been transferred from the payout storage to the cashbox
                case CCommands.SSP_POLL_NOTE_TRANSFERED_TO_STACKER:
                    Log.WriteLog("Note stacked ", "CashAcceptor");
                    UpdateData();
                    EnableValidator();
                    break;

                // This single poll response indicates that the payout device has finished emptying.
                case CCommands.SSP_POLL_EMPTIED:
                    Log.WriteLog("Device emptied ", "CashAcceptor");
                    UpdateData();
                    EnableValidator();
                    break;

                // This response indicates a note is being dispensed and is resting in the bezel waiting to be removed
                // before the validator can continue
                case CCommands.SSP_POLL_NOTE_HELD_IN_BEZEL:
                    for (int j = 0; j < m_CurrentPollResponse[i + 1]; j += 7)
                    {
                        Log.WriteLog((CHelpers.ConvertBytesToInt32(m_CurrentPollResponse, j + i + 2) / 100).ToString() +
                                     " " + (char)m_CurrentPollResponse[j + i + 6] + (char)m_CurrentPollResponse[j + i + 7] +
                                     (char)m_CurrentPollResponse[j + i + 8] + " held in bezel... ", "CashAcceptor");
                    }
                    i += (byte)((m_CurrentPollResponse[i + 1] * 7) + 1);
                    break;

                case CCommands.SSP_POLL_SMART_EMPTYING:
                    Log.WriteLog((CHelpers.ConvertBytesToInt32(m_CurrentPollResponse, i + 2) / 100).ToString() +
                                 " " + (char)m_CurrentPollResponse[i + 6] + (char)m_CurrentPollResponse[i + 7] +
                                 (char)m_CurrentPollResponse[i + 8] + " emptied so far... ", "CashAcceptor");
                    i += 9;
                    break;

                case CCommands.SSP_POLL_SMART_EMPTIED:
                    Log.WriteLog((CHelpers.ConvertBytesToInt32(m_CurrentPollResponse, i + 2) / 100).ToString() +
                                 " " + (char)m_CurrentPollResponse[i + 6] + (char)m_CurrentPollResponse[i + 7] +
                                 (char)m_CurrentPollResponse[i + 8] + " emptied in total. ", "CashAcceptor");
                    i += 9;
                    EnableValidator();
                    break;

                //Default condition: do nothing
                default:
                    break;
                }
            }

            return(true);
        }