//
//  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("");
		}
	}

}