private void searchBridgesBruteforce(BridgeSearchTask task) { HashSet<String> ipsDiscovered = new HashSet<String>(); // Add any existing results if continuing from an existing search for (Bridge b : bridges) { ipsDiscovered.add(b.getIp()); } // Build list of IPs to search (search from center to outer range, because devices are usually // around 192.168.1.100) ArrayList<String> ips = new ArrayList<String>(255); ips.add("192.168.1.127"); for (int i = 1; i <= 127; i++) { ips.add("192.168.1." + (127 - i)); ips.add("192.168.1." + (127 + i)); } // Check every IP for a listening device for (int i = 0; i < 255; i++) { try { final String ip = ips.get(i); if (ipsDiscovered.contains(ip)) continue; tryIP(ip, "http://" + ip + "/description.xml", 20); } catch (IOException e) { // Either no device or not a Philips Hue bridge, move on } catch (Exception e) { // Other types of exceptions sometimes occur when device is misbehaving (e.g. bad UPnP // description file) } } }
private void searchBridgesUPnP(BridgeSearchTask task) throws IOException { // Search bridges on local network using UPnP String upnpRequest = "M-SEARCH * HTTP/1.1\nHOST: 239.255.255.250:1900\nMAN: ssdp:discover\nMX: 8\nST:SsdpSearch:all"; DatagramSocket upnpSock = new DatagramSocket(); upnpSock.setSoTimeout(100); upnpSock.send( new DatagramPacket( upnpRequest.getBytes(), upnpRequest.length(), new InetSocketAddress("239.255.255.250", 1900))); HashSet<String> ipsDiscovered = new HashSet<String>(); // Add any existing results from bruteforce search and previous searches for (Bridge b : bridges) { ipsDiscovered.add(b.getIp()); } long start = System.currentTimeMillis(); long nextBroadcast = start + BROADCAST_INTERVAL; while (true) { // Send a new discovery broadcast once a second if (System.currentTimeMillis() > nextBroadcast) { upnpSock.send( new DatagramPacket( upnpRequest.getBytes(), upnpRequest.length(), new InetSocketAddress("239.255.255.250", 1900))); nextBroadcast = System.currentTimeMillis() + BROADCAST_INTERVAL; } byte[] responseBuffer = new byte[1024]; DatagramPacket responsePacket = new DatagramPacket(responseBuffer, responseBuffer.length); try { upnpSock.receive(responsePacket); } catch (SocketTimeoutException e) { if (System.currentTimeMillis() - start > SEARCH_TIMEOUT || task.isCancelled()) { break; } else { continue; } } final String ip = responsePacket.getAddress().getHostAddress(); final String response = new String(responsePacket.getData()); if (!ipsDiscovered.contains(ip)) { Matcher m = Pattern.compile("LOCATION: (.*)", Pattern.CASE_INSENSITIVE).matcher(response); if (m.find()) { tryIP(ip, m.group(1), 1000); } // Ignore subsequent packets ipsDiscovered.add(ip); } } }