package net.floodlightcontroller.handover;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.UnknownHostException;
import java.net.UnknownServiceException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.HttpsURLConnection;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONStringer;
import org.openflow.protocol.OFFlowMod;
import org.openflow.protocol.OFMatch;
import org.openflow.protocol.OFPort;
import org.openflow.protocol.action.OFAction;
import org.openflow.protocol.action.OFActionDataLayerDestination;
import org.openflow.protocol.action.OFActionDataLayerSource;
import org.openflow.protocol.action.OFActionOutput;
import org.openflow.protocol.action.OFActionType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.floodlightcontroller.core.IFloodlightProviderService;
import net.floodlightcontroller.core.module.FloodlightModuleContext;
import net.floodlightcontroller.core.module.FloodlightModuleException;
import net.floodlightcontroller.core.module.IFloodlightModule;
import net.floodlightcontroller.core.module.IFloodlightService;
import net.floodlightcontroller.packet.Ethernet;
import net.floodlightcontroller.packet.IPv4;
import net.floodlightcontroller.packet.UDP;
import net.floodlightcontroller.staticflowentry.IStaticFlowEntryPusherService;
import de.taimos.gpsd4java.*;
import de.taimos.gpsd4java.api.IObjectListener;
import de.taimos.gpsd4java.api.ObjectListener;
import de.taimos.gpsd4java.backend.AbstractResultParser;
import de.taimos.gpsd4java.backend.GPSdEndpoint;
import de.taimos.gpsd4java.backend.ResultParser;
import de.taimos.gpsd4java.types.ATTObject;
import de.taimos.gpsd4java.types.DeviceObject;
import de.taimos.gpsd4java.types.DevicesObject;
import de.taimos.gpsd4java.types.ParseException;
import de.taimos.gpsd4java.types.SKYObject;
import de.taimos.gpsd4java.types.TPVObject;
import de.taimos.gpsd4java.types.subframes.SUBFRAMEObject;
public class Handover implements IFloodlightModule {
protected static Logger log;
protected IFloodlightProviderService floodlightProvider;
protected IStaticFlowEntryPusherService sfp;
private static ScheduledThreadPoolExecutor grcProbeMgr;
private static Runnable grcProbe;
private static GPSdEndpoint GPSD_CONN = null;
private static ResultParser GPSD_RESULT_PARSER = null;
private static int GPSD_TCP_PORT = 0; // default in GPSD of 2947
private static double GPSD_LATITUDE = 0;
private static double GPSD_LONGITUDE = 0;
private static double GPSD_ALTITUDE = 0;
private static long GRC_PROBE_INTERVAL_SECONDS;
private static String GRC_URL = null;
private static String OVS_TAP_DPID;
private static String OVS_WIFI0_DPID;
private static String OVS_WIFI1_DPID;
private static String OVS_WIMAX0_DPID;
private static String OVS_WIMAX1_DPID;
private static String OVS_ETHERNET_DPID;
private static byte[] TAP_MAC;
private static byte[] WIFI0_MAC;
private static byte[] WIFI1_MAC;
private static byte[] WIMAX0_MAC;
private static byte[] WIMAX1_MAC;
private static byte[] ETHERNET_MAC;
private static String TAP_IFACE_NAME;
private static String WIFI0_IFACE_NAME;
private static String WIFI1_IFACE_NAME;
private static String WIMAX0_IFACE_NAME;
private static String WIMAX1_IFACE_NAME;
private static String ETHERNET_IFACE_NAME;
private static short OVS_TAP_TO_WIFI0_PATCH;
private static short OVS_TAP_TO_WIFI1_PATCH;
private static short OVS_TAP_TO_WIMAX0_PATCH;
private static short OVS_TAP_TO_WIMAX1_PATCH;
private static short OVS_TAP_TO_ETHERNET_PATCH;
private static short OVS_WIFI0_TO_TAP_PATCH;
private static short OVS_WIFI1_TO_TAP_PATCH;
private static short OVS_WIMAX0_TO_TAP_PATCH;
private static short OVS_WIMAX1_TO_TAP_PATCH;
private static short OVS_ETHERNET_TO_TAP_PATCH;
private static short OVS_TAP_LOCAL_PORT;
private static short OVS_WIFI0_IFACE_PORT;
private static short OVS_WIFI1_IFACE_PORT;
private static short OVS_WIMAX0_IFACE_PORT;
private static short OVS_WIMAX1_IFACE_PORT;
private static short OVS_ETHERNET_IFACE_PORT;
private static ArrayList<String> ACTIVE_FLOWS;
private static final String OFFLINE = "offline";
private static String ACTIVE_NETWORK_TYPE = OFFLINE;
@Override
public Collection<Class<? extends IFloodlightService>> getModuleServices() {
return null;
}
@Override
public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
return null;
}
@Override
public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
return null;
}
@Override
public void init(FloodlightModuleContext context) throws FloodlightModuleException {
floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
sfp = context.getServiceImpl(IStaticFlowEntryPusherService.class);
log = LoggerFactory.getLogger(Handover.class);
return;
}
@Override
public void startUp(FloodlightModuleContext context) {
Map<String, String> configOptions = context.getConfigParams(this);
try {
GRC_PROBE_INTERVAL_SECONDS = Long.parseLong(configOptions.get("grc-probe-interval-seconds"));
GPSD_TCP_PORT = Integer.parseInt(configOptions.get("gpsd-tcp-port"));
GRC_URL = configOptions.get("grc-url");
TAP_IFACE_NAME = configOptions.get("tap-iface-name");
WIFI0_IFACE_NAME = configOptions.get("wifi0-iface-name");
WIFI1_IFACE_NAME = configOptions.get("wifi1-iface-name");
WIMAX0_IFACE_NAME = configOptions.get("wimax0-iface-name");
WIMAX1_IFACE_NAME = configOptions.get("wimax1-iface-name");
ETHERNET_IFACE_NAME = configOptions.get("ethernet-iface-name");
TAP_MAC = Ethernet.toMACAddress(configOptions.get("tap-mac"));
WIFI0_MAC = Ethernet.toMACAddress(configOptions.get("wifi0-mac"));
WIFI1_MAC = Ethernet.toMACAddress(configOptions.get("wifi1-mac"));
WIMAX0_MAC = Ethernet.toMACAddress(configOptions.get("wimax0-mac"));
WIMAX1_MAC = Ethernet.toMACAddress(configOptions.get("wimax1-mac"));
ETHERNET_MAC = Ethernet.toMACAddress(configOptions.get("ethernet-mac"));
OVS_TAP_DPID = configOptions.get("ovs-tap-dpid");
OVS_WIFI0_DPID = configOptions.get("ovs-wifi0-dpid");
OVS_WIFI1_DPID = configOptions.get("ovs-wifi1-dpid");
OVS_WIMAX0_DPID = configOptions.get("ovs-wimax0-dpid");
OVS_WIMAX1_DPID = configOptions.get("ovs-wimax1-dpid");
OVS_ETHERNET_DPID = configOptions.get("ovs-ethernet-dpid");
OVS_TAP_TO_WIFI0_PATCH = Short.parseShort(configOptions.get("ovs-tap-to-wifi0-patch"));
OVS_TAP_TO_WIFI1_PATCH = Short.parseShort(configOptions.get("ovs-tap-to-wifi1-patch"));
OVS_TAP_TO_WIMAX0_PATCH = Short.parseShort(configOptions.get("ovs-tap-to-wimax0-patch"));
OVS_TAP_TO_WIMAX1_PATCH = Short.parseShort(configOptions.get("ovs-tap-to-wimax1-patch"));
OVS_TAP_TO_ETHERNET_PATCH = Short.parseShort(configOptions.get("ovs-tap-to-ethernet-patch"));
OVS_WIFI0_TO_TAP_PATCH = Short.parseShort(configOptions.get("ovs-wifi0-to-tap-patch"));
OVS_WIFI1_TO_TAP_PATCH = Short.parseShort(configOptions.get("ovs-wifi1-to-tap-patch"));
OVS_WIMAX0_TO_TAP_PATCH = Short.parseShort(configOptions.get("ovs-wimax0-to-tap-patch"));
OVS_WIMAX1_TO_TAP_PATCH = Short.parseShort(configOptions.get("ovs-wimax1-to-tap-patch"));
OVS_ETHERNET_TO_TAP_PATCH = Short.parseShort(configOptions.get("ovs-ethernet-to-tap-patch"));
OVS_TAP_LOCAL_PORT = Short.parseShort(configOptions.get("ovs-tap-local-port"));
OVS_WIFI0_IFACE_PORT = Short.parseShort(configOptions.get("ovs-wifi0-iface-port"));
OVS_WIFI1_IFACE_PORT = Short.parseShort(configOptions.get("ovs-wifi1-iface-port"));
OVS_WIMAX0_IFACE_PORT = Short.parseShort(configOptions.get("ovs-wimax0-iface-port"));
OVS_WIMAX1_IFACE_PORT = Short.parseShort(configOptions.get("ovs-wimax1-iface-port"));
OVS_ETHERNET_IFACE_PORT = Short.parseShort(configOptions.get("ovs-ethernet-iface-port"));
} catch(Exception e) {
log.error("Incorrect Handover configuration options", e);
//throw e;
}
ACTIVE_FLOWS = new ArrayList<String>();
try {
GPSD_CONN = new GPSdEndpoint("127.0.0.1", GPSD_TCP_PORT, new ResultParser());
GPSD_CONN.addListener(new ObjectListener(){
@Override
public void handleTPV(TPVObject tpv) {
log.debug("GPSD: Updated TPV");
GPSD_LATITUDE = tpv.getLatitude();
GPSD_LONGITUDE = tpv.getLongitude();
GPSD_ALTITUDE = tpv.getAltitude();
}
@Override
public void handleSKY(SKYObject sky) {
log.debug("GPSD: Updated SKY");
}
@Override
public void handleATT(ATTObject att) {
log.debug("GPSD: Updated ATT");
}
@Override
public void handleSUBFRAME(SUBFRAMEObject subframe) {
log.debug("GPSD: Updated SUBFRAME");
}
@Override
public void handleDevices(DevicesObject devices) {
log.debug("GPSD: Updated DEVICES");
for (DeviceObject d : devices.getDevices()){
log.debug("Device: " + d.toString());
}
try {
GPSD_CONN.poll();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void handleDevice(DeviceObject device) {
log.debug("GPSD: Updated DEVICE");
}
});
GPSD_CONN.start();
log.debug("Version: " + GPSD_CONN.version().toString());
GPSD_CONN.watch(true, true);
} catch (IllegalArgumentException e) {
e.printStackTrace();
throw e;
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
throw e;
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Periodically ask GRC for a handover decision
grcProbeMgr = new ScheduledThreadPoolExecutor(1);
grcProbe = new GRCProbe();
grcProbeMgr.scheduleAtFixedRate(grcProbe, 10, GRC_PROBE_INTERVAL_SECONDS, TimeUnit.SECONDS);
return;
}
private static String cmdExec(String cmdLine) {
String line;
String output = "";
try {
Process p = Runtime.getRuntime().exec(cmdLine);
BufferedReader input = new BufferedReader
(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
output += (line + '\n');
}
input.close();
}
catch (Exception ex) {
ex.printStackTrace();
}
return output;
}
private void switchInterface(String networkType) {
if(ACTIVE_NETWORK_TYPE.equals(networkType) || networkType.equals(OFFLINE))
return;
OFFlowMod flow;
OFMatch match;
ArrayList<OFAction> actionList = new ArrayList<OFAction>();
OFActionOutput outputAction;
OFActionDataLayerDestination dlDstAction;
OFActionDataLayerSource dlSrcAction;
String flowName;
int flowLength;
String ifaceOVSdpid;
String tapOVSdpid = OVS_TAP_DPID;
short tapOVSpatchPort;
short tapOVShostPort = OVS_TAP_LOCAL_PORT;
short ifaceOVSifacePort;
short ifaceOVSpatchPort;
byte[] ifaceMACaddr;
byte[] tapMACaddr = TAP_MAC;
// based on the iface chosen, set appropriate parameters
if (networkType.equals("Wifi")) {
ifaceOVSdpid = OVS_WIFI0_DPID;
tapOVSpatchPort = OVS_TAP_TO_WIFI0_PATCH;
ifaceOVSifacePort = OVS_WIFI0_IFACE_PORT;
ifaceOVSpatchPort = OVS_WIFI0_TO_TAP_PATCH;
ifaceMACaddr = WIFI0_MAC;
} else if (networkType.equals("WiMAX")) {
ifaceOVSdpid = OVS_WIMAX0_DPID;
tapOVSpatchPort = OVS_TAP_TO_WIMAX0_PATCH;
ifaceOVSifacePort = OVS_WIMAX0_IFACE_PORT;
ifaceOVSpatchPort = OVS_WIMAX0_TO_TAP_PATCH;
ifaceMACaddr = WIMAX0_MAC;
} else {
//TODO: remove this... not needed
//fail over to ethernet
ifaceOVSdpid = OVS_ETHERNET_DPID;
tapOVSpatchPort = OVS_TAP_TO_ETHERNET_PATCH;
ifaceOVSifacePort = OVS_ETHERNET_IFACE_PORT;
ifaceOVSpatchPort = OVS_ETHERNET_TO_TAP_PATCH;
ifaceMACaddr = ETHERNET_MAC;
}
// Remove old flows and switch only if we are switching to a different interface.
if (!networkType.equals(ACTIVE_NETWORK_TYPE)) {
while (!ACTIVE_FLOWS.isEmpty()) {
String tmp = ACTIVE_FLOWS.remove(0);
log.debug("In prep. for switch, removing flow " + tmp);
sfp.deleteFlow(tmp);
}
// update to the new interface we have been told to use
ACTIVE_NETWORK_TYPE = networkType;
// first, insert flows at the tap OVS. Do the MAC rewrites here (just to keep them all on one OVS).
// this means there should be no ARP flows at the tap OVS (all ARP packets will be sent to the controller auto-magically).
// tap --> patch (IP)
flow = new OFFlowMod();
match = new OFMatch();
outputAction = new OFActionOutput();
dlSrcAction = new OFActionDataLayerSource();
flowLength = OFFlowMod.MINIMUM_LENGTH;
match.setInputPort(tapOVShostPort);
match.setDataLayerType((short) 0x0800);
dlSrcAction.setType(OFActionType.SET_DL_SRC);
dlSrcAction.setDataLayerAddress(ifaceMACaddr);
dlSrcAction.setLength((short) OFActionDataLayerSource.MINIMUM_LENGTH);
flowLength = flowLength + dlSrcAction.getLengthU();
actionList.add(dlSrcAction);
outputAction.setType(OFActionType.OUTPUT);
outputAction.setPort(tapOVSpatchPort);
outputAction.setLength((short) OFActionOutput.MINIMUM_LENGTH);
flowLength = flowLength + outputAction.getLengthU();
actionList.add(outputAction);
flow.setCookie(0);
flow.setBufferId(-1);
flow.setOutPort(tapOVSpatchPort);
flow.setActions(actionList);
flow.setMatch(match);
flow.setPriority((short) 32768);
flow.setLengthU(flowLength);
flowName = "tap-to-patch-ip";
sfp.addFlow(flowName, flow, tapOVSdpid);
ACTIVE_FLOWS.add(flowName);
log.info("added flow on SW " + tapOVSdpid + flowName);
actionList.clear();
// tap --> patch (CONTROLLER) (ARP)
flow = new OFFlowMod();
match = new OFMatch();
flowLength = OFFlowMod.MINIMUM_LENGTH;
match.setInputPort(tapOVShostPort);
match.setDataLayerType((short) 0x0806);
outputAction.setType(OFActionType.OUTPUT);
outputAction.setPort(OFPort.OFPP_CONTROLLER.getValue());
outputAction.setLength((short) OFActionOutput.MINIMUM_LENGTH);
flowLength = flowLength + outputAction.getLengthU();
actionList.add(outputAction);
flow.setCookie(0);
flow.setBufferId(-1);
flow.setOutPort(OFPort.OFPP_CONTROLLER.getValue());
flow.setActions(actionList);
flow.setMatch(match);
flow.setPriority((short) 32768);
flow.setLengthU(flowLength);
flowName = "tap-to-patch(controller)-arp";
sfp.addFlow(flowName, flow, tapOVSdpid);
ACTIVE_FLOWS.add(flowName);
log.info("added flow on SW " + tapOVSdpid + flowName);
actionList.clear();
// tap <-- patch (IP)
flow = new OFFlowMod();
match = new OFMatch();
dlDstAction = new OFActionDataLayerDestination();
flowLength = OFFlowMod.MINIMUM_LENGTH;
match.setInputPort(tapOVSpatchPort);
match.setDataLayerType((short) 0x0800);
dlDstAction.setType(OFActionType.SET_DL_DST);
dlDstAction.setDataLayerAddress(tapMACaddr);
dlDstAction.setLength((short) OFActionDataLayerDestination.MINIMUM_LENGTH);
flowLength = flowLength + dlDstAction.getLengthU();
actionList.add(dlDstAction);
outputAction.setType(OFActionType.OUTPUT);
outputAction.setPort(tapOVShostPort);
outputAction.setLength((short) OFActionOutput.MINIMUM_LENGTH);
flowLength = flowLength + outputAction.getLengthU();
actionList.add(outputAction);
flow.setCookie(0);
flow.setBufferId(-1);
flow.setOutPort(tapOVShostPort);
flow.setActions(actionList);
flow.setMatch(match);
flow.setPriority((short) 32768);
flow.setLengthU(flowLength);
flowName = "tap-from-patch-ip";
sfp.addFlow(flowName, flow, tapOVSdpid);
ACTIVE_FLOWS.add(flowName);
log.info("added flow on SW " + tapOVSdpid + flowName);
actionList.clear();
// tap (CONTROLLER) <-- patch (ARP)
flow = new OFFlowMod();
match = new OFMatch();
flowLength = OFFlowMod.MINIMUM_LENGTH;
match.setInputPort(tapOVSpatchPort);
match.setDataLayerType((short) 0x0806);
outputAction.setType(OFActionType.OUTPUT);
outputAction.setPort(OFPort.OFPP_CONTROLLER.getValue());
outputAction.setLength((short) OFActionOutput.MINIMUM_LENGTH);
flowLength = flowLength + outputAction.getLengthU();
actionList.add(outputAction);
flow.setCookie(0);
flow.setBufferId(-1);
flow.setOutPort(OFPort.OFPP_CONTROLLER.getValue());
flow.setActions(actionList);
flow.setMatch(match);
flow.setPriority((short) 32768);
flow.setLengthU(flowLength);
flowName = "tap(controller)-from-patch-arp";
sfp.addFlow(flowName, flow, tapOVSdpid);
ACTIVE_FLOWS.add(flowName);
log.info("added flow on SW " + tapOVSdpid + flowName);
actionList.clear();
// now, insert the flows on the OVS corresponding to the iface of choice.
// no rewrites should occur here. Forward all packets of any ethertype.
// iface <-- patch (IP)
flow = new OFFlowMod();
match = new OFMatch();
flowLength = OFFlowMod.MINIMUM_LENGTH;
match.setInputPort(ifaceOVSpatchPort);
match.setDataLayerType((short) 0x0800);
outputAction.setType(OFActionType.OUTPUT);
outputAction.setPort(ifaceOVSifacePort);
outputAction.setLength((short) OFActionOutput.MINIMUM_LENGTH);
flowLength = flowLength + outputAction.getLengthU();
actionList.add(outputAction);
flow.setCookie(0);
flow.setBufferId(-1);
flow.setOutPort(ifaceOVSifacePort);
flow.setActions(actionList);
flow.setMatch(match);
flow.setPriority((short) 32768);
flow.setLengthU(flowLength);
flowName = "iface-from-patch-ip";
sfp.addFlow(flowName, flow, ifaceOVSdpid);
ACTIVE_FLOWS.add(flowName);
log.info("added flow on SW " + ifaceOVSdpid + flowName);
actionList.clear();
// iface <-- patch (ARP)
flow = new OFFlowMod();
match = new OFMatch();
flowLength = OFFlowMod.MINIMUM_LENGTH;
match.setInputPort(ifaceOVSpatchPort);
match.setDataLayerType((short) 0x0806);
outputAction.setType(OFActionType.OUTPUT);
outputAction.setPort(ifaceOVSifacePort);
outputAction.setLength((short) OFActionOutput.MINIMUM_LENGTH);
flowLength = flowLength + outputAction.getLengthU();
actionList.add(outputAction);
flow.setCookie(0);
flow.setBufferId(-1);
flow.setOutPort(ifaceOVSifacePort);
flow.setActions(actionList);
flow.setMatch(match);
flow.setPriority((short) 32768);
flow.setLengthU(flowLength);
flowName = "iface-from-patch-arp";
sfp.addFlow(flowName, flow, ifaceOVSdpid);
ACTIVE_FLOWS.add(flowName);
log.info("added flow on SW " + ifaceOVSdpid + flowName);
actionList.clear();
// iface --> patch (IP)
flow = new OFFlowMod();
match = new OFMatch();
flowLength = OFFlowMod.MINIMUM_LENGTH;
match.setInputPort(ifaceOVSifacePort);
match.setDataLayerType((short) 0x0800);
outputAction.setType(OFActionType.OUTPUT);
outputAction.setPort(ifaceOVSpatchPort);
outputAction.setLength((short) OFActionOutput.MINIMUM_LENGTH);
flowLength = flowLength + outputAction.getLengthU();
actionList.add(outputAction);
flow.setCookie(0);
flow.setBufferId(-1);
flow.setOutPort(ifaceOVSpatchPort);
flow.setActions(actionList);
flow.setMatch(match);
flow.setPriority((short) 32768);
flow.setLengthU(flowLength);
flowName = "iface-to-patch-ip";
sfp.addFlow(flowName, flow, ifaceOVSdpid);
ACTIVE_FLOWS.add(flowName);
log.info("added flow on SW " + ifaceOVSdpid + flowName);
actionList.clear();
// iface --> patch (ARP)
flow = new OFFlowMod();
match = new OFMatch();
flowLength = OFFlowMod.MINIMUM_LENGTH;
match.setInputPort(ifaceOVSifacePort);
match.setDataLayerType((short) 0x0806);
outputAction.setType(OFActionType.OUTPUT);
outputAction.setPort(ifaceOVSpatchPort);
outputAction.setLength((short) OFActionOutput.MINIMUM_LENGTH);
flowLength = flowLength + outputAction.getLengthU();
actionList.add(outputAction);
flow.setCookie(0);
flow.setBufferId(-1);
flow.setOutPort(ifaceOVSpatchPort);
flow.setActions(actionList);
flow.setMatch(match);
flow.setPriority((short) 32768);
flow.setLengthU(flowLength);
flowName = "iface-to-patch-arp";
sfp.addFlow(flowName, flow, ifaceOVSdpid);
ACTIVE_FLOWS.add(flowName);
log.info("added flow on SW " + ifaceOVSdpid + flowName);
actionList.clear();
}
return;
}
// HTTP POST request
private String askGRC() {
try {
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(GRC_URL);
List <NameValuePair> nvps = new ArrayList <NameValuePair>();
//we need a list of all available network types, this shouldn't be hard coded
ArrayList<String> networkTypes = new ArrayList<String>();
networkTypes.add("WiMAX");
networkTypes.add("Wifi");
//create a JSON object for every interface name, containing collected details
ArrayList<JSONObject> netTypeObjs = new ArrayList<JSONObject>();
for(String netType : networkTypes){
JSONObject obj = new JSONObject();
obj.put("name", netType);
obj.put("operator", netType.equals("Wifi")? "" :"Clemson");
netTypeObjs.add(obj);
}
//create a JSON array containing all of our JSON objects, and include it in our request
log.debug("Latitude: " + Double.toString(GPSD_LATITUDE) + ", Longitude: " + Double.toString(GPSD_LONGITUDE));
JSONArray jNetTypesArray = new JSONArray(netTypeObjs);
nvps.add(new BasicNameValuePair("latitude", Double.toString(GPSD_LATITUDE)));
nvps.add(new BasicNameValuePair("longitude", Double.toString(GPSD_LONGITUDE)));
nvps.add(new BasicNameValuePair("network_types", jNetTypesArray.toString()));
//set POST parameters and execute request
httpPost.setEntity(new UrlEncodedFormEntity(nvps));
HttpResponse response = httpclient.execute(httpPost);
int status = response.getStatusLine().getStatusCode();
//retreive JSON response
String body;
if(status >= 200 && status < 300){
HttpEntity entity = response.getEntity();
body = EntityUtils.toString(entity);
} else {
body = "ERROR";
}
//parse JSON response
JSONObject responseObj = new JSONObject(body);
String responseNet = responseObj.getString("network");
if(responseNet.isEmpty()){
log.debug("ERROR: Empty response from server, check args.");
return OFFLINE;
}
log.debug("Switching to: " + responseNet);
return responseObj.getString("network");
} catch(Exception e) {
e.printStackTrace();
}
return OFFLINE;
}
class GRCProbe implements Runnable {
@Override
public void run() {
log.info("Asking GRC (Cybertiger) for a handover decision...");
// do it here
switchInterface(askGRC());
return;
}
} // END GRCProbe Class
} // END Handover Module