001package jmri.jmrix.nce;
002
003import jmri.JmriException;
004import org.slf4j.Logger;
005import org.slf4j.LoggerFactory;
006
007/**
008 * Checks that a NCE message is valid for the connection type. Throws an
009 * exception if message isn't appropriate for the connection type.
010 *
011 * @author Dan Boudreau Copyright (C) 2010
012 * @author ken cameron Copyright (C) 2013
013  *
014 */
015public class NceMessageCheck {
016
017    public static void checkMessage(NceSystemConnectionMemo memo, NceMessage m) throws JmriException {
018        if (m != null) {
019            switch (m.getOpCode()) {
020                /* NCE USB can now address the full range of accessory addresses dboudreau 1/18/2012
021                 case NceMessage.ACC_CMD: checkACC_CMD(memo, m);
022                 break;*/
023                case NceMessage.READ1_CMD:
024                    checkSerial_CMD(memo, m);
025                    break;
026                case NceMessage.READ16_CMD:
027                    checkSerial_CMD(memo, m);
028                    break;
029                case NceMessage.WRITE_N_CMD:
030                    checkSerial_CMD(memo, m);
031                    break;
032                case NceMessage.WRITE1_CMD:
033                    checkSerial_CMD(memo, m);
034                    break;
035                case NceMessage.WRITE2_CMD:
036                    checkSerial_CMD(memo, m);
037                    break;
038                case NceMessage.WRITE4_CMD:
039                    checkSerial_CMD(memo, m);
040                    break;
041                case NceMessage.WRITE8_CMD:
042                    checkSerial_CMD(memo, m);
043                    break;
044                case NceMessage.STOP_CLOCK_CMD:
045                    checkSerial_CMD(memo, m);
046                    break;
047                case NceMessage.START_CLOCK_CMD:
048                    checkSerial_CMD(memo, m);
049                    break;
050                case NceMessage.SET_CLOCK_CMD:
051                    checkSerial_CMD(memo, m);
052                    break;
053                case NceMessage.CLOCK_1224_CMD:
054                    checkSerial_CMD(memo, m);
055                    break;
056                case NceMessage.CLOCK_RATIO_CMD:
057                    checkSerial_CMD(memo, m);
058                    break;
059                case NceMessage.OPS_PROG_LOCO_CMD:
060                    checkOPS_PROG_CMD(memo, m);
061                    break;
062                case NceMessage.OPS_PROG_ACCY_CMD:
063                    checkOPS_PROG_CMD(memo, m);
064                    break;
065                case NceMessage.USB_MEM_POINTER_CMD:
066                    checkUsbMem_CMD(memo, m);
067                    break;
068                case NceMessage.USB_MEM_READ_CMD:
069                    checkUsbMem_CMD(memo, m);
070                    break;
071                case NceMessage.USB_MEM_WRITE_CMD:
072                    checkUsbMem_CMD(memo, m);
073                    break;
074                default:
075                    break;
076            }
077        }
078    }
079
080    /* NCE USB no longer has an accessory address restriction dboudreau 1/18/2012
081     private static void checkACC_CMD(NceSystemConnectionMemo memo, NceMessage m) throws JmriException{
082     // USB connected to PowerCab or SB3 can only access addresses up to 250
083     int number = m.getElement(1);   // high byte address
084     number = number*256 + m.getElement(2); // low byte address
085     if (number > 250 && 
086     (memo.getNceUSB() == NceTrafficController.USB_SYSTEM_POWERCAB 
087     || (memo.getNceUSB() == NceTrafficController.USB_SYSTEM_SB3))){
088     log.debug("invalid NCE accessory address for USB " + number);
089     throw new JmriException("invalid NCE accessory address for USB " + number);
090     }
091     }
092     */
093    private static void checkSerial_CMD(NceSystemConnectionMemo memo, NceMessage m) throws JmriException {
094        if (memo.getNceUsbSystem() != NceTrafficController.USB_SYSTEM_NONE) {
095            String txt = "attempt to send unsupported binary command to NCE USB: " + Integer.toHexString(m.getOpCode()).toUpperCase();
096            log.debug(txt);
097            throw new JmriException(txt);
098        }
099    }
100
101    private static void checkOPS_PROG_CMD(NceSystemConnectionMemo memo, NceMessage m) throws JmriException {
102        // ONLY USB connected to PowerCab or SB3 can send this message
103        if (memo.getNceUsbSystem() != NceTrafficController.USB_SYSTEM_NONE
104                && (memo.getNceCmdGroups() & NceTrafficController.CMDS_OPS_PGM) != NceTrafficController.CMDS_NONE) {
105            return;
106        }
107        String txt = "attempt to send unsupported binary command: " + Integer.toHexString(m.getOpCode()).toUpperCase();
108        log.debug(txt);
109        throw new JmriException(txt);
110
111    }
112
113    private static void checkUsbMem_CMD(NceSystemConnectionMemo memo, NceMessage m) throws JmriException {
114        // ONLY 7.* USB connected to >-1.65  can send this message
115        if (memo.getNceUsbSystem() != NceTrafficController.USB_SYSTEM_NONE
116                && (memo.getNceCmdGroups() & NceTrafficController.CMDS_MEM) != NceTrafficController.CMDS_NONE) {
117            return;
118        }
119        String txt = "attempt to send unsupported binary command: " + Integer.toHexString(m.getOpCode()).toUpperCase();
120        log.debug(txt);
121        throw new JmriException(txt);
122    }
123
124    private final static Logger log = LoggerFactory.getLogger(NceMessageCheck.class);
125}
126
127