001package jmri.jmrix.sprog; 002 003import java.io.DataInputStream; 004import java.io.DataOutputStream; 005import jmri.jmrix.AbstractStreamPortController; 006import jmri.jmrix.sprog.SprogConstants.SprogMode; 007import org.slf4j.Logger; 008import org.slf4j.LoggerFactory; 009 010/** 011 * Abstract base for classes representing an SPROG Command Station 012 * communications port 013 * <p> 014 * NOTE: This currently only supports the SPROG Command Station interfaces. 015 * 016 * @author Paul Bender Copyright (C) 2014 017 */ 018public class SprogCSStreamPortController extends AbstractStreamPortController implements SprogInterface { 019 020 private Thread rcvNotice = null; 021 private SprogMode operatingMode = SprogMode.OPS; 022 023 public SprogCSStreamPortController(DataInputStream in, DataOutputStream out, String pname) { 024 super(new SprogSystemConnectionMemo(SprogConstants.SprogMode.OPS), in, out, pname); 025 } 026 027 public SprogCSStreamPortController() { 028 super(new SprogSystemConnectionMemo(SprogConstants.SprogMode.OPS)); 029 } 030 031 @Override 032 public void configure() { 033 log.debug("configure() called."); 034 SprogTrafficController control = new SprogTrafficController(this.getSystemConnectionMemo()); 035 036 this.getSystemConnectionMemo().setSprogMode(operatingMode); // first update mode in memo 037 038 // connect to the traffic controller 039 this.getSystemConnectionMemo().setSprogTrafficController(control); 040 control.setAdapterMemo(this.getSystemConnectionMemo()); 041 this.getSystemConnectionMemo().configureCommandStation(); 042 this.getSystemConnectionMemo().configureManagers(); 043 control.connectPort(this); 044 045 // start thread to notify controller when data is available 046 rcvNotice = new Thread(new RcvCheck(input, control)); 047 rcvNotice.setName("SPROG Stream Port Controller Receive thread"); 048 rcvNotice.start(); 049 } 050 051 /** 052 * Check that this object is ready to operate. This is a question of 053 * configuration, not transient hardware status. 054 */ 055 @Override 056 public boolean status() { 057 return true; 058 } 059 060 /** 061 * Can the port accept additional characters? 062 * 063 * @return true 064 */ 065 public boolean okToSend() { 066 return (true); 067 } 068 069 // SPROG Interface methods. 070 @Override 071 public void addSprogListener(SprogListener l) { 072 this.getSystemConnectionMemo().getSprogTrafficController().addSprogListener(l); 073 } 074 075 @Override 076 public void removeSprogListener(SprogListener l) { 077 this.getSystemConnectionMemo().getSprogTrafficController().removeSprogListener(l); 078 } 079 080 @Override 081 public void sendSprogMessage(SprogMessage m, SprogListener l) { 082 this.getSystemConnectionMemo().getSprogTrafficController().sendSprogMessage(m, l); 083 } 084 085 @Override 086 public SprogSystemConnectionMemo getSystemConnectionMemo() { 087 return (SprogSystemConnectionMemo) super.getSystemConnectionMemo(); 088 } 089 090 // internal thread to check to see if the stream has data and 091 // notify the Traffic Controller. 092 static protected class RcvCheck implements Runnable { 093 094 private SprogTrafficController control; 095 private DataInputStream in; 096 097 public RcvCheck(DataInputStream in, SprogTrafficController control) { 098 this.in = in; 099 this.control = control; 100 } 101 102 @Override 103 public void run() { 104 do { 105 try { 106 if (in.available() > 0) { 107 control.handleOneIncomingReply(); 108 } 109 } catch (java.io.IOException ioe) { 110 log.error("Error reading data from stream"); 111 } 112 // need to sleep here? 113 } while (true); 114 } 115 } 116 117 private final static Logger log = LoggerFactory.getLogger(SprogCSStreamPortController.class); 118 119}