package com.bwssystems.HABridge.upnp; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.bwssystems.HABridge.BridgeSettings; import com.bwssystems.HABridge.BridgeSettingsDescriptor; import com.bwssystems.HABridge.api.hue.HueConstants; import com.bwssystems.HABridge.api.hue.HuePublicConfig; import com.bwssystems.HABridge.util.AddressUtil; import static spark.Spark.get; /** * */ public class UpnpSettingsResource { private Logger log = LoggerFactory.getLogger(UpnpSettingsResource.class); private BridgeSettingsDescriptor theSettings; private BridgeSettings bridgeSettings; private String hueTemplate_pre = "\n" + "\n" + "\n" + "1\n" + "0\n" + "\n" + "http://%s:%s/\n" + "\n" + "urn:schemas-upnp-org:device:Basic:1\n" + "Philips hue (%s)\n" + "Royal Philips Electronics\n" + "http://www.philips.com\n" + "Philips hue Personal Wireless Lighting\n" + "Philips hue bridge 2015\n" + "" + HueConstants.MODEL_ID + "\n" + "http://www.meethue.com\n" + "%s\n" + "uuid:" + HueConstants.UUID_PREFIX + "%s\n"; private String hueTemplate_post = "index.html\n" + "\n" + "\n" + "image/png\n" + "48\n" + "48\n" + "24\n" + "hue_logo_0.png\n" + "\n" + "\n" + "image/png\n" + "120\n" + "120\n" + "24\n" + "hue_logo_3.png\n" + "\n" + "\n"; private String hueTemplate_end = "\n" + "\n"; /* not utilizing this section any more private String hueTemplate_mid_orig = "\n" + "\n" + "(null)\n" + "(null)\n" + "(null)\n" + "(null)\n" + "(null)\n" + "\n" + "\n"; */ public UpnpSettingsResource(BridgeSettings theBridgeSettings) { super(); this.bridgeSettings = theBridgeSettings; this.theSettings = theBridgeSettings.getBridgeSettingsDescriptor(); } public void setupServer() { log.info("Description xml service started...."); // http://ip_adress:port/description.xml which returns the xml configuration for the hue emulator get("/description.xml", "application/xml; charset=utf-8", (request, response) -> { if(bridgeSettings.getBridgeControl().isReinit() || bridgeSettings.getBridgeControl().isStop()) { log.info("Get description.xml called while in re-init or stop state"); response.status(503); return null; } String portNumber = Integer.toString(request.port()); String filledTemplate = null; String httpLocationAddr = null; String hueTemplate = null; if(theSettings.isUpnporiginal()) { httpLocationAddr = theSettings.getUpnpConfigAddress(); hueTemplate = hueTemplate_pre + hueTemplate_end; } else if(!theSettings.isUpnpadvanced()) { if(theSettings.isUseupnpiface()) { httpLocationAddr = theSettings.getUpnpConfigAddress(); } else { log.debug("Get Outbound address for ip:" + request.ip() + " and port:" + request.port()); httpLocationAddr = AddressUtil.getOutboundAddress(request.ip(), request.port()).getHostAddress(); } hueTemplate = hueTemplate_pre + hueTemplate_end; } else { if(theSettings.isUseupnpiface()) { httpLocationAddr = theSettings.getUpnpConfigAddress(); } else { log.debug("Get Outbound address for ip:" + request.ip() + " and port:" + request.port()); httpLocationAddr = AddressUtil.getOutboundAddress(request.ip(), request.port()).getHostAddress(); } hueTemplate = hueTemplate_pre + hueTemplate_post + hueTemplate_end; } String bridgeIdMac = HuePublicConfig.createConfig("temp", httpLocationAddr, HueConstants.HUB_VERSION, theSettings.getHubmac()).getSNUUIDFromMac(); filledTemplate = String.format(hueTemplate, httpLocationAddr, portNumber, httpLocationAddr, bridgeIdMac, bridgeIdMac); if(theSettings.isTraceupnp()) log.info("Traceupnp: request of description.xml from: " + request.ip() + ":" + request.port() + " filled in with address: " + httpLocationAddr + ":" + portNumber); else log.debug("request of description.xml from: " + request.ip() + ":" + request.port() + " filled in with address: " + httpLocationAddr + ":" + portNumber); // response.header("Cache-Control", "no-store, no-cache, must-revalidate, post-check=0, pre-check=0"); // response.header("Pragma", "no-cache"); // response.header("Expires", "Mon, 1 Aug 2011 09:00:00 GMT"); // response.header("Connection", "close"); // Not sure if the server will actually close the connections by just setting the header // response.header("Access-Control-Max-Age", "0"); // response.header("Access-Control-Allow-Origin", "*"); // response.header("Access-Control-Allow-Credentials", "true"); // response.header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE"); // response.header("Access-Control-Allow-Headers", "Content-Type"); // response.header("Content-Type", "application/xml; charset=utf-8"); response.type("application/xml; charset=utf-8"); response.status(200); return filledTemplate; } ); // http://ip_adress:port/favicon.ico get("/favicon.ico", "application/xml; charset=utf-8", (request, response) -> { return ""; } ); // http://ip_adress:port/hue_logo_0.png get("/hue_logo_0.png", "application/xml; charset=utf-8", (request, response) -> { return ""; } ); // http://ip_adress:port/hue_logo_3.png get("/hue_logo_3.png", "application/xml; charset=utf-8", (request, response) -> { return ""; } ); } }