diff --git a/jni/pjproject-android/pjsip/src/pjsua2/endpoint.cpp b/jni/pjproject-android/pjsip/src/pjsua2/endpoint.cpp
new file mode 100644
index 0000000..4b11bda
--- /dev/null
+++ b/jni/pjproject-android/pjsip/src/pjsua2/endpoint.cpp
@@ -0,0 +1,1612 @@
+/* $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();
+}
