
/* 
 * h245.h: this file should be always included when using the H.245
 * subsystem. It defines all needed structures, functions and
 * identifiers.
 *
 * Author: M.Rój (mroj@elka.pw.edu.pl)
 * Date: 2001.03, Last modified: 2001.07.19
 *
 * $Id: h245.h,v 1.4 2001/04/23 19:40:23 mroj Exp $ 
 */

#ifndef H245_H
#define H245_H


/* 
 * The following structure defines an H.245 system. h245_p is a
 * so-called H.245 system handler, used to manage a system.
 */  
struct system_h245;
typedef struct system_h245 *h245_p;

/* 
 * The following structure defines an H.245 primitive. prim_h245_p
 * is a so-called primitive handler that will be passed to and received
 * from a H.245 system.
 */
struct primitive_h245;
typedef struct primitive_h245 *prim_h245_p;
typedef struct primitive_h245 h245_prim;


/*
 * It is a primitive's parameter - every primitive can handle many
 * parameters.
 */

struct primitive_param;
typedef struct primitive_param *prim_param;


/* 
 * The following enum type defines all primitives that can be passed
 * to or received from a H.245 system.
 */
enum primitive_name 
{ 

  MSDSE_DETERM_REQ, MSDSE_DETERM_IND, MSDSE_DETERM_CONF, MSDSE_REJECT_IND, 
  MSDSE_ERROR_IND /* "error indication" */, /*DONE*/

  RTDSE_TRANS_REQ, RTDSE_TRANS_CONF, RTDSE_EXPIR_IND, /*DONE*/

  CESE_TRANS_REQ, CESE_TRANS_IND, CESE_TRANS_RESP, CESE_TRANS_CONF,
  CESE_REJECT_REQ, CESE_REJECT_IND, /*DONE*/

  LCSE_EST_REQ, LCSE_EST_IND, LCSE_EST_RESP, LCSE_EST_CONF, LCSE_REL_REQ,
  LCSE_REL_IND, LCSE_REL_CONF, LCSE_ERROR_IND /* "error indication" */, /*DONE*/

  CLCSE_CLOSE_REQ, CLCSE_CLOSE_IND, CLCSE_CLOSE_RESP, CLCSE_CLOSE_CONF, 
  CLCSE_REJECT_REQ, CLCSE_REJECT_IND, /*TODO*/

  MRSE_TRANS_REQ, MRSE_TRANS_IND, MRSE_TRANS_RESP, MRSE_TRANS_CONF,
  MRSE_REJECT_REQ, MRSE_REJECT_IND, /*TODO*/

  SEND_TERMINAL_CAP, /*TODO*/
  FLOW_CONTROL, /*TODO*/

/* MiscellaneousCommand */
  MULT_MODE_COMMAND/*!*/, 
  CANC_MULT_MODE_COMMAND, 
  VIDEO_FREEZE, 
  VIDEO_FAST_UPD_PICT, 
  VIDEO_FAST_UPD_GOB, 
  VIDEO_FAST_UPD_MB,
 
  COMM_MODE_COMMAND/*CommunicationModeCommand!*/, 

/* MiscellaneousIndication */ 
  MULT_CONF/*!*/,   
  CANCEL_MULT_CONF, 

/* ConferenceIndication */
  TERM_NUM_ASSIGN, /*TODO*/

  MC_LOCAL_IND, /*TODO*/

  USER_INPUT, /*TODO*/
  
  END_SESSION, /* DONE */

  H245_MESSAGE, /* THIS PRIMITIVE MUST BE THE LAST ONE! If you want to add
	some new ones write it down BEFORE the H245_MESSAGE primitive */

};



/* 
 * The following type is used to determine the type of any primitive
 * parameter (cast into the void * type) or/and the meaning of the
 * parameter. Above all parameters there are primitives' names 
 * they relate to. 
 */
enum param_name {

/* MSDSE_DETERM_IND, MSDSE_DETERM_CONF */ 
	MSD_DECISION = 0, /* enum msdse_decision* */

/* MSDSE_REJECT_IND */ 
	MSD_IDENTICAL_NUMBERS, /* NULL, NULL */

/*  MSDSE_ERROR_IND */
	MSD_ERROR,  /* enum msdse_error_code* */


/* CESE_TRANS_REQ, CESE_TRANS_IND */
	CE_CAP_TABLE, /* SET SIZE(0..255) OF CapabilityTableEntry,
				struct captable*  */
	CE_CAP_DESCR, /* SET SIZE(0..255) OF CapabilityDescriptors,
				struct descriptors* */


/* CESE_REJECT_IND */
	CE_CAP_REJECT_SOURCE, /* enum cese_source* */

/* CESE_REJECT_REQ, CESE_REJECT_IND */
	CE_CAP_REJECT_CAUSE_UNSPECIFIED, /* NULL, NULL */
	CE_CAP_REJECT_CAUSE_UNDEF_TABLE_ENTRY, /* NULL, NULL */
	CE_CAP_REJECT_CAUSE_DESCR_EXC, /* NULL, NULL */
	CE_CAP_REJECT_CAUSE_TABLE_EXC_HIGHEST, /* INTEGER(1..65535), u_int16* */
	CE_CAP_REJECT_CAUSE_TABLE_EXC_NONE, /* NULL, NULL */


/* LCSE_EST_REQ, LCSE_EST_IND: */
	LC_CHANNEL_NUM, /* INTEGER(1..65535), u_int16* */
	LC_AUDIO, /* enum audio_codec* */
	LC_SESSION_ID, /* INTEGER(0..255), u_int8* */ /* THIS IS NOT OPTIONAL !!! */
	LC_ASSOC_SESSION_ID, /* INTEGER(1..255), u_int8*, opt */
	LC_MEDIA_CH_IPADDR, /* OCTET STRING (SIZE(4)), u_int32 */
	LC_MEDIA_CH_PORT, /* INTEGER(0..65535), u_int16 */
	LC_MEDIA_CONTROL_CH_IPADDR, /* OCTET STRING (SIZE(4)), u_int32 */
	LC_MEDIA_CONTROL_CH_PORT, /* INTEGER(0..65535), u_int16 */

/* LCSE_EST_RESP, LCSE_EST_CONF: */
	LC_ACK_CHANNEL_NUM, /* INTEGER(1..65535), u_int16* */
	LC_ACK_SESSION_ID, /* INTEGER(0..255), u_int8*, opt */
	LC_ACK_MEDIA_CH_IPADDR, /* OCTET STRING (SIZE(4)), u_int32 */
	LC_ACK_MEDIA_CH_PORT, /* INTEGER(0..65535), u_int16 */
	LC_ACK_MEDIA_CONTROL_CH_IPADDR, /* OCTET STRING (SIZE(4)), u_int32 */
	LC_ACK_MEDIA_CONTROL_CH_PORT, /* INTEGER(0..65535), u_int16 */

/* LCSE_REL_REQ (outgoing), LCSE_REL_IND (incoming) */
	LC_CLOSE_CHANNEL_NUM, /* INTEGER(1..65535), u_int16* */

/* LCSE_REL_REQ (incoming), LCSE_REL_IND (outgoing) */
	LC_REJECT_CHANNEL_NUM, /* INTEGER(1..65535), u_int16* */

/* LCSE_REL_IND (incoming): */
	LC_CLOSE_SOURCE_USER, /* NULL, NULL */
	LC_CLOSE_SOURCE_LCSE, /* NULL, NULL */

/* LCSE_REL_IND (outgoing): */
	LC_REJECT_SOURCE_USER, /* NULL, NULL */
	LC_REJECT_SOURCE_LCSE, /* NULL, NULL */

/* LCSE_REL_REQ (incoming), LCSE_REL_IND (outgoing) */
	LC_REJECT_CAUSE, /* enum lcse_reject_cause* */

/* LCSE_ERROR_IND: */
	LC_ERROR, /* enum lcse_error_code* */
	
/* CLCSE_CLOSE_REQ, CLCSE_CLOSE_IND, CLCSE_CLOSE_RESP, CLCSE_CLOSE_CONF */
	CLC_CLOSE_CHANNEL_NUM, /* INTEGER(1..65535), u_int16* */

/* MRSE_TRANS_REQ, MRSE_TRANS_IND: */
	MR_SEQ_NUM, /* INTEGER(0..255), u_int8* */
	MR_REQ_MODES, /* enum audio_codec** */

	MR_ACK_SEQ_NUM, /* INTEGER(0..255), u_int8* */
	MR_ACK_MOST_PREF_MODE, /* NULL, NULL */
	MR_ACK_LESS_PREF_MODE, /* NULL, NULL */
	
	MR_REJECT_SEQ_NUM, /* INTEGER(0..255), u_int8* */
	MR_REJECT_MODE_UNAVAILABLE, /* NULL, NULL */
	MR_REJECT_MULT_CONSTRAINT,  /* NULL, NULL */
	MR_REJECT_REQUEST_DENIED,  /* NULL, NULL */

/* RTDSE_TRANS_CONF */
	RTD_DELAY, /* int* */

/* For all MiscellaneousCommand-derived primitives, e.g.:
  MULT_MODE_COMMAND, CANC_MULT_MODE_COMMAND, VIDEO_FREEZE, 
  VIDEO_FAST_UPD_PICT, VIDEO_FAST_UPD_GOB (seq!), 
  VIDEO_FAST_UPD_MB (seq!) */
	MISC_COM_CHANNEL_NUM,

/* For all MiscellaneousIndication-derived primitives, e.g.:
  MULT_CONF, CANCEL_MULT_CONF */
	MISC_IND_CHANNEL_NUM,

/* COMM_MODE_COMMAND */
	CM_SESSION_ID, /* INTEGER(0..255), u_int8* */
	CM_ASSOC_SESSION_ID, /* INTEGER(0..255), u_int8* */
 /* CM_TERMLAB_MCU_NUM, */ 
 /*	CM_TERMLAB_TERM_NUM, */
	CM_SESSION_DESCR, /* BMP_STRING(SIZE(1..128)), char* */
	CM_DATA_TYPE_AUDIO_DATA, /* enum audio_codec* */
	CM_MEDIA_CH_IPADDR, /* OCTET STRING (SIZE(4)), u_int32 */
	CM_MEDIA_CH_PORT, /* INTEGER(0..65535), u_int16 */
	CM_MEDIA_CONTROL_CH_IPADDR, /* OCTET STRING (SIZE(4)), u_int32 */
	CM_MEDIA_CONTROL_CH_PORT, /* INTEGER(0..65535), u_int16 */

	// tutaj trzeba wymyślić albo jakąs strukture albo 10 paramów	
};


enum h245_initiation { LOCAL_SYSTEM, LOCAL_DYNAMIC_SYSTEM, REMOTE_SYSTEM };

enum terminal_type { 
	TERMINAL = 50, 
	GATEWAY = 60, 
	TERMINAL_WITH_MC = 70,
	GATEWAY_WITH_MC = 80, 
	GATEKEEPER_WITH_MC = 120, 
	MCU = 160,
	GATEWAY_WITH_MC_WITH_DATA_MP = 90, 
	GATEKEEPER_WITH_MC_WITH_DATA_MP = 130, 
	MCU_WITH_DATA_MP = 170, 
	GATEWAY_WITH_MC_WITH_DATA_AND_AUDIO_MP = 100, 
	GATEKEEPER_WITH_MC_WITH_DATA_AND_AUDIO_MP = 140, 
	MCU_WITH_DATA_AND_AUDIO_MP = 180,
	GATEWAY_WITH_MC_WITH_DATA_AND_AUDIO_AND_VIDEO_MP = 110, 
	GATEKEEPER_WITH_MC_WITH_DATA_AND_AUDIO_AND_VIDEO_MP = 150,
	MCU_WITH_DATA_AND_AUDIO_AND_VIDEO_MP = 190
};

/* 
 * create_h245_system(): Creates an H.245 system instance. 
 * Initiates all nesesary queues. Returns a handler to the system 
 * or NULL if an error occured. 
 */

h245_p create_h245_system(enum h245_initiation how_to_initiate,
						  char *ip_address /* ip */,
						  unsigned short port,
						  enum terminal_type tt);


/* 
 * delete_h245_system(): Deletes the system previously created by
 * create_h245_system(). Frees all dynamic structures. Returnes non-zero
 * if an error occured.
 */

int delete_h245_system(h245_p);


/* 
 * h245_wait_until_connected(h245_p syst): Hangs up until syst is connected
 * to another one. Very useful when syst was created with 
 * the LOCAL_SYSTEM or LOCAL_DYNAMIC_SYSTEM flag. 
 * If syst is already connected then this function returns immediately.
 */

void h245_wait_until_connected(h245_p);


/* 
 * h245_is_connected(h245_p syst): returns 0 if connected or non-zero
 * if not connected.
 */  

int h245_is_connected(h245_p syst);



/* 
 * create_h245_primitive(): This function must be called to prepare
 * a primitive object that can be passed then to the H.245 system.
 * Returns a primitive handler or NULL if error occured.
 * pn is a primitive identifier.
 */
 
prim_h245_p create_h245_primitive(enum primitive_name pn);


/* 
 * delete_h245_primitive(): This one must must be called after a primitive
 * was received and examined. Frees all dynamic structures. Returnes non-zero
 * if an error occured.
 */

int delete_h245_primitive(prim_h245_p);


/* 
 * set_h245_primitive_param(): Adds an parameter to a primitive 
 * (some primitives do not need any parameters - this routine is 
 * NOT for them). Three parameters are required: 
 * prim is a primitive handler previously created by the
 * create_h245_primitive() routine. pn is a name of parameter, and val 
 * is its value (cast into the void * type).
 */

int set_h245_primitive_param(prim_h245_p prim, enum param_name pn, void *val);


/* 
 * get_h245_primitive_param(): Acquires a demanded parameter from
 * the set of primitive's parameters. 
 */

void *get_h245_primitive_param(prim_h245_p prim, enum param_name pn);


/*
 * set_h245_primitive_name(): This resets a primitive name. This 
 * can be usually used the change an H245_MESSAGE primitive (with or without
 * parameters) into another one. 
 */
int set_h245_primitive_name(prim_h245_p prim, enum primitive_name pn);


/*
 * pass_h245_primitive(): Passes a primitive to a h245 system. syst is a 
 * proper H.245 system handler, prim is a primitive previously created
 * by the create_h245_primitve() routine and optionally 'loaded' with
 * parametrs by means of set_parameter(). Returns non-zero if an error
 * occured.
 */

int pass_h245_primitive(h245_p syst, prim_h245_p prim);


/* 
 * get_h245_primitive(): Gets a primitive from a H.245 system (pointed by the
 * syst parameter). If no primitives are ready to be received from the 
 * system this function 'blocks' waiting for any primitive. This primitive 
 * should be deleted by means of delete_h245_primitive() after examining it. 
 * It returns a primitive handler.
 */

prim_h245_p get_h245_primitive(h245_p syst);


/* 
 * get_h245_primitive_nb(): A non-blocking equivalent of the 
 * get_h245_primitive() routine. Returns NULL if no primitives are ready 
 * to be received.
 */

prim_h245_p get_h245_primitive_nb(h245_p);

/*
 * get_h245_primitive_name() returnes a name of the primitive 
 */

enum primitive_name get_h245_primitive_name(prim_h245_p prim);


/*
 * get_h245_system_id(): an integer, which can be used to distiguish
 * H.245 systems one from another.
 */

int get_h245_system_id(h245_p system);



/* 
 * Structures that are used as primitive's parameters:
 */


#define DEFAULT_AUDIO_FRAMES 256

enum audio_codec { 

	bad_codec = -1, 
	nonStandard = 0,
	g711Alaw64k, 
	g711Alaw56k, 
	g711Ulaw64k, 
	g711Ulaw56k, 
	g722_64k,  
	g722_56k,  
	g722_48k,  
	g7231,					/* Don't use it now!!! */
	g728, 
	g729, 
	g729AnnexA,
	is11172AudioCapability, /* Don't use it now!!! */
	is13818AudioCapability, /* Don't use it now!!! */
	threeCommas /* ... */,
	g729wAnnexB,
	g729AnnexAwAnnexB,
	g7231AnnexCCapability	/* Don't use it now!!! */

	/*,.. */ /* add other codecs here */ 
};


struct audio_cap {

	enum audio_codec codec;
	int audio_frames;
	/* .. add  non-standard codec posiibility here */

};

struct capability {

	struct audio_cap *rec_p;
	struct audio_cap *trans_p;
	struct audio_cap *rec_and_trans_p;
	/* .. video & data go here */

};

struct captable_entry { 

	unsigned short captable_entry_num;
	struct capability cap;

};

struct capdescr {

	unsigned char capability_descr_number; /* capability ID */

	int rows;			// a number of rows in 'caps'
	int elements[255];	// a number of elements in every row
	unsigned short **caps; // simultanous * alternative capabilities

};

/* ^^^^ Ufffff ^^^^^ */

/* ..and finally those are the real primitive's parameters: */
 
struct captable {

	int number;
	struct captable_entry *entries;

};

struct descriptors {

	int number;
	struct capdescr *descr;

};



enum msdse_error_code { MSDSE_ERR_A, MSDSE_ERR_B, MSDSE_ERR_C, MSDSE_ERR_D, 
						MSDSE_ERR_E, MSDSE_ERR_F };

enum msdse_decision { MSDSE_DECISION_MASTER, MSDSE_DECISION_SLAVE };

enum cese_source { CESE_USER, CESE_PROTOCOL };

enum lcse_error_code { LCSE_ERR_A, LCSE_ERR_B, LCSE_ERR_C, LCSE_ERR_D };

enum lcse_reject_cause { 
	LCSE_CAUSE_UNSPECIFIED = 0, 
	LCSE_CAUSE_UNSUITABLE_REVERSE_PARAMS,
	LCSE_CAUSE_DATA_TYPE_NOT_SUPP, 
	LCSE_CAUSE_DATA_TYPE_NOT_AVAIL,
	LCSE_CAUSE_UNKNOWN_DATA_TYPE, 
	LCSE_CAUSE_DATA_TYPE_AL_COMB_NOT_SUPP,
	LCSE_CAUSE_MULTICAST_CHANNEL_NOT_ALLOWED,
	LCSE_CAUSE_INSUFFICIENT_BANDWIDTH,
	LCSE_CAUSE_SEPARATE_STACK_EST_FAILED,
	LCSE_CAUSE_INVALID_SESSION_ID,
	LCSE_CAUSE_MASTER_SLAVE_CONFLICT 
};


/* What follows helps to oparate on mentioned structures: */

enum capability_direction { RECEIVE, TRANSMIT, RECEIVE_AND_TRANSMIT };

typedef struct captable *capt_p;


capt_p create_captable();

int add_codec(capt_p, enum audio_codec, enum capability_direction);

int add_codec_with_number(capt_p, enum audio_codec, 
						  enum capability_direction, unsigned short number);

unsigned short get_num(capt_p, enum audio_codec);

int destroy_captable(capt_p);

void print_captable(capt_p ct);

int how_many_codecs(capt_p ct);




typedef struct descriptors *desc_p;


desc_p create_descriptors();

int add_capab(desc_p, int descr_num, int row, int column, unsigned short codec_num);

int destroy_descriptors(desc_p);

void print_descr_table(desc_p);

int how_many_descriptors(desc_p);

//struct codec_names {
//	enum audio_codec symbol;
//	char *name;
//};

char* codec_str_table[];

/* Added by Krzysztof Senenko */
/******************* moje dodatki K.S. **************************************/

int add_codec_with_frames(capt_p ct, enum audio_codec ac, enum capability_direction cd, int frames);

int add_codec_with_number_and_frames(capt_p ct, enum audio_codec ac, 
			  enum capability_direction cd, unsigned short number, int frames);

/*****************************************************************************/


#endif
