Blame | Last modification | View Log | Download | RSS feed
/*************************************************************************** Copyright 2011 Jules White** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.***************************************************************************/package ioio.debugger.server;import ioio.debugger.server.NetworkIOIOProtocol.Message;import ioio.debugger.server.NetworkIOIOProtocol.Message.Builder;import ioio.debugger.server.NetworkIOIOProtocol.TrackingMessage;import java.util.List;import java.util.logging.Level;import java.util.logging.Logger;import org.jboss.netty.channel.Channel;import org.jboss.netty.channel.ChannelEvent;import org.jboss.netty.channel.ChannelHandlerContext;import org.jboss.netty.channel.ChannelStateEvent;import org.jboss.netty.channel.ExceptionEvent;import org.jboss.netty.channel.MessageEvent;import org.jboss.netty.channel.SimpleChannelUpstreamHandler;import org.jboss.netty.channel.group.ChannelGroup;import org.jboss.netty.channel.group.DefaultChannelGroup;public class IOIODebuggerServerHandler extends SimpleChannelUpstreamHandler {private static final Logger logger = Logger.getLogger(IOIODebuggerServerHandler.class.getName());static final ChannelGroup channels = new DefaultChannelGroup();private ServerHelper helperClass;private boolean clientConnected;public void setServerHelper(ServerHelper helper) {helperClass = helper;}@Overridepublic void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e)throws Exception {if (e instanceof ChannelStateEvent) {logger.info(e.toString());}super.handleUpstream(ctx, e);}public void broadcast(TrackingMessage msg) {for (Channel c : channels) {c.write(msg);}}@Overridepublic void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)throws Exception {channels.add(e.getChannel());}@Overridepublic void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {// Unregister the channel from the global channel list// so the channel does not receive messages anymore.channels.remove(e.getChannel());clientConnected = false;}@Overridepublic void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {TrackingMessage tmsg = (TrackingMessage) e.getMessage();List<Message> msgList;// Handle each message depending on the typeswitch (tmsg.getType()) {case 10:// If there are no clients connected, reply with an ok reponseif (!clientConnected) {System.out.println("No clients currently connected, allowing connection");clientConnected = true;TrackingMessage newMsg = TrackingMessage.newBuilder().setId(0).setType(11).build();e.getChannel().write(newMsg);// Otherwise reply with an error response} else {System.out.println("Client currently connected, rejecting connection");TrackingMessage newMsg = TrackingMessage.newBuilder().setId(0).setType(12).build();e.getChannel().write(newMsg);}break;case 50:msgList = tmsg.getMessageList();for (Message msg : msgList) {if (msg.getType().compareTo("InAnalog") == 0) {helperClass.AddNewAnalogIn(msg.getPin(), msg.getFreq());} else if (msg.getType().compareTo("InDigital") == 0) {helperClass.AddNewDigitalIn(msg.getPin(), msg.getFreq(), msg.getMode());} else if (msg.getType().compareTo("OutDigital") == 0) {helperClass.AddNewDigitalOut(msg.getPin(), msg.getState(), msg.getBoolean());}}break;case 51:msgList = tmsg.getMessageList();for (Message msg : msgList) {helperClass.StopPin(msg.getPin());}break;case 52:msgList = tmsg.getMessageList();for (Message msg : msgList) {helperClass.RemovePin(msg.getPin());}break;case 70:msgList = tmsg.getMessageList();for (Message msg : msgList) {List<Double> dataList = msg.getDataList();helperClass.DataRecieved(msg.getPin(), dataList);}break;}}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {logger.log(Level.WARNING, "Unexpected exception from downstream.",e.getCause());e.getChannel().close();}/** Queries if clients are currently connected to the server** @return true if there are clients connected, false otherwise* */public boolean areClientsConnected() {return clientConnected;}/** Sends a command to the client to add a new analog input** @param pin - Pin number to add* @param freq - Frequency that pin should update*/public void sendAddNewAnalogIn(int pin, long freq) {System.out.println("Sending command to add new analog input Pin: " + pin + " Freq: " + freq);Builder message = Message.newBuilder().setPin(pin).setFreq(freq).setType("InAnalog");TrackingMessage newMsg = TrackingMessage.newBuilder().setId(0).setType(50).addMessage(message).build();broadcast(newMsg);}/** Sends a command to the client to add a new digital input** @param pin - Pin number to add* @param freq - Frequency that pin should update* @param mode - Mode that pin should be started in [Float/Pull Up/Pull Down]*/public void sendAddNewDigitalIn(int pin, long freq, String mode) {System.out.println("Sending command to add new digital input Pin: " + pin + " Freq: " + freq + "Mode: " + mode);Builder message = Message.newBuilder().setPin(pin).setFreq(freq).setMode(mode).setType("InDigital");TrackingMessage newMsg = TrackingMessage.newBuilder().setId(0).setType(50).addMessage(message).build();broadcast(newMsg);}/** Sends a command to the client to add a new digital output** @param pin - Pin number to add* @param state - Initial state of pin [Low/High]* @param openDrain - Option to start pin in open drain mode [true if yes, false if no]*/public void sendAddNewDigitalOut(int pin, String state, boolean openDrain) {System.out.println("Sending command to add new analog input Pin: " + pin + " InitialState: " + state + " OpenDrainMode: " + openDrain);Builder message = Message.newBuilder().setPin(pin).setState(state).setBoolean(openDrain).setType("OutDigital");TrackingMessage newMsg = TrackingMessage.newBuilder().setId(0).setType(50).addMessage(message).build();broadcast(newMsg);}/** Sends a command to the client to execute a hard reset */public void sendHardReset() {TrackingMessage newMsg = TrackingMessage.newBuilder().setId(0).setType(13).build();broadcast(newMsg);}}