 1Content-type: application/x-Unknown; charset=UTF8
package nmc.sidekick;

// 200205011630

import java.io.*;
import javax.microedition.io.Connection;
import javax.microedition.io.Connector;
import javax.microedition.io.Datagram;
import javax.microedition.io.DatagramConnection;
import com.ajile.drivers.spi.*;
import javax.comm.SerialPort;
import javax.comm.CommPortIdentifier;

//import java.io.DataOutputStream;
//import java.io.ByteArrayOutputStream;
//import java.io.ByteArrayInputStream;
//import java.io.DataInputStream;

import nmc.common.*;
import com.ajile.jem.Configuration;

public class CommandParser  {
    
    private static Rtc rtc = Rtc.getInstance();
    
    SystemHardwiredInfo settings = SystemHardwiredInfo.Current;

    public IoResource[] channel;

    /**
     * Starts the application.
     * @param args an array of command-line arguments
     */
//      public static void main(java.lang.String[] args) {
//      	CommandParser cp = new CommandParser();
//      	cp.loadAndGo(); // this is still the main thread;
//      	          // we just transition to working on an instance
//      	          // I am not sure whether the main thread should be
//      	          // treated specially or not...  at this point,
//      	          // I am not treating it specially, and from here
//      	          // it will go on to wait for a command, look it 
//      	          // up, and do it.
//      }


    // This does not inherit from Runnable, so it is not a "real" run...
    public void loadAndGo() {
	
//  	channel = new IoResource[60]; // initial values are nulls

//  	initializePlatform();

	OutboundMessageQ outbound = null;
	InboundMessageQ inbound = null;

		// Set up the outbound and inbound queues
	try {
            DebugMessage.println("loadAndGo() Creating outbound message queue...");
            DebugMessage.println("   sidearmIpAddr=" 
                               + settings.sidearmIpAddr
                               + "; sidearmRcvPort=" 
                               + settings.sidearmRcvPort);
	    outbound = new OutboundMessageQ(settings.sidearmIpAddr,
                                            settings.sidearmRcvPort );
	    //outbound.startOutboundMessaging();



            DebugMessage.println("loadAndGo() Creating inbound message queue...");
            DebugMessage.println("   sidekickRcvPort=" 
                               + settings.sidekickRcvPort);
	    inbound = new InboundMessageQ(settings.sidekickRcvPort);
	    //inbound.startInboundMessaging();

	} catch (Exception e) {
	    DebugMessage.println("loadAndGo() Caught exception while opening connection: "+ e);
	    return;
	}
	
	
	DebugMessage.println("loadAndGo() Initializing drivers");
	Instantiator.InitializeDrivers(outbound);
	bp("after driver init");
	DebugMessage.println("loadAndGo() Starting Outbound Message Queue");	
	outbound.startOutboundMessaging();
	bp("after IBQ start");
	DebugMessage.println("loadAndGo() Starting Inbound Message Queue");	
	inbound.startInboundMessaging();
	bp("after OBQ start");
	
/*
	try{
	DebugMessage.println("loadAndGo() Waiting 5 sec for message queues to spin up...");
	  Thread.sleep(5000);
	}catch(InterruptedException e){DebugMessage.println("Should never see this InterruptedException");}    
*/	
	DebugMessage.println("loadAndGo() Priming communications pump...");
	initializeComms(outbound,inbound);
	


/*This is test code for flash boot debugging
DebugMessage.println("Be sure to remove this from CommandParser!!!");
PollCmd x=new PollCmd(7);
Instantiator.instrumentDrivers[7].enqueueMessage(x);
*/
        int j = 0;
        while(true) {
	Message m = inbound.blockingGet();
            DebugMessage.println("loadAndGo() Just returned from blocking get");
	    int msgType = m.getMessageType();
	    switch (msgType) {
	    case Message.POLL_CMD: {
		DebugMessage.println("detected POLL_CMD");
		PollCmd p = (PollCmd)m;
		try{
               	   Instantiator.instrumentDrivers[p.channelNumber].enqueueMessage(m);               	   	
          		}catch(Exception e){
		  DebugMessage.println("commandParser() pollCmd exception "+e);
		}		
	     }
		break;

	    case Message.INITIALIZE_INSTRUMENT_CMD: {
		DebugMessage.println("detected INITIALIZE_INSTRUMENT_CMD");
                	// This is a placeholder in case the SideArm really
               	// wants to control the initialization.
               	InitializeInstrumentCmd i = (InitializeInstrumentCmd)m;
                	try{
               	   Instantiator.instrumentDrivers[i.channelNumber].enqueueMessage(m);               	   	
		}catch(Exception e){
		  DebugMessage.println(e);
		}		

                }
	    	break;

            case Message.CONFIGURATION_CMD:
                	DebugMessage.println("detected CONFIGURATION_CMD");
                	ConfigurationCmd c = (ConfigurationCmd)m;
	 	try{
               	   Instantiator.instrumentDrivers[c.channelNumber].enqueueMessage(m);               	   	
		}catch(Exception e){
		  DebugMessage.println(e);
	}		
 	             break;

            case Message.WAKEUP_CMD: 
                {
                    DebugMessage.println("detected WAKEUP_CMD");
                
                    WakeupCmd wc = (WakeupCmd)m;
                    AckReply reply = new AckReply(wc);
                    outbound.put(reply);
                }
                break;
            case Message.GET_ABSOLUTE_TIME_CMD:
                {
                    DebugMessage.println("detected GET_ABSOLUTE_TIME_CMD");
                    GetAbsoluteTimeCmd g = (GetAbsoluteTimeCmd)m;
                    long tA = 0;
                    long tR=0;
                    synchronized(rtc){
                       tR = rtc.currentTimeMillis();
                    }
                  tA = System.currentTimeMillis();
                  DebugMessage.println("CmdParser(GET_ABSOLUTE_TIME): Ajile System time currently: "+Rtc.toString(tA)+" ("+tA+")");
                  DebugMessage.println("CmdParser(GET_ABSOLUTE_TIME): RTC time currently            : "+Rtc.toString(tR)+" ("+tR+")");
                  
                  AbsoluteTimeReply r = new AbsoluteTimeReply(m, tA);
                    outbound.put(r);
                }
                break;
            case Message.SET_ABSOLUTE_TIME_CMD:
                {
                    DebugMessage.println("detected SET_ABSOLUTE_TIME_CMD");
                    SetAbsoluteTimeCmd s = (SetAbsoluteTimeCmd)m;
                    long t = s.msTime;
	        long nowR=0;
	        long nowA=0;
                      DebugMessage.println("CmdParser(SET_ABSOLUTE_TIME): Ajile System time currently: "+Rtc.toString((long)System.currentTimeMillis()));
                    synchronized(rtc){
                      DebugMessage.println("CmdParser(SET_ABSOLUTE_TIME): RTC time currently: "+Rtc.toString((long)rtc.currentTimeMillis()));
                      DebugMessage.println("CmdParser(SET_ABSOLUTE_TIME): Setting RTC clock");
	           rtc.setTime(t);
                      nowR = rtc.currentTimeMillis();// second resolution
                     }
                       Configuration.setBaseTime(t);
                      nowA=System.currentTimeMillis();
                       DebugMessage.println("CmdParser(SET_ABSOLUTE_TIME): Setting Ajile System clock to "+t);
                      DebugMessage.println("CmdParser(SET_ABSOLUTE_TIME): Ajile System time currently: "+Rtc.toString((long)nowA)+" ("+nowA+")");
                      DebugMessage.println("CmdParser(SET_ABSOLUTE_TIME): RTC time currently: "+Rtc.toString((long)nowR)+" ("+nowR+")");

                    SetTimeReply r = new SetTimeReply(m, t);
                    outbound.put(r);
                }
                break;
	    default:
		DebugMessage.println("unknown message received");
 
	    }// end switch
	    DebugMessage.println("Around the loop " + j + " time(s).");
	}// end while
	    
    }//end loadngo()

    // We only use this function to initialize SK/SA communications from
    // the sidekick side because of an ARP related bug (possibly in the
    // AJile tcp/ip stack. If SA sends the first message (and ARP requests)
    // SK ignores ARP requests and nothing happens. If SK sends first message
    // everything works fine. 
    private void initializeComms(OutboundMessageQ outbound, InboundMessageQ inbound){

    	// Send an ALIVE_NOTICE to sidearm until an ACK_REPLY 
    	// is received. We need to delay for 6 seconds or so after sending
    	// the first message, since it takes 4-5.5 seconds or so for the ARP 
    	// messages to be exchanged. After that, we can send them more quickly.
    	// NOTE: We Will Be Here Forever If No Reply Is Received
    	
	//InitCommsCmd c = new InitCommsCmd();
	//DebugMessage.println("sending " + c);
	//outbound.put(c);

	
	AliveNotice a  = new AliveNotice();
	DebugMessage.println("sending " + a);
	outbound.put(a);
	Message m = null;
	{
		m = inbound.blockingGet(6000);
		if(m==null){
		 	boolean done=false;
		 	while(done==false){
		 		DebugMessage.println("Timed Out");
		 		a=null;
				a=new AliveNotice();
				DebugMessage.println("sending " + a);
				outbound.put(a);
				m = inbound.blockingGet(2000);
				if(m != null)
					done=true;				
		 	}	
		}
	}
	
	DebugMessage.println("received " + m);
	
    }// end initializeComms()
    public static void bp(String s){DebugMessage.println("commandParser.bp()"+s);}
}
