001package jmri.jmrix.loconet;
002
003/**
004 * Constants to represent values seen in LocoNet traffic.
005 * <p>
006 * Some, but not all, of the names have a convention where the
007 * first "word" gives the type of the constant:
008 *  <ul>
009 *  <li>CONSIST - Consist type codes
010 *  <li>DEC - Decoder type codes
011 *  <li>OPC - LocoNet op code
012 *  <li>PCMD - Programming command
013 *  <li>RE - Re-engineered, not from the LocoNet documentations
014 *  <li>STAT1 - bits in status byte 1
015 *  <li>STAT2 - bits in status byte 2
016 *  </ul>
017 * <p>
018 * Slot Status byte definitions and macros
019 * <ul>
020 * <li>D7-SL_SPURGE : 1=SLOT purge en, ALSO adrSEL (INTERNAL use only) (not seen on NET!)
021 *
022 * <li>D6-SL_CONUP : CONDN/CONUP: bit encoding-Control double
023 * linked Consist List
024 *    <ul>
025 *    <li> 11=LOGICAL MID CONSIST , Linked up AND down
026 *    <li> 10=LOGICAL CONSIST TOP, Only linked downwards
027 *    <li> 01=LOGICAL CONSIST SUB-MEMBER, Only linked upwards
028 *    <li> 00=FREE locomotive, no CONSIST indirection/linking
029 *    </ul>
030 * ALLOWS "CONSISTS of CONSISTS". Uplinked means that Slot SPD number is
031 * now SLOT adr of SPD/DIR and STATUS of
032 * consist. i.e. is an Indirect pointer. This Slot
033 * has same BUSY/ACTIVE bits as TOP of Consist. TOP is
034 * loco with SPD/DIR for whole consist. (top of list).
035 *
036 * <li> D5-SL_BUSY: BUSY/ACTIVE: bit encoding for SLOT activity
037 *      <ul>
038 *      <li> 11=IN_USE loco adr in SLOT -REFRESHED
039 *      </ul>
040 *
041 * <li> D4-SL_ACTIVE ;
042 *      <ul>
043 *      <li>10=IDLE loco adr in SLOT -NOT refreshed
044 *      <li>01=COMMON loco adr IN SLOT-refreshed
045 *      <li>00=FREE SLOT, no valid DATA -not refreshed
046 *      </ul>
047 *
048 * <li>D3-SL_CONDN : shows other SLOT Consist linked INTO this slot, see SL_CONUP
049 *
050 * <li>D2-SL_SPDEX ; 3 BITS for Decoder TYPE encoding for this SLOT
051 *
052 * <li>D1-SL_SPD14
053 *      <ul>
054 *      <li>011=send 128 speed mode packets
055 *      </ul>
056 *
057 * <li>D0-SL_SPD28
058 *      <ul>
059 *      <li>010=14 step MODE
060 *      <li>001=28 step. Generate Trinary packets for this Mobile ADR
061 *      <li>000=28 step. 3 BYTE PKT regular mode
062 *      <li>111=128 Step decoder, Allow Advanced DCC consisting
063 *      <li>100=28 Step decoder ,Allow Advanced DCC consisting
064 *      </ul>
065 * </ul>
066 * Note that the values in this class have been taken from the llnmom C program
067 * of Ron W. Auld, which included some work of John Kabat. The symbol names are
068 * copied from the loconet.h file, CVS revision 1.1.1.1, program release 0.3.0
069 * Those parts are (C) Copyright 2001 Ron W. Auld, and are used with direct
070 * permission of the copyright holder.
071 * <p>
072 * Most major comment blocks here are quotes from the Digitrax LocoNet(r) OPCODE
073 * SUMMARY found in the LocoNet(r) Personal Edition 1.
074 * <p>
075 * Al Silverstein provided the reverse-engineering effort for the
076 * OPC_MULTI_SENSE message.
077 * <p>
078 * Alain Le Marchand completed the list of constants for Uhlenbrock Intellibox-I
079 * and -II, from observations of Intellibox traffic.
080 * <p>
081 * Some of the message formats used in this class are Copyright Digitrax, Inc.
082 * and used with permission as part of the JMRI project. That permission does
083 * not extend to uses in other software products. If you wish to use this code,
084 * algorithm or these message formats outside of JMRI, please contact Digitrax
085 * Inc for separate permission.
086 *
087 * @author Bob Jacobsen Copyright (C) 2001, 2008, 2015
088 * @author Ron W. Auld
089 * @author John Kabat
090 * @author Alain Le Marchand
091 * @author B. Milhaupt Copyright (C) 2018
092 * @author Michael Richardson Copyright (C) 2021
093 */
094public final class LnConstants {
095
096    /* various bit masks */
097    public final static int DIRF_DIR = 0x20;  /* direction bit    */
098
099    public final static int DIRF_F0 = 0x10;  /* Function 0 bit   */
100
101    public final static int DIRF_F4 = 0x08;  /* Function 1 bit   */
102
103    public final static int DIRF_F3 = 0x04;  /* Function 2 bit   */
104
105    public final static int DIRF_F2 = 0x02;  /* Function 3 bit   */
106
107    public final static int DIRF_F1 = 0x01;  /* Function 4 bit   */
108
109    public final static int SND_F8 = 0x08;  /* Sound 4/Function 8 bit */
110
111    public final static int SND_F7 = 0x04;  /* Sound 3/Function 7 bit */
112
113    public final static int SND_F6 = 0x02;  /* Sound 2/Function 6 bit */
114
115    public final static int SND_F5 = 0x01;  /* Sound 1/Function 5 bit */
116
117    public final static int OPC_SW_ACK_CLOSED = 0x20;  /* command switch closed/open bit   */
118
119    public final static int OPC_SW_ACK_OUTPUT = 0x10;  /* command switch output on/off bit */
120
121    public final static int OPC_INPUT_REP_CB = 0x40;  /* control bit, reserved otherwise      */
122
123    public final static int OPC_INPUT_REP_SW = 0x20;  /* input is switch input, aux otherwise */
124
125    public final static int OPC_INPUT_REP_HI = 0x10;  /* input is HI, LO otherwise            */
126
127    public final static int OPC_SW_REP_SW = 0x20;  /* switch input, aux input otherwise    */
128
129    public final static int OPC_SW_REP_HI = 0x10;  /* input is HI, LO otherwise            */
130
131    public final static int OPC_SW_REP_CLOSED = 0x20;  /* 'Closed' line is ON, OFF otherwise   */
132
133    public final static int OPC_SW_REP_THROWN = 0x10;  /* 'Thrown' line is ON, OFF otherwise   */
134
135    public final static int OPC_SW_REP_INPUTS = 0x40;  /* sensor inputs, outputs otherwise     */
136
137    public final static int OPC_SW_REQ_DIR = 0x20;  /* switch direction - closed/thrown     */
138
139    public final static int OPC_SW_REQ_OUT = 0x10;  /* output On/Off                        */
140
141    public final static int OPC_LOCO_SPD_ESTOP = 0x01; /* emergency stop command               */
142
143    public final static int OPC_MULTI_SENSE_MSG = 0x60; // byte 1
144    public final static int OPC_MULTI_SENSE_PRESENT = 0x20; // MSG field: transponder seen
145    public final static int OPC_MULTI_SENSE_ABSENT = 0x00; // MSG field: transponder lost
146    public final static int OPC_MULTI_SENSE_RAILCOM_AD = 0x40; // MSG field: RailCom App Dyn
147    public final static int OPC_MULTI_SENSE_POWER = 0x60; // MSG field: Power message
148
149    public final static int STAT1_SL_SPURGE = 0x80;  /* internal use only, not seen on net */
150
151    /** consist status                     */
152    public final static int STAT1_SL_CONUP = 0x40;
153
154    /** Used with STAT1_SL_ACTIVE         */
155    public final static int STAT1_SL_BUSY = 0x20;
156
157    public final static int STAT1_SL_ACTIVE = 0x10;
158
159    public final static int STAT1_SL_CONDN = 0x08;
160
161    public final static int STAT1_SL_SPDEX = 0x04;
162
163    public final static int STAT1_SL_SPD14 = 0x02;
164
165    public final static int STAT1_SL_SPD28 = 0x01;
166
167    /** 1 = Adv. Consisting supressed      */
168    public final static int STAT2_SL_SUPPRESS = 0x01;
169
170    /** 1 = ID1/ID2 is not ID usage        */
171    public final static int STAT2_SL_NOT_ID = 0x04;
172
173    /** 1 = ID1/ID2 is not encoded alias   */
174    public final static int STAT2_SL_NOTENCOD = 0x08;
175
176    public final static int STAT2_ALIAS_MASK = STAT2_SL_NOTENCOD | STAT2_SL_NOT_ID;
177    public final static int STAT2_ID_IS_ALIAS = STAT2_SL_NOT_ID;
178
179    /* mask and values for consist determination */
180    public final static int CONSIST_MASK = STAT1_SL_CONDN | STAT1_SL_CONUP;
181    public final static int CONSIST_MID = STAT1_SL_CONDN | STAT1_SL_CONUP;
182    public final static int CONSIST_TOP = STAT1_SL_CONDN;
183    public final static int CONSIST_SUB = STAT1_SL_CONUP;
184    public final static int CONSIST_NO = 0;
185
186    /**
187     * Encode consisting status as a string
188     *
189     * @param s  consist status bits
190     * @return string contaning a description of the consisting state
191     */
192    public final static String CONSIST_STAT(int s) {
193        return ((s & CONSIST_MASK) == CONSIST_MID) ? "Mid Consist" // NOI18N
194                : (((s & CONSIST_MASK) == CONSIST_TOP) ? "Consist TOP" // NOI18N
195                        : (((s & CONSIST_MASK) == CONSIST_SUB) ? "Sub Consist" // NOI18N
196                                : "Not Consisted")); // NOI18N
197    }
198
199   /** Mask for locomotive use determination.
200    * Compare value to {@link #LOCO_IN_USE},  {@link #LOCO_IDLE},
201    * {@link #LOCO_COMMON},  {@link #LOCO_FREE}
202    */
203    public final static int LOCOSTAT_MASK = STAT1_SL_BUSY | STAT1_SL_ACTIVE;
204    /** Value for locomotive use determination */
205    public final static int LOCO_IN_USE = STAT1_SL_BUSY | STAT1_SL_ACTIVE;
206    /** Value for locomotive use determination */
207    public final static int LOCO_IDLE = STAT1_SL_BUSY;
208    /** Value for locomotive use determination */
209    public final static int LOCO_COMMON = STAT1_SL_ACTIVE;
210    /** Value for locomotive use determination */
211    public final static int LOCO_FREE = 0;
212
213    /**
214     * Encode loco status as a string
215     *
216     * @param s  integer containing loco "status"
217     * @return string containing a description of the loco "status"
218     */
219    public final static String LOCO_STAT(int s) {
220        return ((s & LOCOSTAT_MASK) == LOCO_IN_USE) ? "In-Use" // NOI18N
221                : (((s & LOCOSTAT_MASK) == LOCO_IDLE) ? "Idle" // NOI18N
222                        : (((s & LOCOSTAT_MASK) == LOCO_COMMON) ? "Common" // NOI18N
223                                : "Free")); // NOI18N
224    }
225
226   /** Mask for decoder type encoding for this slot.
227    * Compare value to
228    * {@link #DEC_MODE_128A}, {@link #DEC_MODE_28A}, {@link #DEC_MODE_128},
229    * {@link #DEC_MODE_14}, {@link #DEC_MODE_28TRI}, {@link #DEC_MODE_28}
230    */
231    public final static int DEC_MODE_MASK = STAT1_SL_SPDEX | STAT1_SL_SPD14 | STAT1_SL_SPD28;
232    /** Decoder Type: 128 step, Advanced Consisting allowed */
233    public final static int DEC_MODE_128A = STAT1_SL_SPDEX | STAT1_SL_SPD14 | STAT1_SL_SPD28;
234    /** Decoder Type: 28 step, Advanced Consisting allowed */
235    public final static int DEC_MODE_28A = STAT1_SL_SPDEX;
236    /** Decoder Type:  128 step */
237    public final static int DEC_MODE_128 = STAT1_SL_SPD14 | STAT1_SL_SPD28;
238    /** Decoder Type:  14 step */
239    public final static int DEC_MODE_14 = STAT1_SL_SPD14;
240    /** Decoder Type:  28 step, send Motorola Trinary */
241    public final static int DEC_MODE_28TRI = STAT1_SL_SPD28;
242    /** Decoder Type:  28 step */
243    public final static int DEC_MODE_28 = 0;
244
245    public final static String DEC_MODE(int s) { // encode decoder type as a string
246        return ((s & DEC_MODE_MASK) == DEC_MODE_128A) ? "128 (Allow Adv. consisting)" // NOI18N
247                : (((s & DEC_MODE_MASK) == DEC_MODE_28A) ? "28 (Allow Adv. consisting)" // NOI18N
248                        : (((s & DEC_MODE_MASK) == DEC_MODE_128) ? "128" // NOI18N
249                                : (((s & DEC_MODE_MASK) == DEC_MODE_14) ? "14" // NOI18N
250                                        : (((s & DEC_MODE_MASK) == DEC_MODE_28TRI) ? "28 (Motorola)" // NOI18N
251                                                : "28")))); // NOI18N
252    }
253
254    /* values for track status encoding for this slot */
255    public final static int GTRK_PROG_BUSY = 0x08; /* 1 = programming track in this master is Busy         */
256
257    public final static int GTRK_MLOK1 = 0x04;     /* 0 = Master is DT200, 1=Master implements LocoNet 1.1 */
258
259    public final static int GTRK_IDLE = 0x02;      /* 0=TRACK is PAUSED, B'cast EMERG STOP.                */
260
261    public final static int GTRK_POWER = 0x01;     /* 1=DCC packets are ON in MASTER, Global POWER up      */
262
263    /** Fast clock is in this slot                           */
264    public final static int FC_SLOT = 0x7b;
265
266    /** Fast CLock valid **/
267    public final static int FC_VALID = 0X40;
268
269     /** This slot communicates with the programming track   */
270    public final static int PRG_SLOT = 0x7c;
271
272    /** This slot holds extended configuration bits for some command stations */
273    public final static int CFG_EXT_SLOT = 0x7e;
274
275    /** This slot holds configuration bits                   */
276    public final static int CFG_SLOT = 0x7f;
277
278    /** Values and macros to decode programming messages */
279    public final static int PCMD_RW = 0x40;        /* 1 = write, 0 = read                                  */
280
281    public final static int PCMD_BYTE_MODE = 0x20; /* 1 = byte operation, 0 = bit operation (if possible)  */
282
283    public final static int PCMD_TY1 = 0x10;       /* TY1 Programming type select bit                      */
284
285    public final static int PCMD_TY0 = 0x08;       /* TY0 Programming type select bit                      */
286
287    public final static int PCMD_OPS_MODE = 0x04;  /* 1 = Ops Mode, 0 = Service Mode                       */
288
289    public final static int PCMD_RSVRD1 = 0x02;    /* reserved                                             */
290
291    public final static int PCMD_RSVRD0 = 0x01;    /* reserved                                             */
292
293    /** Programming mode mask */
294    public final static int PCMD_MODE_MASK = PCMD_BYTE_MODE | PCMD_OPS_MODE | PCMD_TY1 | PCMD_TY0;
295
296    /** Programming modes: Paged mode byte R/W on Service Track */
297    public final static int PAGED_ON_SRVC_TRK = PCMD_BYTE_MODE;
298
299    /** Programming modes: Direct mode byte R/W on Service Track */
300    public final static int DIR_BYTE_ON_SRVC_TRK = PCMD_BYTE_MODE | PCMD_TY0;
301
302    /** Programming modes: Direct mode bit  R/W on Service Track */
303    public final static int DIR_BIT_ON_SRVC_TRK = PCMD_TY0;
304
305    /** Programming modes: Physical Register byte R/W on Service Track */
306    public final static int REG_BYTE_RW_ON_SRVC_TRK = PCMD_TY1;
307
308    /** Programming modes: Service Track Reserved function */
309    public final static int SRVC_TRK_RESERVED = PCMD_TY1 | PCMD_TY0;
310
311    /** Programming modes: Ops mode byte program - no feedback */
312    public final static int OPS_BYTE_NO_FEEDBACK = PCMD_BYTE_MODE | PCMD_OPS_MODE;
313
314    /** Programming modes: Ops mode byte program - feedback */
315    public final static int OPS_BYTE_FEEDBACK = OPS_BYTE_NO_FEEDBACK | PCMD_TY0;
316
317    /** Programming modes: Ops mode bit program - no feedback */
318    public final static int OPS_BIT_NO_FEEDBACK = PCMD_OPS_MODE;
319
320    /** Programming modes: Ops mode bit program - feedback */
321    public final static int OPS_BIT_FEEDBACK = OPS_BIT_NO_FEEDBACK | PCMD_TY0;
322
323    /** Programmer status error flags: User aborted this command */
324    public final static int PSTAT_USER_ABORTED = 0x08;
325
326    /** Programmer status error flags: Failed to detect Read Compare Acknowledge from decoder */
327    public final static int PSTAT_READ_FAIL = 0x04;
328
329    /** Programmer status error flags: No Write acknowledge from decoder */
330    public final static int PSTAT_WRITE_FAIL = 0x02;
331
332    /** Programmer status error flags: Service mode programming track empty  */
333    public final static int PSTAT_NO_DECODER = 0x01;
334
335    /* bit masks for CVH */
336    public final static int CVH_CV8_CV9 = 0x30; /* mask for CV# bits 8 and 9 */
337
338    public final static int CVH_CV7 = 0x01;     /* mask for CV# bit 7        */
339
340    public final static int CVH_D7 = 0x02;      /* MSbit for data value      */
341
342    /* LocoNet opcodes */
343    public final static int OPC_GPBUSY = 0x81;
344    public final static int OPC_GPOFF = 0x82;
345    public final static int OPC_GPON = 0x83;
346    public final static int OPC_IDLE = 0x85;
347    public final static int OPC_RE_LOCORESET_BUTTON = 0x8A; // Undocumented name
348    public final static int OPC_LOCO_SPD = 0xa0;
349    public final static int OPC_LOCO_DIRF = 0xa1;
350    public final static int OPC_LOCO_SND = 0xa2;
351    public final static int OPC_SW_REQ = 0xb0;
352    public final static int OPC_SW_REP = 0xb1;
353    public final static int OPC_INPUT_REP = 0xb2;
354    public final static int OPC_UNKNOWN = 0xb3;
355    public final static int OPC_LONG_ACK = 0xb4;
356    public final static int OPC_SLOT_STAT1 = 0xb5;
357    public final static int OPC_CONSIST_FUNC = 0xb6;
358    public final static int OPC_UNLINK_SLOTS = 0xb8;
359    public final static int OPC_LINK_SLOTS = 0xb9;
360    public final static int OPC_MOVE_SLOTS = 0xba;
361    public final static int OPC_RQ_SL_DATA = 0xbb;
362    public final static int OPC_SW_STATE = 0xbc;
363    public final static int OPC_SW_ACK = 0xbd;
364    public final static int OPC_LOCO_ADR = 0xbf;
365    public final static int OPC_MULTI_SENSE = 0xd0; // Undocumented name
366    public final static int OPC_MULTI_SENSE_LONG = 0xe0; // Undocumented name
367    public final static int OPC_PANEL_RESPONSE = 0xd7; // Undocumented name
368    public final static int OPC_PANEL_QUERY = 0xdf; // Undocumented name
369    public final static int OPC_LISSY_UPDATE = 0xe4; // Undocumented name
370    public final static int OPC_PEER_XFER = 0xe5;
371    public final static int OPC_ALM_READ = 0xe6; // Undocumented name
372    public final static int OPC_SL_RD_DATA = 0xe7;
373    public final static int OPC_IMM_PACKET = 0xed;
374    public final static int OPC_IMM_PACKET_2 = 0xee;
375    public final static int OPC_WR_SL_DATA = 0xef;
376    public final static int OPC_ALM_WRITE = 0xee; // Undocumented name
377    public final static int OPC_MASK = 0x7f;  /* mask for acknowledge opcodes */
378
379    /* protocol level */
380
381    /** The protocol has not been established */
382    public final static int LOCONETPROTOCOL_UNKNOWN = 0;
383    /** Supports loconet 1.1 */
384    public final static int LOCONETPROTOCOL_ONE = 1;
385    /** Supports the protocol introduced to DCS240, DCS210 */
386    public final static int LOCONETPROTOCOL_TWO = 2;
387
388    /* Expanded slot codes */
389    public final static int OPC_EXP_REQ_SLOT = 0xbe;
390    // public final static int OPC_EXP_SLOT_MOVE = 0xd4;
391    public final static int OPC_EXP_RD_SL_DATA = 0xe6;
392    public final static int OPC_EXP_WR_SL_DATA = 0xee;
393    // Functions, Speed and directions
394    public final static int OPC_EXP_SEND_FUNCTION_OR_SPEED_AND_DIR = 0xd5;
395    public final static int OPC_EXP_SEND_SUB_CODE_MASK_SPEED = 0b11110000;
396    public final static int OPC_EXP_SEND_SPEED_AND_DIR_FWD = 0b00000000;
397    public final static int OPC_EXP_SEND_SPEED_AND_DIR_REV = 0b00001000;
398    public final static int OPC_EXP_SEND_SUB_CODE_MASK_FUNCTION = 0b11111000;
399    public final static int OPC_EXP_SEND_FUNCTION_GROUP_F0F6 =          0b00010000;
400    public final static int OPC_EXP_SEND_FUNCTION_GROUP_F7F13 =         0b00011000;
401    public final static int OPC_EXP_SEND_FUNCTION_GROUP_F14F20 =        0b00100000;
402    public final static int OPC_EXP_SEND_FUNCTION_GROUP_F21F28_F28OFF = 0b00101000;
403    public final static int OPC_EXP_SEND_FUNCTION_GROUP_F21F28_F28ON =  0b00110000;
404
405    /**
406     * Encode LocoNet Opcode as a string
407     *
408     * @param opcode  a LocoNet opcode value
409     * @return string containing the opcode "name"
410     */
411    public final static String OPC_NAME(int opcode) {
412        switch (opcode) {
413            case OPC_GPBUSY     : return "OPC_GPBUSY"; // NOI18N
414            case OPC_GPOFF      : return "OPC_GPOFF"; // NOI18N
415            case OPC_GPON       : return "OPC_GPON"; // NOI18N
416            case OPC_IDLE       : return "OPC_IDLE"; // NOI18N
417            case OPC_RE_LOCORESET_BUTTON:   return "OPC_RE_LOCORESET_BUTTON"; // NOI18N
418            case OPC_LOCO_SPD   : return "OPC_LOCO_SPD"; // NOI18N
419            case OPC_LOCO_DIRF  : return "OPC_LOCO_DIRF"; // NOI18N
420            case OPC_LOCO_SND   : return "OPC_LOCO_SND"; // NOI18N
421            case OPC_SW_REQ     : return "OPC_SW_REQ"; // NOI18N
422            case OPC_SW_REP     : return "OPC_SW_REP"; // NOI18N
423            case OPC_INPUT_REP  : return "OPC_INPUT_REP"; // NOI18N
424            case OPC_UNKNOWN    : return "OPC_UNKNOWN"; // NOI18N
425            case OPC_LONG_ACK   : return "OPC_LONG_ACK"; // NOI18N
426            case OPC_SLOT_STAT1 : return "OPC_SLOT_STAT1"; // NOI18N
427            case OPC_CONSIST_FUNC: return "OPC_CONSIST_FUNC"; // NOI18N
428            case OPC_UNLINK_SLOTS: return "OPC_UNLINK_SLOTS"; // NOI18N
429            case OPC_LINK_SLOTS : return "OPC_LINK_SLOTS"; // NOI18N
430            case OPC_MOVE_SLOTS : return "OPC_MOVE_SLOTS"; // NOI18N
431            case OPC_RQ_SL_DATA : return "OPC_RQ_SL_DATA"; // NOI18N
432            case OPC_SW_STATE   : return "OPC_SW_STATE"; // NOI18N
433            case OPC_SW_ACK     : return "OPC_SW_ACK"; // NOI18N
434            case OPC_LOCO_ADR   : return "OPC_LOCO_ADR"; // NOI18N
435            case OPC_MULTI_SENSE: return "OPC_MULTI_SENSE"; // NOI18N
436            case OPC_MULTI_SENSE_LONG: return "OPC_MULTI_SENSE_LONG"; // NOI18N
437            case OPC_PANEL_QUERY: return "OPC_PANEL_QUERY"; // NOI18N
438            case OPC_PANEL_RESPONSE: return "OPC_PANEL_RESPONSE"; // NOI18N
439            case OPC_LISSY_UPDATE: return "OPC_LISSY_UPDATE"; // NOI18N
440            case OPC_PEER_XFER  : return "OPC_PEER_XFER"; // NOI18N
441            case OPC_ALM_READ   : return "OPC_ALM_READ"; // NOI18N
442            case OPC_SL_RD_DATA : return "OPC_SL_RD_DATA"; // NOI18N
443            case OPC_IMM_PACKET : return "OPC_IMM_PACKET"; // NOI18N
444            case OPC_IMM_PACKET_2: return "OPC_IMM_PACKET_2"; // NOI18N
445            case OPC_WR_SL_DATA : return "OPC_WR_SL_DATA"; // NOI18N
446            // case OPC_WR_SL_DATA_EXP: return "OPC_WR_SL_DATA_EXP"; // duplicates 0xEE
447            // case OPC_ALM_WRITE: return "OPC_ALM_WRITE"; // duplicates 0xEE
448            default: return "<unknown>"; // NOI18N
449        }
450    }
451    /**
452     * Encode Device IPL code as a string
453     *
454     * @param device code
455     * @return string containing the opcode "name"
456     */
457    public final static String IPL_NAME(int device) {
458        switch (device) {
459            case RE_IPL_DIGITRAX_HOST_LNRP:
460                return "LNRP";
461            case RE_IPL_DIGITRAX_HOST_UT4:
462                return "UT4";
463            case RE_IPL_DIGITRAX_HOST_UT6:
464                return "UT6";
465            case RE_IPL_DIGITRAX_HOST_WTL12:
466                return "WTL12";
467            case RE_IPL_DIGITRAX_HOST_DB210OPTO:
468                return "DB210OPTO";
469            case RE_IPL_DIGITRAX_HOST_DB210:
470                return "DB210";
471            case RE_IPL_DIGITRAX_HOST_DB220:
472                return "DB220";
473            case RE_IPL_DIGITRAX_HOST_DCS210PLUS:
474                return "DCS210PLUS";
475            case RE_IPL_DIGITRAX_HOST_DCS210:
476                return "DCS210";
477            case RE_IPL_DIGITRAX_HOST_DCS240:
478                return "DCS240";
479            case RE_IPL_DIGITRAX_HOST_DCS240PLUS:
480                return "DCS240PLUS";
481            case RE_IPL_DIGITRAX_HOST_DCS52:
482                return "DCS52";
483            case RE_IPL_DIGITRAX_HOST_PR3:
484                return "PR3";
485            case RE_IPL_DIGITRAX_HOST_PR4:
486                return "PR4";
487            case RE_IPL_DIGITRAX_HOST_DT402:
488                return "DT402";
489            case RE_IPL_DIGITRAX_HOST_DT500:
490                return "DT500";
491            case RE_IPL_DIGITRAX_HOST_DT602:
492                return "DT602";
493            case RE_IPL_DIGITRAX_HOST_DCS51:
494                return "DCS51";
495            case RE_IPL_DIGITRAX_HOST_BXPA1:
496                return "BXPA1";
497            case RE_IPL_DIGITRAX_HOST_UR92:
498                return "UR92";
499            case RE_IPL_DIGITRAX_HOST_UR93:
500                return "UR93";
501            case RE_IPL_DIGITRAX_HOST_BXP88:
502                return "BXP88";
503            case RE_IPL_DIGITRAX_HOST_DS74:
504                return "DS74";
505            case RE_IPL_DIGITRAX_HOST_DS78V:
506                return "DS78V";
507            case RE_IPL_DIGITRAX_HOST_LNWI:
508                return "LNWI";
509            case RE_IPL_DIGITRAX_SLAVE_RF24:
510                return "RF24";
511            case RE_IPL_DIGITRAX_HOST_PM74:
512                return "PM74";
513            case RE_IPL_DIGITRAX_HOST_SE74:
514                return "SE74";
515            default: return "<unknown>"; // NOI18N
516        }
517    }
518
519
520// start of values not from llnmon.c
521
522// Multimeter polling interval
523    public final static int METER_INTERVAL_MS = 30000;
524
525// Expanded slot index values
526    public final static int EXP_MAST = 0;
527    public final static int EXP_SLOT = 0x01;
528    public final static int EXPD_LENGTH = 16;
529//offsets into message
530    public final static int EXPD_STAT = 0;
531    public final static int EXPD_ADRL = 1;
532    public final static int EXPD_ADRH = 2;
533    public final static int EXPD_FLAGS = 3;
534    public final static int EXPD_SPD = 4;
535    public final static int EXPD_F28F20F12 = 5;
536    public final static int EXPD_DIR_F0F4_F1 = 6;
537    public final static int EXPD_F11_F5 = 7;
538    public final static int EXPD_F19_F13 = 8;
539    public final static int EXPD_F27_F21 = 9;
540
541//  opcode keys used to express interest in various messages
542//            note these are _not_ the LocoNet opcode values!
543    public final static int KEY_GPBUSY = 1 << 0;
544    public final static int KEY_GPOFF = 1 << 1;
545    public final static int KEY_GPON = 1 << 2;
546    public final static int KEY_IDLE = 1 << 3;
547
548    public final static int KEY_LOCO_SPD = 1 << 4;
549    public final static int KEY_LOCO_DIRF = 1 << 5;
550    public final static int KEY_LOCO_SND = 1 << 6;
551    public final static int KEY_SW_REQ = 1 << 7;
552
553    public final static int KEY_SW_REP = 1 << 8;
554    public final static int KEY_INPUT_REP = 1 << 9;
555    public final static int KEY_LONG_ACK = 1 << 10;
556    public final static int KEY_SLOT_STAT1 = 1 << 11;
557
558    public final static int KEY_CONSIST_FUNC = 1 << 12;
559    public final static int KEY_UNLINK_SLOTS = 1 << 13;
560    public final static int KEY_LINK_SLOTS = 1 << 14;
561    public final static int KEY_MOVE_SLOTS = 1 << 15;
562
563    public final static int KEY_RQ_SL_DATA = 1 << 16;
564    public final static int KEY_SW_STATE = 1 << 17;
565    public final static int KEY_SW_ACK = 1 << 18;
566    public final static int KEY_LOCO_ADR = 1 << 19;
567
568    public final static int KEY_PEER_XFR = 1 << 20;
569    public final static int KEY_IMM_PACKET = 1 << 21;
570    public final static int KEY_WR_SL_DATA = 1 << 22;
571
572// reverse-engineered constants
573    public final static int RE_IPL_MFR_DIGITRAX = 0x00;
574    public final static int RE_IPL_MFR_ALL = 0x00;
575    public final static int RE_IPL_DIGITRAX_HOST_LNRP = 0x01;
576    public final static int RE_IPL_DIGITRAX_HOST_UT4 = 0x04;
577    public final static int RE_IPL_DIGITRAX_HOST_UT6 = 0x06;
578    public final static int RE_IPL_DIGITRAX_HOST_WTL12 = 0x0c;
579    public final static int RE_IPL_DIGITRAX_HOST_DB210OPTO = 0x14;
580    public final static int RE_IPL_DIGITRAX_HOST_DB210 = 0x15;
581    public final static int RE_IPL_DIGITRAX_HOST_DB220 = 0x16;
582    public final static int RE_IPL_DIGITRAX_HOST_DCS210PLUS = 0x1a;
583    public final static int RE_IPL_DIGITRAX_HOST_DCS210 = 0x1b;
584    public final static int RE_IPL_DIGITRAX_HOST_DCS240 = 0x1c;
585    public final static int RE_IPL_DIGITRAX_HOST_DCS240PLUS = 0x1d;
586    public final static int RE_IPL_DIGITRAX_HOST_DCS52 = 0x34;
587    public final static int RE_IPL_DIGITRAX_HOST_PR3 = 0x23;
588    public final static int RE_IPL_DIGITRAX_HOST_PR4 = 0x24;
589    public final static int RE_IPL_DIGITRAX_HOST_DT402 = 0x2A;
590    public final static int RE_IPL_DIGITRAX_HOST_DT500 = 0x32;
591    public final static int RE_IPL_DIGITRAX_HOST_DT602 = 0x3E;
592    public final static int RE_IPL_DIGITRAX_HOST_DCS51 = 0x33;
593    public final static int RE_IPL_DIGITRAX_HOST_SE74 = 0x46;
594    public final static int RE_IPL_DIGITRAX_HOST_PM74 = 0x4A;
595    public final static int RE_IPL_DIGITRAX_HOST_BXPA1 = 0x51;
596    public final static int RE_IPL_DIGITRAX_HOST_UR92 = 0x5C;
597    public final static int RE_IPL_DIGITRAX_HOST_UR93 = 0x5D;
598    public final static int RE_IPL_DIGITRAX_HOST_BXP88 = 0x58;
599    public final static int RE_IPL_DIGITRAX_HOST_DS74 = 0x74;
600    public final static int RE_IPL_DIGITRAX_HOST_DS78V = 0x7C;
601    public final static int RE_IPL_DIGITRAX_HOST_LNWI = 0x63;
602    public final static int RE_IPL_DIGITRAX_HOST_ALL = 0x00;
603    public final static int RE_IPL_DIGITRAX_SLAVE_RF24 = 0x18;
604    public final static int RE_IPL_DIGITRAX_SLAVE_ALL = 0x00;
605    public final static int RE_IPL_PING_OPERATION = 0x08;
606    public final static int RE_IPL_IDENTITY_OPERATION = 0x0f;
607    public final static int RE_LACK_SPEC_CASE1 = 0x50; // special case LACK response for OpSw accesses
608    public final static int RE_LACK_SPEC_CASE2 = 0x00; // special case LACK response for OpSw accesses
609    public final static int RE_OPC_PR3_MODE = 0xD3;
610    public final static int RE_MULTI_SENSE_DEV_TYPE_PM4X = 0x00;
611    public final static int RE_MULTI_SENSE_DEV_TYPE_BDL16X = 0x01;
612    public final static int RE_MULTI_SENSE_DEV_TYPE_SE8 = 0x02;
613    public final static int RE_MULTI_SENSE_DEV_TYPE_DS64 = 0x03;
614
615// Below data is assumed, based on firmware files available from RR-Cirkits web site
616    public final static int RE_IPL_MFR_RR_CIRKITS = 87;
617    public final static int RE_IPL_RRCIRKITS_HOST_TC64 = 11;
618    public final static int RE_IPL_RRCIRKITS_HOST_LNCP = 12;
619    public final static int RE_IPL_RRCIRKITS_HOST_SIGNALMAN = 21;
620    public final static int RE_IPL_RRCIRKITS_HOST_TOWERMAN = 22;
621    public final static int RE_IPL_RRCIRKITS_HOST_WATCHMAN = 23;
622    public final static int RE_IPL_RRCIRKITS_HOST_TC64_MKII = 24;
623    public final static int RE_IPL_RRCIRKITS_HOST_MOTORMAN = 25;
624    public final static int RE_IPL_RRCIRKITS_HOST_MOTORMAN_II = 28;
625    public final static int RE_IPL_RRCIRKITS_SLAVE_ALL = 00;
626
627// Constants associated with OPC_PEER_XFR for Duplex operations
628    public final static int RE_DPLX_OP_TYPE_WRITE = 0x00;
629    public final static int RE_DPLX_OP_TYPE_QUERY = 0x08;
630    public final static int RE_DPLX_OP_TYPE_REPORT = 0x10;
631    public final static int RE_DPLX_OP_LEN = 0x14;
632    public final static int RE_IPL_OP_LEN = 0x14;
633    public final static int RE_IPL_OP_QUERY = 0x08;
634    public final static int RE_IPL_OP_REPORT = 0x10;
635    public final static int RE_IPL_OP_SLV_QUERY = 0x00;
636    public final static int RE_IPL_OP_HFW_QUERY = 0x00;
637    public final static int RE_IPL_OP_HSNM_QUERY = 0x00;
638    public final static int RE_IPL_OP_SFW_QUERY = 0x00;
639    public final static int RE_IPL_OP_HSN0_QUERY = 0x01;
640    public final static int RE_IPL_OP_HSN1_QUERY = 0x00;
641    public final static int RE_IPL_OP_HSN2_QUERY = 0x00;
642    public final static int RE_IPL_OP_SSNM_QUERY = 0x00;
643    public final static int RE_IPL__OP_SSN0_QUERY = 0x00;
644    public final static int RE_IPL_OP_SSN1_QUERY = 0x00;
645    public final static int RE_IPL_OP_SSN2_QUERY = 0x00;
646    public final static int RE_IPL_OP_SSN3_QUERY = 0x00;
647    public final static int RE_DPLX_GP_CHAN_TYPE = 2;
648    public final static int RE_DPLX_GP_NAME_TYPE = 3;
649    public final static int RE_DPLX_GP_ID_TYPE = 4;
650    public final static int RE_DPLX_GP_PW_TYPE = 7;
651    public final static int RE_DPLX_OPC_BAD = 0x80;
652    public final static int RE_DPLX_MSB1_BIT = 1;
653    public final static int RE_DPLX_MSB2_BIT = 2;
654    public final static int RE_DPLX_MSB3_BIT = 4;
655    public final static int RE_DPLX_MSB4_BIT = 8;
656    public final static int RE_DPLX_BUMP_MSB1_BIT = 7;
657    public final static int RE_DPLX_BUMP_MSB2_BIT = 6;
658    public final static int RE_DPLX_BUMP_MSB3_BIT = 5;
659    public final static int RE_DPLX_BUMP_MSB4_BIT = 4;
660    public final static int RE_DPLX_7BITS_MAX = 127;
661    public final static int RE_DPLX_MAX_NOT_OPC = 0x7F;
662    public final static int RE_DPLX_ALT_CH_MSB_BIT = 0x4;
663    public final static int RE_DPLX_ALT_CH_MSB_SHIFT = 0x5;
664    public final static int RE_DPLX_ALT_ID_MSB_BIT = 0x8;
665    public final static int RE_DPLX_ALT_ID_MSB_SHIFT = 0x4;
666    public final static int RE_DPLX_ALT_PW1_MSB_BIT = 0x1;
667    public final static int RE_DPLX_ALT_PW1_MSB_SHIFT = 0x3;
668    public final static int RE_DPLX_ALT_PW3_MSB_BIT = 0x2;
669    public final static int RE_DPLX_ALT_PW3_MSB_SHIFT = 0x2;
670
671    public final static int RE_DPLX_DATA_LS_NIBBLE = 0x0F;
672    public final static int RE_DPLX_DATA_MS_NIBBLE = 0x70;
673    public final static int RE_DPLX_DATA_MS_NIBBLE_SHIFT = 4;
674
675// Duplex Group Scan Operation Constants
676    public final static int RE_DPLX_SCAN_OP_LEN = 0x14;
677    public final static int RE_DPLX_SCAN_QUERY_B2 = 0x10;
678    public final static int RE_DPLX_SCAN_QUERY_B3 = 0x08;
679    public final static int RE_DPLX_SCAN_QUERY_B4 = 0x00;
680    public final static int RE_DPLX_SCAN_REPORT_B2 = 0x10;
681    public final static int RE_DPLX_SCAN_REPORT_B3 = 0x10;
682
683    /* Intellibox-II mobile decoder function control beyond F8
684     * also used for Intellibox-I ("one") with SW version 2.x for control of functions beyond F8
685     * Intellibox-I version 2.x has two ways to control F0-F8:
686     *    - with regular LocoNet OPC_LOCO_SND and OPC_LOCO_DIRF
687     *    - with special Uhlenbrock RE_OPC_IB2_SPECIAL
688     *
689     * 4 byte MESSAGE with OPCODE = RE_OPC_IB2_F9_F12
690     * Used by Intellibox-II only, for F9-F12
691     * FORMAT = <OPC>,<SLOT>,<FUNC>,<CKSUM>
692     * :
693     *  <SLOT> = Slot number
694     *  <FUNC> = functions F9-F12 mask
695     */
696    public final static int RE_OPC_IB2_F9_F12 = 0xA3;
697    public final static int RE_IB2_F9_MASK = 0x01;
698    public final static int RE_IB2_F10_MASK = 0x02;
699    public final static int RE_IB2_F11_MASK = 0x04;
700    public final static int RE_IB2_F12_MASK = 0x08;
701
702    /* 6 byte MESSAGE with OPCODE = RE_OPC_IB2_SPECIAL
703     * Used by Intellibox-I for F0-F28 and Intellibox-II for F13-F28
704     * For Intellibox-I, for F0-F8:
705     *      - F0-F8 triggers this message only when controlling function after pressing twice on lok# button
706     *      - Direct control of functions through function buttons triggers the regular LocoNet function message
707     * :
708     * FORMAT = <OPC>,<SPE>,<SLOT>,<FTOK>,<FUNC>,<CKSUM>
709     * :
710     *  <SPE> = Specific value RE_IB2_SPECIAL_FUNCS_TOKEN
711     *  <SLOT> = Slot number
712     *  <FTOK> = functions token
713     *  <FUNC> = functions mask
714     */
715// Common to Intellibox-I and -II :
716    public final static int OPC_EXP_SLOT_MOVE_RE_OPC_IB2_SPECIAL= 0xD4; //For functions F13-F28 (IB-II) and by IB-I v2.x ("one") for F0-F28
717    public final static int RE_IB2_SPECIAL_FUNCS_TOKEN = 0x20;
718//Used only by Intellibox-I ("one") version 2.x
719    public final static int RE_IB1_SPECIAL_F0_F4_TOKEN = 0x06; //Used by Intellibox-I ("one") version 2.x
720    public final static int RE_IB1_F0_MASK = 0x10; //Used by Intellibox-I ("one") version 2.x only for F0
721    public final static int RE_IB1_F1_MASK = 0x01; //Used by Intellibox-I ("one") version 2.x only for F1
722    public final static int RE_IB1_F2_MASK = 0x02; //Used by Intellibox-I ("one") version 2.x only for F2
723    public final static int RE_IB1_F3_MASK = 0x04; //Used by Intellibox-I ("one") version 2.x only for F3
724    public final static int RE_IB1_F4_MASK = 0x08; //Used by Intellibox-I ("one") version 2.x only for F4
725//Used only by Intellibox-I ("one") version 2.x
726    public final static int RE_IB1_SPECIAL_F5_F11_TOKEN = 0x07; //Used by Intellibox-I ("one") version 2.x
727    public final static int RE_IB1_F5_MASK = 0x01; //Used by Intellibox-I ("one") version 2.x only for F5
728    public final static int RE_IB1_F6_MASK = 0x02; //Used by Intellibox-I ("one") version 2.x only for F6
729    public final static int RE_IB1_F7_MASK = 0x04; //Used by Intellibox-I ("one") version 2.x only for F7
730    public final static int RE_IB1_F8_MASK = 0x08; //Used by Intellibox-I ("one") version 2.x only for F8
731    public final static int RE_IB1_F9_MASK = 0x10; //Used by Intellibox-I ("one") version 2.x only for F9
732    public final static int RE_IB1_F10_MASK = 0x20; //Used by Intellibox-I ("one") version 2.x only for F10
733    public final static int RE_IB1_F11_MASK = 0x40; //Used by Intellibox-I ("one") version 2.x only for F11
734// Common to Intellibox-I and -II :
735    public final static int RE_IB2_SPECIAL_F13_F19_TOKEN = 0x08;
736    public final static int RE_IB2_F13_MASK = 0x01;
737    public final static int RE_IB2_F14_MASK = 0x02;
738    public final static int RE_IB2_F15_MASK = 0x04;
739    public final static int RE_IB2_F16_MASK = 0x08;
740    public final static int RE_IB2_F17_MASK = 0x10;
741    public final static int RE_IB2_F18_MASK = 0x20;
742    public final static int RE_IB2_F19_MASK = 0x40;
743// Common to Intellibox-I and -II :
744    public final static int RE_IB2_SPECIAL_F21_F27_TOKEN = 0x09;
745    public final static int RE_IB2_F21_MASK = 0x01;
746    public final static int RE_IB2_F22_MASK = 0x02;
747    public final static int RE_IB2_F23_MASK = 0x04;
748    public final static int RE_IB2_F24_MASK = 0x08;
749    public final static int RE_IB2_F25_MASK = 0x10;
750    public final static int RE_IB2_F26_MASK = 0x20;
751    public final static int RE_IB2_F27_MASK = 0x40;
752// Common to Intellibox-I and -II :
753    public final static int RE_IB2_SPECIAL_F20_F28_TOKEN = 0x05; // Also applicable to F12
754    public final static int RE_IB2_SPECIAL_F12_MASK = 0x10; //F12 is also controlled with the special F20-F28 command
755    public final static int RE_IB2_SPECIAL_F20_MASK = 0x20;
756    public final static int RE_IB2_SPECIAL_F28_MASK = 0x40;
757
758    public final static String DIGITRAX_STRING = "Digitrax"; // NOI18N
759    public final static String RR_CIRKITS_STRING = "RR-CirKits"; // NOI18N
760
761}