/*
 * Partial implementation of Session Description Protocol. Contains 
 * session description message contents and the handling of them.

 * The SDP object encapsulates a SDP message contents and provides
 * methods to construct, parse, send, and receive messages over the 
 * TCP/IP connection.  It is used by both the user agent client 
 * (CallerDialog) and the user agent server (UAServer). The client
 * constructs an SDP object by incorporating user input such as
 * media, caller host address, and connection address. 
 * The server constructs a SIP object by reading the SDP messages
 * directly from the socket input stream. 
 *
 *
 * Author: Janet H. Park
 * Date: August, 1998
 *
 */

import java.util.Random;
import java.math.*;
import java.net.*;
import java.io.*;
import java.awt.*;
import java.util.*;

public class SDP {

	
	final static String VER = "0";
	final static String TTL = "16";
	String ver;		// version number, 0
	String owner;		// originator, caller info
	String name = "";	// session name
	String info = "";	// session information
	String conn;		// connection address. The callee's UAS will 
	                        // connect its media agents to this address 
	String[] media;		// list of media information. port number,
	                        // tranport, and formats are determined by
	                        // the program based on the media type.


	public SDP (String orig, String oaddr, String sname, String sinfo, 
	            String saddr, Media[] ma)
	{
		// called by CallerDialog to construct a sdp message set -
		// for conference call.

		ver = "v=" + VER;
		owner = "o=" + orig + " IN IP4 " + oaddr;
		if (sname != "") 
			name = "s=" + sname;
		if (sinfo != "") 
			info = "i=" + sinfo;
		if (saddr != "") 
			conn = "c=IN IP4 " + saddr + "/" + TTL;

		if (ma == null) 
			System.out.println("\nNo Media Agent defined\n");
		else {
			media = new String[ma.length];
			for (int i = 0; i < ma.length;  i++) 
				media[i] = "m=" + ma[i].type() + " " + ma[i].port() + " " + 
		             	            ma[i].transport() + " " + ma[i].format();
		}
	}



	public SDP (String orig, String oaddr,  Media[] ma)
	{
		// called by CallerDialog to construct a sdp message set 
		// for unicast two-party call. the sessoin address is
		// always the same as the originator's address

		ver = "v=" + VER;
		owner = "o=" + orig + " IN IP4 " + oaddr;
		conn = "c=IN IP4 " + oaddr;

		if (ma == null) 
			System.out.println("\nNo Media Agent defined\n");
		else {
			media = new String[ma.length];
			for (int i = 0; i < ma.length;  i++) 
				media[i] = "m=" + ma[i].type() + " " + ma[i].port() + " " + 
		             	            ma[i].transport() + " " + ma[i].format();
		}
	}



	String getConnAddr() { 
		StringTokenizer st = new StringTokenizer(conn);
		String tok = st.nextToken();
		tok = st.nextToken();
		return(st.nextToken("/"));
	}


	int length() {
		int len = 0;

		len = len + ver.length();
		len = len + owner.length();
		len = len + name.length();
		len = len + info.length();
		len = len + conn.length();
		if (media != null) {
			for (int i = 0; i < media.length; i++)
				len = len + media[i].length();
		}
		return len;
	} 


	void send(PrintWriter out, CallerDialog win) {

		// write SDP messages to the given outputstream handler

		out.println(ver);
		win.log("SEND> " + ver);

		out.println(owner);
		win.log("SEND> " + owner);

		if (!name.equals("")) {
			out.println(name);
			win.log("SEND> " + name);
		}
		if (!info.equals("")) {
			out.println(info);
			win.log("SEND> " + info);
		}
		out.println(conn);
		win.log("SEND> " + conn);
		for (int i = 0; i < media.length;  i++) {
			out.println(media[i]);
			win.log("SEND> " + media[i]);
		}
		out.println("");
		win.log("SEND>");

	} // end of send()
	


	void read(BufferedReader in, CallerDialog win) {

	// reads SDP messages from the inputstream handle
	  try {
		String line;
		Vector mediaList = new Vector();
		while ((line = in.readLine()) != null) {
			win.log("RECV> " + line);
			if (line.length() == 0)
				break;

			StringTokenizer st = new StringTokenizer(line);
			String tok = st.nextToken();

			if (tok.equals("v=")) 
				ver = line;
			else if (tok.equals("o=")) 
				owner = line;
			else if (tok.equals("s=")) 
				name = line;
			else if (tok.equals("i=")) 
				info = line;
			else if (tok.equals("c=")) 
				conn = line;
			else if (tok.equals("m="))
				mediaList.addElement(line);
		}
		media = new String[mediaList.size()];
		mediaList.copyInto(media);

	  } catch(IOException e) {
		win.log("IOException occured" );
		System.out.println("SIP.readRequest():"+e);
	  }
	} // end of read()
	
}
