/* $Id: endpoint.cpp 4704 2014-01-16 05:30:46Z ming $ */
/* 
 * Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
 *
 * 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 2 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, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */
#include <pjsua2/endpoint.hpp>
#include <pjsua2/account.hpp>
#include <pjsua2/call.hpp>
#include <pjsua2/presence.hpp>
#include <algorithm>
#include "util.hpp"

using namespace pj;
using namespace std;

#include <pjsua2/account.hpp>
#include <pjsua2/call.hpp>

#define THIS_FILE		"endpoint.cpp"
#define MAX_STUN_SERVERS	32
#define TIMER_SIGNATURE		0x600D878A
#define MAX_CODEC_NUM 		64

struct UserTimer
{
    pj_uint32_t		signature;
    OnTimerParam	prm;
    pj_timer_entry	entry;
};

Endpoint *Endpoint::instance_;

///////////////////////////////////////////////////////////////////////////////

UaConfig::UaConfig()
{
    pjsua_config ua_cfg;

    pjsua_config_default(&ua_cfg);
    fromPj(ua_cfg);
}

void UaConfig::fromPj(const pjsua_config &ua_cfg)
{
    unsigned i;

    this->maxCalls = ua_cfg.max_calls;
    this->threadCnt = ua_cfg.thread_cnt;
    this->userAgent = pj2Str(ua_cfg.user_agent);

    for (i=0; i<ua_cfg.nameserver_count; ++i) {
	this->nameserver.push_back(pj2Str(ua_cfg.nameserver[i]));
    }

    for (i=0; i<ua_cfg.stun_srv_cnt; ++i) {
	this->stunServer.push_back(pj2Str(ua_cfg.stun_srv[i]));
    }

    this->stunIgnoreFailure = PJ2BOOL(ua_cfg.stun_ignore_failure);
    this->natTypeInSdp = ua_cfg.nat_type_in_sdp;
    this->mwiUnsolicitedEnabled = PJ2BOOL(ua_cfg.enable_unsolicited_mwi);
}

pjsua_config UaConfig::toPj() const
{
    unsigned i;
    pjsua_config pua_cfg;

    pjsua_config_default(&pua_cfg);

    pua_cfg.max_calls = this->maxCalls;
    pua_cfg.thread_cnt = this->threadCnt;
    pua_cfg.user_agent = str2Pj(this->userAgent);

    for (i=0; i<this->nameserver.size() && i<PJ_ARRAY_SIZE(pua_cfg.nameserver);
	 ++i)
    {
	pua_cfg.nameserver[i] = str2Pj(this->nameserver[i]);
    }
    pua_cfg.nameserver_count = i;

    for (i=0; i<this->stunServer.size() && i<PJ_ARRAY_SIZE(pua_cfg.stun_srv);
	 ++i)
    {
	pua_cfg.stun_srv[i] = str2Pj(this->stunServer[i]);
    }
    pua_cfg.stun_srv_cnt = i;

    pua_cfg.nat_type_in_sdp = this->natTypeInSdp;
    pua_cfg.enable_unsolicited_mwi = this->mwiUnsolicitedEnabled;

    return pua_cfg;
}

void UaConfig::readObject(const ContainerNode &node) throw(Error)
{
    ContainerNode this_node = node.readContainer("UaConfig");

    NODE_READ_UNSIGNED( this_node, maxCalls);
    NODE_READ_UNSIGNED( this_node, threadCnt);
    NODE_READ_BOOL    ( this_node, mainThreadOnly);
    NODE_READ_STRINGV ( this_node, nameserver);
    NODE_READ_STRING  ( this_node, userAgent);
    NODE_READ_STRINGV ( this_node, stunServer);
    NODE_READ_BOOL    ( this_node, stunIgnoreFailure);
    NODE_READ_INT     ( this_node, natTypeInSdp);
    NODE_READ_BOOL    ( this_node, mwiUnsolicitedEnabled);
}

void UaConfig::writeObject(ContainerNode &node) const throw(Error)
{
    ContainerNode this_node = node.writeNewContainer("UaConfig");

    NODE_WRITE_UNSIGNED( this_node, maxCalls);
    NODE_WRITE_UNSIGNED( this_node, threadCnt);
    NODE_WRITE_BOOL    ( this_node, mainThreadOnly);
    NODE_WRITE_STRINGV ( this_node, nameserver);
    NODE_WRITE_STRING  ( this_node, userAgent);
    NODE_WRITE_STRINGV ( this_node, stunServer);
    NODE_WRITE_BOOL    ( this_node, stunIgnoreFailure);
    NODE_WRITE_INT     ( this_node, natTypeInSdp);
    NODE_WRITE_BOOL    ( this_node, mwiUnsolicitedEnabled);
}

///////////////////////////////////////////////////////////////////////////////

LogConfig::LogConfig()
{
    pjsua_logging_config lc;

    pjsua_logging_config_default(&lc);
    fromPj(lc);
}

void LogConfig::fromPj(const pjsua_logging_config &lc)
{
    this->msgLogging = lc.msg_logging;
    this->level = lc.level;
    this->consoleLevel = lc.console_level;
    this->decor = lc.decor;
    this->filename = pj2Str(lc.log_filename);
    this->fileFlags = lc.log_file_flags;
    this->writer = NULL;
}

pjsua_logging_config LogConfig::toPj() const
{
    pjsua_logging_config lc;

    pjsua_logging_config_default(&lc);

    lc.msg_logging = this->msgLogging;
    lc.level = this->level;
    lc.console_level = this->consoleLevel;
    lc.decor = this->decor;
    lc.log_file_flags = this->fileFlags;
    lc.log_filename = str2Pj(this->filename);

    return lc;
}

void LogConfig::readObject(const ContainerNode &node) throw(Error)
{
    ContainerNode this_node = node.readContainer("LogConfig");

    NODE_READ_UNSIGNED( this_node, msgLogging);
    NODE_READ_UNSIGNED( this_node, level);
    NODE_READ_UNSIGNED( this_node, consoleLevel);
    NODE_READ_UNSIGNED( this_node, decor);
    NODE_READ_STRING  ( this_node, filename);
    NODE_READ_UNSIGNED( this_node, fileFlags);
}

void LogConfig::writeObject(ContainerNode &node) const throw(Error)
{
    ContainerNode this_node = node.writeNewContainer("LogConfig");

    NODE_WRITE_UNSIGNED( this_node, msgLogging);
    NODE_WRITE_UNSIGNED( this_node, level);
    NODE_WRITE_UNSIGNED( this_node, consoleLevel);
    NODE_WRITE_UNSIGNED( this_node, decor);
    NODE_WRITE_STRING  ( this_node, filename);
    NODE_WRITE_UNSIGNED( this_node, fileFlags);
}

///////////////////////////////////////////////////////////////////////////////

MediaConfig::MediaConfig()
{
    pjsua_media_config mc;

    pjsua_media_config_default(&mc);
    fromPj(mc);
}

void MediaConfig::fromPj(const pjsua_media_config &mc)
{
    this->clockRate = mc.clock_rate;
    this->sndClockRate = mc.snd_clock_rate;
    this->channelCount = mc.channel_count;
    this->audioFramePtime = mc.audio_frame_ptime;
    this->maxMediaPorts = mc.max_media_ports;
    this->hasIoqueue = PJ2BOOL(mc.has_ioqueue);
    this->threadCnt = mc.thread_cnt;
    this->quality = mc.quality;
    this->ptime = mc.ptime;
    this->noVad = PJ2BOOL(mc.no_vad);
    this->ilbcMode = mc.ilbc_mode;
    this->txDropPct = mc.tx_drop_pct;
    this->rxDropPct = mc.rx_drop_pct;
    this->ecOptions = mc.ec_options;
    this->ecTailLen = mc.ec_tail_len;
    this->sndRecLatency = mc.snd_rec_latency;
    this->sndPlayLatency = mc.snd_play_latency;
    this->jbInit = mc.jb_init;
    this->jbMinPre = mc.jb_min_pre;
    this->jbMaxPre = mc.jb_max_pre;
    this->jbMax = mc.jb_max;
    this->sndAutoCloseTime = mc.snd_auto_close_time;
    this->vidPreviewEnableNative = PJ2BOOL(mc.vid_preview_enable_native);
}

pjsua_media_config MediaConfig::toPj() const
{
    pjsua_media_config mcfg;

    pjsua_media_config_default(&mcfg);

    mcfg.clock_rate = this->clockRate;
    mcfg.snd_clock_rate = this->sndClockRate;
    mcfg.channel_count = this->channelCount;
    mcfg.audio_frame_ptime = this->audioFramePtime;
    mcfg.max_media_ports = this->maxMediaPorts;
    mcfg.has_ioqueue = this->hasIoqueue;
    mcfg.thread_cnt = this->threadCnt;
    mcfg.quality = this->quality;
    mcfg.ptime = this->ptime;
    mcfg.no_vad = this->noVad;
    mcfg.ilbc_mode = this->ilbcMode;
    mcfg.tx_drop_pct = this->txDropPct;
    mcfg.rx_drop_pct = this->rxDropPct;
    mcfg.ec_options = this->ecOptions;
    mcfg.ec_tail_len = this->ecTailLen;
    mcfg.snd_rec_latency = this->sndRecLatency;
    mcfg.snd_play_latency = this->sndPlayLatency;
    mcfg.jb_init = this->jbInit;
    mcfg.jb_min_pre = this->jbMinPre;
    mcfg.jb_max_pre = this->jbMaxPre;
    mcfg.jb_max = this->jbMax;
    mcfg.snd_auto_close_time = this->sndAutoCloseTime;
    mcfg.vid_preview_enable_native = this->vidPreviewEnableNative;

    return mcfg;
}

void MediaConfig::readObject(const ContainerNode &node) throw(Error)
{
    ContainerNode this_node = node.readContainer("MediaConfig");

    NODE_READ_UNSIGNED( this_node, clockRate);
    NODE_READ_UNSIGNED( this_node, sndClockRate);
    NODE_READ_UNSIGNED( this_node, channelCount);
    NODE_READ_UNSIGNED( this_node, audioFramePtime);
    NODE_READ_UNSIGNED( this_node, maxMediaPorts);
    NODE_READ_BOOL    ( this_node, hasIoqueue);
    NODE_READ_UNSIGNED( this_node, threadCnt);
    NODE_READ_UNSIGNED( this_node, quality);
    NODE_READ_UNSIGNED( this_node, ptime);
    NODE_READ_BOOL    ( this_node, noVad);
    NODE_READ_UNSIGNED( this_node, ilbcMode);
    NODE_READ_UNSIGNED( this_node, txDropPct);
    NODE_READ_UNSIGNED( this_node, rxDropPct);
    NODE_READ_UNSIGNED( this_node, ecOptions);
    NODE_READ_UNSIGNED( this_node, ecTailLen);
    NODE_READ_UNSIGNED( this_node, sndRecLatency);
    NODE_READ_UNSIGNED( this_node, sndPlayLatency);
    NODE_READ_INT     ( this_node, jbInit);
    NODE_READ_INT     ( this_node, jbMinPre);
    NODE_READ_INT     ( this_node, jbMaxPre);
    NODE_READ_INT     ( this_node, jbMax);
    NODE_READ_INT     ( this_node, sndAutoCloseTime);
    NODE_READ_BOOL    ( this_node, vidPreviewEnableNative);
}

void MediaConfig::writeObject(ContainerNode &node) const throw(Error)
{
    ContainerNode this_node = node.writeNewContainer("MediaConfig");

    NODE_WRITE_UNSIGNED( this_node, clockRate);
    NODE_WRITE_UNSIGNED( this_node, sndClockRate);
    NODE_WRITE_UNSIGNED( this_node, channelCount);
    NODE_WRITE_UNSIGNED( this_node, audioFramePtime);
    NODE_WRITE_UNSIGNED( this_node, maxMediaPorts);
    NODE_WRITE_BOOL    ( this_node, hasIoqueue);
    NODE_WRITE_UNSIGNED( this_node, threadCnt);
    NODE_WRITE_UNSIGNED( this_node, quality);
    NODE_WRITE_UNSIGNED( this_node, ptime);
    NODE_WRITE_BOOL    ( this_node, noVad);
    NODE_WRITE_UNSIGNED( this_node, ilbcMode);
    NODE_WRITE_UNSIGNED( this_node, txDropPct);
    NODE_WRITE_UNSIGNED( this_node, rxDropPct);
    NODE_WRITE_UNSIGNED( this_node, ecOptions);
    NODE_WRITE_UNSIGNED( this_node, ecTailLen);
    NODE_WRITE_UNSIGNED( this_node, sndRecLatency);
    NODE_WRITE_UNSIGNED( this_node, sndPlayLatency);
    NODE_WRITE_INT     ( this_node, jbInit);
    NODE_WRITE_INT     ( this_node, jbMinPre);
    NODE_WRITE_INT     ( this_node, jbMaxPre);
    NODE_WRITE_INT     ( this_node, jbMax);
    NODE_WRITE_INT     ( this_node, sndAutoCloseTime);
    NODE_WRITE_BOOL    ( this_node, vidPreviewEnableNative);
}

///////////////////////////////////////////////////////////////////////////////

void EpConfig::readObject(const ContainerNode &node) throw(Error)
{
    ContainerNode this_node = node.readContainer("EpConfig");
    NODE_READ_OBJ( this_node, uaConfig);
    NODE_READ_OBJ( this_node, logConfig);
    NODE_READ_OBJ( this_node, medConfig);
}

void EpConfig::writeObject(ContainerNode &node) const throw(Error)
{
    ContainerNode this_node = node.writeNewContainer("EpConfig");
    NODE_WRITE_OBJ( this_node, uaConfig);
    NODE_WRITE_OBJ( this_node, logConfig);
    NODE_WRITE_OBJ( this_node, medConfig);
}

///////////////////////////////////////////////////////////////////////////////
/* Class to post log to main thread */
struct PendingLog : public PendingJob
{
    LogEntry entry;
    virtual void execute(bool is_pending)
    {
	PJ_UNUSED_ARG(is_pending);
	Endpoint::instance().utilLogWrite(entry);
    }
};

///////////////////////////////////////////////////////////////////////////////
/*
 * Endpoint instance
 */
Endpoint::Endpoint()
: writer(NULL), mainThreadOnly(false), mainThread(NULL), pendingJobSize(0)
{
    if (instance_) {
	PJSUA2_RAISE_ERROR(PJ_EEXISTS);
    }

    instance_ = this;
}

Endpoint& Endpoint::instance() throw(Error)
{
    if (!instance_) {
	PJSUA2_RAISE_ERROR(PJ_ENOTFOUND);
    }
    return *instance_;
}

Endpoint::~Endpoint()
{
    while (!pendingJobs.empty()) {
	delete pendingJobs.front();
	pendingJobs.pop_front();
    }

    while(mediaList.size() > 0) {
	AudioMedia *cur_media = mediaList[0];
	delete cur_media; /* this will remove itself from the list */
    }

    clearCodecInfoList();

    try {
	libDestroy();
    } catch (Error &err) {
	// Ignore
	PJ_UNUSED_ARG(err);
    }

    instance_ = NULL;
}

void Endpoint::utilAddPendingJob(PendingJob *job)
{
    enum {
	MAX_PENDING_JOBS = 1024
    };

    /* See if we can execute immediately */
    if (!mainThreadOnly || pj_thread_this()==mainThread) {
	job->execute(false);
	delete job;
	return;
    }

    if (pendingJobSize > MAX_PENDING_JOBS) {
	enum { NUMBER_TO_DISCARD = 5 };

	pj_enter_critical_section();
	for (unsigned i=0; i<NUMBER_TO_DISCARD; ++i) {
	    delete pendingJobs.back();
	    pendingJobs.pop_back();
	}

	pendingJobSize -= NUMBER_TO_DISCARD;
	pj_leave_critical_section();

	utilLogWrite(1, THIS_FILE,
	             "*** ERROR: Job queue full!! Jobs discarded!!! ***");
    }

    pj_enter_critical_section();
    pendingJobs.push_back(job);
    pendingJobSize++;
    pj_leave_critical_section();
}

/* Handle log callback */
void Endpoint::utilLogWrite(LogEntry &entry)
{
    if (mainThreadOnly && pj_thread_this() != mainThread) {
	PendingLog *job = new PendingLog;
	job->entry = entry;
	utilAddPendingJob(job);
    } else {
	writer->write(entry);
    }
}

/* Run pending jobs only in main thread */
void Endpoint::performPendingJobs()
{
    if (pj_thread_this() != mainThread)
	return;

    if (pendingJobSize == 0)
	return;

    for (;;) {
	PendingJob *job = NULL;

	pj_enter_critical_section();
	if (pendingJobSize != 0) {
	    job = pendingJobs.front();
	    pendingJobs.pop_front();
	    pendingJobSize--;
	}
	pj_leave_critical_section();

	if (job) {
	    job->execute(true);
	    delete job;
	} else
	    break;
    }
}

///////////////////////////////////////////////////////////////////////////////
/*
 * Endpoint static callbacks
 */
void Endpoint::logFunc(int level, const char *data, int len)
{
    Endpoint &ep = Endpoint::instance();

    if (!ep.writer)
	return;

    LogEntry entry;
    entry.level = level;
    entry.msg = string(data, len);
    entry.threadId = (long)pj_thread_this();
    entry.threadName = string(pj_thread_get_name(pj_thread_this()));

    ep.utilLogWrite(entry);
}

void Endpoint::stun_resolve_cb(const pj_stun_resolve_result *res)
{
    Endpoint &ep = Endpoint::instance();

    if (!res)
	return;

    OnNatCheckStunServersCompleteParam prm;

    prm.userData = res->token;
    prm.status = res->status;
    if (res->status == PJ_SUCCESS) {
	char straddr[PJ_INET6_ADDRSTRLEN+10];

	prm.name = string(res->name.ptr, res->name.slen);
	pj_sockaddr_print(&res->addr, straddr, sizeof(straddr), 3);
	prm.addr = straddr;
    }

    ep.onNatCheckStunServersComplete(prm);
}

void Endpoint::on_timer(pj_timer_heap_t *timer_heap,
                        pj_timer_entry *entry)
{
    PJ_UNUSED_ARG(timer_heap);

    Endpoint &ep = Endpoint::instance();
    UserTimer *ut = (UserTimer*) entry->user_data;

    if (ut->signature != TIMER_SIGNATURE)
	return;

    ep.onTimer(ut->prm);
}

void Endpoint::on_nat_detect(const pj_stun_nat_detect_result *res)
{
    Endpoint &ep = Endpoint::instance();

    if (!res)
	return;

    OnNatDetectionCompleteParam prm;

    prm.status = res->status;
    prm.reason = res->status_text;
    prm.natType = res->nat_type;
    prm.natTypeName = res->nat_type_name;

    ep.onNatDetectionComplete(prm);
}

void Endpoint::on_transport_state( pjsip_transport *tp,
				   pjsip_transport_state state,
				   const pjsip_transport_state_info *info)
{
    Endpoint &ep = Endpoint::instance();

    OnTransportStateParam prm;

    prm.hnd = (TransportHandle)tp;
    prm.state = state;
    prm.lastError = info ? info->status : PJ_SUCCESS;

    ep.onTransportState(prm);
}

///////////////////////////////////////////////////////////////////////////////
/*
 * Account static callbacks
 */

Account *Endpoint::lookupAcc(int acc_id, const char *op)
{
    Account *acc = Account::lookup(acc_id);
    if (!acc) {
	PJ_LOG(1,(THIS_FILE,
		  "Error: cannot find Account instance for account id %d in "
		  "%s", acc_id, op));
    }

    return acc;
}

Call *Endpoint::lookupCall(int call_id, const char *op)
{
    Call *call = Call::lookup(call_id);
    if (!call) {
	PJ_LOG(1,(THIS_FILE,
		  "Error: cannot find Call instance for call id %d in "
		  "%s", call_id, op));
    }

    return call;
}

void Endpoint::on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id,
                                pjsip_rx_data *rdata)
{
    Account *acc = lookupAcc(acc_id, "on_incoming_call()");
    if (!acc) {
	pjsua_call_hangup(call_id, PJSIP_SC_INTERNAL_SERVER_ERROR, NULL, NULL);
	return;
    }

    /* call callback */
    OnIncomingCallParam prm;
    prm.callId = call_id;
    prm.rdata.fromPj(*rdata);

    acc->onIncomingCall(prm);

    /* disconnect if callback doesn't handle the call */
    pjsua_call_info ci;

    pjsua_call_get_info(call_id, &ci);
    if (!pjsua_call_get_user_data(call_id) &&
	ci.state != PJSIP_INV_STATE_DISCONNECTED)
    {
	pjsua_call_hangup(call_id, PJSIP_SC_INTERNAL_SERVER_ERROR, NULL, NULL);
    }
}

void Endpoint::on_reg_started(pjsua_acc_id acc_id, pj_bool_t renew)
{
    Account *acc = lookupAcc(acc_id, "on_reg_started()");
    if (!acc) {
	return;
    }

    OnRegStartedParam prm;
    prm.renew = PJ2BOOL(renew);
    acc->onRegStarted(prm);
}

void Endpoint::on_reg_state2(pjsua_acc_id acc_id, pjsua_reg_info *info)
{
    Account *acc = lookupAcc(acc_id, "on_reg_state2()");
    if (!acc) {
	return;
    }

    OnRegStateParam prm;
    prm.status		= info->cbparam->status;
    prm.code 		= (pjsip_status_code) info->cbparam->code;
    prm.reason		= pj2Str(info->cbparam->reason);
    if (info->cbparam->rdata)
	prm.rdata.fromPj(*info->cbparam->rdata);
    prm.expiration	= info->cbparam->expiration;

    acc->onRegState(prm);
}

void Endpoint::on_incoming_subscribe(pjsua_acc_id acc_id,
                                     pjsua_srv_pres *srv_pres,
                                     pjsua_buddy_id buddy_id,
                                     const pj_str_t *from,
                                     pjsip_rx_data *rdata,
                                     pjsip_status_code *code,
                                     pj_str_t *reason,
                                     pjsua_msg_data *msg_data)
{
    PJ_UNUSED_ARG(buddy_id);
    PJ_UNUSED_ARG(srv_pres);

    Account *acc = lookupAcc(acc_id, "on_incoming_subscribe()");
    if (!acc) {
	/* default behavior should apply */
	return;
    }

    OnIncomingSubscribeParam prm;
    prm.srvPres		= srv_pres;
    prm.fromUri 	= pj2Str(*from);
    prm.rdata.fromPj(*rdata);
    prm.code		= *code;
    prm.reason		= pj2Str(*reason);
    prm.txOption.fromPj(*msg_data);

    acc->onIncomingSubscribe(prm);

    *code = prm.code;
    acc->tmpReason = prm.reason;
    *reason = str2Pj(acc->tmpReason);
    prm.txOption.toPj(*msg_data);
}

void Endpoint::on_pager2(pjsua_call_id call_id,
                         const pj_str_t *from,
                         const pj_str_t *to,
                         const pj_str_t *contact,
                         const pj_str_t *mime_type,
                         const pj_str_t *body,
                         pjsip_rx_data *rdata,
                         pjsua_acc_id acc_id)
{
    OnInstantMessageParam prm;
    prm.fromUri		= pj2Str(*from);
    prm.toUri		= pj2Str(*to);
    prm.contactUri	= pj2Str(*contact);
    prm.contentType	= pj2Str(*mime_type);
    prm.msgBody		= pj2Str(*body);
    prm.rdata.fromPj(*rdata);

    if (call_id != PJSUA_INVALID_ID) {
	Call *call = lookupCall(call_id, "on_pager2()");
	if (!call) {
	    /* Ignored */
	    return;
	}

	call->onInstantMessage(prm);
    } else {
	Account *acc = lookupAcc(acc_id, "on_pager2()");
	if (!acc) {
	    /* Ignored */
	    return;
	}

	acc->onInstantMessage(prm);
    }
}

void Endpoint::on_pager_status2( pjsua_call_id call_id,
				 const pj_str_t *to,
				 const pj_str_t *body,
				 void *user_data,
				 pjsip_status_code status,
				 const pj_str_t *reason,
				 pjsip_tx_data *tdata,
				 pjsip_rx_data *rdata,
				 pjsua_acc_id acc_id)
{
    PJ_UNUSED_ARG(tdata);

    OnInstantMessageStatusParam prm;
    prm.userData	= user_data;
    prm.toUri		= pj2Str(*to);
    prm.msgBody		= pj2Str(*body);
    prm.code		= status;
    prm.reason		= pj2Str(*reason);
    if (rdata)
	prm.rdata.fromPj(*rdata);

    if (call_id != PJSUA_INVALID_ID) {
	Call *call = lookupCall(call_id, "on_pager_status2()");
	if (!call) {
	    /* Ignored */
	    return;
	}

	call->onInstantMessageStatus(prm);
    } else {
	Account *acc = lookupAcc(acc_id, "on_pager_status2()");
	if (!acc) {
	    /* Ignored */
	    return;
	}

	acc->onInstantMessageStatus(prm);
    }
}

void Endpoint::on_typing2( pjsua_call_id call_id,
			   const pj_str_t *from,
			   const pj_str_t *to,
			   const pj_str_t *contact,
			   pj_bool_t is_typing,
			   pjsip_rx_data *rdata,
			   pjsua_acc_id acc_id)
{
    OnTypingIndicationParam prm;
    prm.fromUri		= pj2Str(*from);
    prm.toUri		= pj2Str(*to);
    prm.contactUri	= pj2Str(*contact);
    prm.isTyping	= is_typing != 0;
    prm.rdata.fromPj(*rdata);

    if (call_id != PJSUA_INVALID_ID) {
	Call *call = lookupCall(call_id, "on_typing2()");
	if (!call) {
	    /* Ignored */
	    return;
	}

	call->onTypingIndication(prm);
    } else {
	Account *acc = lookupAcc(acc_id, "on_typing2()");
	if (!acc) {
	    /* Ignored */
	    return;
	}

	acc->onTypingIndication(prm);
    }
}

void Endpoint::on_mwi_info(pjsua_acc_id acc_id,
                           pjsua_mwi_info *mwi_info)
{
    OnMwiInfoParam prm;
    prm.state	= pjsip_evsub_get_state(mwi_info->evsub);
    prm.rdata.fromPj(*mwi_info->rdata);

    Account *acc = lookupAcc(acc_id, "on_mwi_info()");
    if (!acc) {
	/* Ignored */
	return;
    }

    acc->onMwiInfo(prm);
}

void Endpoint::on_buddy_state(pjsua_buddy_id buddy_id)
{
    Buddy *buddy = (Buddy*)pjsua_buddy_get_user_data(buddy_id);
    if (!buddy || !buddy->isValid()) {
	/* Ignored */
	return;
    }

    buddy->onBuddyState();
}

// Call callbacks
void Endpoint::on_call_state(pjsua_call_id call_id, pjsip_event *e)
{
    Call *call = Call::lookup(call_id);
    if (!call) {
	return;
    }
    
    OnCallStateParam prm;
    prm.e.fromPj(*e);
    
    call->processStateChange(prm);
    /* If the state is DISCONNECTED, call may have already been deleted
     * by the application in the callback, so do not access it anymore here.
     */
}

void Endpoint::on_call_tsx_state(pjsua_call_id call_id,
                                 pjsip_transaction *tsx,
                                 pjsip_event *e)
{
    PJ_UNUSED_ARG(tsx);

    Call *call = Call::lookup(call_id);
    if (!call) {
	return;
    }
    
    OnCallTsxStateParam prm;
    prm.e.fromPj(*e);
    
    call->onCallTsxState(prm);
}

void Endpoint::on_call_media_state(pjsua_call_id call_id)
{
    Call *call = Call::lookup(call_id);
    if (!call) {
	return;
    }

    OnCallMediaStateParam prm;
    call->processMediaUpdate(prm);
}

void Endpoint::on_call_sdp_created(pjsua_call_id call_id,
                                   pjmedia_sdp_session *sdp,
                                   pj_pool_t *pool,
                                   const pjmedia_sdp_session *rem_sdp)
{
    Call *call = Call::lookup(call_id);
    if (!call) {
	return;
    }
    
    OnCallSdpCreatedParam prm;
    string orig_sdp;
    
    prm.sdp.fromPj(*sdp);
    orig_sdp = prm.sdp.wholeSdp;
    if (rem_sdp)
        prm.remSdp.fromPj(*rem_sdp);
    
    call->onCallSdpCreated(prm);
    
    /* Check if application modifies the SDP */
    if (orig_sdp != prm.sdp.wholeSdp) {
        pjmedia_sdp_parse(pool, (char*)prm.sdp.wholeSdp.c_str(),
                          prm.sdp.wholeSdp.size(), &sdp);
    }
}

void Endpoint::on_stream_created(pjsua_call_id call_id,
                                 pjmedia_stream *strm,
                                 unsigned stream_idx,
                                 pjmedia_port **p_port)
{
    Call *call = Call::lookup(call_id);
    if (!call) {
	return;
    }
    
    OnStreamCreatedParam prm;
    prm.stream = strm;
    prm.streamIdx = stream_idx;
    prm.pPort = (void *)*p_port;
    
    call->onStreamCreated(prm);
    
    if (prm.pPort != (void *)*p_port)
        *p_port = (pjmedia_port *)prm.pPort;
}

void Endpoint::on_stream_destroyed(pjsua_call_id call_id,
                                   pjmedia_stream *strm,
                                   unsigned stream_idx)
{
    Call *call = Call::lookup(call_id);
    if (!call) {
	return;
    }
    
    OnStreamDestroyedParam prm;
    prm.stream = strm;
    prm.streamIdx = stream_idx;
    
    call->onStreamDestroyed(prm);
}

struct PendingOnDtmfDigitCallback : public PendingJob
{
    int call_id;
    OnDtmfDigitParam prm;

    virtual void execute(bool is_pending)
    {
	PJ_UNUSED_ARG(is_pending);

	Call *call = Call::lookup(call_id);
	if (!call)
	    return;

	call->onDtmfDigit(prm);
    }
};

void Endpoint::on_dtmf_digit(pjsua_call_id call_id, int digit)
{
    Call *call = Call::lookup(call_id);
    if (!call) {
	return;
    }
    
    PendingOnDtmfDigitCallback *job = new PendingOnDtmfDigitCallback;
    job->call_id = call_id;
    char buf[10];
    pj_ansi_sprintf(buf, "%c", digit);
    job->prm.digit = (string)buf;
    
    Endpoint::instance().utilAddPendingJob(job);
}

void Endpoint::on_call_transfer_request2(pjsua_call_id call_id,
                                         const pj_str_t *dst,
                                         pjsip_status_code *code,
                                         pjsua_call_setting *opt)
{
    Call *call = Call::lookup(call_id);
    if (!call) {
	return;
    }
    
    OnCallTransferRequestParam prm;
    prm.dstUri = pj2Str(*dst);
    prm.statusCode = *code;
    prm.opt.fromPj(*opt);
    
    call->onCallTransferRequest(prm);
    
    *code = prm.statusCode;
    *opt = prm.opt.toPj();
}

void Endpoint::on_call_transfer_status(pjsua_call_id call_id,
                                       int st_code,
                                       const pj_str_t *st_text,
                                       pj_bool_t final,
                                       pj_bool_t *p_cont)
{
    Call *call = Call::lookup(call_id);
    if (!call) {
	return;
    }
    
    OnCallTransferStatusParam prm;
    prm.statusCode = (pjsip_status_code)st_code;
    prm.reason = pj2Str(*st_text);
    prm.finalNotify = PJ2BOOL(final);
    prm.cont = PJ2BOOL(*p_cont);
    
    call->onCallTransferStatus(prm);
    
    *p_cont = prm.cont;
}

void Endpoint::on_call_replace_request2(pjsua_call_id call_id,
                                        pjsip_rx_data *rdata,
                                        int *st_code,
                                        pj_str_t *st_text,
                                        pjsua_call_setting *opt)
{
    Call *call = Call::lookup(call_id);
    if (!call) {
	return;
    }
    
    OnCallReplaceRequestParam prm;
    prm.rdata.fromPj(*rdata);
    prm.statusCode = (pjsip_status_code)*st_code;
    prm.reason = pj2Str(*st_text);
    prm.opt.fromPj(*opt);
    
    call->onCallReplaceRequest(prm);
    
    *st_code = prm.statusCode;
    *st_text = str2Pj(prm.reason);
    *opt = prm.opt.toPj();
}

void Endpoint::on_call_replaced(pjsua_call_id old_call_id,
                                pjsua_call_id new_call_id)
{
    Call *call = Call::lookup(old_call_id);
    if (!call) {
	return;
    }
    
    OnCallReplacedParam prm;
    prm.newCallId = new_call_id;
    
    call->onCallReplaced(prm);
}

void Endpoint::on_call_rx_offer(pjsua_call_id call_id,
                                const pjmedia_sdp_session *offer,
                                void *reserved,
                                pjsip_status_code *code,
                                pjsua_call_setting *opt)
{
    PJ_UNUSED_ARG(reserved);

    Call *call = Call::lookup(call_id);
    if (!call) {
	return;
    }
    
    OnCallRxOfferParam prm;
    prm.offer.fromPj(*offer);
    prm.statusCode = *code;
    prm.opt.fromPj(*opt);
    
    call->onCallRxOffer(prm);
    
    *code = prm.statusCode;
    *opt = prm.opt.toPj();
}

pjsip_redirect_op Endpoint::on_call_redirected(pjsua_call_id call_id,
                                               const pjsip_uri *target,
                                               const pjsip_event *e)
{
    Call *call = Call::lookup(call_id);
    if (!call) {
	return PJSIP_REDIRECT_STOP;
    }
    
    OnCallRedirectedParam prm;
    char uristr[PJSIP_MAX_URL_SIZE];
    int len = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, target, uristr,
                              sizeof(uristr));
    if (len < 1) {
        pj_ansi_strcpy(uristr, "--URI too long--");
    }
    prm.targetUri = string(uristr);
    if (e)
        prm.e.fromPj(*e);
    else
        prm.e.type = PJSIP_EVENT_UNKNOWN;
    
    return call->onCallRedirected(prm);
}


struct PendingOnMediaTransportCallback : public PendingJob
{
    int call_id;
    OnCallMediaTransportStateParam prm;

    virtual void execute(bool is_pending)
    {
	PJ_UNUSED_ARG(is_pending);

	Call *call = Call::lookup(call_id);
	if (!call)
	    return;

	call->onCallMediaTransportState(prm);
    }
};

pj_status_t
Endpoint::on_call_media_transport_state(pjsua_call_id call_id,
                                        const pjsua_med_tp_state_info *info)
{
    Call *call = Call::lookup(call_id);
    if (!call) {
	return PJ_SUCCESS;
    }

    PendingOnMediaTransportCallback *job = new PendingOnMediaTransportCallback;
    
    job->call_id = call_id;
    job->prm.medIdx = info->med_idx;
    job->prm.state = info->state;
    job->prm.status = info->status;
    job->prm.sipErrorCode = info->sip_err_code;
    
    Endpoint::instance().utilAddPendingJob(job);

    return PJ_SUCCESS;
}

struct PendingOnMediaEventCallback : public PendingJob
{
    int call_id;
    OnCallMediaEventParam prm;

    virtual void execute(bool is_pending)
    {
	Call *call = Call::lookup(call_id);
	if (!call)
	    return;

	if (is_pending) {
	    /* Can't do this anymore, pointer is invalid */
	    prm.ev.pjMediaEvent = NULL;
	}

	call->onCallMediaEvent(prm);
    }
};

void Endpoint::on_call_media_event(pjsua_call_id call_id,
                                   unsigned med_idx,
                                   pjmedia_event *event)
{
    Call *call = Call::lookup(call_id);
    if (!call) {
	return;
    }
    
    PendingOnMediaEventCallback *job = new PendingOnMediaEventCallback;

    job->call_id = call_id;
    job->prm.medIdx = med_idx;
    job->prm.ev.fromPj(*event);
    
    Endpoint::instance().utilAddPendingJob(job);
}

pjmedia_transport*
Endpoint::on_create_media_transport(pjsua_call_id call_id,
                                    unsigned media_idx,
                                    pjmedia_transport *base_tp,
                                    unsigned flags)
{
    Call *call = Call::lookup(call_id);
    if (!call) {
	return base_tp;
    }
    
    OnCreateMediaTransportParam prm;
    prm.mediaIdx = media_idx;
    prm.mediaTp = base_tp;
    prm.flags = flags;
    
    call->onCreateMediaTransport(prm);
    
    return (pjmedia_transport *)prm.mediaTp;
}

///////////////////////////////////////////////////////////////////////////////
/*
 * Endpoint library operations
 */
Version Endpoint::libVersion() const
{
    Version ver;
    ver.major = PJ_VERSION_NUM_MAJOR;
    ver.minor = PJ_VERSION_NUM_MINOR;
    ver.rev = PJ_VERSION_NUM_REV;
    ver.suffix = PJ_VERSION_NUM_EXTRA;
    ver.full = pj_get_version();
    ver.numeric = PJ_VERSION_NUM;
    return ver;
}

void Endpoint::libCreate() throw(Error)
{
    PJSUA2_CHECK_EXPR( pjsua_create() );
    mainThread = pj_thread_this();
}

pjsua_state Endpoint::libGetState() const
{
    return pjsua_get_state();
}

void Endpoint::libInit(const EpConfig &prmEpConfig) throw(Error)
{
    pjsua_config ua_cfg;
    pjsua_logging_config log_cfg;
    pjsua_media_config med_cfg;

    ua_cfg = prmEpConfig.uaConfig.toPj();
    log_cfg = prmEpConfig.logConfig.toPj();
    med_cfg = prmEpConfig.medConfig.toPj();

    /* Setup log callback */
    if (prmEpConfig.logConfig.writer) {
	this->writer = prmEpConfig.logConfig.writer;
	log_cfg.cb = &Endpoint::logFunc;
    }
    mainThreadOnly = prmEpConfig.uaConfig.mainThreadOnly;

    /* Setup UA callbacks */
    pj_bzero(&ua_cfg.cb, sizeof(ua_cfg.cb));
    ua_cfg.cb.on_nat_detect 	= &Endpoint::on_nat_detect;
    ua_cfg.cb.on_transport_state = &Endpoint::on_transport_state;

    ua_cfg.cb.on_incoming_call	= &Endpoint::on_incoming_call;
    ua_cfg.cb.on_reg_started	= &Endpoint::on_reg_started;
    ua_cfg.cb.on_reg_state2	= &Endpoint::on_reg_state2;
    ua_cfg.cb.on_incoming_subscribe = &Endpoint::on_incoming_subscribe;
    ua_cfg.cb.on_pager2		= &Endpoint::on_pager2;
    ua_cfg.cb.on_pager_status2	= &Endpoint::on_pager_status2;
    ua_cfg.cb.on_typing2	= &Endpoint::on_typing2;
    ua_cfg.cb.on_mwi_info	= &Endpoint::on_mwi_info;
    ua_cfg.cb.on_buddy_state	= &Endpoint::on_buddy_state;

    /* Call callbacks */
    ua_cfg.cb.on_call_state             = &Endpoint::on_call_state;
    ua_cfg.cb.on_call_tsx_state         = &Endpoint::on_call_tsx_state;
    ua_cfg.cb.on_call_media_state       = &Endpoint::on_call_media_state;
    ua_cfg.cb.on_call_sdp_created       = &Endpoint::on_call_sdp_created;
    ua_cfg.cb.on_stream_created         = &Endpoint::on_stream_created;
    ua_cfg.cb.on_stream_destroyed       = &Endpoint::on_stream_destroyed;
    ua_cfg.cb.on_dtmf_digit             = &Endpoint::on_dtmf_digit;
    ua_cfg.cb.on_call_transfer_request2 = &Endpoint::on_call_transfer_request2;
    ua_cfg.cb.on_call_transfer_status   = &Endpoint::on_call_transfer_status;
    ua_cfg.cb.on_call_replace_request2  = &Endpoint::on_call_replace_request2;
    ua_cfg.cb.on_call_replaced          = &Endpoint::on_call_replaced;
    ua_cfg.cb.on_call_rx_offer          = &Endpoint::on_call_rx_offer;
    ua_cfg.cb.on_call_redirected        = &Endpoint::on_call_redirected;
    ua_cfg.cb.on_call_media_transport_state =
        &Endpoint::on_call_media_transport_state;
    ua_cfg.cb.on_call_media_event       = &Endpoint::on_call_media_event;
    ua_cfg.cb.on_create_media_transport = &Endpoint::on_create_media_transport;

    /* Init! */
    PJSUA2_CHECK_EXPR( pjsua_init(&ua_cfg, &log_cfg, &med_cfg) );
}

void Endpoint::libStart() throw(Error)
{
    PJSUA2_CHECK_EXPR(pjsua_start());
}

void Endpoint::libRegisterWorkerThread(const string &name) throw(Error)
{
    PJSUA2_CHECK_EXPR(pjsua_register_worker_thread(name.c_str()));
}

void Endpoint::libStopWorkerThreads()
{
    pjsua_stop_worker_threads();
}

int Endpoint::libHandleEvents(unsigned msec_timeout)
{
    performPendingJobs();
    return pjsua_handle_events(msec_timeout);
}

void Endpoint::libDestroy(unsigned flags) throw(Error)
{
    pj_status_t status;

    status = pjsua_destroy2(flags);

    delete this->writer;
    this->writer = NULL;

    if (pj_log_get_log_func() == &Endpoint::logFunc) {
	pj_log_set_log_func(NULL);
    }

    PJSUA2_CHECK_RAISE_ERROR(status);
}

///////////////////////////////////////////////////////////////////////////////
/*
 * Endpoint Utilities
 */
string Endpoint::utilStrError(pj_status_t prmErr)
{
    char errmsg[PJ_ERR_MSG_SIZE];
    pj_strerror(prmErr, errmsg, sizeof(errmsg));
    return errmsg;
}

static void ept_log_write(int level, const char *sender,
                          const char *format, ...)
{
    va_list arg;
    va_start(arg, format);
    pj_log(sender, level, format, arg );
    va_end(arg);
}

void Endpoint::utilLogWrite(int prmLevel,
			    const string &prmSender,
			    const string &prmMsg)
{
    ept_log_write(prmLevel, prmSender.c_str(), "%s", prmMsg.c_str());
}

pj_status_t Endpoint::utilVerifySipUri(const string &prmUri)
{
    return pjsua_verify_sip_url(prmUri.c_str());
}

pj_status_t Endpoint::utilVerifyUri(const string &prmUri)
{
    return pjsua_verify_url(prmUri.c_str());
}

Token Endpoint::utilTimerSchedule(unsigned prmMsecDelay,
                                  Token prmUserData) throw (Error)
{
    UserTimer *ut;
    pj_time_val delay;
    pj_status_t status;

    ut = new UserTimer;
    ut->signature = TIMER_SIGNATURE;
    ut->prm.msecDelay = prmMsecDelay;
    ut->prm.userData = prmUserData;
    pj_timer_entry_init(&ut->entry, 1, ut, &Endpoint::on_timer);

    delay.sec = 0;
    delay.msec = prmMsecDelay;
    pj_time_val_normalize(&delay);

    status = pjsua_schedule_timer(&ut->entry, &delay);
    if (status != PJ_SUCCESS) {
	delete ut;
	PJSUA2_CHECK_RAISE_ERROR(status);
    }

    return (Token)ut;
}

void Endpoint::utilTimerCancel(Token prmTimerToken)
{
    UserTimer *ut = (UserTimer*)(void*)prmTimerToken;

    if (ut->signature != TIMER_SIGNATURE) {
	PJ_LOG(1,(THIS_FILE,
		  "Invalid timer token in Endpoint::utilTimerCancel()"));
	return;
    }

    ut->entry.id = 0;
    ut->signature = 0xFFFFFFFE;
    pjsua_cancel_timer(&ut->entry);

    delete ut;
}

IntVector Endpoint::utilSslGetAvailableCiphers() throw (Error)
{
#if PJ_HAS_SSL_SOCK
    pj_ssl_cipher ciphers[64];
    unsigned count = PJ_ARRAY_SIZE(ciphers);

    PJSUA2_CHECK_EXPR( pj_ssl_cipher_get_availables(ciphers, &count) );

    return IntVector(ciphers, ciphers + count);
#else
    return IntVector();
#endif
}

///////////////////////////////////////////////////////////////////////////////
/*
 * Endpoint NAT operations
 */
void Endpoint::natDetectType(void) throw(Error)
{
    PJSUA2_CHECK_EXPR( pjsua_detect_nat_type() );
}

pj_stun_nat_type Endpoint::natGetType() throw(Error)
{
    pj_stun_nat_type type;

    PJSUA2_CHECK_EXPR( pjsua_get_nat_type(&type) );

    return type;
}

void Endpoint::natCheckStunServers(const StringVector &servers,
				   bool wait,
				   Token token) throw(Error)
{
    pj_str_t srv[MAX_STUN_SERVERS];
    unsigned i, count = 0;

    for (i=0; i<servers.size() && i<MAX_STUN_SERVERS; ++i) {
	srv[count].ptr = (char*)servers[i].c_str();
	srv[count].slen = servers[i].size();
	++count;
    }

    PJSUA2_CHECK_EXPR(pjsua_resolve_stun_servers(count, srv, wait, token,
                                                 &Endpoint::stun_resolve_cb) );
}

void Endpoint::natCancelCheckStunServers(Token token,
                                         bool notify_cb) throw(Error)
{
    PJSUA2_CHECK_EXPR( pjsua_cancel_stun_resolution(token, notify_cb) );
}

///////////////////////////////////////////////////////////////////////////////
/*
 * Transport API
 */
TransportId Endpoint::transportCreate(pjsip_transport_type_e type,
                                      const TransportConfig &cfg) throw(Error)
{
    pjsua_transport_config tcfg;
    pjsua_transport_id tid;

    tcfg = cfg.toPj();
    PJSUA2_CHECK_EXPR( pjsua_transport_create(type,
                                              &tcfg, &tid) );

    return tid;
}

IntVector Endpoint::transportEnum() throw(Error)
{
    pjsua_transport_id tids[32];
    unsigned count = PJ_ARRAY_SIZE(tids);

    PJSUA2_CHECK_EXPR( pjsua_enum_transports(tids, &count) );

    return IntVector(tids, tids+count);
}

TransportInfo Endpoint::transportGetInfo(TransportId id) throw(Error)
{
    pjsua_transport_info pj_tinfo;
    TransportInfo tinfo;

    PJSUA2_CHECK_EXPR( pjsua_transport_get_info(id, &pj_tinfo) );
    tinfo.fromPj(pj_tinfo);

    return tinfo;
}

void Endpoint::transportSetEnable(TransportId id, bool enabled) throw(Error)
{
    PJSUA2_CHECK_EXPR( pjsua_transport_set_enable(id, enabled) );
}

void Endpoint::transportClose(TransportId id) throw(Error)
{
    PJSUA2_CHECK_EXPR( pjsua_transport_close(id, PJ_FALSE) );
}

///////////////////////////////////////////////////////////////////////////////
/*
 * Call operations
 */

void Endpoint::hangupAllCalls(void)
{
    pjsua_call_hangup_all();
}

///////////////////////////////////////////////////////////////////////////////
/*
 * Media API
 */
unsigned Endpoint::mediaMaxPorts() const
{
    return pjsua_conf_get_max_ports();
}

unsigned Endpoint::mediaActivePorts() const
{
    return pjsua_conf_get_active_ports();
}

const AudioMediaVector &Endpoint::mediaEnumPorts() const throw(Error)
{
    return mediaList;
}

void Endpoint::mediaAdd(AudioMedia &media)
{
    if (mediaExists(media))
	return;

    mediaList.push_back(&media);
}

void Endpoint::mediaRemove(AudioMedia &media)
{
    AudioMediaVector::iterator it = std::find(mediaList.begin(),
					      mediaList.end(),
					      &media);

    if (it != mediaList.end())
	mediaList.erase(it);

}

bool Endpoint::mediaExists(const AudioMedia &media) const
{
    AudioMediaVector::const_iterator it = std::find(mediaList.begin(),
						    mediaList.end(),
						    &media);

    return (it != mediaList.end());
}

AudDevManager &Endpoint::audDevManager()
{
    return audioDevMgr;
}

/*
 * Codec operations.
 */
const CodecInfoVector &Endpoint::codecEnum() throw(Error)
{
    pjsua_codec_info pj_codec[MAX_CODEC_NUM];
    unsigned count = 0;

    PJSUA2_CHECK_EXPR( pjsua_enum_codecs(pj_codec, &count) );

    pj_enter_critical_section();
    clearCodecInfoList();
    for (unsigned i=0;(i<count && i<MAX_CODEC_NUM);++i) {
	CodecInfo *codec_info = new CodecInfo;

	codec_info->fromPj(pj_codec[i]);
	codecInfoList.push_back(codec_info);
    }
    pj_leave_critical_section();
    return codecInfoList;
}

void Endpoint::codecSetPriority(const string &codec_id,
			        pj_uint8_t priority) throw(Error)
{
    pj_str_t codec_str = str2Pj(codec_id);
    PJSUA2_CHECK_EXPR( pjsua_codec_set_priority(&codec_str, priority) );
}

CodecParam Endpoint::codecGetParam(const string &codec_id) const throw(Error)
{
    pjmedia_codec_param *pj_param = NULL;
    pj_str_t codec_str = str2Pj(codec_id);

    PJSUA2_CHECK_EXPR( pjsua_codec_get_param(&codec_str, pj_param) );

    return pj_param;
}

void Endpoint::codecSetParam(const string &codec_id,
			     const CodecParam param) throw(Error)
{
    pj_str_t codec_str = str2Pj(codec_id);
    pjmedia_codec_param *pj_param = (pjmedia_codec_param*)param;

    PJSUA2_CHECK_EXPR( pjsua_codec_set_param(&codec_str, pj_param) );
}

void Endpoint::clearCodecInfoList()
{
    for (unsigned i=0;i<codecInfoList.size();++i) {
	delete codecInfoList[i];
    }
    codecInfoList.clear();
}
