/********************************************************************************
* The copyright of the modification source code:
* Copyright 2004 of Hong Kong University of Science and Technology.
* All rights reserved.

* Redistributions of source code from HKUST must retain the above copyright notice,
* this list of conditions,the authors and the following disclaimer.

* THE HONG KONG UNIVERSITY OF SCIENCE AND TECHNOLOGY SPECIFICALLY DISCLAIMS ANY
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED
* HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF HONG KONG UNIVERSITY OF
* SCIENCE AND TECHNOLOGY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
* ENHANCEMENTS, OR MODIFICATIONS.

* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT,
* INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE
* OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

* Author: Hejun Wu, [whjnn@ust.hk].
********************************************************************************/
package net.tinyos.packet;

import java.net.*;
import java.io.*;
import net.tinyos.packet.*;
import net.tinyos.sim.*;
import net.tinyos.sim.event.*;

public class VMNetSource extends AbstractSource {
  private Socket eventSocket = null;
  private Socket cmdSocket = null;
  protected SimProtocol eventProtocol = null;
  protected SimProtocol cmdProtocol = null;
  protected InputStream VMNetEv_is, VMNetCm_is;
  protected OutputStream VMNetEv_os, VMNetCm_os;
  private DataInputStream dis;
  private DataOutputStream  dos; 
  static int MTU_SIZE_UART;
  String kind, host;

  public VMNetSource(String kind, String host) {
    super(kind + "@" + host);
    this.kind = kind;
    this.host = host;
    MTU_SIZE_UART=1024;
  }

  protected void openSource() throws IOException {
    message("Opening " + kind + " source");
    try {
      message("Connecting to VMNet at " + host + ":" +
	      SimProtocol.TOSSIM_EVENT_PORT);
      eventSocket = new Socket(host, SimProtocol.TOSSIM_EVENT_PORT);
      VMNetEv_is = eventSocket.getInputStream();
      VMNetEv_os = eventSocket.getOutputStream();
      dis =new DataInputStream(VMNetEv_is);
   //   eventProtocol = new SimProtocol(VMNetEv_is, VMNetEv_os);
      
      
      
      message("Connecting to VMNet port at" + host + ":" +
	      SimProtocol.TOSSIM_COMMAND_PORT);
      cmdSocket = new Socket(host, SimProtocol.TOSSIM_COMMAND_PORT);
      VMNetCm_is = cmdSocket.getInputStream();
      VMNetCm_os = cmdSocket.getOutputStream();
      //cmdProtocol = new SimProtocol(VMNetCm_is, VMNetCm_os);
      
      dos = new DataOutputStream(new BufferedOutputStream(VMNetCm_os));
      message("Connection opened to VMNet ");
    }
    catch (IOException e) {
      closeSockets();
      System.exit(-1);
      throw e;
    }
  }

  protected void closeSockets() throws IOException {
    if (eventSocket != null) {
      eventSocket.close();
    }
    if (cmdSocket != null) {
      cmdSocket.close();
    }
    eventSocket = null;
    cmdSocket = null;
  }

  public void closeSource() throws IOException {
    message("Closing " + kind + " source");
    closeSockets();
  }
public byte readSourceByte() throws IOException {
	return dis.readByte();
}
  public byte[] readSourcePacket() throws IOException {
      byte[] received ;
      try{
      for(;;){
      	short datalen = dis.readShort();
	//System.err.println(" heheheheh receiving the bytes he lenth ==  : " + datalen);	
	received =new byte [datalen];
      	dis.readFully(received);
	if(received!=null)
	{
	//VMNet temp debugging...+++++++++++++++++
	/*for(int i=0;i<datalen;i++)
	{
	String bs = Integer.toHexString(received[i] & 0xff).toUpperCase();
	System.err.print(bs);
	System.err.print("   ");
	}*/

	/*if(datalen>37)
	{
	if(received[36]==1)
	System.err.println("1");	
	}*/
	//++++++++++++++++++++++++++++++++++++++
	return received; 
	}
	else System.exit(-1);
	}
	}
      // Remove extraneous bytes
      catch (IOException e) {
      closeSockets();
      System.exit(-1);
      throw e;
    }
	     
  }

  public boolean writeSourcePacket(byte[] packet, int len) throws IOException {
   // cmdProtocol.writeCommand(writeVMNetPacket(packet)); 
    dos.write(packet, 0, len);
    dos.flush();
    return true;
  }

}

 
