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 ConnectionStatus.instance().setConnectionState( 064 this.getSystemConnectionMemo(), 065 ConnectionStatus.CONNECTION_DOWN); 066 throw (se); 067 } 068 if (opened) { 069 ConnectionStatus.instance().setConnectionState( 070 this.getSystemConnectionMemo(), 071 ConnectionStatus.CONNECTION_UP); 072 } 073 074 } 075 076 /** 077 * @return the DatagramSocket of this connection. Returns null 078 * if not connected. 079 */ 080 public DatagramSocket getSocket() { 081 return socket; 082 } 083 084 /** 085 * Check that this object is ready to operate. This is a question of 086 * configuration, not transient hardware status. 087 */ 088 @Override 089 public boolean status() { 090 return opened; 091 } 092 093 @Override 094 public Z21SystemConnectionMemo getSystemConnectionMemo() { 095 return (Z21SystemConnectionMemo) super.getSystemConnectionMemo(); 096 } 097 098 /** 099 * Customizable method to deal with resetting a system connection after a 100 * successful recovery of a connection. 101 */ 102 @Override 103 protected void resetupConnection() { 104 // UDP connection is re-established for each message. 105 } 106 107 @Override 108 public void dispose(){ 109 super.dispose(); 110 if (opened) { 111 socket.close(); 112 } 113 opened = false; 114 allowConnectionRecovery = false; // disposing of the object should 115 // result in not allowing reconnection. 116 } 117 118 private static final Logger log = LoggerFactory.getLogger(Z21Adapter.class); 119 120}