001package jmri.jmrix.can.cbus.simulator; 002 003import jmri.jmrix.AbstractMessage; 004import jmri.jmrix.can.CanReply; 005import jmri.jmrix.can.CanSystemConnectionMemo; 006import jmri.jmrix.can.cbus.CbusConstants; 007 008// import org.slf4j.Logger; 009// import org.slf4j.LoggerFactory; 010 011/** 012 * Class to represent a Processing of CAN Frames for a CbusDummyNode. 013 * 014 * @author Steve Young Copyright (C) 2019,2020 015 */ 016public class CbusDummyNodeCanListener extends CbusSimCanListener { 017 018 private final CbusDummyNode _dummyNode; 019 020 /** 021 * Create a new CbusDummyNodeCanListener 022 * 023 * @param connmemo The CAN Connection to listen to. 024 * @param node The Node 025 */ 026 public CbusDummyNodeCanListener ( CanSystemConnectionMemo connmemo, CbusDummyNode node ){ 027 super(connmemo,node); 028 _dummyNode = node; 029 setDelay (40); 030 } 031 032 @Override 033 protected void startProcessFrame(AbstractMessage m) { 034 // extended or module type unset 035 if ( _dummyNode.getNodeParamManager().getParameter(3) == 0 ) { 036 return; 037 } 038 039 if ( _dummyNode.getNodeInSetupMode() ) { 040 processDummyCanSetupMode(m); 041 } 042 else if ( _dummyNode.getNodeInFLiMMode() ) { 043 if ( m.getElement(0) == CbusConstants.CBUS_QNN ) { // Query Nodes 044 _dummyNode.sendPNN(); 045 } 046 if (_dummyNode.getNodeNumber() == ( m.getElement(1) * 256 ) + m.getElement(2) ) { 047 processDummyCanFLimMode(m); 048 } 049 if ( _dummyNode.getNodeInLearnMode() ){ 050 processDummyCanLearnMode(m); 051 } 052 } 053 } 054 055 private void processDummyCanFLimMode(AbstractMessage m){ 056 switch (m.getElement(0)) { 057 case CbusConstants.CBUS_NNULN: 058 // Node exit learn mode 059 _dummyNode.setNodeInLearnMode(false); 060 break; 061 case CbusConstants.CBUS_NNLRN: 062 // Node enter learn mode 063 _dummyNode.setNodeInLearnMode(true); 064 break; 065 case CbusConstants.CBUS_RQNPN: 066 // Request Node Parameters by Index 067 _dummyNode.sendPARAN(m.getElement(3)); 068 break; 069 case CbusConstants.CBUS_NVRD: 070 // Request Node Variable by Index 071 _dummyNode.sendNVANS(m.getElement(3)); 072 break; 073 case CbusConstants.CBUS_NVSET: 074 // Set Node Variable 075 _dummyNode.setDummyNV(m.getElement(3),m.getElement(4)); 076 break; 077 default: 078 processDummyCanFLimModeEventStuff(m); 079 } 080 } 081 082 private void processDummyCanFLimModeEventStuff(AbstractMessage m){ 083 switch (m.getElement(0)) { 084 case CbusConstants.CBUS_RQEVN: 085 // Request number of events 086 _dummyNode.sendNUMEV(); 087 break; 088 case CbusConstants.CBUS_NERD: 089 // Readback all stored events in node 090 _dummyNode.sendENRSP(); 091 break; 092 case CbusConstants.CBUS_REVAL: 093 // Request for read of an event variable 094 _dummyNode.sendNEVAL(m.getElement(3),m.getElement(4)); 095 break; 096 default: 097 break; 098 } 099 } 100 101 private void processDummyCanSetupMode(AbstractMessage m){ 102 103 switch (m.getElement(0)) { 104 case CbusConstants.CBUS_RQNP: 105 // Request Node Parameters 106 _dummyNode.sendPARAMS(); 107 break; 108 case CbusConstants.CBUS_SNN: 109 // Set Node Number 110 _dummyNode.setDNN( ( m.getElement(1) * 256 ) + m.getElement(2) ); 111 break; 112 case CbusConstants.CBUS_RQMN: 113 // Request Module Name 114 115 byte[] byteArr = jmri.util.StringUtil.fullTextToHexArray( _dummyNode.getNodeNameFromName(),7 ); 116 CanReply r = new CanReply(8); 117 r.setElement(0, CbusConstants.CBUS_NAME); 118 r.setElement(1, byteArr[0] & 0xff); 119 r.setElement(2, byteArr[1] & 0xff); 120 r.setElement(3, byteArr[2] & 0xff); 121 r.setElement(4, byteArr[3] & 0xff); 122 r.setElement(5, byteArr[4] & 0xff); 123 r.setElement(6, byteArr[5] & 0xff); 124 r.setElement(7, byteArr[6] & 0xff); 125 send.sendWithDelay(r,getSendIn(),getSendOut(),getDelay()); 126 break; 127 default: 128 break; 129 } 130 131 } 132 133 private void processDummyCanLearnMode(AbstractMessage m){ 134 switch (m.getElement(0)) { 135 case CbusConstants.CBUS_EVLRN: 136 // Teach node event 137 evLearn( 138 ( ( m.getElement(1) * 256 ) + m.getElement(2) ), 139 ( ( m.getElement(3) * 256 ) + m.getElement(4) ), 140 m.getElement(5), 141 m.getElement(6) ); 142 break; 143 case CbusConstants.CBUS_EVULN: 144 // Node Unlearn event 145 _dummyNode.getNodeEventManager().removeEvent( ( m.getElement(1) * 256 ) + m.getElement(2) , 146 ( ( m.getElement(3) * 256 ) + m.getElement(4) ) ); 147 break; 148 case CbusConstants.CBUS_NNCLR: 149 // clear all events 150 if ( ( ( m.getElement(1) * 256 ) + m.getElement(2) ) == _dummyNode.getNodeNumber() ) { 151 // no response expected 152 _dummyNode.getNodeEventManager().resetNodeEventsToZero(); 153 } break; 154 default: 155 break; 156 } 157 } 158 159 private void evLearn(int nn, int en, int index, int val){ 160 161 if ( val < 0 || val > 255 ) { 162 _dummyNode.sendCMDERR(11); 163 return; 164 } 165 if ( index < 0 || index > 255 ) { 166 _dummyNode.sendCMDERR(6); 167 return; 168 } 169 _dummyNode.getNodeEventManager().provideNodeEvent(nn,en).setEvVar(index,val); 170 if ( _dummyNode.getNodeEventManager().provideNodeEvent(nn,en).getIndex()< 0 ) { 171 _dummyNode.getNodeEventManager().provideNodeEvent(nn,en).setIndex( 172 _dummyNode.getNodeEventManager().getNextFreeIndex() ); 173 } 174 _dummyNode.sendWRACK(); 175 } 176 177 // private static final Logger log = LoggerFactory.getLogger(CbusDummyNodeCanListener.class); 178 179}