001package jmri.jmrix.roco.z21; 002 003import java.net.DatagramSocket; 004import java.util.ResourceBundle; 005import jmri.jmrix.ConnectionStatus; 006import org.slf4j.Logger; 007import org.slf4j.LoggerFactory; 008 009/** 010 * Adapter representing a Z21 communication port. 011 * <p> 012 * Note: This connection uses UDP for communication. 013 * 014 * @author Bob Jacobsen Copyright (C) 2001, 2008 015 * @author Paul Bender Copyright (C) 2004,2010,2011,2014 016 */ 017public class Z21Adapter extends jmri.jmrix.AbstractNetworkPortController { 018 019 protected static ResourceBundle rb = ResourceBundle.getBundle("jmri.jmrix.roco.z21.z21AdapterConfigurationBundle"); 020 protected static int COMMUNICATION_UDP_PORT = java.lang.Integer.parseInt(rb.getString("z21UDPPort1")); 021 protected static String DEFAULT_IP_ADDRESS = rb.getString("defaultZ21IPAddress"); 022 023 private DatagramSocket socket = null; 024 025 public Z21Adapter() { 026 super(new Z21SystemConnectionMemo()); 027 setHostName(DEFAULT_IP_ADDRESS); 028 setPort(COMMUNICATION_UDP_PORT); 029 allowConnectionRecovery = true; // all classes derived from this class 030 // can recover from a connection failure 031 032 } 033 034 /** 035 * Configure all of the other jmrix widgets needed to work with this adapter 036 */ 037 @Override 038 public void configure() { 039 if (log.isDebugEnabled()) { 040 log.debug("configure called"); 041 } 042 // connect to a packetizing traffic controller 043 Z21TrafficController packets = new Z21TrafficController(); 044 packets.connectPort(this); 045 046 // start operation 047 this.getSystemConnectionMemo().setTrafficController(packets); 048 this.getSystemConnectionMemo().configureManagers(); 049 } 050 051 @Override 052 public void connect() throws java.io.IOException { 053 opened = false; 054 if (getHostAddress() == null || m_port == 0) { 055 log.error("No host name or port set : {}:{}", m_HostName, m_port); 056 return; 057 } 058 try { 059 socket = new DatagramSocket(); 060 opened = true; 061 } catch (java.net.SocketException se) { 062 log.error("Socket Exception creating connection."); 063 if (m_port != 0) { 064 ConnectionStatus.instance().setConnectionState( 065 this.getSystemConnectionMemo().getUserName(), 066 m_HostName + ":" + m_port, ConnectionStatus.CONNECTION_DOWN); 067 } else { 068 ConnectionStatus.instance().setConnectionState( 069 this.getSystemConnectionMemo().getUserName(), 070 m_HostName, ConnectionStatus.CONNECTION_DOWN); 071 } 072 throw (se); 073 } 074 if (opened && m_port != 0) { 075 ConnectionStatus.instance().setConnectionState( 076 this.getSystemConnectionMemo().getUserName(), 077 m_HostName + ":" + m_port, ConnectionStatus.CONNECTION_UP); 078 } else if (opened) { 079 ConnectionStatus.instance().setConnectionState( 080 this.getSystemConnectionMemo().getUserName(), 081 m_HostName, ConnectionStatus.CONNECTION_UP); 082 } 083 084 } 085 086 /** 087 * @return the DatagramSocket of this connection. Returns null 088 * if not connected. 089 */ 090 public DatagramSocket getSocket() { 091 return socket; 092 } 093 094 /** 095 * Check that this object is ready to operate. This is a question of 096 * configuration, not transient hardware status. 097 */ 098 @Override 099 public boolean status() { 100 return opened; 101 } 102 103 @Override 104 public Z21SystemConnectionMemo getSystemConnectionMemo() { 105 return (Z21SystemConnectionMemo) super.getSystemConnectionMemo(); 106 } 107 108 /** 109 * Customizable method to deal with resetting a system connection after a 110 * successful recovery of a connection. 111 */ 112 @Override 113 protected void resetupConnection() { 114 // UDP connection is re-established for each message. 115 } 116 117 @Override 118 public void dispose(){ 119 super.dispose(); 120 if (opened) { 121 socket.close(); 122 } 123 opened = false; 124 allowConnectionRecovery = false; // disposing of the object should 125 // result in not allowing reconnection. 126 } 127 128 private static final Logger log = LoggerFactory.getLogger(Z21Adapter.class); 129 130}