โค้ด: เลือกทั้งหมด
package com.andrewchatham;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import android.net.DhcpInfo;
import android.net.wifi.WifiManager;
import android.util.Log;
//import android.util.Log;
/*
* This class tries to send a broadcast UDP packet over your wifi network to discover the boxee service.
*/
public class Discoverer extends Thread {
private static final String TAG = "Discovery";
private static final String REMOTE_KEY = "b0xeeRem0tE!";
private static final int DISCOVERY_PORT = 2562;
private static final int TIMEOUT_MS = 500;
// TODO: Vary the challenge, or it's not much of a challenge :)
private static final String mChallenge = "myvoice";
private WifiManager mWifi;
interface DiscoveryReceiver {
void addAnnouncedServers(InetAddress[] host, int port[]);
}
Discoverer(WifiManager wifi) {
mWifi = wifi;
}
public void run() {
try {
DatagramSocket socket = new DatagramSocket(DISCOVERY_PORT);
socket.setBroadcast(true);
socket.setSoTimeout(TIMEOUT_MS);
sendDiscoveryRequest(socket);
listenForResponses(socket);
} catch (IOException e) {
Log.e(TAG, "Could not send discovery request", e);
}
}
/**
* Send a broadcast UDP packet containing a request for boxee services to
* announce themselves.
*
* @throws IOException
*/
private void sendDiscoveryRequest(DatagramSocket socket) throws IOException {
String data = String
.format(
"<bdp1 cmd=\"discover\" application=\"iphone_remote\" challenge=\"%s\" signature=\"%s\"/>",
mChallenge, getSignature(mChallenge));
Log.d(TAG, "Sending data " + data);
DatagramPacket packet = new DatagramPacket(data.getBytes(), data.length(),
getBroadcastAddress(), DISCOVERY_PORT);
socket.send(packet);
}
/**
* Calculate the broadcast IP we need to send the packet along. If we send it
* to 255.255.255.255, it never gets sent. I guess this has something to do
* with the mobile network not wanting to do broadcast.
*/
private InetAddress getBroadcastAddress() throws IOException {
DhcpInfo dhcp = mWifi.getDhcpInfo();
if (dhcp == null) {
Log.d(TAG, "Could not get dhcp info");
return null;
}
int broadcast = (dhcp.ipAddress & dhcp.netmask) | ~dhcp.netmask;
byte[] quads = new byte[4];
for (int k = 0; k < 4; k++)
quads[k] = (byte) ((broadcast >> k * 8) & 0xFF);
return InetAddress.getByAddress(quads);
}
/**
* Listen on socket for responses, timing out after TIMEOUT_MS
*
* @param socket
* socket on which the announcement request was sent
* @throws IOException
*/
private void listenForResponses(DatagramSocket socket) throws IOException {
byte[] buf = new byte[1024];
try {
while (true) {
DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
String s = new String(packet.getData(), 0, packet.getLength());
Log.d(TAG, "Received response " + s);
}
} catch (SocketTimeoutException e) {
Log.d(TAG, "Receive timed out");
}
}
/**
* Calculate the signature we need to send with the request. It is a string
* containing the hex md5sum of the challenge and REMOTE_KEY.
*
* @return signature string
*/
private String getSignature(String challenge) {
MessageDigest digest;
byte[] md5sum = null;
try {
digest = java.security.MessageDigest.getInstance("MD5");
digest.update(challenge.getBytes());
digest.update(REMOTE_KEY.getBytes());
md5sum = digest.digest();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
StringBuffer hexString = new StringBuffer();
for (int k = 0; k < md5sum.length; ++k) {
String s = Integer.toHexString((int) md5sum[k] & 0xFF);
if (s.length() == 1)
hexString.append('0');
hexString.append(s);
}
return hexString.toString();
}
public static void main(String[] args) {
new Discoverer(null).start();
while (true) {
}
}
}