//
// UdpListenerThread.java
// CoboxQuery
//
// Created by Tom Igoe on Wed Jun 23 2004.
//
import java.util.*;
import java.io.*;
import java.text.*;
import java.net.*;
import java.lang.*;
public class UdpListenerThread extends Thread implements Runnable{
boolean stillRunning; // whether we're running
DatagramSocket mySocket; // socket to listen on
int bytesToReceive; // number of incoming bytes per datagram
InetAddress address; // address of the sender
String message = new String("");
UdpListenerThread(DatagramSocket whichSocket) {
//get the socket to send and receive on:
mySocket = whichSocket;
bytesToReceive = 30; // number of incoming bytes per datagram
stillRunning = true;
}
public void kill() {
stillRunning = false;
}
public void run() {
while (stillRunning) {
// prompt for input:
System.out.println("Type <s> and <return> to send a query.\n\n");
// listen for new connections:
try {
DatagramPacket packet = new DatagramPacket(new byte[bytesToReceive], bytesToReceive);
// wait for a packet:
mySocket.receive(packet);
// process the packet:
Integer packetLength = new Integer(packet.getLength());
System.out.println("Packet received. Length: " + packetLength.toString());
// get the address of the siteplayer who sent to us:
address = packet.getAddress();
System.out.println("From: " + address.toString());
// convert the packet payload to a string:
message = new String( packet.getData( ) );
// if it's at least as long as what we expect, parse it:
if (packetLength.intValue() >= bytesToReceive) {
parseMessage(message);
}
// sleep 100 milliseconds when we're not doing anything:
try { Thread.sleep(100); } catch (InterruptedException interrupted) {}
} catch(IOException e) {
// if we can't receive from the datagram; quit this thread:
System.out.println("UDPListener has a problem: " + e);
stillRunning = false;
}
}
}
/*
The Query message is <00> <00> <00> <F6>
The answer will be formatted as:
<00> <00> <00> <F7> <16 bytes of firmware info> < 4 bytes not used> <6 bytes MAC address>
Once you've got a response from the device, can query it for other data,
as detailed in the Cobox EIK guide, under "UDP Datagrams".
Write your own methods for that.
*/
public void parseMessage(String payload) {
int i;
byte[] byteArray = new byte[payload.length()];
int[] intArray = new int[payload.length()];
// convert the String to a byte array:
byteArray = payload.getBytes();
// convert the byte array to an integer array,
// so we can have values of greater than 127
for (i=0; i < byteArray.length; i++) {
intArray[i] = (int)byteArray[i];
if (intArray[i] < 0) {
intArray[i] += 256;
}
}
// parse the payload for the appropriate data:
System.out.print("Opcode: ");
System.out.println(Integer.toHexString(intArray[3]));
// if the fourth byte is <F7>, we got a status reply:
if (intArray[3] == 0xF7) {
// firmware data is bytes 4 to 20:
System.out.print("Firmware data: ");
for (i=4; i < 20; i++) {
System.out.print(" " + Integer.toHexString(intArray[i]));
}
// MAC address is bytes 24 to 30 (the end):
System.out.print("\nMAC Addr: ");
for (i=24; i < intArray.length; i++) {
System.out.print(" " + Integer.toHexString(intArray[i]));
}
System.out.println("");
}
}
}