mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2025-07-22 12:33:02 +00:00
mDNS no longer crashes on malformed packets
This commit is contained in:
parent
1d5adff0d5
commit
7038384d36
@ -5,5 +5,6 @@
|
|||||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
|
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
|
||||||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
|
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
|
||||||
|
<classpathentry kind="lib" path="C:/Users/Andrew/Documents/GitHub/EECS293/mDNSTest/libs/dnsjava-2.1.6.jar"/>
|
||||||
<classpathentry kind="output" path="bin/classes"/>
|
<classpathentry kind="output" path="bin/classes"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
@ -35,15 +35,11 @@ or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>na
|
|||||||
public static final int ic_launcher=0x7f020000;
|
public static final int ic_launcher=0x7f020000;
|
||||||
}
|
}
|
||||||
public static final class id {
|
public static final class id {
|
||||||
<<<<<<< HEAD
|
public static final int hostTextView=0x7f080003;
|
||||||
public static final int mDNSResultView=0x7f080000;
|
public static final int mDNSResultView=0x7f080002;
|
||||||
public static final int surfaceView=0x7f080001;
|
|
||||||
=======
|
|
||||||
public static final int hostTextView=0x7f080002;
|
|
||||||
public static final int pairButton=0x7f080000;
|
public static final int pairButton=0x7f080000;
|
||||||
public static final int statusButton=0x7f080001;
|
public static final int statusButton=0x7f080001;
|
||||||
public static final int surfaceView=0x7f080003;
|
public static final int surfaceView=0x7f080004;
|
||||||
>>>>>>> d7062ac2e0b306c42144c84690a3735c5878e11d
|
|
||||||
}
|
}
|
||||||
public static final class layout {
|
public static final class layout {
|
||||||
public static final int activity_connection=0x7f030000;
|
public static final int activity_connection=0x7f030000;
|
||||||
|
Binary file not shown.
@ -16,7 +16,7 @@
|
|||||||
android:layout_centerHorizontal="true"
|
android:layout_centerHorizontal="true"
|
||||||
android:text="Pair with PC"/>
|
android:text="Pair with PC"/>
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
<ListView
|
<ListView
|
||||||
android:id="@+id/mDNSResultView"
|
android:id="@+id/mDNSResultView"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
@ -24,7 +24,7 @@
|
|||||||
android:layout_alignParentLeft="true"
|
android:layout_alignParentLeft="true"
|
||||||
android:layout_alignParentTop="true" >
|
android:layout_alignParentTop="true" >
|
||||||
</ListView>
|
</ListView>
|
||||||
=======
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/hostTextView"
|
android:id="@+id/hostTextView"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@ -42,6 +42,6 @@
|
|||||||
android:layout_below="@+id/hostTextView"
|
android:layout_below="@+id/hostTextView"
|
||||||
android:layout_centerHorizontal="true"
|
android:layout_centerHorizontal="true"
|
||||||
android:text="Start Streaming Steam!" />
|
android:text="Start Streaming Steam!" />
|
||||||
>>>>>>> d7062ac2e0b306c42144c84690a3735c5878e11d
|
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
package com.limelight;
|
package com.limelight;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
<<<<<<< HEAD
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.TimeoutException;
|
|
||||||
=======
|
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
>>>>>>> d7062ac2e0b306c42144c84690a3735c5878e11d
|
|
||||||
|
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
@ -34,15 +29,13 @@ public class Connection extends Activity {
|
|||||||
private static final String DEFAULT_HOST = "192.168.1.240";
|
private static final String DEFAULT_HOST = "192.168.1.240";
|
||||||
public static final String HOST_KEY = "hostText";
|
public static final String HOST_KEY = "hostText";
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
}
|
}
|
||||||
|
|
||||||
=======
|
|
||||||
>>>>>>> d7062ac2e0b306c42144c84690a3735c5878e11d
|
|
||||||
@Override
|
@Override
|
||||||
public void onPause() {
|
public void onPause() {
|
||||||
SharedPreferences.Editor editor = prefs.edit();
|
SharedPreferences.Editor editor = prefs.edit();
|
||||||
@ -64,41 +57,29 @@ public class Connection extends Activity {
|
|||||||
|
|
||||||
Log.v("NvmDNS", "onCreate");
|
Log.v("NvmDNS", "onCreate");
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
NvmDNS dns = new NvmDNS();
|
NvmDNS dns = new NvmDNS();
|
||||||
dns.execute();
|
dns.execute();
|
||||||
} catch (IOException e2) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e2.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
setContentView(R.layout.activity_connection);
|
setContentView(R.layout.activity_connection);
|
||||||
|
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
// this.statusButton = (Button) findViewById(R.id.statusButton);
|
|
||||||
// this.hostText = (TextView) findViewById(R.id.hostTextView);
|
|
||||||
=======
|
|
||||||
this.statusButton = (Button) findViewById(R.id.statusButton);
|
this.statusButton = (Button) findViewById(R.id.statusButton);
|
||||||
this.pairButton = (Button) findViewById(R.id.pairButton);
|
this.pairButton = (Button) findViewById(R.id.pairButton);
|
||||||
this.hostText = (TextView) findViewById(R.id.hostTextView);
|
this.hostText = (TextView) findViewById(R.id.hostTextView);
|
||||||
>>>>>>> d7062ac2e0b306c42144c84690a3735c5878e11d
|
|
||||||
|
|
||||||
//prefs = getPreferences(0);
|
//prefs = getPreferences(0);
|
||||||
//this.hostText.setText(prefs.getString(Connection.HOST_KEY, Connection.DEFAULT_HOST));
|
//this.hostText.setText(prefs.getString(Connection.HOST_KEY, Connection.DEFAULT_HOST));
|
||||||
|
|
||||||
/*this.statusButton.setOnClickListener(new OnClickListener() {
|
this.statusButton.setOnClickListener(new OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View arg0) {
|
public void onClick(View arg0) {
|
||||||
Intent intent = new Intent(Connection.this, Game.class);
|
Intent intent = new Intent(Connection.this, Game.class);
|
||||||
intent.putExtra("host", Connection.this.hostText.getText().toString());
|
intent.putExtra("host", Connection.this.hostText.getText().toString());
|
||||||
Connection.this.startActivity(intent);
|
Connection.this.startActivity(intent);
|
||||||
}
|
}
|
||||||
<<<<<<< HEAD
|
|
||||||
});*/
|
|
||||||
=======
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.pairButton.setOnClickListener(new OnClickListener() {
|
this.pairButton.setOnClickListener(new OnClickListener() {
|
||||||
@ -154,7 +135,7 @@ public class Connection extends Activity {
|
|||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
>>>>>>> d7062ac2e0b306c42144c84690a3735c5878e11d
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package com.limelight.nvstream;
|
package com.limelight.nvstream;
|
||||||
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class NvComputer {
|
public class NvComputer {
|
||||||
private String mDNSResponse;
|
private String mDNSResponse;
|
||||||
@ -12,15 +12,14 @@ public class NvComputer {
|
|||||||
private int numOfApps;
|
private int numOfApps;
|
||||||
private String gpuType;
|
private String gpuType;
|
||||||
private String mac;
|
private String mac;
|
||||||
private String uniqueID;
|
private UUID uniqueID;
|
||||||
|
|
||||||
private HashSet<NvComputerGame> games;
|
|
||||||
private int sessionID;
|
private int sessionID;
|
||||||
private boolean paired;
|
private boolean paired;
|
||||||
private boolean isBusy;
|
private boolean isBusy;
|
||||||
|
|
||||||
|
|
||||||
public NvComputer(String mDNSResponse, InetAddress ipAddress, String ipAddressString, int state, int numOfApps, String gpuType, String mac, String uniqueID) {
|
public NvComputer(String mDNSResponse, InetAddress ipAddress, String ipAddressString, int state, int numOfApps, String gpuType, String mac, UUID uniqueID) {
|
||||||
this.mDNSResponse = mDNSResponse;
|
this.mDNSResponse = mDNSResponse;
|
||||||
this.ipAddress = ipAddress;
|
this.ipAddress = ipAddress;
|
||||||
this.ipAddressString = ipAddressString;
|
this.ipAddressString = ipAddressString;
|
||||||
@ -29,8 +28,6 @@ public class NvComputer {
|
|||||||
this.gpuType = gpuType;
|
this.gpuType = gpuType;
|
||||||
this.mac = mac;
|
this.mac = mac;
|
||||||
this.uniqueID = uniqueID;
|
this.uniqueID = uniqueID;
|
||||||
|
|
||||||
this.games = new HashSet<NvComputerGame>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getmDNSResponse() {
|
public String getmDNSResponse() {
|
||||||
@ -46,7 +43,7 @@ public class NvComputer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getIPAddressString() {
|
public String getIPAddressString() {
|
||||||
return this.ipAddress.getCanonicalHostName().toLowerCase();
|
return this.ipAddress.getCanonicalHostName().toLowerCase(Locale.getDefault());
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getState() {
|
public int getState() {
|
||||||
@ -65,18 +62,10 @@ public class NvComputer {
|
|||||||
return this.mac;
|
return this.mac;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUniqueID() {
|
public UUID getUniqueID() {
|
||||||
return this.uniqueID;
|
return this.uniqueID;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean addGame(NvComputerGame game) {
|
|
||||||
return this.games.add(game);
|
|
||||||
}
|
|
||||||
|
|
||||||
public HashSet<NvComputerGame> getGames() {
|
|
||||||
return this.games;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateAfterPairQuery(int sessionID, boolean paired, boolean isBusy) {
|
public void updateAfterPairQuery(int sessionID, boolean paired, boolean isBusy) {
|
||||||
|
|
||||||
this.sessionID = sessionID;
|
this.sessionID = sessionID;
|
||||||
@ -127,53 +116,10 @@ public class NvComputer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
NvComputer otherComputer = (NvComputer)obj;
|
if (obj instanceof UUID) {
|
||||||
if (this.ipAddress == null && otherComputer.getIpAddress() == null) {
|
return this.uniqueID.equals(obj);
|
||||||
return true;
|
|
||||||
} else if (this.ipAddress == null || otherComputer.getIpAddress() == null) {
|
|
||||||
return false;
|
|
||||||
} else {
|
} else {
|
||||||
return this.ipAddress.equals(otherComputer.getIpAddress());
|
return false;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class NvComputerGame {
|
|
||||||
private Integer ID;
|
|
||||||
private String appTitle;
|
|
||||||
private Boolean isRunning;
|
|
||||||
private Integer gameSession;
|
|
||||||
private Integer winLogon;
|
|
||||||
|
|
||||||
public NvComputerGame(int ID, String appTitle, boolean isRunning) {
|
|
||||||
this.ID = ID;
|
|
||||||
this.appTitle = appTitle;
|
|
||||||
this.isRunning = isRunning;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void launchedGame(int gameSession, int winLogon) {
|
|
||||||
this.isRunning = true;
|
|
||||||
this.gameSession = gameSession;
|
|
||||||
this.winLogon = winLogon;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getID() {
|
|
||||||
return this.ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAppTitle() {
|
|
||||||
return this.appTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Boolean getIsRunning() {
|
|
||||||
return this.isRunning;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getGameSession() {
|
|
||||||
return this.gameSession;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer winLogon() {
|
|
||||||
return this.winLogon;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -7,7 +7,11 @@ import java.net.InetAddress;
|
|||||||
import java.net.MulticastSocket;
|
import java.net.MulticastSocket;
|
||||||
|
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.xbill.DNS.DClass;
|
import org.xbill.DNS.DClass;
|
||||||
import org.xbill.DNS.Header;
|
import org.xbill.DNS.Header;
|
||||||
@ -15,214 +19,228 @@ import org.xbill.DNS.Message;
|
|||||||
import org.xbill.DNS.Name;
|
import org.xbill.DNS.Name;
|
||||||
import org.xbill.DNS.Record;
|
import org.xbill.DNS.Record;
|
||||||
import org.xbill.DNS.Section;
|
import org.xbill.DNS.Section;
|
||||||
|
import org.xbill.DNS.TXTRecord;
|
||||||
|
import org.xbill.DNS.TextParseException;
|
||||||
import org.xbill.DNS.Type;
|
import org.xbill.DNS.Type;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.net.nsd.NsdManager;
|
|
||||||
import android.net.nsd.NsdManager.DiscoveryListener;
|
|
||||||
import android.net.nsd.NsdManager.ResolveListener;
|
|
||||||
import android.net.nsd.NsdServiceInfo;
|
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
/**
|
|
||||||
* NvmDNS implements a clone of the NVidia Shield mDNS service for use on Limelight
|
|
||||||
* @author yetanothername
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class NvmDNS extends AsyncTask<Void, Integer, Void> {
|
public class NvmDNS extends AsyncTask<Void, Integer, Void> {
|
||||||
|
|
||||||
public static String NVSTREAM_MDNS_QUERY = "_nvstream._tcp.local.";
|
public static String MDNS_QUERY = "_nvstream._tcp.local.";
|
||||||
public static String NVSTREAM_MDNS_MULTICAST_GROUP = "224.0.0.251";
|
public static String MDNS_MULTICAST_GROUP = "224.0.0.251";
|
||||||
public static InetAddress NVSTREAM_MDNS_MULTICAST_ADDRESS;
|
public static InetAddress MDNS_MULTICAST_ADDRESS;
|
||||||
public static final short NVSTREAM_MDNS_PORT = 5353;
|
public static final short MDNS_PORT = 5353;
|
||||||
|
|
||||||
private HashSet<NvComputer> nvstream_mdns_responses;
|
public static final int WAIT_MS = 5000;
|
||||||
|
|
||||||
private MulticastSocket nvstream_socket;
|
private HashSet<NvComputer> responses;
|
||||||
|
private MulticastSocket socket;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
NVSTREAM_MDNS_MULTICAST_ADDRESS = InetAddress.getByName(NvmDNS.NVSTREAM_MDNS_MULTICAST_GROUP);
|
MDNS_MULTICAST_ADDRESS = InetAddress.getByName(NvmDNS.MDNS_MULTICAST_GROUP);
|
||||||
} catch (UnknownHostException e) {
|
} catch (UnknownHostException e) {
|
||||||
NVSTREAM_MDNS_MULTICAST_ADDRESS = null;
|
MDNS_MULTICAST_ADDRESS = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public NvmDNS() {
|
||||||
|
this.responses = new HashSet<NvComputer>();
|
||||||
|
|
||||||
/**
|
// Create our Socket Connection
|
||||||
* We need to convert the IP Address into an IP Object
|
|
||||||
*/
|
|
||||||
static {
|
|
||||||
try {
|
try {
|
||||||
NVSTREAM_MDNS_MULTICAST_ADDRESS = InetAddress.getByName(NvmDNS.NVSTREAM_MDNS_MULTICAST_GROUP);
|
this.socket = new MulticastSocket(NvmDNS.MDNS_PORT);
|
||||||
} catch (UnknownHostException e) {
|
this.socket.setLoopbackMode(false);
|
||||||
NVSTREAM_MDNS_MULTICAST_ADDRESS = null;
|
this.socket.joinGroup(NvmDNS.MDNS_MULTICAST_ADDRESS);
|
||||||
|
Log.v("NvmDNS Socket Constructor", "Created mDNS listening socket");
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e("NvmDNS Socket Constructor", "There was an error creating the DNS socket.");
|
||||||
|
Log.e("NvmDNS Socket Constructor", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public Set<NvComputer> getComputers() {
|
||||||
* This sets up the query sockets and the list, as well as sends out the query and listens for responses
|
return Collections.unmodifiableSet(this.responses);
|
||||||
* @throws IOException When shit breaks
|
|
||||||
*/
|
|
||||||
public NvmDNS() throws IOException {
|
|
||||||
Log.v("NvmDNS", "Constructor entered");
|
|
||||||
this.nvstream_mdns_responses = new HashSet<NvComputer>();
|
|
||||||
Log.v("NvmDNS", "Constructor exited");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void makeFakeData() {
|
private void sendQuery() {
|
||||||
try {
|
|
||||||
this.nvstream_mdns_responses.add(new NvComputer("127.0.0.1",
|
|
||||||
InetAddress.getByName("127.0.0.1"),
|
|
||||||
InetAddress.getByName("127.0.0.1").getCanonicalHostName(),
|
|
||||||
0,
|
|
||||||
4,
|
|
||||||
"Intel(R) Extreme Graphics 3",
|
|
||||||
"DE:AD:BE:EF:CA:FE",
|
|
||||||
"foo"));
|
|
||||||
this.nvstream_mdns_responses.add(new NvComputer("10.0.2.15",
|
|
||||||
InetAddress.getByName("10.0.2.15"),
|
|
||||||
InetAddress.getByName("10.0.2.15").getCanonicalHostName(),
|
|
||||||
0,
|
|
||||||
5,
|
|
||||||
"Intel(R) Extreme Graphics 2",
|
|
||||||
"DE:AD:BE:EF:CA:FE",
|
|
||||||
"bar"));
|
|
||||||
} catch (Exception e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendQueryAndWait() {
|
|
||||||
this.makeFakeData();
|
|
||||||
try {
|
|
||||||
Log.v("NvmDNS UDP Loop", "mDNS Loop Started");
|
|
||||||
|
|
||||||
this.nvstream_socket = new MulticastSocket(NvmDNS.NVSTREAM_MDNS_PORT);
|
|
||||||
this.nvstream_socket.setLoopbackMode(false);
|
|
||||||
this.nvstream_socket.joinGroup(NvmDNS.NVSTREAM_MDNS_MULTICAST_ADDRESS);
|
|
||||||
|
|
||||||
Log.v("NvmDNS UDP Loop", "Multicast Socket Created @" + this.nvstream_socket.getLocalPort());
|
|
||||||
|
|
||||||
Header queryHeader = new Header();
|
Header queryHeader = new Header();
|
||||||
|
|
||||||
|
// If we set the RA (Recursion Available) flag and our message ID to 0
|
||||||
|
// then the packet matches the real mDNS query packet as displayed in Wireshark
|
||||||
queryHeader.setFlag(org.xbill.DNS.Flags.RA);
|
queryHeader.setFlag(org.xbill.DNS.Flags.RA);
|
||||||
queryHeader.setID(0);
|
queryHeader.setID(0);
|
||||||
|
|
||||||
Record question = Record.newRecord(new Name(NvmDNS.NVSTREAM_MDNS_QUERY), Type.PTR, DClass.IN);
|
Record question = null;
|
||||||
|
try {
|
||||||
|
// We need to create our "Question" DNS query that is a pointer record to
|
||||||
|
// the mDNS Query "Name"
|
||||||
|
question = Record.newRecord(new Name(NvmDNS.MDNS_QUERY), Type.PTR, DClass.IN);
|
||||||
|
} catch (TextParseException e) {
|
||||||
|
Log.e("NvmDNS Query", e.getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We combine our header and our question into a single message
|
||||||
Message query = new Message();
|
Message query = new Message();
|
||||||
query.setHeader(queryHeader);
|
query.setHeader(queryHeader);
|
||||||
query.addRecord(question, Section.QUESTION);
|
query.addRecord(question, Section.QUESTION);
|
||||||
|
|
||||||
|
// Convert the message into Network Byte Order
|
||||||
byte[] wireQuery = query.toWire();
|
byte[] wireQuery = query.toWire();
|
||||||
|
Log.v("NvmDNS Query", query.toString());
|
||||||
|
|
||||||
Log.v("NvmDNS UDP Loop", "Query: " + query.toString());
|
// Convert our byte array into a Packet
|
||||||
|
|
||||||
DatagramPacket transmitPacket = new DatagramPacket(wireQuery, wireQuery.length);
|
DatagramPacket transmitPacket = new DatagramPacket(wireQuery, wireQuery.length);
|
||||||
transmitPacket.setAddress(NvmDNS.NVSTREAM_MDNS_MULTICAST_ADDRESS);
|
transmitPacket.setAddress(NvmDNS.MDNS_MULTICAST_ADDRESS);
|
||||||
transmitPacket.setPort(NvmDNS.NVSTREAM_MDNS_PORT);
|
transmitPacket.setPort(NvmDNS.MDNS_PORT);
|
||||||
|
|
||||||
|
// And (attempt) to send the packet
|
||||||
|
try {
|
||||||
|
Log.v("NvmDNS Query", "Blocking on this.nvstream_socket.send(transmitPacket)");
|
||||||
|
this.socket.send(transmitPacket);
|
||||||
|
Log.v("NvmDNS Query", "Passed this.nvstream_socket.send(transmitPacket)");
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e("NvmDNS Query", "There was an error sending the DNS query.");
|
||||||
|
Log.e("NvmDNS Query", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void waitForResponses() {
|
||||||
|
Log.v("NvmDNS Response", "mDNS Loop Started");
|
||||||
|
|
||||||
this.nvstream_socket.send(transmitPacket);
|
// We support up to 1500 byte packets
|
||||||
Log.v("NvmDNS UDP Loop", "Query Sent");
|
|
||||||
|
|
||||||
byte[] data = new byte[1500];
|
byte[] data = new byte[1500];
|
||||||
DatagramPacket packet = new DatagramPacket(data, data.length);
|
DatagramPacket packet = new DatagramPacket(data, data.length);
|
||||||
|
|
||||||
Message message = null;
|
Message message = null;
|
||||||
|
|
||||||
while (true) {
|
while (!this.socket.isClosed()) {
|
||||||
|
// Attempt to receive a packet/response
|
||||||
Log.d("NvmDNS UDP Loop", "Blocking on this.nvstream_query_socket.recieve()");
|
try {
|
||||||
this.nvstream_socket.receive(packet);
|
Log.d("NvmDNS Response", "Blocking on this.nvstream_query_socket.recieve()");
|
||||||
Log.d("NvmDNS UDP Loop", "Blocking passed on this.nvstream_query_socket.recieve()");
|
this.socket.receive(packet);
|
||||||
|
Log.d("NvmDNS Response", "Blocking passed on this.nvstream_query_socket.recieve()");
|
||||||
message = new Message(packet.getData());
|
message = new Message(packet.getData());
|
||||||
|
} catch (IOException e) {
|
||||||
|
if (this.socket.isClosed()) {
|
||||||
|
Log.e("NvmDNS Response", "The socket was closed on us. The timer must have been reached.");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
Log.e("NvmDNS Response", "There was an error receiving the response.");
|
||||||
|
Log.e("NvmDNS Response", e.getMessage());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We really only care about the ADDITIONAL section (specifically the text records)
|
||||||
Record[] responses = message.getSectionArray(Section.ADDITIONAL);
|
Record[] responses = message.getSectionArray(Section.ADDITIONAL);
|
||||||
if (responses.length != 0 && message.getSectionArray(Section.ANSWER).length != 0 &&
|
|
||||||
message.getSectionArray(Section.ANSWER)[0].getName().toString().equals(NvmDNS.NVSTREAM_MDNS_QUERY)) {
|
|
||||||
|
|
||||||
Log.v("NvmDNS UDP Reply", "Got a packet from " + packet.getAddress().getCanonicalHostName());
|
// We only want to process records that actually have a length, have an ANSWER
|
||||||
Log.v("NvmDNS UDP Reply", "Question: " + message.getSectionArray(Section.ANSWER)[0].getName().toString());
|
// section that has stuff in it and that the ANSWER to our query is what we sent
|
||||||
Log.v("NvmDNS UDP Reply", "Response: " + responses[0].getName().toString());
|
if (responses.length != 0 &&
|
||||||
|
message.getSectionArray(Section.ANSWER).length != 0 &&
|
||||||
|
message.getSectionArray(Section.ANSWER)[0].getName().toString().equals(NvmDNS.MDNS_QUERY)) {
|
||||||
|
|
||||||
String[] txtRecords = responses[0].rdataToString().split("\" \"");
|
Log.v("NvmDNS Response", "Got a packet from " + packet.getAddress().getCanonicalHostName());
|
||||||
|
Log.v("NvmDNS Response", "Question: " + message.getSectionArray(Section.ANSWER)[0].getName().toString());
|
||||||
|
Log.v("NvmDNS Response", "Response: " + responses[0].getName().toString());
|
||||||
|
|
||||||
// No, but really, there has to be a better way of doing this...
|
// The DNS library we are using does not use inferred generics :(
|
||||||
txtRecords[0] = txtRecords[0].substring(1);
|
|
||||||
txtRecords[txtRecords.length - 1] = txtRecords[txtRecords.length - 1].split("\"")[0];
|
|
||||||
|
|
||||||
int state = -1;
|
TXTRecord txtRecord = null;
|
||||||
int numOfApps = -1;
|
|
||||||
String gpuType = "Intel(R) Extreme Graphics 2";
|
|
||||||
String mac = "DE:AD:BE:EF:CA:FE";
|
|
||||||
String uniqueID = "4";
|
|
||||||
|
|
||||||
for (int i = 0; i < txtRecords.length; i++) {
|
|
||||||
if (i == 0) {
|
for (Record record : responses) {
|
||||||
state = Integer.parseInt(txtRecords[i].split("=")[1]);
|
Log.v("NvmDNS Response", "We recieved a DNS repsonse with a " + record.getClass().getName() + " record.");
|
||||||
} else if (i == 1) {
|
if (record instanceof TXTRecord) {
|
||||||
numOfApps = Integer.parseInt(txtRecords[i].split("=")[1]);
|
txtRecord = (TXTRecord)record;
|
||||||
} else if (i == 2) {
|
|
||||||
gpuType = txtRecords[i].split("=")[1];
|
|
||||||
} else if (i == 3) {
|
|
||||||
mac = txtRecords[i].split("=")[1];
|
|
||||||
} else if (i == 4) {
|
|
||||||
uniqueID = txtRecords[i].split("=")[1];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (txtRecord == null) {
|
||||||
|
Log.e("NvmDNS Response", "We recieved a malformed DNS repsonse with no TXTRecord");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
ArrayList<?> txtRecordStringList = new ArrayList<Object>(txtRecord.getStrings());
|
||||||
|
|
||||||
|
if (txtRecordStringList.size() != 5) {
|
||||||
|
Log.e("NvmDNS Response", "We recieved a malformed DNS repsonse with the improper amount of TXTRecord Entries.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The general format of the text records is:
|
||||||
|
// SERVICE_STATE=1
|
||||||
|
// SERVICE_NUMOFAPPS=5
|
||||||
|
// SERVICE_GPUTYPE=GeForce GTX 760 x2
|
||||||
|
// SERVICE_MAC=DE:AD:BE:EF:CA:FE
|
||||||
|
// SERVICE_UNIQUEID={A Wild UUID Appeared!}
|
||||||
|
// Every single record I've seen so far has been in this format
|
||||||
|
try {
|
||||||
|
int serviceState = Integer.parseInt(txtRecordStringList.get(0).toString().split("=")[1]);
|
||||||
|
int numberOfApps = Integer.parseInt(txtRecordStringList.get(1).toString().split("=")[1]);
|
||||||
|
String gpuType = txtRecordStringList.get(2).toString().split("=")[1];
|
||||||
|
String mac = txtRecordStringList.get(3).toString().split("=")[1];
|
||||||
|
UUID uniqueID = UUID.fromString(txtRecordStringList.get(4).toString().split("=")[1]);
|
||||||
|
|
||||||
|
// We need to resolve the hostname in this thread so that we can use it in the GUI
|
||||||
packet.getAddress().getCanonicalHostName();
|
packet.getAddress().getCanonicalHostName();
|
||||||
|
|
||||||
NvComputer computer = new NvComputer(responses[0].getName().toString(), packet.getAddress(), packet.getAddress().getCanonicalHostName(), state, numOfApps, gpuType, mac, uniqueID);
|
NvComputer computer = new NvComputer(responses[0].getName().toString(), packet.getAddress(), packet.getAddress().getCanonicalHostName(), serviceState, numberOfApps, gpuType, mac, uniqueID);
|
||||||
this.nvstream_mdns_responses.add(computer);
|
this.responses.add(computer);
|
||||||
Log.v("NvmDNS NvComputer", computer.toString());
|
} catch (ArrayIndexOutOfBoundsException e) {
|
||||||
|
Log.e("NvmDNS Response", "We recieved a malformed DNS repsonse.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Void doInBackground(Void... thisParameterIsUseless) {
|
protected Void doInBackground(Void... thisParameterIsUseless) {
|
||||||
Log.v("NvmDNS", "doInBackground init");
|
Log.v("NvmDNS ASync", "doInBackground entered");
|
||||||
|
|
||||||
|
this.sendQuery();
|
||||||
|
|
||||||
|
|
||||||
|
// We want to run our wait thread for an amount of time then close the socket.
|
||||||
new Thread(new Runnable() {
|
new Thread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
Log.v("NvmDNS 1000 mS Wait", "going to sleep");
|
Log.v("NvmDNS Wait", "Going to sleep for " + NvmDNS.WAIT_MS + "ms");
|
||||||
try {
|
try {
|
||||||
|
Thread.sleep(NvmDNS.WAIT_MS);
|
||||||
Thread.sleep(5000);
|
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
Log.e("NvmDNS Wait", "Woke up from sleep before time.");
|
||||||
|
Log.e("NvmDNS Wait", e.getMessage());
|
||||||
}
|
}
|
||||||
Log.v("NvmDNS 1000 mS Wait", "waking from sleep");
|
Log.v("NvmDNS Wait", "Woke up from sleep");
|
||||||
NvmDNS.this.nvstream_socket.close();
|
NvmDNS.this.socket.close();
|
||||||
NvmDNS.this.nvstream_socket = null;
|
Log.v("NvmDNS Wait", "Socket Closed");
|
||||||
Log.v("NvmDNS 1000 mS Wait", "socket closed");
|
|
||||||
}
|
}
|
||||||
}).start();
|
}).start();
|
||||||
|
|
||||||
|
|
||||||
this.sendQueryAndWait();
|
|
||||||
Log.v("NvmDNS", "doInBackground return");
|
this.waitForResponses();
|
||||||
|
|
||||||
|
Log.v("NvmDNS ASync", "doInBackground exit");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onProgressUpdate(Integer... progress) {
|
protected void onProgressUpdate(Integer... progress) {
|
||||||
Log.v("NvmDNS", "onProgressUpdate ");
|
Log.v("NvmDNS ASync", "onProgressUpdate");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(Void moreUselessParameters) {
|
protected void onPostExecute(Void moreUselessParameters) {
|
||||||
Log.v("NvmDNS", "onPostExecute");
|
Log.v("NvmDNS ASync", "onPostExecute");
|
||||||
for (NvComputer computer : this.nvstream_mdns_responses) {
|
for (NvComputer computer : this.responses) {
|
||||||
Log.i("NvmDNS NvComputer Printout", computer.toString());
|
Log.i("NvmDNS NvComputer", computer.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user