0,0 → 1,231 |
/************************************************************************** |
* 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; |
} |
|
@Override |
public 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); |
} |
} |
|
@Override |
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) |
throws Exception { |
|
channels.add(e.getChannel()); |
} |
|
@Override |
public 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; |
} |
|
@Override |
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) { |
|
TrackingMessage tmsg = (TrackingMessage) e.getMessage(); |
|
List<Message> msgList; |
// Handle each message depending on the type |
switch (tmsg.getType()) { |
case 10: |
// If there are no clients connected, reply with an ok reponse |
if (!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; |
} |
} |
|
@Override |
public 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); |
} |
} |