001package jmri.jmrix.cmri.serial.serialmon; 002 003import jmri.jmrix.cmri.CMRISystemConnectionMemo; 004import jmri.jmrix.cmri.serial.SerialListener; 005import jmri.jmrix.cmri.serial.SerialMessage; 006import jmri.jmrix.cmri.serial.SerialReply; 007import jmri.jmrix.cmri.serial.SerialNode; 008 009import java.awt.event.ActionEvent; 010 011import javax.swing.BoxLayout; 012import javax.swing.JButton; 013import javax.swing.JPanel; 014 015/** 016 * Frame displaying (and logging) CMRI serial command messages. 017 * 018 * @author Bob Jacobsen Copyright (C) 2001 019 * @author Chuck Catania Copyright (C) 2014, 2016, 2017 020 */ 021public class SerialMonFrame extends jmri.jmrix.AbstractMonFrame implements SerialListener { 022 // member declarations 023 // String deltaTCheck = this.getClass().getName()+".DeltaT"; // NOI18N 024 025 protected JButton packetfilterButton = new JButton(Bundle.getMessage("FilterPacketsText") ); // NOI18N 026 protected static int _DLE = 0x10; 027 028 private CMRISystemConnectionMemo _memo = null; 029 030 public SerialMonFrame(CMRISystemConnectionMemo memo) { 031 super(); 032 _memo = memo; 033 } 034 035 @Override 036 public void dispose() { 037 super.dispose(); 038 } 039 040 @Override 041 protected String title() { 042 return Bundle.getMessage("SerialCommandMonTitle")+" "+Bundle.getMessage("Connection")+_memo.getUserName(); // NOI18N 043 } 044 045 @Override 046 protected void init() { 047 // connect to TrafficController 048 _memo.getTrafficController().addSerialListener(this); 049 // Load the packet filter bits 050 initializePacketFilters(); 051 052 // Add additional controls to the super class window 053 JPanel paneA = new JPanel(); 054 paneA.setLayout(new BoxLayout(paneA, BoxLayout.Y_AXIS)); 055 056 JPanel pane1 = new JPanel(); 057 pane1.setLayout(new BoxLayout(pane1, BoxLayout.X_AXIS)); 058 059 packetfilterButton.setText(Bundle.getMessage("FilterPacketsText")); // NOI18N 060 packetfilterButton.setVisible(true); 061 packetfilterButton.setToolTipText(Bundle.getMessage("FilterPacketTip")); // NOI18N 062 pane1.add(packetfilterButton); 063 packetfilterButton.addActionListener(this::openPacketFilterPerformed); 064 065 paneA.add(pane1); 066 getContentPane().add(paneA); 067 pack(); 068 paneA.setMaximumSize(paneA.getSize()); 069 pack(); 070 071 // Move the filter packets button to the middle 072 getContentPane().setComponentZOrder(paneA,1); 073 } 074 075 /** 076 * Define system-specific help item. 077 */ 078 @Override 079 protected void setHelp() { 080 addHelpMenu("package.jmri.jmrix.cmri.serial.serialmon.SerialMonFrame", true); // NOI18N 081 } 082 083 /** 084 * Initialize packet type filters. 085 */ 086 public void initializePacketFilters() { 087 // get all configured nodes 088 SerialNode node = (SerialNode) _memo.getTrafficController().getNode(0); 089 int index = 1, 090 pktTypeIndex = 0; 091 092 while (node != null) { 093 // Set all nodes and packet types to be monitored 094 //----------------------------------------------- 095 do { 096 node.setMonitorPacketBit(pktTypeIndex, true); 097 pktTypeIndex++; 098 } while (pktTypeIndex < SerialFilterFrame.numMonPkts); 099 100 node = (SerialNode) _memo.getTrafficController().getNode(index); 101 index++; 102 pktTypeIndex = 0; 103 } 104 } 105 106 /** 107 * Open the node/packet filter window. 108 * @param e unused. 109 */ 110 public void openPacketFilterPerformed(ActionEvent e) { 111 // create a SerialFilterFrame 112 SerialFilterFrame f = new SerialFilterFrame(_memo); 113 try { 114 f.initComponents(); 115 } 116 catch (Exception ex) { 117 log.warn("SerialMonFrame starting SerialFilterFrame: Exception: {}", ex.toString()); 118 } 119 f.setVisible(true); 120 } 121 122 //------------------- 123 // Transmit Packets 124 //------------------- 125 @Override 126 public synchronized void message(SerialMessage l) { 127 128 SerialNode monitorNode = (SerialNode) _memo.getTrafficController().getNodeFromAddress(l.getUA()); 129 130 // Test for node and packets being monitored 131 //------------------------------------------ 132 if (monitorNode == null) return; 133 if (!monitorNode.getMonitorNodePackets()) return; 134 135 int aPacketTypeID = l.getElement(1); 136 137 // check for valid length 138 if (l.getNumDataElements() < 2) { 139 nextLine("Truncated message of length "+l.getNumDataElements()+"\n",l.toString()); 140 return; 141 } 142 143 switch(aPacketTypeID) { 144 case 0x50: // (P) Poll 145 if(monitorNode.getMonitorPacketBit(SerialFilterFrame.monPktPoll)) 146 { 147 nextLine("Poll ua="+l.getUA()+"\n", l.toString()); 148 } 149 break; 150 151 case 0x54: // (T) Transmit 152 if (monitorNode.getMonitorPacketBit(SerialFilterFrame.monPktTransmit)) 153 { 154 StringBuilder sb = new StringBuilder("Transmit ua="); 155 sb.append(l.getUA()); 156 sb.append(" OB="); 157 for (int i=2; i<l.getNumDataElements(); i++) 158 { 159 if ((rawCheckBox.isSelected()) && ( l.getElement(i) == _DLE )) //c2 160 { 161 sb.append("<dle>"); // Convert DLE (0x10) to text 162 i++; 163 } 164 165 sb.append(Integer.toHexString(l.getElement(i)&0x000000ff).toUpperCase()); //c2 166 sb.append(" "); 167 } 168 sb.append("\n"); 169 nextLine(new String(sb), l.toString()); 170 } 171 break; 172 173 case 0x49: // (I) Initialize 174 if (monitorNode.getMonitorPacketBit(SerialFilterFrame.monPktInit)) { 175 StringBuilder sb = new StringBuilder("Init ua="); 176 sb.append(l.getUA()); 177 sb.append(" type="); 178 int ndp=l.getElement(2); // ndp node type 179 sb.append((char)ndp); 180 int len = l.getNumDataElements(); 181 182 switch (ndp) { 183 // SMINI/SUSIC/USIC 184 case SerialNode.NDP_USICSUSIC24: 185 case SerialNode.NDP_USICSUSIC32: 186 case SerialNode.NDP_SMINI: 187 if (len>=5) 188 { 189 sb.append(" DL="); 190 sb.append(l.getElement(3)*256+l.getElement(4)); 191 } 192 193 if (len>=6) 194 { 195 sb.append(" NS="); 196 sb.append(l.getElement(5)); 197 sb.append(" CT: "); 198 for (int i=6; i<l.getNumDataElements(); i++) 199 { 200 sb.append(Integer.toHexString(l.getElement(i)&0x000000ff).toUpperCase()); //c2 201 sb.append(" "); 202 } 203 } 204 break; 205 206 case SerialNode.NDP_CPNODE: // CPNODE 207 case SerialNode.NDP_CPMEGA: // CPMEGA 208 if (len>=5) 209 { 210 sb.append(" DL="); 211 sb.append(l.getElement(3)*256+l.getElement(4)); 212 } 213 sb.append(" Opts="); 214 int i=5; 215 while (i<l.getNumDataElements()) { 216 if (l.getElement(i) != _DLE) { // skip DLE 217 sb.append(Integer.toHexString(l.getElement(i)&0x000000ff).toUpperCase()); //c2 218 sb.append(" "); 219 } 220 i++; 221 } 222 break; 223 224 default: 225 sb.append("Unrecognized node type NDP: [").append(ndp).append("] "); 226 break; 227 228 } //ndp case 229 230 sb.append("\n"); 231 nextLine(new String(sb), l.toString()); 232 } 233 break; 234 235 default: 236 nextLine("Unrecognized cmd: \""+l.toString()+"\"\n", ""); 237 } // end packet ID case 238 } 239 240 //------------------- 241 // Receive Packets 242 //------------------- 243 @Override 244 public synchronized void reply(SerialReply l) { 245 246 // Test for node and packets being monitored 247 //------------------------------------------ 248 SerialNode monitorNode = (SerialNode) _memo.getTrafficController().getNodeFromAddress(l.getUA()); 249 250 if (monitorNode == null) { 251 return; 252 } 253 if (!monitorNode.getMonitorNodePackets()) { 254 return; 255 } 256 257 int aPacketTypeID = l.getElement(1); 258 259 // check for valid length 260 if (l.getNumDataElements() < 2) { 261 nextLine("Truncated reply of length " + l.getNumDataElements() + "\n", l.toString()); 262 // CMRInetMetricsData.incMetricErrValue( CMRInetMetricsData.CMRInetMetricTruncReply ); 263 return; 264 } 265 switch (aPacketTypeID) { 266 case 0x52: // (R) Receive (poll reply) 267 if (monitorNode.getMonitorPacketBit(SerialFilterFrame.monPktRead)) { 268 StringBuilder sb = new StringBuilder("Receive ua="); 269 sb.append(l.getUA()); 270 sb.append(" IB="); 271 for (int i = 2; i < l.getNumDataElements(); i++) { 272 if ((rawCheckBox.isSelected()) && (l.getElement(i) == _DLE)) //c2 273 { 274 sb.append("<dle>"); 275 i++; 276 } 277 sb.append(Integer.toHexString(l.getElement(i) & 0x000000ff).toUpperCase()); //c2 278 sb.append(" "); 279 } 280 sb.append("\n"); 281 nextLine(new String(sb), l.toString()); 282 } 283 break; 284 285 case 0x45: // (E) EOT c2 286 if (monitorNode.getMonitorPacketBit(SerialFilterFrame.monPktEOT)) { 287 StringBuilder sb = new StringBuilder("Receive ua="); 288 sb.append(l.getUA()); 289 sb.append(" eot"); 290 sb.append("\n"); 291 nextLine(new String(sb), l.toString()); 292 } 293 break; 294 295 default: 296 // CMRInetMetricsData.incMetricErrValue( CMRInetMetricsData.CMRInetMetricUnrecResponse ); 297 nextLine("Unrecognized response: \"" + l.toString() + "\"\n", ""); 298 break; 299 } 300 } 301 302 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(SerialMonFrame.class); 303 304} 305