001package jmri.jmrix.dccpp;
002
003/**
004 * DCCppConstants.java
005 *
006 * Constants to represent values seen in DCC++ traffic
007 *
008 * @author Paul Bender Copyright (C) 2003-2009
009 * @author Mark Underwood Copyright (C) 2015
010 * @author Harald Barth Copyright (C) 2019
011 *
012 * Variable prefix abbreviation keys: ACC_ is for accessory messages BC_ is for
013 * broadcast messages CS_ is for command station messages PROG_ is for
014 * programming related messages LOCO_ is for locomotive related commands
015 * OPS_MODE_ is for operations mode programming commands
016 *
017 * A few variables don't have a prefix. The name should be self explanatory, but
018 * a prefix may be added later.
019 */
020public final class DCCppConstants {
021
022    private DCCppConstants() {
023        // final class of static values, no values to construct.
024    }
025
026    public static final int MAX_MESSAGE_SIZE = 30;
027    public static final int MAX_REPLY_SIZE = 2048; //max size of DCC++EX wifi send buffer
028    public static final int MAX_MAIN_REGISTERS = 12;
029    public static final int MAX_FUNCTION_NUMBER = 68; //
030    public static final int REGISTER_UNALLOCATED = -1;
031    public static final int NO_REGISTER_FREE = -1; // TODO: Should this be a unique value?
032
033    // DCC++ over TCP Port Number
034    public static final int DCCPP_OVER_TCP_PORT = 1235;
035
036    // Communications Port Info
037    public static final int COMM_TYPE_SERIAL = 0;
038    public static final int COMM_TYPE_ENET = 1;
039    public static final int COMM_TYPE_ENETV2 = 2;
040
041    // Command Station Types
042    public static final int DCCPP_UNO_1_0 = 1;
043    public static final int DCCPP_ARDUINO_1_1 = 2;
044    static final String[] CommandStationNames = {
045     "DCCPP Arduino Uno v1.0",
046     "DCCPP Arduino V1.1",
047    };
048    // Meter Type codes and descriptions
049    public static final String VOLTAGE = "V";
050    public static final String CURRENT = "C";
051
052    // DCC++ Command OpCodes
053    public static final char THROTTLE_CMD           = 't'; // Throttle command <t reg cab speed dir>
054    public static final char FUNCTION_CMD           = 'f'; // F0-F28 <f cab byte1 [byte2]>
055    public static final char FUNCTION_V4_CMD        = 'F'; // F0-F68 <F CAB FUNC 1|0>
056    public static final char FORGET_CAB_CMD         = '-'; // Forgets one or all locos. <- [CAB]>
057    public static final char ACCESSORY_CMD          = 'a'; // Stationary accessory decoder <a addr subaddr activate>
058    public static final char TURNOUT_CMD            = 'T'; // Turnout command <T id throw> -- NEW versions V1.1
059    public static final char SENSOR_CMD             = 'S'; // Sensor command -- NEW V1.1
060    public static final char OUTPUT_CMD             = 'Z'; // Output command -- NEW V1.2?
061    public static final char OPS_WRITE_CV_BYTE      = 'w'; // Write CV byte on ops track
062    public static final char OPS_WRITE_CV_BIT       = 'b'; // Set/Clear a single CV bit on ops track
063    public static final char PROG_WRITE_CV_BYTE     = 'W'; // Write CV byte on program track
064    public static final char PROG_WRITE_CV_BIT      = 'B'; // Set/Clear a single CV bit on ops track
065    public static final char PROG_READ_CV           = 'R'; // 3 different messages
066    public static final char PROG_VERIFY_CV         = 'V'; // Verify CV byte on program track
067    public static final char TRACK_POWER_ON         = '1'; // Track power ON
068    public static final char TRACK_POWER_OFF        = '0'; // Track power OFF
069    public static final char READ_TRACK_CURRENT     = 'c'; // Request current and voltage readings
070    public static final char READ_CS_STATUS         = 's'; // Read status from command station
071    public static final char READ_MAXNUMSLOTS       = '#'; // Read max number of slots supported by CS
072    public static final char WRITE_TO_EEPROM_CMD    = 'E'; // Store settings to eeprom  -- NEW V1.1
073    public static final char CLEAR_EEPROM_CMD       = 'e'; // Clear EEPROM settings     -- NEW V1.1
074    public static final char QUERY_SENSOR_STATES_CMD= 'Q'; // Show all sensors -- NEW V1.2?
075    public static final char ESTOP_ALL_CMD          = '!'; // Stops all locos on the track but leaves power on.
076
077    // Special Commands not for normal use.  Diagnostic and Test Use Only
078    public static final char WRITE_DCC_PACKET_MAIN  = 'M';
079    public static final char WRITE_DCC_PACKET_PROG  = 'P';
080    public static final char LIST_REGISTER_CONTENTS = 'L';
081    public static final char DIAG_CMD               = 'D'; // Send various diagnostics commands
082    public static final char CONTROL_CMD            = '/'; // Send various control commands (e.g. </START 1224 4>), replies via DIAG_REPLY
083
084    // Message Replies
085    public static final char THROTTLE_REPLY   = 'T'; // <T reg speed dir>
086    public static final char TURNOUT_REPLY    = 'H'; // <H id throw> or <X>
087    public static final char PROGRAM_REPLY    = 'r';
088    public static final char VERIFY_REPLY     = 'v';
089    public static final char STATUS_REPLY    = 'i';
090    public static final char MAXNUMSLOTS_REPLY = '#';
091    public static final char POWER_REPLY      = 'p';
092    public static final char CURRENT_REPLY    = 'a';
093    public static final char METER_REPLY      = 'c';
094    public static final char SENSOR_REPLY     = 'Q';
095    public static final char SENSOR_REPLY_H   = 'q';
096    public static final char SENSOR_REPLY_L   = 'Q';
097    public static final char OUTPUT_REPLY     = 'Y';
098    public static final char WRITE_EEPROM_REPLY = 'e';
099    public static final char MADC_FAIL_REPLY  = 'X';
100    public static final char MADC_SUCCESS_REPLY = 'O';
101    public static final char COMM_TYPE_REPLY = 'N';
102    public static final char DIAG_REPLY      = '*';
103    public static final char LOCO_STATE_REPLY= 'l';
104
105    // Message / Reply Regexes
106    public static final String THROTTLE_CMD_REGEX    = "t\\s*(\\d+)\\s+(\\d+)\\s+([-]*\\d+)\\s+([1,0])\\s*"; // <t REG CAB SPEED DIR>
107    public static final String THROTTLE_V3_CMD_REGEX = "t\\s*(\\d+)\\s+([-]*\\d+)\\s+([01])\\s*"; // <t CAB SPEED DIR>
108    public static final String FUNCTION_CMD_REGEX = "f\\s(\\d+)\\s(\\d+)\\s*(\\d+)?"; // <f ADDR BYTE1 (BYTE2)>
109    public static final String FUNCTION_V4_CMD_REGEX="F\\s*([0-9]{1,4})\\s+([0-9]{1,2})\\s+([01])\\s*"; // <F CAB FUNC STATE>
110    public static final String FORGET_CAB_CMD_REGEX ="-\\s*([0-9]{0,4})\\s*"; // <- [CAB]>
111    public static final String ACCESSORY_CMD_REGEX = "a\\s(\\d+)\\s(\\d+)\\s([1,0])"; // <a ADDR SUBADDR ACTIVATE>
112    public static final String TURNOUT_CMD_REGEX = "T\\s(\\d+)\\s([1,0])"; // <T ID THROW>
113    public static final String TURNOUT_ADD_REGEX =     "T\\s(\\d+)\\s(\\d+)\\s(\\d+)";                          // <T id addr subaddr> (deprecated at 3.1.7, use DCC)
114    public static final String TURNOUT_ADD_DCC_REGEX = "T\\s(\\d+)\\sDCC\\s(\\d+)\\s(\\d+)";                    // <T id DCC addr subaddr>
115    public static final String TURNOUT_ADD_SERVO_REGEX="T\\s(\\d+)\\sSERVO\\s(\\d+)\\s(\\d+)\\s(\\d+)\\s(\\d+)";// <T id SERVO pin thrownposition closedposition profile>
116    public static final String TURNOUT_ADD_VPIN_REGEX ="T\\s(\\d+)\\sVPIN\\s(\\d+)";                            // <T id VPIN pin>
117    public static final String TURNOUT_DELETE_REGEX = "T\\s*(\\d+)"; // <T ID>
118    public static final String TURNOUT_LIST_REGEX = "T"; // <T>
119    public static final String SENSOR_ADD_REGEX = "S\\s(\\d+)\\s(\\d+)\\s([1,0])";
120    public static final String SENSOR_DELETE_REGEX = "S\\s(\\d+)";
121    public static final String SENSOR_LIST_REGEX = "S";
122    public static final String OUTPUT_CMD_REGEX = "Z\\s(\\d+)\\s([1,0])"; // <Z ID STATE>
123    public static final String OUTPUT_ADD_REGEX = "\\s*Z\\s*(\\d+)\\s+(\\d+)\\s+(\\d+)\\s*"; // <Z ID PIN IFLAG>
124    public static final String OUTPUT_DELETE_REGEX = "\\s*Z\\s*(\\d+)\\s*"; // <Z ID>
125    public static final String OUTPUT_LIST_REGEX = "\\s*Z\\s*"; // <Z>
126    public static final String QUERY_SENSOR_STATES_REGEX = "\\s*Q\\s*"; // <Q>
127    public static final String LOCO_STATE_REGEX = "\\s*l\\s*(\\d+)\\s*(\\d+)\\s*(\\d+)\\s*(\\d+)\\s*"; // <l loco slot speedByte functions>
128
129    public static final String WRITE_TO_EEPROM_REGEX = "E";
130    public static final String CLEAR_EEPROM_REGEX = "e";
131
132    public static final String OPS_WRITE_BYTE_REGEX = "\\s*w\\s*(\\d+)\\s+(\\d+)\\s+(\\d+)\\s*"; // TODO
133    public static final String OPS_WRITE_BIT_REGEX = "\\s*b\\s*(\\d+)\\s+(\\d+)\\s+([0-7])\\s+([01])\\s*"; // TODO
134
135    public static final String PROG_WRITE_BYTE_REGEX = "W\\s*(\\d+)\\s(\\d+)\\s(\\d+)\\s(\\d+)"; // <W cv value callbacknum callbacksub>
136    public static final String PROG_WRITE_BYTE_V4_REGEX =  "W\\s*(\\d+)\\s(\\d+)"; // <W cv value>
137    public static final String PROG_WRITE_BIT_REGEX = "B\\s*(\\d+)\\s([0-7])\\s([1,0])\\s(\\d+)\\s(\\d+)"; // <B cv bit value callbacknum callbacksub>
138    public static final String PROG_WRITE_BIT_V4_REGEX =   "B\\s*(\\d+)\\s([0-7])\\s([01])"; // <B cv bit value> 
139    public static final String PROG_READ_CV_REGEX = "R\\s*(\\d+)\\s+(\\d+)\\s+(\\d+)"; // <R cv callbacknum callbacksub> 
140    public static final String PROG_READ_CV_V4_REGEX = "R\\s*(\\d+)"; // <R cv> - use <V cv guess> instead
141    public static final String PROG_READ_LOCOID_REGEX =  "R"; // <R>
142    public static final String PROG_VERIFY_REGEX = "V\\s*(\\d+)\\s+(\\d+)\\s*"; //<V cv bytevalue>
143    public static final String TRACK_POWER_REGEX = "\\s*[0,1]\\s*"; // <1> or <0>
144    public static final String READ_TRACK_CURRENT_REGEX = "\\s*c\\s*"; // <c>
145    public static final String READ_CS_STATUS_REGEX = "\\s*s\\s*";// <s>
146    public static final String QUERY_SENSOR_REGEX = "\\s*[Q,q]\\s*(\\d+)\\s*";
147    public static final String WRITE_DCC_PACKET_MAIN_REGEX = "M\\s+(\\d+)((\\s+[0-9a-fA-F]{1,2}){2,5})\\s*"; // M REG pktbyte1 pktbyte2 pktbyte3 ?pktbyte4 ?pktbyte5
148    public static final String WRITE_DCC_PACKET_PROG_REGEX = "P\\s+(\\d+)((\\s+[0-9a-fA-F]{1,2}){2,5})\\s*"; // P REG pktbyte1 pktbyte2 pktbyte3 ?pktbyte4 ?pktbyte5
149    public static final String LIST_REGISTER_CONTENTS_REGEX = "\\s*L\\s*";
150    public static final String READ_MAXNUMSLOTS_REGEX = "\\s*#\\s*";
151    public static final String DIAG_CMD_REGEX         = "\\s*D\\s.*"; //D alone or followed by various commands
152    public static final String CONTROL_CMD_REGEX      = "\\s*/\\s.*"; // slash followed by various commands
153    public static final String ESTOP_ALL_REGEX        = "\\s*!";
154
155    // Reply Regexes
156    public static final String THROTTLE_REPLY_REGEX =      "\\s*T\\s*(\\d+)\\s+([-]*\\d+)\\s+([1,0]).*";
157    public static final String TURNOUT_REPLY_REGEX =       "\\s*H\\s*(\\d+)\\s+([1,0])\\s*";
158    public static final String TURNOUT_DEF_REPLY_REGEX =   "\\s*H\\s*(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+([0|1]).*"; // <T id addr subaddr thrown> (deprecated at 3.1.7, use DCC)
159    public static final String TURNOUT_DEF_DCC_REPLY_REGEX = "\\s*H\\s(\\d+)\\sDCC\\s(\\d+)\\s(\\d+)\\s+([0|1]).*";                    // <H id DCC addr subaddr thrown>
160    public static final String TURNOUT_DEF_SERVO_REPLY_REGEX="\\s*H\\s(\\d+)\\sSERVO\\s(\\d+)\\s(\\d+)\\s(\\d+)\\s(\\d+)\\s+([0|1]).*";// <H id SERVO pin thrownposition closedposition profile thrown>
161    public static final String TURNOUT_DEF_VPIN_REPLY_REGEX ="\\s*H\\s(\\d+)\\sVPIN\\s(\\d+)\\s+([0|1]).*";                            // <H id VPIN pin thrown>
162    public static final String TURNOUT_DEF_LCN_REPLY_REGEX = "\\s*H\\s(\\d+)\\sLCN\\s+([0|1]).*";                                      // <H id LCN thrown>
163    public static final String PROGRAM_REPLY_REGEX =       "\\s*r\\s*(\\d+)\\|(\\d+)\\|(\\d+)\\s+([-]*\\d+)\\s*"; //<r CALLBACKNUM|CALLBACKSUB|CV Value> deprecated
164    public static final String PROGRAM_REPLY_V4_REGEX =    "\\s*r\\s*(\\d+)\\s+([-]*\\d+)\\s*"; // <r cv value> 
165    public static final String PROGRAM_LOCOID_REPLY_REGEX = "\\s*r\\s+([-]*\\d+)\\s*"; //<r locoid> 
166    public static final String PROGRAM_VERIFY_REPLY_REGEX = "\\s*v\\s*(\\d+)\\s*([-]*\\d+)\\s*"; //<v cv bytevalue>
167    public static final String PROGRAM_BIT_REPLY_REGEX =   "\\s*r\\s*(\\d+)\\|(\\d+)\\|(\\d+)\\s+(\\d+)\\s+(\\d+)\\s*";
168    public static final String PROGRAM_BIT_REPLY_V4_REGEX ="\\s*r\\s*(\\d+)\\s+(\\d+)\\s+(\\d+)\\s*";
169    public static final String MAXNUMSLOTS_REPLY_REGEX =   "\\s*#\\s*(\\d+).*"; //<# 50>
170    public static final String DIAG_REPLY_REGEX        =   "^\\*\\s*([\\S\\s]*)\\*$"; //matches anything between leading and trailing asterisks, left-trimmed
171    public static final String CURRENT_REPLY_REGEX =       "\\s*a\\s*(\\d+).*";
172    public static final String CURRENT_REPLY_NAMED_REGEX = "\\s*a\\s*(\\w*?[a-zA-Z])\\s*(\\d+).*";
173    public static final String METER_REPLY_REGEX = " *c *(.+) +([\\d\\.]+) +([A-Z]) +(\\w+) +([\\d\\.]+) +([\\d\\.]+) +([\\d\\.]+) +([\\d\\.]+).*";
174
175    public static final String TRACK_POWER_REPLY_REGEX =       "\\s*p\\s*([0,1])\\s*";
176    public static final String TRACK_POWER_REPLY_NAMED_REGEX = "\\s*p\\s*(\\d+)\\s+(\\w+).*";
177    public static final String SENSOR_REPLY_REGEX =          "\\s*[Qq]\\s*(\\d+)\\s*";
178    public static final String SENSOR_DEF_REPLY_REGEX =      "\\s*Q\\s*(\\d+)\\s+(\\d+)\\s+([0|1]).*";
179    public static final String SENSOR_ACTIVE_REPLY_REGEX =   "\\s*Q\\s*(\\d+)\\s*";
180    public static final String SENSOR_INACTIVE_REPLY_REGEX = "\\s*q\\s*(\\d+)\\s*";
181    public static final String OUTPUT_REPLY_REGEX =       "\\s*Y\\s*(\\d+)\\s+(\\d+)\\s*"; // <Y ID STATE>
182    public static final String OUTPUT_DEF_REPLY_REGEX =   "\\s*Y\\s*(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+).*"; // <Y ID PIN IFLAG STATE>
183    public static final String MADC_FAIL_REPLY_REGEX =    "\\s*X.*";
184    public static final String MADC_SUCCESS_REPLY_REGEX = "\\s*O.*";
185    public static final String STATUS_REPLY_REGEX =       "i(DCC\\+\\+[^:]*):(?:\\sBUILD)? (.*)"; // V1.0 / V1.1 / V1.2
186    public static final String STATUS_REPLY_BSC_REGEX =   "i(DCC\\+\\+.*): V-(.*)\\+\\s\\/\\s(.*)"; // BaseStation Classic
187    public static final String STATUS_REPLY_ESP32_REGEX = "iDCC\\+\\+.*ESP32.*: V-([\\d\\.]+)\\s+/\\s+(.*)"; // V1.0
188    public static final String STATUS_REPLY_DCCEX_REGEX = "i(DCC-EX) V-([\\d\\.]*).*G-(.*)";
189    public static final String WRITE_EEPROM_REPLY_REGEX = "\\s*e\\s*(\\d+)\\s+(\\d+)\\s+(\\d+).*";
190    public static final String COMM_TYPE_REPLY_REGEX =    "\\s*N\\s*(\\d+):\\s+((SERIAL)|(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})).*";
191
192    // Misc standard values
193    public static final char WHITESPACE = ' ';
194    public static final int MAX_SPEED = 126;
195    public static final char FORWARD_DIR = '1';
196    public static final char REVERSE_DIR = '0';
197
198    public static final int REGISTER_1 = '1';
199
200    public static final int FUNCTION_GROUP4_BYTE1 = 222;
201    public static final int FUNCTION_GROUP5_BYTE1 = 223;
202
203    public static final String TURNOUT_THROWN      = "1";
204    public static final String TURNOUT_CLOSED      = "0";
205    public static final String THROTTLE_FORWARD    = "1";
206    public static final String THROTTLE_REVERSE    = "0";
207    public static final String ACCESSORY_ON        = "1";
208    public static final String ACCESSORY_OFF       = "0";
209    public static final String POWER_ON            = "1";
210    public static final String POWER_OFF           = "0";
211    public static final String SENSOR_ON           = "1";
212    public static final String SENSOR_OFF          = "0";
213    public static final String SENSOR_FALLING_EDGE = "Q";
214    public static final String SENSOR_RISING_EDGE  = "q";
215
216    // Various min/max values for messages
217    public static final int MAX_SENSOR_ID = 32767;
218    public static final int MAX_SENSOR_NUMBER = 2048; // TODO: Check this
219    public static final int MAX_ACC_DECODER_ADDRESS = 511;
220    public static final int MAX_ACC_DECODER_SUBADDR = 3;
221    // Max JMRI addr = ((MAX_ADDRESS - 1) * (MAX_SUBADDR+1)) + (MAX_SUBADDR) + 1
222    public static final int MAX_ACC_DECODER_JMRI_ADDR = 2044;
223    public static final int MAX_TURNOUT_ADDRESS = 32767;
224    public static final int MAX_DIRECT_CV = 1024;
225    public static final int MAX_DIRECT_CV_VAL = 255;
226    public static final int MAX_CALLBACK_NUM = 32767;
227    public static final int MAX_CALLBACK_SUB = 32767;
228    public static final int MAX_LOCO_ADDRESS = 10293;
229    public static final int MAX_CURRENT = 1024;
230    public static final int METER_INTERVAL_MS = 1000;
231
232    //Turnout types (added in DCC-EX 3.1.7)
233    public static final String TURNOUT_TYPE_DCC = "DCC";
234    public static final String TURNOUT_TYPE_SERVO="SERVO";
235    public static final String TURNOUT_TYPE_VPIN ="VPIN";
236    public static final String TURNOUT_TYPE_LCN = "LCN";
237
238    public static final String OUTPUT_TYPE = "OUTPUT";
239    public static final String SENSOR_TYPE = "SENSOR";
240
241    //Property Keys
242    public static final String PROP_TYPE =     "Type";
243    public static final String PROP_ID   =     "ID";
244    public static final String PROP_ADDRESS =  "Address";
245    public static final String PROP_INDEX =    "Index";
246    public static final String PROP_DCCADDRESS="DCC Address";
247    public static final String PROP_PIN   =    "Pin";
248    public static final String PROP_THROWNPOS= "ThrownPos";
249    public static final String PROP_CLOSEDPOS= "ClosedPos";
250    public static final String PROP_PROFILE  = "Profile";
251    public static final String PROP_IFLAG  =   "IFlag";
252    public static final String PROP_PULLUP =   "Pullup";
253
254    //Referred to as Throttle commands for some reason
255    public static final char THROTTLE_COMMANDS         = 'J'; // First char of Jx two-letter commands
256    public static final char THROTTLE_COMMANDS_REPLY   = 'j'; // First char of Jx two-letter responses
257    public static final String TURNOUT_IDS             = "J T"; //Request turnout IDs
258    public static final String TURNOUT_IDS_REGEX       = "^J\\s*T$"; // <J T> or <JT>
259    public static final String TURNOUT_ID_REGEX        = "^J\\s*T\\s*(\\d+)$"; // <J T 123>
260    public static final String TURNOUT_IDS_REPLY_REGEX = "^j\\s*T\\s*((?:\\s*\\d+)*)$"; // <j T 123 456 789>
261    public static final String TURNOUT_ID_REPLY_REGEX  = "^j\\s*T\\s+(\\d+)\\s([C|T])\\s\\\"(.*)\\\""; // <jT 123 C "description">   
262    public static final String TURNOUT_IMPL_REGEX      = "^T\\s+(\\d+)\\s+X$"; // <T 123 X> Note: may be dropped from DCC-EX
263    public static final String CLOCK_REQUEST_TIME      = "J C"; //<J C> Request current time from DCC-EX
264    public static final String CLOCK_REQUEST_TIME_REGEX= "^J\\s*C$"; // <J C> or <JC>
265    public static final String CLOCK_SET_REGEX         = "^J\\s*C\\s+(\\d+)\\s*(\\d*)$"; // <J C 123 4> or <j C 124> outgoing set to 123min past midnight, rate 4
266    public static final String CLOCK_REPLY_REGEX       = "^j\\s*C\\s+(\\d+)\\s*(\\d*)$"; // <j C 123 4> or <j C 124> incoming version of above 
267    
268    //Track Manager (in 5.x)
269    public static final char   TRACKMANAGER_CMD        = '=';
270    public static final String TRACKMANAGER_CMD_REGEX  = "=";
271    public static final String TRACKMANAGER_REPLY_REGEX= "\\s*=\\s*[A-H]\\s+([A-Z]+)\\s*(\\d*)"; //<= A PROG> or <= B DC 1234>  
272
273    //LCD message
274    public static final char   LCD_TEXT_CMD         = '@'; //request that LCD messages be sent to this instance of JMRI
275    public static final String LCD_TEXT_CMD_REGEX   = "@";
276    public static final char   LCD_TEXT_REPLY       = '@';
277    public static final String LCD_TEXT_REPLY_REGEX = "^\\s*@\\s*(\\d+)\\s+(\\d+)\\s+\\\"(.*)\\\"$"; //<@ 0 3 "message text"> where 0 is display# and 3 is line#  
278
279}