mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2025-07-19 19:13:03 +00:00
Add mDNS support with a patched version of jmDNS 3.4.1
This commit is contained in:
parent
ef1f44f873
commit
1cdcc6d190
@ -4,5 +4,6 @@
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="lib" path="libs/xpp3-1.1.4c.jar"/>
|
||||
<classpathentry kind="lib" path="libs/tinyrtsp.jar"/>
|
||||
<classpathentry kind="lib" path="libs/jmdns-fixed.jar"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
|
BIN
moonlight-common/libs/jmdns-fixed.jar
Normal file
BIN
moonlight-common/libs/jmdns-fixed.jar
Normal file
Binary file not shown.
31
moonlight-common/patches/jmdns-3.4.1-changes.patch
Normal file
31
moonlight-common/patches/jmdns-3.4.1-changes.patch
Normal file
@ -0,0 +1,31 @@
|
||||
Index: build.xml
|
||||
===================================================================
|
||||
--- build.xml (revision 353)
|
||||
+++ build.xml (working copy)
|
||||
@@ -58,7 +58,7 @@
|
||||
</javac>
|
||||
</target>
|
||||
|
||||
- <target name="jar" depends="build,tools" description="Jar the files">
|
||||
+ <target name="jar" depends="build" description="Jar the files">
|
||||
<mkdir dir="${buildlib}" />
|
||||
<jar destfile="${buildlib}/jmdns.jar" manifest="${lib}/jmdns.manifest" basedir="${dest}">
|
||||
<fileset dir="${dest}" defaultexcludes="yes">
|
||||
Index: src/main/java/javax/jmdns/impl/tasks/resolver/ServiceInfoResolver.java
|
||||
===================================================================
|
||||
--- src/main/java/javax/jmdns/impl/tasks/resolver/ServiceInfoResolver.java (revision 353)
|
||||
+++ src/main/java/javax/jmdns/impl/tasks/resolver/ServiceInfoResolver.java (working copy)
|
||||
@@ -80,12 +80,7 @@
|
||||
protected DNSOutgoing addQuestions(DNSOutgoing out) throws IOException {
|
||||
DNSOutgoing newOut = out;
|
||||
if (!_info.hasData()) {
|
||||
- newOut = this.addQuestion(newOut, DNSQuestion.newQuestion(_info.getQualifiedName(), DNSRecordType.TYPE_SRV, DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE));
|
||||
- newOut = this.addQuestion(newOut, DNSQuestion.newQuestion(_info.getQualifiedName(), DNSRecordType.TYPE_TXT, DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE));
|
||||
- if (_info.getServer().length() > 0) {
|
||||
- newOut = this.addQuestion(newOut, DNSQuestion.newQuestion(_info.getServer(), DNSRecordType.TYPE_A, DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE));
|
||||
- newOut = this.addQuestion(newOut, DNSQuestion.newQuestion(_info.getServer(), DNSRecordType.TYPE_AAAA, DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE));
|
||||
- }
|
||||
+ newOut = this.addQuestion(newOut, DNSQuestion.newQuestion(_info.getQualifiedName(), DNSRecordType.TYPE_PTR, DNSRecordClass.CLASS_IN, DNSRecordClass.NOT_UNIQUE));
|
||||
}
|
||||
return newOut;
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package com.limelight.nvstream.mdns;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.UUID;
|
||||
|
||||
public class MdnsComputer {
|
||||
private InetAddress ipAddr;
|
||||
private UUID uniqueId;
|
||||
private String name;
|
||||
|
||||
public MdnsComputer(String name, UUID uniqueId, InetAddress addr) {
|
||||
this.name = name;
|
||||
this.uniqueId = uniqueId;
|
||||
this.ipAddr = addr;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public UUID getUniqueId() {
|
||||
return uniqueId;
|
||||
}
|
||||
|
||||
public InetAddress getAddress() {
|
||||
return ipAddr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return uniqueId.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof MdnsComputer) {
|
||||
MdnsComputer other = (MdnsComputer)o;
|
||||
if (other.uniqueId.equals(uniqueId) &&
|
||||
other.ipAddr.equals(ipAddr) &&
|
||||
other.name.equals(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "["+name+" - "+uniqueId+" - "+ipAddr+"]";
|
||||
}
|
||||
}
|
@ -0,0 +1,173 @@
|
||||
package com.limelight.nvstream.mdns;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.jmdns.JmDNS;
|
||||
import com.jmdns.ServiceEvent;
|
||||
import com.jmdns.ServiceListener;
|
||||
|
||||
import com.limelight.LimeLog;
|
||||
|
||||
public class MdnsDiscoveryAgent {
|
||||
public static final String SERVICE_TYPE = "_nvstream._tcp.local.";
|
||||
|
||||
private JmDNS resolver;
|
||||
private HashMap<InetAddress, MdnsComputer> computers;
|
||||
private Timer discoveryTimer;
|
||||
private MdnsDiscoveryListener listener;
|
||||
private ArrayList<String> pendingResolution;
|
||||
private ServiceListener nvstreamListener = new ServiceListener() {
|
||||
public void serviceAdded(ServiceEvent event) {
|
||||
LimeLog.info("mDNS: Machine appeared: "+event.getInfo().getName());
|
||||
|
||||
// This machine is pending resolution until we get the serviceResolved callback
|
||||
pendingResolution.add(event.getInfo().getName());
|
||||
|
||||
// We call this to kick the resolver
|
||||
resolver.getServiceInfo(SERVICE_TYPE, event.getInfo().getName());
|
||||
}
|
||||
|
||||
public void serviceRemoved(ServiceEvent event) {
|
||||
LimeLog.info("mDNS: Machine disappeared: "+event.getInfo().getName());
|
||||
|
||||
Inet4Address addrs[] = event.getInfo().getInet4Addresses();
|
||||
for (Inet4Address addr : addrs) {
|
||||
synchronized (computers) {
|
||||
MdnsComputer computer = computers.remove(addr);
|
||||
if (computer != null) {
|
||||
listener.notifyComputerRemoved(computer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void serviceResolved(ServiceEvent event) {
|
||||
MdnsComputer computer;
|
||||
|
||||
LimeLog.info("mDNS: Machine resolved: "+event.getInfo().getName());
|
||||
|
||||
pendingResolution.remove(event.getInfo().getName());
|
||||
|
||||
try {
|
||||
computer = parseMdnsResponse(event);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
// Invalid DNS response
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (computers) {
|
||||
if (computers.put(computer.getAddress(), computer) == null) {
|
||||
// This was a new entry
|
||||
listener.notifyComputerAdded(computer);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private static ArrayList<String> parseTxtBytes(byte[] txtBytes) throws UnsupportedEncodingException {
|
||||
int i = 0;
|
||||
ArrayList<String> strings = new ArrayList<String>();
|
||||
|
||||
while (i < txtBytes.length) {
|
||||
int length = txtBytes[i++];
|
||||
|
||||
byte[] stringData = Arrays.copyOfRange(txtBytes, i, i+length);
|
||||
strings.add(new String(stringData, "UTF-8"));
|
||||
|
||||
i += length;
|
||||
}
|
||||
|
||||
return strings;
|
||||
}
|
||||
|
||||
private static MdnsComputer parseMdnsResponse(ServiceEvent event) throws UnsupportedEncodingException {
|
||||
Inet4Address addrs[] = event.getInfo().getInet4Addresses();
|
||||
if (addrs.length == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Inet4Address address = addrs[0];
|
||||
String name = event.getInfo().getName();
|
||||
ArrayList<String> txtStrs = parseTxtBytes(event.getInfo().getTextBytes());
|
||||
String uniqueId = null;
|
||||
for (String txtStr : txtStrs) {
|
||||
if (txtStr.startsWith("SERVICE_UNIQUEID=")) {
|
||||
uniqueId = txtStr.substring(txtStr.indexOf("=")+1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (uniqueId == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
UUID uuid;
|
||||
try {
|
||||
// fromString() throws an exception for a
|
||||
// malformed string
|
||||
uuid = UUID.fromString(uniqueId);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// UUID must be properly formed
|
||||
return null;
|
||||
}
|
||||
|
||||
return new MdnsComputer(name, uuid, address);
|
||||
}
|
||||
|
||||
private MdnsDiscoveryAgent(MdnsDiscoveryListener listener) {
|
||||
computers = new HashMap<InetAddress, MdnsComputer>();
|
||||
discoveryTimer = new Timer();
|
||||
pendingResolution = new ArrayList<String>();
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public static MdnsDiscoveryAgent createDiscoveryAgent(MdnsDiscoveryListener listener) throws IOException {
|
||||
MdnsDiscoveryAgent agent = new MdnsDiscoveryAgent(listener);
|
||||
|
||||
agent.resolver = JmDNS.create();
|
||||
|
||||
return agent;
|
||||
}
|
||||
|
||||
public void startDiscovery(final int discoveryIntervalMs) {
|
||||
resolver.addServiceListener(SERVICE_TYPE, nvstreamListener);
|
||||
|
||||
discoveryTimer.schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
// Send another mDNS query
|
||||
resolver.requestServiceInfo(SERVICE_TYPE, null, discoveryIntervalMs);
|
||||
|
||||
// Run service resolution again for pending machines
|
||||
ArrayList<String> pendingNames = new ArrayList<String>(pendingResolution);
|
||||
for (String name : pendingNames) {
|
||||
LimeLog.info("mDNS: Retrying service resolution for machine: "+name);
|
||||
resolver.getServiceInfo(SERVICE_TYPE, name);
|
||||
}
|
||||
}
|
||||
}, 0, discoveryIntervalMs);
|
||||
}
|
||||
|
||||
public void stopDiscovery() {
|
||||
resolver.removeServiceListener(SERVICE_TYPE, nvstreamListener);
|
||||
|
||||
discoveryTimer.cancel();
|
||||
}
|
||||
|
||||
public List<MdnsComputer> getComputerSet() {
|
||||
synchronized (computers) {
|
||||
return new ArrayList<MdnsComputer>(computers.values());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package com.limelight.nvstream.mdns;
|
||||
|
||||
public interface MdnsDiscoveryListener {
|
||||
public void notifyComputerAdded(MdnsComputer computer);
|
||||
public void notifyComputerRemoved(MdnsComputer computer);
|
||||
public void notifyDiscoveryFailure(Exception e);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user