/*
 * Copyright (c) 2012-2019 Belledonne Communications SARL.
 *
 * This file is part of belle-sip.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef BELLE_SDP_H_
#define BELLE_SDP_H_

#include "belle-sip/defs.h"
#include "belle-sip/list.h"

#define BELLE_SDP_CAST(obj,t) BELLE_SIP_CAST(obj,t)

BELLE_SIP_BEGIN_DECLS

/***************************************************************************************
 * Attribute
 *
 **************************************************************************************/
typedef struct _belle_sdp_attribute belle_sdp_attribute_t;
BELLESIP_EXPORT belle_sdp_attribute_t* belle_sdp_attribute_new(void);
BELLESIP_EXPORT belle_sdp_attribute_t* belle_sdp_attribute_parse (const char* attribute);
BELLESIP_EXPORT belle_sdp_attribute_t* belle_sdp_attribute_create (const char* name,const char* value);
BELLESIP_EXPORT const char* belle_sdp_attribute_get_name(const belle_sdp_attribute_t* attribute);
BELLESIP_EXPORT void belle_sdp_attribute_set_name(belle_sdp_attribute_t* attribute, const char* name);
BELLESIP_EXPORT const char* belle_sdp_attribute_get_value(belle_sdp_attribute_t* attribute);
BELLESIP_EXPORT unsigned int belle_sdp_attribute_has_value(belle_sdp_attribute_t* attribute);
#define BELLE_SDP_ATTRIBUTE(t) BELLE_SDP_CAST(t,belle_sdp_attribute_t)
#define belle_sdp_attribute_init(obj)		/*nothing*/

/***************************************************************************************
 * Attributes Holder
 *
 **************************************************************************************/
typedef struct _belle_sdp_attribute_holder belle_sdp_attribute_holder_t;
BELLESIP_EXPORT belle_sdp_attribute_holder_t* belle_sdp_attribute_holder_new(void);
BELLESIP_EXPORT void belle_sdp_attribute_holder_set_attribute(belle_sdp_attribute_holder_t* holder, void* attribute);
BELLESIP_EXPORT belle_sdp_attribute_t* belle_sdp_attribute_holder_get_attribute(belle_sdp_attribute_holder_t* holder);

/***************************************************************************************
 * RAW Attribute
 *
 **************************************************************************************/
typedef struct _belle_sdp_raw_attribute belle_sdp_raw_attribute_t;
BELLESIP_EXPORT belle_sdp_raw_attribute_t* belle_sdp_raw_attribute_new(void);
BELLESIP_EXPORT belle_sdp_raw_attribute_t* belle_sdp_raw_attribute_parse(const char* attribute);
BELLESIP_EXPORT belle_sdp_raw_attribute_t* belle_sdp_raw_attribute_create(const char* name, const char* value);
BELLESIP_EXPORT void belle_sdp_raw_attribute_set_value(belle_sdp_raw_attribute_t* attribute, const char* value);
BELLESIP_EXPORT void belle_sdp_raw_attribute_set_name(belle_sdp_raw_attribute_t* attribute, const char* name);
#define BELLE_SDP_RAW_ATTRIBUTE(t) BELLE_SDP_CAST(t,belle_sdp_raw_attribute_t)

/***************************************************************************************
 * RFC4574 Attributes
 *
 **************************************************************************************/

// label

typedef struct _belle_sdp_label_attribute belle_sdp_label_attribute_t;
BELLESIP_EXPORT belle_sdp_label_attribute_t* belle_sdp_label_attribute_new(void);
BELLESIP_EXPORT belle_sdp_label_attribute_t* belle_sdp_label_attribute_parse(const char* attribute);
BELLESIP_EXPORT belle_sdp_label_attribute_t* belle_sdp_label_attribute_create(void);
BELLESIP_EXPORT const char* belle_sdp_label_attribute_get_pointer(const belle_sdp_label_attribute_t* attribute);
BELLESIP_EXPORT void belle_sdp_label_attribute_set_pointer(belle_sdp_label_attribute_t* attribute, const char* pointer);
#define BELLE_SDP_LABEL_ATTRIBUTE(t) BELLE_SDP_CAST(t,belle_sdp_label_attribute_t)

/***************************************************************************************
 * RFC4796 Attributes
 *
 **************************************************************************************/

// content

typedef struct _belle_sdp_content_attribute belle_sdp_content_attribute_t;
BELLESIP_EXPORT belle_sdp_content_attribute_t* belle_sdp_content_attribute_parse(const char* attribute);
BELLESIP_EXPORT belle_sdp_content_attribute_t* belle_sdp_content_attribute_new(void);
BELLESIP_EXPORT belle_sdp_content_attribute_t* belle_sdp_content_attribute_create(void);
BELLESIP_EXPORT void belle_sdp_content_attribute_add_media_tag(belle_sdp_content_attribute_t* attribute, const char* media_tag);
BELLESIP_EXPORT belle_sip_list_t* belle_sdp_content_attribute_get_media_tags(belle_sdp_content_attribute_t* attribute);
#define BELLE_SDP_CONTENT_ATTRIBUTE(t) BELLE_SDP_CAST(t,belle_sdp_content_attribute_t)

/***************************************************************************************
 * RFC5939 Attributes
 *
 **************************************************************************************/

// csup
typedef struct _belle_sdp_csup_attribute belle_sdp_csup_attribute_t;
BELLESIP_EXPORT belle_sdp_csup_attribute_t* belle_sdp_csup_attribute_new(void);
BELLESIP_EXPORT belle_sdp_csup_attribute_t* belle_sdp_csup_attribute_parse(const char* attribute);
BELLESIP_EXPORT belle_sdp_csup_attribute_t* belle_sdp_csup_attribute_create(void);
BELLESIP_EXPORT void belle_sdp_csup_attribute_add_option_tag(belle_sdp_csup_attribute_t* attribute, const char* option_tag);
BELLESIP_EXPORT belle_sip_list_t* belle_sdp_csup_attribute_get_option_tags(belle_sdp_csup_attribute_t* attribute);
#define BELLE_SDP_CSUP_ATTRIBUTE(t) BELLE_SDP_CAST(t,belle_sdp_csup_attribute_t)

// creq
typedef struct _belle_sdp_creq_attribute belle_sdp_creq_attribute_t;
BELLESIP_EXPORT belle_sdp_creq_attribute_t* belle_sdp_creq_attribute_new(void);
BELLESIP_EXPORT belle_sdp_creq_attribute_t* belle_sdp_creq_attribute_parse(const char* attribute);
BELLESIP_EXPORT belle_sdp_creq_attribute_t* belle_sdp_creq_attribute_create(void);
BELLESIP_EXPORT void belle_sdp_creq_attribute_add_option_tag(belle_sdp_creq_attribute_t* attribute, const char* option_tag);
BELLESIP_EXPORT belle_sip_list_t* belle_sdp_creq_attribute_get_option_tags(belle_sdp_creq_attribute_t* attribute);
#define BELLE_SDP_CREQ_ATTRIBUTE(t) BELLE_SDP_CAST(t,belle_sdp_creq_attribute_t)

//tcap
typedef struct _belle_sdp_tcap_attribute belle_sdp_tcap_attribute_t;
BELLESIP_EXPORT belle_sdp_tcap_attribute_t* belle_sdp_tcap_attribute_new(void);
BELLESIP_EXPORT belle_sdp_tcap_attribute_t* belle_sdp_tcap_attribute_parse(const char* attribute);
BELLESIP_EXPORT belle_sdp_tcap_attribute_t* belle_sdp_tcap_attribute_create(void);
BELLESIP_EXPORT void belle_sdp_tcap_attribute_set_id(belle_sdp_tcap_attribute_t* attribute, int id);
BELLESIP_EXPORT int belle_sdp_tcap_attribute_get_id(const belle_sdp_tcap_attribute_t* attribute);
BELLESIP_EXPORT void belle_sdp_tcap_attribute_add_proto(belle_sdp_tcap_attribute_t* attribute, const char* proto);
BELLESIP_EXPORT belle_sip_list_t* belle_sdp_tcap_attribute_get_protos(belle_sdp_tcap_attribute_t* attribute);
#define BELLE_SDP_TCAP_ATTRIBUTE(t) BELLE_SDP_CAST(t,belle_sdp_tcap_attribute_t)

// acap
typedef struct _belle_sdp_acap_attribute belle_sdp_acap_attribute_t;
BELLESIP_EXPORT belle_sdp_acap_attribute_t* belle_sdp_acap_attribute_new(void);
BELLESIP_EXPORT belle_sdp_acap_attribute_t* belle_sdp_acap_attribute_parse(const char* attribute);
BELLESIP_EXPORT belle_sdp_acap_attribute_t* belle_sdp_acap_attribute_create(void);
BELLESIP_EXPORT int belle_sdp_acap_attribute_get_id(const belle_sdp_acap_attribute_t* attribute);
BELLESIP_EXPORT void belle_sdp_acap_attribute_set_id(belle_sdp_acap_attribute_t* attribute, int id);
BELLESIP_EXPORT const char* belle_sdp_acap_attribute_get_name(const belle_sdp_acap_attribute_t* attribute);
BELLESIP_EXPORT void belle_sdp_acap_attribute_set_name(belle_sdp_acap_attribute_t* attribute, const char* name);
BELLESIP_EXPORT const char* belle_sdp_acap_attribute_get_value(const belle_sdp_acap_attribute_t* attribute);
BELLESIP_EXPORT void belle_sdp_acap_attribute_set_value(belle_sdp_acap_attribute_t* attribute, const char* value);
#define BELLE_SDP_ACAP_ATTRIBUTE(t) BELLE_SDP_CAST(t,belle_sdp_acap_attribute_t)

// acfg
typedef struct _belle_sdp_acfg_attribute belle_sdp_acfg_attribute_t;
BELLESIP_EXPORT belle_sdp_acfg_attribute_t* belle_sdp_acfg_attribute_new(void);
BELLESIP_EXPORT belle_sdp_acfg_attribute_t* belle_sdp_acfg_attribute_parse(const char* attribute);
BELLESIP_EXPORT belle_sdp_acfg_attribute_t* belle_sdp_acfg_attribute_create(void);
BELLESIP_EXPORT int belle_sdp_acfg_attribute_get_id(const belle_sdp_acfg_attribute_t* attribute);
BELLESIP_EXPORT void belle_sdp_acfg_attribute_set_id(belle_sdp_acfg_attribute_t* attribute, int id);
BELLESIP_EXPORT void belle_sdp_acfg_attribute_add_config(belle_sdp_acfg_attribute_t* attribute, const char* config);
BELLESIP_EXPORT belle_sip_list_t* belle_sdp_acfg_attribute_get_configs(const belle_sdp_acfg_attribute_t* attribute);
#define BELLE_SDP_ACFG_ATTRIBUTE(t) BELLE_SDP_CAST(t,belle_sdp_acfg_attribute_t)

// pcfg
typedef struct _belle_sdp_pcfg_attribute belle_sdp_pcfg_attribute_t;
BELLESIP_EXPORT belle_sdp_pcfg_attribute_t* belle_sdp_pcfg_attribute_new(void);
BELLESIP_EXPORT belle_sdp_pcfg_attribute_t* belle_sdp_pcfg_attribute_parse(const char* attribute);
BELLESIP_EXPORT belle_sdp_pcfg_attribute_t* belle_sdp_pcfg_attribute_create(void);
BELLESIP_EXPORT int belle_sdp_pcfg_attribute_get_id(const belle_sdp_pcfg_attribute_t* attribute);
BELLESIP_EXPORT void belle_sdp_pcfg_attribute_set_id(belle_sdp_pcfg_attribute_t* attribute, int id);
BELLESIP_EXPORT void belle_sdp_pcfg_attribute_add_config(belle_sdp_pcfg_attribute_t* attribute, const char* config);
BELLESIP_EXPORT belle_sip_list_t* belle_sdp_pcfg_attribute_get_configs(const belle_sdp_pcfg_attribute_t* attribute);;
#define BELLE_SDP_PCFG_ATTRIBUTE(t) BELLE_SDP_CAST(t,belle_sdp_pcfg_attribute_t)

/***************************************************************************************
 * RTCP-FB Attribute
 *
 **************************************************************************************/
typedef enum _belle_sdp_rtcp_fb_val_type {
	BELLE_SDP_RTCP_FB_ACK,
	BELLE_SDP_RTCP_FB_NACK,
	BELLE_SDP_RTCP_FB_TRR_INT,
	BELLE_SDP_RTCP_FB_CCM
} belle_sdp_rtcp_fb_val_type_t;
typedef enum _belle_sdp_rtcp_fb_val_param {
	BELLE_SDP_RTCP_FB_NONE,
	BELLE_SDP_RTCP_FB_PLI,
	BELLE_SDP_RTCP_FB_SLI,
	BELLE_SDP_RTCP_FB_RPSI,
	BELLE_SDP_RTCP_FB_APP,
	BELLE_SDP_RTCP_FB_FIR,
	BELLE_SDP_RTCP_FB_TMMBR
} belle_sdp_rtcp_fb_val_param_t;
typedef struct _belle_sdp_rtcp_fb_attribute belle_sdp_rtcp_fb_attribute_t;
BELLESIP_EXPORT belle_sdp_rtcp_fb_attribute_t* belle_sdp_rtcp_fb_attribute_new(void);
BELLESIP_EXPORT belle_sdp_rtcp_fb_attribute_t* belle_sdp_rtcp_fb_attribute_parse(const char* attribute);
BELLESIP_EXPORT belle_sdp_rtcp_fb_attribute_t* belle_sdp_rtcp_fb_attribute_create(void);
BELLESIP_EXPORT int8_t belle_sdp_rtcp_fb_attribute_get_id(const belle_sdp_rtcp_fb_attribute_t* attribute);
BELLESIP_EXPORT void belle_sdp_rtcp_fb_attribute_set_id(belle_sdp_rtcp_fb_attribute_t* attribute, int8_t id);
BELLESIP_EXPORT void belle_sdp_rtcp_fb_attribute_set_raw_id(belle_sdp_rtcp_fb_attribute_t* attribute, const char* value);
BELLESIP_EXPORT belle_sdp_rtcp_fb_val_type_t belle_sdp_rtcp_fb_attribute_get_type(const belle_sdp_rtcp_fb_attribute_t* attribute);
BELLESIP_EXPORT void belle_sdp_rtcp_fb_attribute_set_type(belle_sdp_rtcp_fb_attribute_t* attribute, belle_sdp_rtcp_fb_val_type_t type);
BELLESIP_EXPORT void belle_sdp_rtcp_fb_attribute_set_raw_type(belle_sdp_rtcp_fb_attribute_t* attribute, const char* type);
BELLESIP_EXPORT belle_sdp_rtcp_fb_val_param_t belle_sdp_rtcp_fb_attribute_get_param(const belle_sdp_rtcp_fb_attribute_t* attribute);
BELLESIP_EXPORT void belle_sdp_rtcp_fb_attribute_set_param(belle_sdp_rtcp_fb_attribute_t* attribute, belle_sdp_rtcp_fb_val_param_t param);
BELLESIP_EXPORT void belle_sdp_rtcp_fb_attribute_set_raw_param(belle_sdp_rtcp_fb_attribute_t* attribute, const char* value);
BELLESIP_EXPORT uint16_t belle_sdp_rtcp_fb_attribute_get_trr_int(const belle_sdp_rtcp_fb_attribute_t* attribute);
BELLESIP_EXPORT void belle_sdp_rtcp_fb_attribute_set_trr_int(belle_sdp_rtcp_fb_attribute_t* attribute, uint16_t milliseconds);
BELLESIP_EXPORT void belle_sdp_rtcp_fb_attribute_set_trr_raw(belle_sdp_rtcp_fb_attribute_t* attribute, const char* value);
BELLESIP_EXPORT uint32_t belle_sdp_rtcp_fb_attribute_get_smaxpr(const belle_sdp_rtcp_fb_attribute_t* attribute);
BELLESIP_EXPORT void belle_sdp_rtcp_fb_attribute_set_smaxpr(belle_sdp_rtcp_fb_attribute_t* attribute, uint32_t smaxpr);
#define BELLE_SDP_RTCP_FB_ATTRIBUTE(t) BELLE_SDP_CAST(t,belle_sdp_rtcp_fb_attribute_t)

/***************************************************************************************
 * RTCP-XR Attribute
 *
 **************************************************************************************/
typedef struct _belle_sdp_rtcp_xr_attribute belle_sdp_rtcp_xr_attribute_t;
BELLESIP_EXPORT belle_sdp_rtcp_xr_attribute_t* belle_sdp_rtcp_xr_attribute_new(void);
BELLESIP_EXPORT belle_sdp_rtcp_xr_attribute_t* belle_sdp_rtcp_xr_attribute_parse(const char* attribute);
BELLESIP_EXPORT belle_sdp_rtcp_xr_attribute_t* belle_sdp_rtcp_xr_attribute_create(void);
BELLESIP_EXPORT const char* belle_sdp_rtcp_xr_attribute_get_rcvr_rtt_mode(const belle_sdp_rtcp_xr_attribute_t* attribute);
BELLESIP_EXPORT void belle_sdp_rtcp_xr_attribute_set_rcvr_rtt_mode(belle_sdp_rtcp_xr_attribute_t* attribute, const char *mode);
BELLESIP_EXPORT int belle_sdp_rtcp_xr_attribute_get_rcvr_rtt_max_size(const belle_sdp_rtcp_xr_attribute_t* attribute);
BELLESIP_EXPORT void belle_sdp_rtcp_xr_attribute_set_rcvr_rtt_max_size(belle_sdp_rtcp_xr_attribute_t* attribute, int max_size);
BELLESIP_EXPORT unsigned int belle_sdp_rtcp_xr_attribute_has_stat_summary(const belle_sdp_rtcp_xr_attribute_t* attribute);
BELLESIP_EXPORT void belle_sdp_rtcp_xr_attribute_set_stat_summary(belle_sdp_rtcp_xr_attribute_t* attribute, unsigned int enable);
BELLESIP_EXPORT void belle_sdp_rtcp_xr_attribute_enable_stat_summary(belle_sdp_rtcp_xr_attribute_t* attribute, const char* flag);
BELLESIP_EXPORT const belle_sip_list_t* belle_sdp_rtcp_xr_attribute_get_stat_summary_flags(const belle_sdp_rtcp_xr_attribute_t* attribute);
BELLESIP_EXPORT void belle_sdp_rtcp_xr_attribute_add_stat_summary_flag(belle_sdp_rtcp_xr_attribute_t* attribute, const char* flag);
BELLESIP_EXPORT unsigned int belle_sdp_rtcp_xr_attribute_has_voip_metrics(const belle_sdp_rtcp_xr_attribute_t* attribute);
BELLESIP_EXPORT void belle_sdp_rtcp_xr_attribute_set_voip_metrics(belle_sdp_rtcp_xr_attribute_t* attribute, unsigned int enable);
BELLESIP_EXPORT void belle_sdp_rtcp_xr_attribute_enable_voip_metrics(belle_sdp_rtcp_xr_attribute_t* attribute, const char* flag);
#define BELLE_SDP_RTCP_XR_ATTRIBUTE(t) BELLE_SDP_CAST(t,belle_sdp_rtcp_xr_attribute_t)

/***************************************************************************************
 * Bandwidth
 *
 **************************************************************************************/
typedef struct _belle_sdp_bandwidth belle_sdp_bandwidth_t;
BELLESIP_EXPORT belle_sdp_bandwidth_t* belle_sdp_bandwidth_new(void);
BELLESIP_EXPORT belle_sdp_bandwidth_t* belle_sdp_bandwidth_parse (const char* bandwidth);
BELLESIP_EXPORT int belle_sdp_bandwidth_get_value(const belle_sdp_bandwidth_t* attribute);
BELLESIP_EXPORT const char* belle_sdp_bandwidth_get_type(const belle_sdp_bandwidth_t* attribute);
BELLESIP_EXPORT void belle_sdp_bandwidth_set_value(belle_sdp_bandwidth_t* attribute, int value);
BELLESIP_EXPORT void belle_sdp_bandwidth_set_type(belle_sdp_bandwidth_t* attribute, const char* type);
#define BELLE_SDP_BANDWIDTH(t) BELLE_SDP_CAST(t,belle_sdp_bandwidth_t)

/***************************************************************************************
 * Connection
 *
 **************************************************************************************/
typedef struct _belle_sdp_connection belle_sdp_connection_t;
BELLESIP_EXPORT belle_sdp_connection_t* belle_sdp_connection_new(void);
BELLESIP_EXPORT belle_sdp_connection_t* belle_sdp_connection_create(const char* net_type, const char* addr_type, const char* addr);
BELLESIP_EXPORT belle_sdp_connection_t* belle_sdp_connection_parse (const char* connection);
BELLESIP_EXPORT const char* belle_sdp_connection_get_address(const belle_sdp_connection_t* connection);
BELLESIP_EXPORT const char* belle_sdp_connection_get_address_type(const belle_sdp_connection_t* connection);
BELLESIP_EXPORT const char* belle_sdp_connection_get_network_type(const belle_sdp_connection_t* connection);
BELLESIP_EXPORT int belle_sdp_connection_get_ttl(const belle_sdp_connection_t* connection);
BELLESIP_EXPORT int belle_sdp_connection_get_range(const belle_sdp_connection_t* connection);
BELLESIP_EXPORT void belle_sdp_connection_set_address(belle_sdp_connection_t* connection, const char* addr);
BELLESIP_EXPORT void belle_sdp_connection_set_address_type(belle_sdp_connection_t* connection, const char* type);
BELLESIP_EXPORT void belle_sdp_connection_set_network_type(belle_sdp_connection_t* connection, const char* type);
BELLESIP_EXPORT void belle_sdp_connection_set_ttl(belle_sdp_connection_t* connection, int ttl);
BELLESIP_EXPORT void belle_sdp_connection_set_range(belle_sdp_connection_t* connection, int range);
#define BELLE_SDP_CONNECTION(t) BELLE_SDP_CAST(t,belle_sdp_connection_t)

/***************************************************************************************
 * Email
 *
 **************************************************************************************/
typedef struct _belle_sdp_email belle_sdp_email_t;
BELLESIP_EXPORT belle_sdp_email_t* belle_sdp_email_new(void);
BELLESIP_EXPORT belle_sdp_email_t* belle_sdp_email_parse (const char* email);
BELLESIP_EXPORT const char* belle_sdp_email_get_value(const belle_sdp_email_t* email);
BELLESIP_EXPORT void belle_sdp_email_set_value(belle_sdp_email_t* email, const char* value);
#define BELLE_SDP_EMAIL(t) BELLE_SDP_CAST(t,belle_sdp_email_t)

/***************************************************************************************
 * Info
 *
 **************************************************************************************/
typedef struct _belle_sdp_info belle_sdp_info_t;
BELLESIP_EXPORT belle_sdp_info_t* belle_sdp_info_new(void);
BELLESIP_EXPORT belle_sdp_info_t* belle_sdp_info_parse (const char* info);
BELLESIP_EXPORT const char* belle_sdp_info_get_value(const belle_sdp_info_t* info);
BELLESIP_EXPORT void belle_sdp_info_set_value(belle_sdp_info_t* info, const char* value);
#define BELLE_SDP_INFO(t) BELLE_SDP_CAST(t,belle_sdp_info_t)

/***************************************************************************************
 * Key
 *
 **************************************************************************************/
//typedef struct _belle_sdp_key belle_sdp_key_t;
//belle_sdp_key_t* belle_sdp_key_new(void);
//belle_sdp_key_t* belle_sdp_key_parse (const char* key);
//const char* belle_sdp_key_get_key(const belle_sdp_key_t* key);
//const char* belle_sdp_key_get_method(const belle_sdp_key_t* key);
//unsigned int belle_sdp_key_as_key(const belle_sdp_key_t* key);
//void belle_sdp_key_set_key(belle_sdp_key_t* key, const char* keyvalue);
//void belle_sdp_key_set_method(belle_sdp_key_t* key, const char* method);
//#define BELLE_SDP_KEY(t) BELLE_SDP_CAST(t,belle_sdp_key_t);

/***************************************************************************************
 * Media
 *
 **************************************************************************************/
typedef struct _belle_sdp_media belle_sdp_media_t;
BELLESIP_EXPORT belle_sdp_media_t* belle_sdp_media_new(void);
BELLESIP_EXPORT belle_sdp_media_t* belle_sdp_media_parse (const char* media);
BELLESIP_EXPORT belle_sdp_media_t* belle_sdp_media_create(const char* media_type
                         , int media_port
                         , int port_count
                         ,const char* protocol
                         ,belle_sip_list_t* static_media_formats);
BELLESIP_EXPORT belle_sip_list_t* belle_sdp_media_get_media_formats(const belle_sdp_media_t* media);
BELLESIP_EXPORT const char* belle_sdp_media_get_raw_fmt(const belle_sdp_media_t* media);
BELLESIP_EXPORT int	belle_sdp_media_get_media_port(const belle_sdp_media_t* media);
BELLESIP_EXPORT const char* belle_sdp_media_get_media_type(const belle_sdp_media_t* media);
BELLESIP_EXPORT int	belle_sdp_media_get_port_count(const belle_sdp_media_t* media);
BELLESIP_EXPORT const char* belle_sdp_media_get_protocol(const belle_sdp_media_t* media);
BELLESIP_EXPORT void belle_sdp_media_set_media_formats(belle_sdp_media_t* media, belle_sip_list_t* mediaFormats);
BELLESIP_EXPORT void belle_sdp_media_set_raw_fmt(belle_sdp_media_t* media, const char* fmt);
BELLESIP_EXPORT void belle_sdp_media_media_formats_add(belle_sdp_media_t* media, const char* fmt);
BELLESIP_EXPORT void belle_sdp_media_set_media_port(belle_sdp_media_t* media, int port);
BELLESIP_EXPORT void belle_sdp_media_set_media_type(belle_sdp_media_t* media, const char* mediaType);
BELLESIP_EXPORT void belle_sdp_media_set_port_count(belle_sdp_media_t* media, int port_count);
BELLESIP_EXPORT void belle_sdp_media_set_protocol(belle_sdp_media_t* media, const char* protocole);

#define BELLE_SDP_MEDIA(t) BELLE_SDP_CAST(t,belle_sdp_media_t)

/***************************************************************************************
 * mime_parameter
 *
 **************************************************************************************/
typedef struct _belle_sdp_mime_parameter belle_sdp_mime_parameter_t;
BELLESIP_EXPORT belle_sdp_mime_parameter_t* belle_sdp_mime_parameter_new(void);
BELLESIP_EXPORT belle_sdp_mime_parameter_t* belle_sdp_mime_parameter_create(const char* type, int media_format, int rate, int channel_count);
BELLESIP_EXPORT int belle_sdp_mime_parameter_get_rate(const belle_sdp_mime_parameter_t* mime_parameter);
BELLESIP_EXPORT void belle_sdp_mime_parameter_set_rate(belle_sdp_mime_parameter_t* mime_parameter, int rate);
BELLESIP_EXPORT int belle_sdp_mime_parameter_get_channel_count(const belle_sdp_mime_parameter_t* mime_parameter);
BELLESIP_EXPORT void belle_sdp_mime_parameter_set_channel_count(belle_sdp_mime_parameter_t* mime_parameter, int count);
BELLESIP_EXPORT int belle_sdp_mime_parameter_get_ptime(const belle_sdp_mime_parameter_t* mime_parameter);
BELLESIP_EXPORT void belle_sdp_mime_parameter_set_ptime(belle_sdp_mime_parameter_t* mime_parameter, int ptime);
BELLESIP_EXPORT int belle_sdp_mime_parameter_get_max_ptime(const belle_sdp_mime_parameter_t* mime_parameter);
BELLESIP_EXPORT void belle_sdp_mime_parameter_set_max_ptime(belle_sdp_mime_parameter_t* mime_parameter, int max_ptime);
BELLESIP_EXPORT const char* belle_sdp_mime_parameter_get_type(const belle_sdp_mime_parameter_t* mime_parameter);
BELLESIP_EXPORT void belle_sdp_mime_parameter_set_type(belle_sdp_mime_parameter_t* mime_parameter,const char* type);
BELLESIP_EXPORT int belle_sdp_mime_parameter_get_media_format(const belle_sdp_mime_parameter_t* mime_parameter);
BELLESIP_EXPORT void belle_sdp_mime_parameter_set_media_format(belle_sdp_mime_parameter_t* mime_parameter, int format);
BELLESIP_EXPORT const char* belle_sdp_mime_parameter_get_parameters(const belle_sdp_mime_parameter_t* mime_parameter);
BELLESIP_EXPORT void belle_sdp_mime_parameter_set_parameters(belle_sdp_mime_parameter_t* mime_parameter,const char* parameters);
#define BELLE_SDP_MIME_PARAMETER(t) BELLE_SDP_CAST(t,belle_sdp_mime_parameter_t)

/***************************************************************************************
 * Media Description
 *
 **************************************************************************************/
typedef struct _belle_sdp_media_description belle_sdp_media_description_t;
BELLESIP_EXPORT belle_sdp_media_description_t* belle_sdp_media_description_new(void);
BELLESIP_EXPORT belle_sdp_media_description_t* belle_sdp_media_description_parse (const char* media_description);
BELLESIP_EXPORT belle_sdp_media_description_t* belle_sdp_media_description_create(const char* media_type
                         	 	 	 	 	 	 	 	 	 	 , int media_port
                         	 	 	 	 	 	 	 	 	 	 , int port_count
                         	 	 	 	 	 	 	 	 	 	 ,const char* protocol
                         	 	 	 	 	 	 	 	 	 	 ,belle_sip_list_t* static_media_formats);
BELLESIP_EXPORT void belle_sdp_media_description_add_dynamic_payloads(belle_sdp_media_description_t* media_description, belle_sip_list_t* payloadNames, belle_sip_list_t* payloadValues);
BELLESIP_EXPORT const char* belle_sdp_media_description_get_attribute_value(const belle_sdp_media_description_t* media_description, const char* name);
BELLESIP_EXPORT belle_sdp_attribute_t* belle_sdp_media_description_get_attribute(const belle_sdp_media_description_t* media_description, const char* name);
BELLESIP_EXPORT belle_sip_list_t* belle_sdp_media_description_get_attributes(const belle_sdp_media_description_t* media_description);
// belle_sdp_media_description_find_attributes_with_name creates a list of attributes with a given name.
// The list must be freed after usage
BELLESIP_EXPORT belle_sip_list_t * belle_sdp_media_description_find_attributes_with_name(const belle_sdp_media_description_t *media_description, const char* name);
BELLESIP_EXPORT int	belle_sdp_media_description_get_bandwidth(const belle_sdp_media_description_t* media_description, const char* name);
BELLESIP_EXPORT belle_sip_list_t* belle_sdp_media_description_get_bandwidths(const belle_sdp_media_description_t* media_description);
BELLESIP_EXPORT belle_sdp_connection_t* belle_sdp_media_description_get_connection(const belle_sdp_media_description_t* media_description);
BELLESIP_EXPORT belle_sdp_info_t* belle_sdp_media_description_get_info(const belle_sdp_media_description_t* media_description);
BELLESIP_EXPORT belle_sdp_media_t* belle_sdp_media_description_get_media(const belle_sdp_media_description_t* media_description);
BELLESIP_EXPORT belle_sip_list_t* belle_sdp_media_description_build_mime_parameters(const belle_sdp_media_description_t* media_description);
BELLESIP_EXPORT void belle_sdp_media_description_remove_attribute(belle_sdp_media_description_t* media_description,const char* attribute);
BELLESIP_EXPORT void belle_sdp_media_description_remove_bandwidth(belle_sdp_media_description_t* media_description,const char* bandwidth);
BELLESIP_EXPORT void belle_sdp_media_description_set_attribute_value(belle_sdp_media_description_t* media_description, const char* name, const char* value);
BELLESIP_EXPORT void belle_sdp_media_description_add_attribute(belle_sdp_media_description_t* media_description, belle_sdp_attribute_t* attr);
BELLESIP_EXPORT void belle_sdp_media_description_set_attributes(belle_sdp_media_description_t* media_description, belle_sip_list_t* Attributes);
BELLESIP_EXPORT void belle_sdp_media_description_set_bandwidth(belle_sdp_media_description_t* media_description, const char* name, int value);
BELLESIP_EXPORT void belle_sdp_media_description_add_bandwidth(belle_sdp_media_description_t* media_description, belle_sdp_bandwidth_t* bandwidth);
BELLESIP_EXPORT void belle_sdp_media_description_set_bandwidths(belle_sdp_media_description_t* media_description, belle_sip_list_t* bandwidths);
BELLESIP_EXPORT void belle_sdp_media_description_set_connection(belle_sdp_media_description_t* media_description, belle_sdp_connection_t* conn);
BELLESIP_EXPORT void belle_sdp_media_description_set_info(belle_sdp_media_description_t* media_description,belle_sdp_info_t* i);
BELLESIP_EXPORT void belle_sdp_media_description_set_media(belle_sdp_media_description_t* media_description, belle_sdp_media_t* media);
BELLESIP_EXPORT void belle_sdp_media_description_append_values_from_mime_parameter(belle_sdp_media_description_t* media_description, const belle_sdp_mime_parameter_t* mime_parameter);

BELLESIP_EXPORT void belle_sdp_media_description_add_attribute_holder(belle_sdp_media_description_t* media_description, belle_sdp_attribute_holder_t *holder);

#define BELLE_SDP_MEDIA_DESCRIPTION(t) BELLE_SDP_CAST(t,belle_sdp_media_description_t)

/***************************************************************************************
 * Origin
 *
 **************************************************************************************/
typedef struct _belle_sdp_origin belle_sdp_origin_t;
BELLESIP_EXPORT belle_sdp_origin_t* belle_sdp_origin_new(void);
BELLESIP_EXPORT belle_sdp_origin_t* belle_sdp_origin_parse (const char* origin);
BELLESIP_EXPORT belle_sdp_origin_t* belle_sdp_origin_create(const char* user_name
											, unsigned int session_id
											, unsigned int session_version
											, const char* network_type
											, const char* addr_type
											, const char* address);
BELLESIP_EXPORT const char* belle_sdp_origin_get_address(const belle_sdp_origin_t* origin);
BELLESIP_EXPORT const char* belle_sdp_origin_get_address_type(const belle_sdp_origin_t* origin);
BELLESIP_EXPORT const char* belle_sdp_origin_get_network_type(const belle_sdp_origin_t* origin);
BELLESIP_EXPORT unsigned int belle_sdp_origin_get_session_id(const belle_sdp_origin_t* origin);
BELLESIP_EXPORT unsigned int belle_sdp_origin_get_session_version(const belle_sdp_origin_t* origin);
BELLESIP_EXPORT const char* belle_sdp_origin_get_username(const belle_sdp_origin_t* origin);
BELLESIP_EXPORT void belle_sdp_origin_set_address(belle_sdp_origin_t* origin, const char* address);
BELLESIP_EXPORT void belle_sdp_origin_set_address_type(belle_sdp_origin_t* origin, const char* address);
BELLESIP_EXPORT void belle_sdp_origin_set_network_type(belle_sdp_origin_t* origin, const char* network_type);
BELLESIP_EXPORT void belle_sdp_origin_set_session_id(belle_sdp_origin_t* origin, unsigned int session_id);
BELLESIP_EXPORT void belle_sdp_origin_set_session_version(belle_sdp_origin_t* origin, unsigned int version);
BELLESIP_EXPORT void belle_sdp_origin_set_username(belle_sdp_origin_t* origin, const char* username);
#define BELLE_SDP_ORIGIN(t) BELLE_SDP_CAST(t,belle_sdp_origin_t)

/***************************************************************************************
 * Phone
 *
 **************************************************************************************/
typedef struct _belle_sdp_phone belle_sdp_phone_t;
BELLESIP_EXPORT belle_sdp_phone_t* belle_sdp_phone_new(void);
BELLESIP_EXPORT belle_sdp_phone_t* belle_sdp_phone_parse (const char* phone);
BELLESIP_EXPORT const char* belle_sdp_phone_get_value(const belle_sdp_phone_t* phone);
BELLESIP_EXPORT void belle_sdp_phone_set_value(belle_sdp_phone_t* phone, const char* value);
#define BELLE_SDP_PHONE(t) BELLE_SDP_CAST(t,belle_sdp_phone_t)

/***************************************************************************************
 * Repeat time
 *
 **************************************************************************************/
typedef struct _belle_sdp_repeate_time belle_sdp_repeate_time_t;
BELLESIP_EXPORT belle_sdp_repeate_time_t* belle_sdp_repeate_time_new(void);
BELLESIP_EXPORT belle_sdp_repeate_time_t* belle_sdp_repeate_time_parse (const char* repeate_time);
BELLESIP_EXPORT const char* belle_sdp_repeate_time_get_value(const belle_sdp_repeate_time_t* repeate_time);
BELLESIP_EXPORT void belle_sdp_repeate_time_set_value(belle_sdp_repeate_time_t* repeate_time, const char* value);
#define BELLE_SDP_REPEATE_TIME(t) BELLE_SDP_CAST(t,belle_sdp_repeate_time_t)

/***************************************************************************************
 * Session Name
 *
 **************************************************************************************/
typedef struct _belle_sdp_session_name belle_sdp_session_name_t;
BELLESIP_EXPORT belle_sdp_session_name_t* belle_sdp_session_name_new(void);
BELLESIP_EXPORT belle_sdp_session_name_t* belle_sdp_session_name_create (const char* name);
BELLESIP_EXPORT const char* belle_sdp_session_name_get_value(const belle_sdp_session_name_t* session_name);
BELLESIP_EXPORT void belle_sdp_session_name_set_value(belle_sdp_session_name_t* session_name, const char* value);
#define BELLE_SDP_SESSION_NAME(t) BELLE_SDP_CAST(t,belle_sdp_session_name_t)

/***************************************************************************************
 * Time
 *
 **************************************************************************************/
typedef struct _belle_sdp_time belle_sdp_time_t;
BELLESIP_EXPORT belle_sdp_time_t* belle_sdp_time_new(void);
BELLESIP_EXPORT belle_sdp_time_t* belle_sdp_time_parse (const char* time);

BELLESIP_EXPORT long long belle_sdp_time_get_start(const belle_sdp_time_t* time);
BELLESIP_EXPORT long long belle_sdp_time_get_stop(const belle_sdp_time_t* time);
BELLESIP_EXPORT void belle_sdp_time_set_start(belle_sdp_time_t* time, long long value);
BELLESIP_EXPORT void belle_sdp_time_set_stop(belle_sdp_time_t* time, long long value);
#define BELLE_SDP_TIME(t) BELLE_SDP_CAST(t,belle_sdp_time_t)

/***************************************************************************************
 * Time description
 *
 **************************************************************************************/
typedef struct _belle_sdp_time_description belle_sdp_time_description_t;
BELLESIP_EXPORT belle_sdp_time_description_t* belle_sdp_time_description_new(void);
BELLESIP_EXPORT belle_sdp_time_description_t* belle_sdp_time_description_parse (const char* time_description);
BELLESIP_EXPORT belle_sdp_time_description_t* belle_sdp_time_description_create (long long start, long long stop);

BELLESIP_EXPORT belle_sip_list_t* belle_sdp_time_description_get_repeate_times(const belle_sdp_time_description_t* time_description);
BELLESIP_EXPORT belle_sdp_time_t* belle_sdp_time_description_get_time(const belle_sdp_time_description_t* time_description);
BELLESIP_EXPORT void belle_sdp_time_description_set_repeate_times(belle_sdp_time_description_t* time_description, belle_sip_list_t* times);
BELLESIP_EXPORT void belle_sdp_time_description_set_time(belle_sdp_time_description_t* time_description, belle_sdp_time_t* times);
#define BELLE_SDP_TIME_DESCRIPTION(t) BELLE_SDP_CAST(t,belle_sdp_time_description_t)

/***************************************************************************************
 * URI
 *
 **************************************************************************************/
typedef struct _belle_sdp_uri belle_sdp_uri_t;
BELLESIP_EXPORT belle_sdp_uri_t* belle_sdp_uri_new(void);
BELLESIP_EXPORT belle_sdp_uri_t* belle_sdp_uri_parse (const char* uri);
BELLESIP_EXPORT const char* belle_sdp_uri_get_value(const belle_sdp_uri_t* uri);
BELLESIP_EXPORT void belle_sdp_uri_set_value(belle_sdp_uri_t* uri, const char* value);
#define BELLE_SDP_URI(t) BELLE_SDP_CAST(t,belle_sdp_uri_t)

/***************************************************************************************
 * Version
 *
 **************************************************************************************/
typedef struct _belle_sdp_version belle_sdp_version_t;
belle_sdp_version_t* belle_sdp_version_new(void);
BELLESIP_EXPORT belle_sdp_version_t* belle_sdp_version_create(int version);
BELLESIP_EXPORT int belle_sdp_version_get_version(const belle_sdp_version_t* version);
BELLESIP_EXPORT void belle_sdp_version_set_version(belle_sdp_version_t* version, int value);
#define BELLE_SDP_VERSION(t) BELLE_SDP_CAST(t,belle_sdp_version_t)

/***************************************************************************************
 * Session Description
 *
 **************************************************************************************/
typedef struct _belle_sdp_session_description belle_sdp_session_description_t;
BELLESIP_EXPORT belle_sdp_session_description_t* belle_sdp_session_description_new(void);
BELLESIP_EXPORT belle_sdp_session_description_t* belle_sdp_session_description_parse (const char* session_description);

BELLESIP_EXPORT belle_sip_list_t * belle_sdp_session_description_get_attributes(const belle_sdp_session_description_t *session_description);
BELLESIP_EXPORT const char* belle_sdp_session_description_get_attribute_value(const belle_sdp_session_description_t* session_description, const char* name);
BELLESIP_EXPORT const belle_sdp_attribute_t* belle_sdp_session_description_get_attribute(const belle_sdp_session_description_t* session_description, const char* name);
// belle_sdp_session_description_find_attributes_with_name creates a list of attributes with a given name.
// The list must be freed after usage
BELLESIP_EXPORT belle_sip_list_t * belle_sdp_session_description_find_attributes_with_name(const belle_sdp_session_description_t *session_description, const char* name);
BELLESIP_EXPORT int	belle_sdp_session_description_get_bandwidth(const belle_sdp_session_description_t* session_description, const char* name);
BELLESIP_EXPORT belle_sip_list_t* belle_sdp_session_description_get_bandwidths(const belle_sdp_session_description_t* session_description);
BELLESIP_EXPORT belle_sdp_connection_t* belle_sdp_session_description_get_connection(const belle_sdp_session_description_t* session_description);
BELLESIP_EXPORT belle_sip_list_t* belle_sdp_session_description_get_emails(const belle_sdp_session_description_t* session_description);
BELLESIP_EXPORT belle_sdp_info_t* belle_sdp_session_description_get_info(const belle_sdp_session_description_t* session_description);
BELLESIP_EXPORT belle_sip_list_t* belle_sdp_session_description_get_media_descriptions(const belle_sdp_session_description_t* session_description);
BELLESIP_EXPORT belle_sdp_origin_t* belle_sdp_session_description_get_origin(const belle_sdp_session_description_t* session_description);
BELLESIP_EXPORT belle_sip_list_t* belle_sdp_session_description_get_phones(const belle_sdp_session_description_t* session_description);
BELLESIP_EXPORT belle_sdp_session_name_t* belle_sdp_session_description_get_session_name(const belle_sdp_session_description_t* session_description);
BELLESIP_EXPORT belle_sip_list_t* belle_sdp_session_description_get_time_descriptions(const belle_sdp_session_description_t* session_description);
BELLESIP_EXPORT belle_sdp_uri_t* belle_sdp_session_description_get_uri(const belle_sdp_session_description_t* session_description);
BELLESIP_EXPORT belle_sdp_version_t* belle_sdp_session_description_get_version(const belle_sdp_session_description_t* session_description);
BELLESIP_EXPORT belle_sdp_uri_t* belle_sdp_session_description_get_zone_adjustments(const belle_sdp_session_description_t* session_description);
BELLESIP_EXPORT void belle_sdp_session_description_remove_attribute(belle_sdp_session_description_t* session_description, const char* name);
BELLESIP_EXPORT void belle_sdp_session_description_remove_bandwidth(belle_sdp_session_description_t* session_description, const char* name);
BELLESIP_EXPORT void belle_sdp_session_description_set_attribute_value(belle_sdp_session_description_t* session_description, const char* name, const char* value);
BELLESIP_EXPORT void belle_sdp_session_description_add_attribute(belle_sdp_session_description_t* session_description, belle_sdp_attribute_t* attribute);
BELLESIP_EXPORT void belle_sdp_session_description_set_attributes(belle_sdp_session_description_t* session_description, belle_sip_list_t* Attributes);
BELLESIP_EXPORT void belle_sdp_session_description_set_bandwidth(belle_sdp_session_description_t* session_description, const char* name, int value);
BELLESIP_EXPORT void belle_sdp_session_description_set_bandwidths(belle_sdp_session_description_t* session_description, belle_sip_list_t* bandwidths);
BELLESIP_EXPORT void belle_sdp_session_description_add_bandwidth(belle_sdp_session_description_t* session_description, belle_sdp_bandwidth_t* bandwidth);
BELLESIP_EXPORT void belle_sdp_session_description_set_connection(belle_sdp_session_description_t* session_description, belle_sdp_connection_t* conn);
BELLESIP_EXPORT void belle_sdp_session_description_set_emails(belle_sdp_session_description_t* session_description, belle_sip_list_t* emails);
BELLESIP_EXPORT void belle_sdp_session_description_set_info(belle_sdp_session_description_t* session_description, belle_sdp_info_t* i);
BELLESIP_EXPORT void belle_sdp_session_description_set_media_descriptions(belle_sdp_session_description_t* session_description, belle_sip_list_t* mediaDescriptions);
BELLESIP_EXPORT void belle_sdp_session_description_add_media_description(belle_sdp_session_description_t* session_description, belle_sdp_media_description_t* media_description);
BELLESIP_EXPORT void belle_sdp_session_description_set_origin(belle_sdp_session_description_t* session_description, belle_sdp_origin_t* origin);
BELLESIP_EXPORT void belle_sdp_session_description_set_phones(belle_sdp_session_description_t* session_description, belle_sip_list_t* phones);
BELLESIP_EXPORT void belle_sdp_session_description_set_session_name(belle_sdp_session_description_t* session_description, belle_sdp_session_name_t* sessionName);
BELLESIP_EXPORT void belle_sdp_session_description_set_time_descriptions(belle_sdp_session_description_t* session_description, belle_sip_list_t* times);
BELLESIP_EXPORT void belle_sdp_session_description_set_time_description(belle_sdp_session_description_t* session_description, belle_sdp_time_description_t* time_desc);
BELLESIP_EXPORT void belle_sdp_session_description_set_uri(belle_sdp_session_description_t* session_description, belle_sdp_uri_t* uri);
BELLESIP_EXPORT void belle_sdp_session_description_set_version(belle_sdp_session_description_t* session_description, belle_sdp_version_t* v);
BELLESIP_EXPORT void belle_sdp_session_description_set_zone_adjustments(belle_sdp_session_description_t* session_description, belle_sdp_uri_t* zoneAdjustments);

BELLESIP_EXPORT void belle_sdp_session_description_add_attribute_holder(belle_sdp_session_description_t* session_description, belle_sdp_attribute_holder_t *holder);

#define BELLE_SDP_SESSION_DESCRIPTION(t) BELLE_SDP_CAST(t,belle_sdp_session_description_t)

BELLE_SIP_END_DECLS
#endif /* BELLE_SDP_H_ */
