XML Feeds

.

[java-dev] Re: Crashing after a while...

mji Michael.x.Ilardi.-ND at disney.com
Tue Aug 7 12:03:10 MDT 2007


Sure. The code is below:

import com.cycling74.max.*;
import java.net.*;



public class Test extends MaxObject {

	public String address = "127.0.0.1";
	public int port = 2209; //default port
	private DatagramSocket dsocket;
	private DatagramPacket packetToSend,packetHeartBeat;
//	byte[] packet;
	boolean heartbeat=false;
	
	boolean registered =false;
	InetAddress ip = null;
	
	MaxClock clockHeartBeatTransmitter; 
	MaxClock clockHeartBeatReceiver;
	ListenerThread lThread;
	boolean transmitted=false; //set to true when we output data
	
	private static final String[] INLET_ASSIST = new String[]
	{
		"Test"
	};
	
	private static final String[] OUTLET_ASSIST = new String[]
	 {
	   "Indicates whether we've received a heartbeat recently"
	 };
	
	//constants:
	private static final long MAGIC_WORD = 0x454c5349;
	private static final byte CMD_CAN_TELEGRAM = 1;
	private static final byte CMD_HEARTBEAT = 2;
	private static final byte CMD_CTRL = 3;
	private static final byte CMD_REGISTER =4;
	
	
	byte[] packetHeaderCanTelegram = new byte[52];
	byte[] packetHeaderHeartBeat = new byte[52];
	byte[] packetHeaderRegister = new byte[52];
	byte[] packetHeaderCtrl = new byte[52];
	
	byte[] packetBaud = new byte[52];;
	byte[] packetEnableRange = new byte[60];
	byte[] telegram = new byte[24];
	byte[] premadeTelegramPacket = new byte[1076]; //the header plus slots for 100 cal telegrams
	
	public Test (Atom[] args) 
	{
	
		declareInlets(new int[]{DataTypes.ALL});
		declareOutlets(NO_OUTLETS);
				
		setInletAssist(INLET_ASSIST);
		setOutletAssist(OUTLET_ASSIST);
		declareAttribute("address");
		declareAttribute("port");
		
		//create the telegram packet header
		//fill with the magic word
		packetHeaderCanTelegram[0] = (byte)((MAGIC_WORD & 0xFF000000L) >> 24);
		packetHeaderCanTelegram[1] = (byte)((MAGIC_WORD & 0x00FF0000L) >> 16);
		packetHeaderCanTelegram[2] = (byte)((MAGIC_WORD & 0x0000FF00L) >> 8);
		packetHeaderCanTelegram[3] = (byte)((MAGIC_WORD & 0x000000FFL));
		
		
		
		
		//duplicate to form the heart beat and registration headers
	    System.arraycopy(packetHeaderCanTelegram,0,packetHeaderHeartBeat,0,4);
	    System.arraycopy(packetHeaderCanTelegram,0,packetHeaderRegister,0,4);
	    System.arraycopy(packetHeaderCanTelegram,0,packetHeaderCtrl,0,4);
	    //differentiate the packets by inserting the commands
	    packetHeaderCanTelegram[11] = CMD_CAN_TELEGRAM;    
	    packetHeaderHeartBeat[11] = CMD_HEARTBEAT;
	    packetHeaderRegister[11]  = CMD_REGISTER;
	    packetHeaderCtrl[11]  = CMD_CTRL;
	    System.arraycopy(packetHeaderCtrl, 0,packetBaud, 0, 52);
	    byte[] bRate = new byte[4];
	    
	    bRate[3] = 2; //500 kbs
	    packetBaud = concatenate(packetBaud,bRate);
	    packetBaud[15] = 4; //payload is 4 bytes
	    packetBaud[19] = 3; //subcommand: set baud rate
	    
	    
	    
	    System.arraycopy(packetHeaderCanTelegram, 0,premadeTelegramPacket, 0, 52);

	    
	   

	}
	
	
	
	public void register()
	{
		post("Test: Registering...");
		
		if (clockHeartBeatTransmitter!=null){
			clockHeartBeatTransmitter.release();
		}
	
		if (clockHeartBeatReceiver !=null){
			clockHeartBeatReceiver.release();
		}
		
		//establish socket connection
		try {
			ip = InetAddress.getByName(address);
		} catch (UnknownHostException uhe) {
			post("Test: Unable to resolve " +address );
			return;
		}
		
		try{
			if (dsocket!=null)dsocket.close();
			dsocket = new DatagramSocket();
		}catch(Exception e){
			post("Test: "+ e);

		return;
	}
		
		lThread = new ListenerThread();
		lThread.start(); //start the listener
		
		

		
		try {
			//register the client
			packetToSend = new DatagramPacket( packetHeaderRegister, packetHeaderRegister.length, ip, port );
			dsocket.send(packetToSend);
			
			packetToSend = new DatagramPacket( packetBaud, packetBaud.length, ip, port );
			dsocket.send(packetToSend);
			
	//		packetToSend = new DatagramPacket( packetEnableRange, packetEnableRange.length, ip, port );
	//		dsocket.send(packetToSend);
			
			
			
		}catch(Exception e){
			post("Test: "+e);
		}
		
	
		post("Test: Connected to "+address + " on port " +port);
		
		 packetHeartBeat = new DatagramPacket( packetHeaderHeartBeat, packetHeaderHeartBeat.length, ip, port );
		   
		clockHeartBeatReceiver = new MaxClock(new Callback(this,"heartBeatReceiverChecker"));
	
		clockHeartBeatTransmitter = new MaxClock(new Callback(this, "heartBeatTransmitter"));
		clockHeartBeatTransmitter.delay(0.0); //set the clock to execute immediately
		clockHeartBeatReceiver.delay(7500.0);
	}

	
	public void stop(){
		if (clockHeartBeatReceiver!=null){
			clockHeartBeatReceiver.release();
		}
		if (clockHeartBeatTransmitter !=null){
			clockHeartBeatTransmitter.release();
		}
		clockHeartBeatReceiver = null;
		clockHeartBeatTransmitter = null;
		
		outlet(0,0);
		dsocket.close();
		lThread.stopListening();
			
	}

	@SuppressWarnings("unused")
	private void heartBeatTransmitter()
	{
		
		clockHeartBeatTransmitter.delay(500.0);//set the clock to execute again in 500 ms
		if (!transmitted){
			//post("sending heart");
			
			try {
			dsocket.send(packetHeartBeat);
			}catch(Exception e){
				post("Test: "+e);
			}
		}
		
		transmitted=false;
	}
	
	@SuppressWarnings("unused")
	private void heartBeatReceiverChecker(){
		heartbeat=false;
		outlet(0,0);
		post("Test: Failed to receive heartbeat. Attempting to re-register...");
		stop();
		register();
	}
	
	
	
	
	public void baud(){
		try {
			
			packetToSend = new DatagramPacket( packetBaud, packetBaud.length, ip, port );
			dsocket.send(packetToSend);
		}catch(Exception e){
			post("Test: "+e);
		}
		
	}
	
	
	
	public void range(){
		try {
			
		packetToSend = new DatagramPacket( packetEnableRange, packetEnableRange.length, ip, port );
		dsocket.send(packetToSend);
		}catch(Exception e){
			post("Test: "+e);
		}
	}
	
	public synchronized void  list(Atom[] args)
	{

	if (!heartbeat){
		return;
	}
	int len=args.length;
	if ( args.length %2 !=0)len--;
	int nTeles = args.length/2;
	int payload = nTeles * 24;
	int offset = 52;
	for(int i = 0; i <len; i+=2)
	{
		prepareCAN( args[i].getInt(), args[i+1].getInt(),premadeTelegramPacket,offset);
		offset+=24;
		
	}
	
	//set the length of the payload
	premadeTelegramPacket[12] = (byte)((payload & 0xFF000000L) >> 24);
	premadeTelegramPacket[13] = (byte)((payload & 0x00FF0000L) >> 16);
	premadeTelegramPacket[14] = (byte)((payload & 0x0000FF00L) >> 8);
	premadeTelegramPacket[15] = (byte)((payload & 0x000000FFL));
	
	//post("it's "+tele.length);
	try {
	
		packetToSend = new DatagramPacket( premadeTelegramPacket, 52+payload, ip, port );
		//post("bytes: "+(52+payload));
		dsocket.send(packetToSend);
		
		}catch(Exception e){
			post("Test: "+e);
		}
	
	}
		
		
			  
	
	
	public byte[] concatenate(byte[] a, byte[] b){
		byte[] ab = new byte[( a.length + b.length)];
		System.arraycopy(a, 0, ab, 0,a.length);
		System.arraycopy(b, 0, ab, a.length,b.length);
		return ab;
	}
	
	
	//extracts a 32-bit, unsigned integer from a byte buffer
	public long extract32BitIntUnsignedInt(byte[] buf, int offset){
		
		long anUnsignedInt = 0;
		int firstByte = 0;
        int secondByte = 0;
        int thirdByte = 0;
        int fourthByte = 0;
		firstByte = (0x000000FF & ((int)buf[offset]));
        secondByte = (0x000000FF & ((int)buf[offset+1]));
        thirdByte = (0x000000FF & ((int)buf[offset+2]));
        fourthByte = (0x000000FF & ((int)buf[offset+3]));
       
		anUnsignedInt  = ((long) (firstByte << 24
	                | secondByte << 16
                        | thirdByte << 8
                        | fourthByte))
                       & 0xFFFFFFFFL;
		return anUnsignedInt;
	}
	
	
	public void prepareCAN(int id, int data,byte[] tele,int offset){
		
		
		
		int ulId =0x600 + id;

		//node ID
		tele[0+offset] = (byte)((ulId & 0xFF000000L) >> 24);
		tele[1+offset] = (byte)((ulId & 0x00FF0000L) >> 16);
		tele[2+offset] = (byte)((ulId & 0x0000FF00L) >> 8);
		tele[3+offset] = (byte)((ulId & 0x000000FFL));
		
		//data length
		tele[4+offset] = (byte)8;
		
		//position (fixed part)
		tele[8+offset] = 0x23;
		tele[9+offset] = 0x00;
		tele[10+offset] = 0x2F;
		tele[11+offset] = 0x01;
		
		// position
		tele[15+offset] = (byte)((data & 0xFF000000L) >> 24);
		tele[14+offset] = (byte)((data & 0x00FF0000L) >> 16);
		tele[13+offset] = (byte)((data & 0x0000FF00L) >> 8);
		tele[12+offset] = (byte)((data & 0x000000FFL));
		
		
	}
	
	 // class containing the thread that listens for messages from the Test server
    class ListenerThread extends Thread {
    	private boolean listen;
      //  DatagramSocket lSocket;
        // This method is called when the thread runs
        public void run() {
        	try {

        		  listen=true;
        	      // Create a socket to listen on the port.
        		 

        	      // Create a buffer to read datagrams into. If a
        	      // packet is larger than this buffer, the
        	      // excess will simply be discarded!
        	      byte[] buffer = new byte[100];

        	      // Create a packet to receive data into the buffer
        	      DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

        	      // Now loop forever, waiting to receive packets and printing them.
        	      while (listen) {
        	    	
        	        // Wait to receive a datagram
        	    	  dsocket.receive(packet); 	
        	    	  long m = extract32BitIntUnsignedInt(buffer,0);
        	    	  if (m == MAGIC_WORD){ //this is an Test packet
        	    		if (buffer[11] == CMD_HEARTBEAT){
        	    			if (heartbeat==false){
        	    				outlet(0,1);
        	    			}
        	    			heartbeat=true;
        	    			clockHeartBeatReceiver.unset();
        	    			clockHeartBeatReceiver.delay(7500.0);
        	    		}
        	    		  
        	    	  }
        	      }
        	    } catch (Exception e) {
        	     // System.err.println(e);
        	    }
        	    
        	    
        }
        
        public void stopListening(){
        	heartbeat=false;
        	//lSocket.close();
        	listen=false;
        }
    }
	
	
				
		//called when the max object is destroyed
		protected void notifyDeleted()
		{
			stop(); //shut everything down
		}
}































More information about the java-dev mailing list