| /* $Id: account.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/account.hpp> |
| #include <pjsua2/endpoint.hpp> |
| #include <pjsua2/presence.hpp> |
| #include <pj/ctype.h> |
| #include "util.hpp" |
| |
| using namespace pj; |
| using namespace std; |
| |
| #define THIS_FILE "account.cpp" |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| void AccountRegConfig::readObject(const ContainerNode &node) throw(Error) |
| { |
| ContainerNode this_node = node.readContainer("AccountRegConfig"); |
| |
| NODE_READ_STRING (this_node, registrarUri); |
| NODE_READ_BOOL (this_node, registerOnAdd); |
| NODE_READ_UNSIGNED (this_node, timeoutSec); |
| NODE_READ_UNSIGNED (this_node, retryIntervalSec); |
| NODE_READ_UNSIGNED (this_node, firstRetryIntervalSec); |
| NODE_READ_UNSIGNED (this_node, delayBeforeRefreshSec); |
| NODE_READ_BOOL (this_node, dropCallsOnFail); |
| NODE_READ_UNSIGNED (this_node, unregWaitSec); |
| NODE_READ_UNSIGNED (this_node, proxyUse); |
| |
| readSipHeaders(this_node, "headers", headers); |
| } |
| |
| void AccountRegConfig::writeObject(ContainerNode &node) const throw(Error) |
| { |
| ContainerNode this_node = node.writeNewContainer("AccountRegConfig"); |
| |
| NODE_WRITE_STRING (this_node, registrarUri); |
| NODE_WRITE_BOOL (this_node, registerOnAdd); |
| NODE_WRITE_UNSIGNED (this_node, timeoutSec); |
| NODE_WRITE_UNSIGNED (this_node, retryIntervalSec); |
| NODE_WRITE_UNSIGNED (this_node, firstRetryIntervalSec); |
| NODE_WRITE_UNSIGNED (this_node, delayBeforeRefreshSec); |
| NODE_WRITE_BOOL (this_node, dropCallsOnFail); |
| NODE_WRITE_UNSIGNED (this_node, unregWaitSec); |
| NODE_WRITE_UNSIGNED (this_node, proxyUse); |
| |
| writeSipHeaders(this_node, "headers", headers); |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| void AccountSipConfig::readObject(const ContainerNode &node) throw(Error) |
| { |
| ContainerNode this_node = node.readContainer("AccountSipConfig"); |
| |
| NODE_READ_STRINGV (this_node, proxies); |
| NODE_READ_STRING (this_node, contactForced); |
| NODE_READ_STRING (this_node, contactParams); |
| NODE_READ_STRING (this_node, contactUriParams); |
| NODE_READ_BOOL (this_node, authInitialEmpty); |
| NODE_READ_STRING (this_node, authInitialAlgorithm); |
| NODE_READ_INT (this_node, transportId); |
| |
| ContainerNode creds_node = this_node.readArray("authCreds"); |
| authCreds.resize(0); |
| while (creds_node.hasUnread()) { |
| AuthCredInfo cred; |
| cred.readObject(creds_node); |
| authCreds.push_back(cred); |
| } |
| } |
| |
| void AccountSipConfig::writeObject(ContainerNode &node) const throw(Error) |
| { |
| ContainerNode this_node = node.writeNewContainer("AccountSipConfig"); |
| |
| NODE_WRITE_STRINGV (this_node, proxies); |
| NODE_WRITE_STRING (this_node, contactForced); |
| NODE_WRITE_STRING (this_node, contactParams); |
| NODE_WRITE_STRING (this_node, contactUriParams); |
| NODE_WRITE_BOOL (this_node, authInitialEmpty); |
| NODE_WRITE_STRING (this_node, authInitialAlgorithm); |
| NODE_WRITE_INT (this_node, transportId); |
| |
| ContainerNode creds_node = this_node.writeNewArray("authCreds"); |
| for (unsigned i=0; i<authCreds.size(); ++i) { |
| authCreds[i].writeObject(creds_node); |
| } |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| void AccountCallConfig::readObject(const ContainerNode &node) throw(Error) |
| { |
| ContainerNode this_node = node.readContainer("AccountCallConfig"); |
| |
| NODE_READ_NUM_T ( this_node, pjsua_call_hold_type, holdType); |
| NODE_READ_NUM_T ( this_node, pjsua_100rel_use, prackUse); |
| NODE_READ_NUM_T ( this_node, pjsua_sip_timer_use, timerUse); |
| NODE_READ_UNSIGNED( this_node, timerMinSESec); |
| NODE_READ_UNSIGNED( this_node, timerSessExpiresSec); |
| } |
| |
| void AccountCallConfig::writeObject(ContainerNode &node) const throw(Error) |
| { |
| ContainerNode this_node = node.writeNewContainer("AccountCallConfig"); |
| |
| NODE_WRITE_NUM_T ( this_node, pjsua_call_hold_type, holdType); |
| NODE_WRITE_NUM_T ( this_node, pjsua_100rel_use, prackUse); |
| NODE_WRITE_NUM_T ( this_node, pjsua_sip_timer_use, timerUse); |
| NODE_WRITE_UNSIGNED( this_node, timerMinSESec); |
| NODE_WRITE_UNSIGNED( this_node, timerSessExpiresSec); |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| void AccountPresConfig::readObject(const ContainerNode &node) throw(Error) |
| { |
| ContainerNode this_node = node.readContainer("AccountPresConfig"); |
| |
| NODE_READ_BOOL ( this_node, publishEnabled); |
| NODE_READ_BOOL ( this_node, publishQueue); |
| NODE_READ_UNSIGNED( this_node, publishShutdownWaitMsec); |
| NODE_READ_STRING ( this_node, pidfTupleId); |
| |
| readSipHeaders(this_node, "headers", headers); |
| } |
| |
| void AccountPresConfig::writeObject(ContainerNode &node) const throw(Error) |
| { |
| ContainerNode this_node = node.writeNewContainer("AccountPresConfig"); |
| |
| NODE_WRITE_BOOL ( this_node, publishEnabled); |
| NODE_WRITE_BOOL ( this_node, publishQueue); |
| NODE_WRITE_UNSIGNED( this_node, publishShutdownWaitMsec); |
| NODE_WRITE_STRING ( this_node, pidfTupleId); |
| |
| writeSipHeaders(this_node, "headers", headers); |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| void AccountMwiConfig::readObject(const ContainerNode &node) throw(Error) |
| { |
| ContainerNode this_node = node.readContainer("AccountMwiConfig"); |
| |
| NODE_READ_BOOL ( this_node, enabled); |
| NODE_READ_UNSIGNED( this_node, expirationSec); |
| } |
| |
| void AccountMwiConfig::writeObject(ContainerNode &node) const throw(Error) |
| { |
| ContainerNode this_node = node.writeNewContainer("AccountMwiConfig"); |
| |
| NODE_WRITE_BOOL ( this_node, enabled); |
| NODE_WRITE_UNSIGNED( this_node, expirationSec); |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| void AccountNatConfig::readObject(const ContainerNode &node) throw(Error) |
| { |
| ContainerNode this_node = node.readContainer("AccountNatConfig"); |
| |
| NODE_READ_NUM_T ( this_node, pjsua_stun_use, sipStunUse); |
| NODE_READ_NUM_T ( this_node, pjsua_stun_use, mediaStunUse); |
| NODE_READ_BOOL ( this_node, iceEnabled); |
| NODE_READ_INT ( this_node, iceMaxHostCands); |
| NODE_READ_BOOL ( this_node, iceAggressiveNomination); |
| NODE_READ_UNSIGNED( this_node, iceNominatedCheckDelayMsec); |
| NODE_READ_INT ( this_node, iceWaitNominationTimeoutMsec); |
| NODE_READ_BOOL ( this_node, iceNoRtcp); |
| NODE_READ_BOOL ( this_node, iceAlwaysUpdate); |
| NODE_READ_BOOL ( this_node, turnEnabled); |
| NODE_READ_STRING ( this_node, turnServer); |
| NODE_READ_NUM_T ( this_node, pj_turn_tp_type, turnConnType); |
| NODE_READ_STRING ( this_node, turnUserName); |
| NODE_READ_INT ( this_node, turnPasswordType); |
| NODE_READ_STRING ( this_node, turnPassword); |
| NODE_READ_INT ( this_node, contactRewriteUse); |
| NODE_READ_INT ( this_node, contactRewriteMethod); |
| NODE_READ_INT ( this_node, viaRewriteUse); |
| NODE_READ_INT ( this_node, sdpNatRewriteUse); |
| NODE_READ_INT ( this_node, sipOutboundUse); |
| NODE_READ_STRING ( this_node, sipOutboundInstanceId); |
| NODE_READ_STRING ( this_node, sipOutboundRegId); |
| NODE_READ_UNSIGNED( this_node, udpKaIntervalSec); |
| NODE_READ_STRING ( this_node, udpKaData); |
| } |
| |
| void AccountNatConfig::writeObject(ContainerNode &node) const throw(Error) |
| { |
| ContainerNode this_node = node.writeNewContainer("AccountNatConfig"); |
| |
| NODE_WRITE_NUM_T ( this_node, pjsua_stun_use, sipStunUse); |
| NODE_WRITE_NUM_T ( this_node, pjsua_stun_use, mediaStunUse); |
| NODE_WRITE_BOOL ( this_node, iceEnabled); |
| NODE_WRITE_INT ( this_node, iceMaxHostCands); |
| NODE_WRITE_BOOL ( this_node, iceAggressiveNomination); |
| NODE_WRITE_UNSIGNED( this_node, iceNominatedCheckDelayMsec); |
| NODE_WRITE_INT ( this_node, iceWaitNominationTimeoutMsec); |
| NODE_WRITE_BOOL ( this_node, iceNoRtcp); |
| NODE_WRITE_BOOL ( this_node, iceAlwaysUpdate); |
| NODE_WRITE_BOOL ( this_node, turnEnabled); |
| NODE_WRITE_STRING ( this_node, turnServer); |
| NODE_WRITE_NUM_T ( this_node, pj_turn_tp_type, turnConnType); |
| NODE_WRITE_STRING ( this_node, turnUserName); |
| NODE_WRITE_INT ( this_node, turnPasswordType); |
| NODE_WRITE_STRING ( this_node, turnPassword); |
| NODE_WRITE_INT ( this_node, contactRewriteUse); |
| NODE_WRITE_INT ( this_node, contactRewriteMethod); |
| NODE_WRITE_INT ( this_node, viaRewriteUse); |
| NODE_WRITE_INT ( this_node, sdpNatRewriteUse); |
| NODE_WRITE_INT ( this_node, sipOutboundUse); |
| NODE_WRITE_STRING ( this_node, sipOutboundInstanceId); |
| NODE_WRITE_STRING ( this_node, sipOutboundRegId); |
| NODE_WRITE_UNSIGNED( this_node, udpKaIntervalSec); |
| NODE_WRITE_STRING ( this_node, udpKaData); |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| void AccountMediaConfig::readObject(const ContainerNode &node) throw(Error) |
| { |
| ContainerNode this_node = node.readContainer("AccountMediaConfig"); |
| |
| NODE_READ_BOOL ( this_node, lockCodecEnabled); |
| NODE_READ_BOOL ( this_node, streamKaEnabled); |
| NODE_READ_NUM_T ( this_node, pjmedia_srtp_use, srtpUse); |
| NODE_READ_INT ( this_node, srtpSecureSignaling); |
| NODE_READ_NUM_T ( this_node, pjsua_ipv6_use, ipv6Use); |
| NODE_READ_OBJ ( this_node, transportConfig); |
| } |
| |
| void AccountMediaConfig::writeObject(ContainerNode &node) const throw(Error) |
| { |
| ContainerNode this_node = node.writeNewContainer("AccountMediaConfig"); |
| |
| NODE_WRITE_BOOL ( this_node, lockCodecEnabled); |
| NODE_WRITE_BOOL ( this_node, streamKaEnabled); |
| NODE_WRITE_NUM_T ( this_node, pjmedia_srtp_use, srtpUse); |
| NODE_WRITE_INT ( this_node, srtpSecureSignaling); |
| NODE_WRITE_NUM_T ( this_node, pjsua_ipv6_use, ipv6Use); |
| NODE_WRITE_OBJ ( this_node, transportConfig); |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| void AccountVideoConfig::readObject(const ContainerNode &node) throw(Error) |
| { |
| ContainerNode this_node = node.readContainer("AccountVideoConfig"); |
| |
| NODE_READ_BOOL ( this_node, autoShowIncoming); |
| NODE_READ_BOOL ( this_node, autoTransmitOutgoing); |
| NODE_READ_UNSIGNED( this_node, windowFlags); |
| NODE_READ_NUM_T ( this_node, pjmedia_vid_dev_index, defaultCaptureDevice); |
| NODE_READ_NUM_T ( this_node, pjmedia_vid_dev_index, defaultRenderDevice); |
| NODE_READ_NUM_T ( this_node, pjmedia_vid_stream_rc_method, rateControlMethod); |
| NODE_READ_UNSIGNED( this_node, rateControlBandwidth); |
| } |
| |
| void AccountVideoConfig::writeObject(ContainerNode &node) const throw(Error) |
| { |
| ContainerNode this_node = node.writeNewContainer("AccountVideoConfig"); |
| |
| NODE_WRITE_BOOL ( this_node, autoShowIncoming); |
| NODE_WRITE_BOOL ( this_node, autoTransmitOutgoing); |
| NODE_WRITE_UNSIGNED( this_node, windowFlags); |
| NODE_WRITE_NUM_T ( this_node, pjmedia_vid_dev_index, defaultCaptureDevice); |
| NODE_WRITE_NUM_T ( this_node, pjmedia_vid_dev_index, defaultRenderDevice); |
| NODE_WRITE_NUM_T ( this_node, pjmedia_vid_stream_rc_method, rateControlMethod); |
| NODE_WRITE_UNSIGNED( this_node, rateControlBandwidth); |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| AccountConfig::AccountConfig() |
| { |
| pjsua_acc_config acc_cfg; |
| pjsua_acc_config_default(&acc_cfg); |
| pjsua_media_config med_cfg; |
| pjsua_media_config_default(&med_cfg); |
| fromPj(acc_cfg, &med_cfg); |
| } |
| |
| /* Convert to pjsip. */ |
| void AccountConfig::toPj(pjsua_acc_config &ret) const |
| { |
| unsigned i; |
| |
| pjsua_acc_config_default(&ret); |
| |
| // Global |
| ret.priority = priority; |
| ret.id = str2Pj(idUri); |
| |
| // AccountRegConfig |
| ret.reg_uri = str2Pj(regConfig.registrarUri); |
| ret.register_on_acc_add = regConfig.registerOnAdd; |
| ret.reg_timeout = regConfig.timeoutSec; |
| ret.reg_retry_interval = regConfig.retryIntervalSec; |
| ret.reg_first_retry_interval= regConfig.firstRetryIntervalSec; |
| ret.reg_delay_before_refresh= regConfig.delayBeforeRefreshSec; |
| ret.drop_calls_on_reg_fail = regConfig.dropCallsOnFail; |
| ret.unreg_timeout = regConfig.unregWaitSec; |
| ret.reg_use_proxy = regConfig.proxyUse; |
| for (i=0; i<regConfig.headers.size(); ++i) { |
| pj_list_push_back(&ret.reg_hdr_list, ®Config.headers[i].toPj()); |
| } |
| |
| // AccountSipConfig |
| ret.cred_count = 0; |
| if (sipConfig.authCreds.size() > PJ_ARRAY_SIZE(ret.cred_info)) |
| PJSUA2_RAISE_ERROR(PJ_ETOOMANY); |
| for (i=0; i<sipConfig.authCreds.size(); ++i) { |
| const AuthCredInfo &src = sipConfig.authCreds[i]; |
| pjsip_cred_info *dst = &ret.cred_info[i]; |
| |
| dst->realm = str2Pj(src.realm); |
| dst->scheme = str2Pj(src.scheme); |
| dst->username = str2Pj(src.username); |
| dst->data_type = src.dataType; |
| dst->data = str2Pj(src.data); |
| dst->ext.aka.k = str2Pj(src.akaK); |
| dst->ext.aka.op = str2Pj(src.akaOp); |
| dst->ext.aka.amf= str2Pj(src.akaAmf); |
| |
| ret.cred_count++; |
| } |
| ret.proxy_cnt = 0; |
| if (sipConfig.proxies.size() > PJ_ARRAY_SIZE(ret.proxy)) |
| PJSUA2_RAISE_ERROR(PJ_ETOOMANY); |
| for (i=0; i<sipConfig.proxies.size(); ++i) { |
| ret.proxy[ret.proxy_cnt++] = str2Pj(sipConfig.proxies[i]); |
| } |
| ret.force_contact = str2Pj(sipConfig.contactForced); |
| ret.contact_params = str2Pj(sipConfig.contactParams); |
| ret.contact_uri_params = str2Pj(sipConfig.contactUriParams); |
| ret.auth_pref.initial_auth = sipConfig.authInitialEmpty; |
| ret.auth_pref.algorithm = str2Pj(sipConfig.authInitialAlgorithm); |
| ret.transport_id = sipConfig.transportId; |
| |
| // AccountCallConfig |
| ret.call_hold_type = callConfig.holdType; |
| ret.require_100rel = callConfig.prackUse; |
| ret.use_timer = callConfig.timerUse; |
| ret.timer_setting.min_se = callConfig.timerMinSESec; |
| ret.timer_setting.sess_expires = callConfig.timerSessExpiresSec; |
| |
| // AccountPresConfig |
| for (i=0; i<presConfig.headers.size(); ++i) { |
| pj_list_push_back(&ret.sub_hdr_list, &presConfig.headers[i].toPj()); |
| } |
| ret.publish_enabled = presConfig.publishEnabled; |
| ret.publish_opt.queue_request= presConfig.publishQueue; |
| ret.unpublish_max_wait_time_msec = presConfig.publishShutdownWaitMsec; |
| ret.pidf_tuple_id = str2Pj(presConfig.pidfTupleId); |
| |
| // AccountNatConfig |
| ret.sip_stun_use = natConfig.sipStunUse; |
| ret.media_stun_use = natConfig.mediaStunUse; |
| ret.ice_cfg_use = PJSUA_ICE_CONFIG_USE_CUSTOM; |
| ret.ice_cfg.enable_ice = natConfig.iceEnabled; |
| ret.ice_cfg.ice_max_host_cands = natConfig.iceMaxHostCands; |
| ret.ice_cfg.ice_opt.aggressive = natConfig.iceAggressiveNomination; |
| ret.ice_cfg.ice_opt.nominated_check_delay = natConfig.iceNominatedCheckDelayMsec; |
| ret.ice_cfg.ice_opt.controlled_agent_want_nom_timeout = natConfig.iceWaitNominationTimeoutMsec; |
| ret.ice_cfg.ice_no_rtcp = natConfig.iceNoRtcp; |
| ret.ice_cfg.ice_always_update = natConfig.iceAlwaysUpdate; |
| |
| ret.turn_cfg_use = PJSUA_TURN_CONFIG_USE_CUSTOM; |
| ret.turn_cfg.enable_turn = natConfig.turnEnabled; |
| ret.turn_cfg.turn_server = str2Pj(natConfig.turnServer); |
| ret.turn_cfg.turn_conn_type = natConfig.turnConnType; |
| ret.turn_cfg.turn_auth_cred.type = PJ_STUN_AUTH_CRED_STATIC; |
| ret.turn_cfg.turn_auth_cred.data.static_cred.username = str2Pj(natConfig.turnUserName); |
| ret.turn_cfg.turn_auth_cred.data.static_cred.data_type = (pj_stun_passwd_type)natConfig.turnPasswordType; |
| ret.turn_cfg.turn_auth_cred.data.static_cred.data = str2Pj(natConfig.turnPassword); |
| ret.turn_cfg.turn_auth_cred.data.static_cred.realm = pj_str((char*)""); |
| ret.turn_cfg.turn_auth_cred.data.static_cred.nonce = pj_str((char*)""); |
| |
| ret.allow_contact_rewrite = natConfig.contactRewriteUse; |
| ret.contact_rewrite_method = natConfig.contactRewriteMethod; |
| ret.allow_via_rewrite = natConfig.viaRewriteUse; |
| ret.allow_sdp_nat_rewrite = natConfig.sdpNatRewriteUse; |
| ret.use_rfc5626 = natConfig.sipOutboundUse; |
| ret.rfc5626_instance_id = str2Pj(natConfig.sipOutboundInstanceId); |
| ret.rfc5626_reg_id = str2Pj(natConfig.sipOutboundRegId); |
| ret.ka_interval = natConfig.udpKaIntervalSec; |
| ret.ka_data = str2Pj(natConfig.udpKaData); |
| |
| // AccountMediaConfig |
| ret.rtp_cfg = mediaConfig.transportConfig.toPj(); |
| ret.lock_codec = mediaConfig.lockCodecEnabled; |
| #if defined(PJMEDIA_STREAM_ENABLE_KA) && (PJMEDIA_STREAM_ENABLE_KA != 0) |
| ret.use_stream_ka = mediaConfig.streamKaEnabled; |
| #endif |
| ret.use_srtp = mediaConfig.srtpUse; |
| ret.srtp_secure_signaling = mediaConfig.srtpSecureSignaling; |
| ret.ipv6_media_use = mediaConfig.ipv6Use; |
| |
| // AccountVideoConfig |
| ret.vid_in_auto_show = videoConfig.autoShowIncoming; |
| ret.vid_out_auto_transmit = videoConfig.autoTransmitOutgoing; |
| ret.vid_wnd_flags = videoConfig.windowFlags; |
| ret.vid_cap_dev = videoConfig.defaultCaptureDevice; |
| ret.vid_rend_dev = videoConfig.defaultRenderDevice; |
| ret.vid_stream_rc_cfg.method= videoConfig.rateControlMethod; |
| ret.vid_stream_rc_cfg.bandwidth = videoConfig.rateControlBandwidth; |
| } |
| |
| /* Initialize from pjsip. */ |
| void AccountConfig::fromPj(const pjsua_acc_config &prm, |
| const pjsua_media_config *mcfg) |
| { |
| const pjsip_hdr *hdr; |
| unsigned i; |
| |
| // Global |
| priority = prm.priority; |
| idUri = pj2Str(prm.id); |
| |
| // AccountRegConfig |
| regConfig.registrarUri = pj2Str(prm.reg_uri); |
| regConfig.registerOnAdd = (prm.register_on_acc_add != 0); |
| regConfig.timeoutSec = prm.reg_timeout; |
| regConfig.retryIntervalSec = prm.reg_retry_interval; |
| regConfig.firstRetryIntervalSec = prm.reg_first_retry_interval; |
| regConfig.delayBeforeRefreshSec = prm.reg_delay_before_refresh; |
| regConfig.dropCallsOnFail = PJ2BOOL(prm.drop_calls_on_reg_fail); |
| regConfig.unregWaitSec = prm.unreg_timeout; |
| regConfig.proxyUse = prm.reg_use_proxy; |
| regConfig.headers.clear(); |
| hdr = prm.reg_hdr_list.next; |
| while (hdr != &prm.reg_hdr_list) { |
| SipHeader new_hdr; |
| new_hdr.fromPj(hdr); |
| |
| regConfig.headers.push_back(new_hdr); |
| |
| hdr = hdr->next; |
| } |
| |
| // AccountSipConfig |
| sipConfig.authCreds.clear(); |
| for (i=0; i<prm.cred_count; ++i) { |
| AuthCredInfo cred; |
| const pjsip_cred_info &src = prm.cred_info[i]; |
| |
| cred.realm = pj2Str(src.realm); |
| cred.scheme = pj2Str(src.scheme); |
| cred.username = pj2Str(src.username); |
| cred.dataType = src.data_type; |
| cred.data = pj2Str(src.data); |
| cred.akaK = pj2Str(src.ext.aka.k); |
| cred.akaOp = pj2Str(src.ext.aka.op); |
| cred.akaAmf = pj2Str(src.ext.aka.amf); |
| |
| sipConfig.authCreds.push_back(cred); |
| } |
| sipConfig.proxies.clear(); |
| for (i=0; i<prm.proxy_cnt; ++i) { |
| sipConfig.proxies.push_back(pj2Str(prm.proxy[i])); |
| } |
| sipConfig.contactForced = pj2Str(prm.force_contact); |
| sipConfig.contactParams = pj2Str(prm.contact_params); |
| sipConfig.contactUriParams = pj2Str(prm.contact_uri_params); |
| sipConfig.authInitialEmpty = PJ2BOOL(prm.auth_pref.initial_auth); |
| sipConfig.authInitialAlgorithm = pj2Str(prm.auth_pref.algorithm); |
| sipConfig.transportId = prm.transport_id; |
| |
| // AccountCallConfig |
| callConfig.holdType = prm.call_hold_type; |
| callConfig.prackUse = prm.require_100rel; |
| callConfig.timerUse = prm.use_timer; |
| callConfig.timerMinSESec = prm.timer_setting.min_se; |
| callConfig.timerSessExpiresSec = prm.timer_setting.sess_expires; |
| |
| // AccountPresConfig |
| presConfig.headers.clear(); |
| hdr = prm.sub_hdr_list.next; |
| while (hdr != &prm.sub_hdr_list) { |
| SipHeader new_hdr; |
| new_hdr.fromPj(hdr); |
| presConfig.headers.push_back(new_hdr); |
| hdr = hdr->next; |
| } |
| presConfig.publishEnabled = PJ2BOOL(prm.publish_enabled); |
| presConfig.publishQueue = PJ2BOOL(prm.publish_opt.queue_request); |
| presConfig.publishShutdownWaitMsec = prm.unpublish_max_wait_time_msec; |
| presConfig.pidfTupleId = pj2Str(prm.pidf_tuple_id); |
| |
| // AccountMwiConfig |
| mwiConfig.enabled = PJ2BOOL(prm.mwi_enabled); |
| mwiConfig.expirationSec = prm.mwi_expires; |
| |
| // AccountNatConfig |
| natConfig.sipStunUse = prm.sip_stun_use; |
| natConfig.mediaStunUse = prm.media_stun_use; |
| if (prm.ice_cfg_use == PJSUA_ICE_CONFIG_USE_CUSTOM) { |
| natConfig.iceEnabled = PJ2BOOL(prm.ice_cfg.enable_ice); |
| natConfig.iceMaxHostCands = prm.ice_cfg.ice_max_host_cands; |
| natConfig.iceAggressiveNomination = PJ2BOOL(prm.ice_cfg.ice_opt.aggressive); |
| natConfig.iceNominatedCheckDelayMsec = prm.ice_cfg.ice_opt.nominated_check_delay; |
| natConfig.iceWaitNominationTimeoutMsec = prm.ice_cfg.ice_opt.controlled_agent_want_nom_timeout; |
| natConfig.iceNoRtcp = PJ2BOOL(prm.ice_cfg.ice_no_rtcp); |
| natConfig.iceAlwaysUpdate = PJ2BOOL(prm.ice_cfg.ice_always_update); |
| } else { |
| pjsua_media_config default_mcfg; |
| if (!mcfg) { |
| pjsua_media_config_default(&default_mcfg); |
| mcfg = &default_mcfg; |
| } |
| natConfig.iceEnabled = PJ2BOOL(mcfg->enable_ice); |
| natConfig.iceMaxHostCands= mcfg->ice_max_host_cands; |
| natConfig.iceAggressiveNomination = PJ2BOOL(mcfg->ice_opt.aggressive); |
| natConfig.iceNominatedCheckDelayMsec = mcfg->ice_opt.nominated_check_delay; |
| natConfig.iceWaitNominationTimeoutMsec = mcfg->ice_opt.controlled_agent_want_nom_timeout; |
| natConfig.iceNoRtcp = PJ2BOOL(mcfg->ice_no_rtcp); |
| natConfig.iceAlwaysUpdate = PJ2BOOL(mcfg->ice_always_update); |
| } |
| |
| if (prm.turn_cfg_use == PJSUA_TURN_CONFIG_USE_CUSTOM) { |
| natConfig.turnEnabled = PJ2BOOL(prm.turn_cfg.enable_turn); |
| natConfig.turnServer = pj2Str(prm.turn_cfg.turn_server); |
| natConfig.turnConnType = prm.turn_cfg.turn_conn_type; |
| natConfig.turnUserName = pj2Str(prm.turn_cfg.turn_auth_cred.data.static_cred.username); |
| natConfig.turnPasswordType = prm.turn_cfg.turn_auth_cred.data.static_cred.data_type; |
| natConfig.turnPassword = pj2Str(prm.turn_cfg.turn_auth_cred.data.static_cred.data); |
| } else { |
| pjsua_media_config default_mcfg; |
| if (!mcfg) { |
| pjsua_media_config_default(&default_mcfg); |
| mcfg = &default_mcfg; |
| } |
| natConfig.turnEnabled = PJ2BOOL(mcfg->enable_turn); |
| natConfig.turnServer = pj2Str(mcfg->turn_server); |
| natConfig.turnConnType = mcfg->turn_conn_type; |
| natConfig.turnUserName = pj2Str(mcfg->turn_auth_cred.data.static_cred.username); |
| natConfig.turnPasswordType = mcfg->turn_auth_cred.data.static_cred.data_type; |
| natConfig.turnPassword = pj2Str(mcfg->turn_auth_cred.data.static_cred.data); |
| } |
| natConfig.contactRewriteUse = prm.allow_contact_rewrite; |
| natConfig.contactRewriteMethod = prm.contact_rewrite_method; |
| natConfig.viaRewriteUse = prm.allow_via_rewrite; |
| natConfig.sdpNatRewriteUse = prm.allow_sdp_nat_rewrite; |
| natConfig.sipOutboundUse = prm.use_rfc5626; |
| natConfig.sipOutboundInstanceId = pj2Str(prm.rfc5626_instance_id); |
| natConfig.sipOutboundRegId = pj2Str(prm.rfc5626_reg_id); |
| natConfig.udpKaIntervalSec = prm.ka_interval; |
| natConfig.udpKaData = pj2Str(prm.ka_data); |
| |
| // AccountMediaConfig |
| mediaConfig.transportConfig.fromPj(prm.rtp_cfg); |
| mediaConfig.lockCodecEnabled= PJ2BOOL(prm.lock_codec); |
| #if defined(PJMEDIA_STREAM_ENABLE_KA) && (PJMEDIA_STREAM_ENABLE_KA != 0) |
| mediaConfig.streamKaEnabled = PJ2BOOL(prm.use_stream_ka); |
| #else |
| mediaConfig.streamKaEnabled = false; |
| #endif |
| mediaConfig.srtpUse = prm.use_srtp; |
| mediaConfig.srtpSecureSignaling = prm.srtp_secure_signaling; |
| mediaConfig.ipv6Use = prm.ipv6_media_use; |
| |
| // AccountVideoConfig |
| videoConfig.autoShowIncoming = PJ2BOOL(prm.vid_in_auto_show); |
| videoConfig.autoTransmitOutgoing = PJ2BOOL(prm.vid_out_auto_transmit); |
| videoConfig.windowFlags = prm.vid_wnd_flags; |
| videoConfig.defaultCaptureDevice = prm.vid_cap_dev; |
| videoConfig.defaultRenderDevice = prm.vid_rend_dev; |
| videoConfig.rateControlMethod = prm.vid_stream_rc_cfg.method; |
| videoConfig.rateControlBandwidth = prm.vid_stream_rc_cfg.bandwidth; |
| } |
| |
| void AccountConfig::readObject(const ContainerNode &node) throw(Error) |
| { |
| ContainerNode this_node = node.readContainer("AccountConfig"); |
| |
| NODE_READ_INT ( this_node, priority); |
| NODE_READ_STRING ( this_node, idUri); |
| NODE_READ_OBJ ( this_node, regConfig); |
| NODE_READ_OBJ ( this_node, sipConfig); |
| NODE_READ_OBJ ( this_node, callConfig); |
| NODE_READ_OBJ ( this_node, presConfig); |
| NODE_READ_OBJ ( this_node, mwiConfig); |
| NODE_READ_OBJ ( this_node, natConfig); |
| NODE_READ_OBJ ( this_node, mediaConfig); |
| NODE_READ_OBJ ( this_node, videoConfig); |
| } |
| |
| void AccountConfig::writeObject(ContainerNode &node) const throw(Error) |
| { |
| ContainerNode this_node = node.writeNewContainer("AccountConfig"); |
| |
| NODE_WRITE_INT ( this_node, priority); |
| NODE_WRITE_STRING ( this_node, idUri); |
| NODE_WRITE_OBJ ( this_node, regConfig); |
| NODE_WRITE_OBJ ( this_node, sipConfig); |
| NODE_WRITE_OBJ ( this_node, callConfig); |
| NODE_WRITE_OBJ ( this_node, presConfig); |
| NODE_WRITE_OBJ ( this_node, mwiConfig); |
| NODE_WRITE_OBJ ( this_node, natConfig); |
| NODE_WRITE_OBJ ( this_node, mediaConfig); |
| NODE_WRITE_OBJ ( this_node, videoConfig); |
| } |
| |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| void AccountInfo::fromPj(const pjsua_acc_info &pai) |
| { |
| id = pai.id; |
| isDefault = pai.is_default != 0; |
| uri = pj2Str(pai.acc_uri); |
| regIsConfigured = pai.has_registration != 0; |
| regIsActive = pai.has_registration && pai.expires > 0 && |
| (pai.status / 100 == 2); |
| regExpiresSec = pai.expires; |
| regStatus = pai.status; |
| regStatusText = pj2Str(pai.status_text); |
| regLastErr = pai.reg_last_err; |
| onlineStatus = pai.online_status != 0; |
| onlineStatusText = pj2Str(pai.online_status_text); |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| Account::Account() |
| : id(PJSUA_INVALID_ID) |
| { |
| } |
| |
| Account::~Account() |
| { |
| /* If this instance is deleted, also delete the corresponding account in |
| * PJSUA library. |
| */ |
| if (isValid() && pjsua_get_state() < PJSUA_STATE_CLOSING) { |
| // Cleanup buddies in the buddy list |
| while(buddyList.size() > 0) { |
| Buddy *b = buddyList[0]; |
| delete b; /* this will remove itself from the list */ |
| } |
| |
| pjsua_acc_set_user_data(id, NULL); |
| pjsua_acc_del(id); |
| } |
| } |
| |
| void Account::create(const AccountConfig &acc_cfg, |
| bool make_default) throw(Error) |
| { |
| pjsua_acc_config pj_acc_cfg; |
| |
| acc_cfg.toPj(pj_acc_cfg); |
| pj_acc_cfg.user_data = (void*)this; |
| PJSUA2_CHECK_EXPR( pjsua_acc_add(&pj_acc_cfg, make_default, &id) ); |
| } |
| |
| void Account::modify(const AccountConfig &acc_cfg) throw(Error) |
| { |
| pjsua_acc_config pj_acc_cfg; |
| |
| acc_cfg.toPj(pj_acc_cfg); |
| pj_acc_cfg.user_data = (void*)this; |
| PJSUA2_CHECK_EXPR( pjsua_acc_modify(id, &pj_acc_cfg) ); |
| } |
| |
| bool Account::isValid() const |
| { |
| return pjsua_acc_is_valid(id) != 0; |
| } |
| |
| void Account::setDefault() throw(Error) |
| { |
| PJSUA2_CHECK_EXPR( pjsua_acc_set_default(id) ); |
| } |
| |
| bool Account::isDefault() const |
| { |
| return pjsua_acc_get_default() == id; |
| } |
| |
| int Account::getId() const |
| { |
| return id; |
| } |
| |
| Account *Account::lookup(int acc_id) |
| { |
| return (Account*)pjsua_acc_get_user_data(acc_id); |
| } |
| |
| AccountInfo Account::getInfo() const throw(Error) |
| { |
| pjsua_acc_info pj_ai; |
| AccountInfo ai; |
| |
| PJSUA2_CHECK_EXPR( pjsua_acc_get_info(id, &pj_ai) ); |
| ai.fromPj(pj_ai); |
| return ai; |
| } |
| |
| void Account::setRegistration(bool renew) throw(Error) |
| { |
| PJSUA2_CHECK_EXPR( pjsua_acc_set_registration(id, renew) ); |
| } |
| |
| void |
| Account::setOnlineStatus(const PresenceStatus &pres_st) throw(Error) |
| { |
| pjrpid_element pj_rpid; |
| |
| pj_bzero(&pj_rpid, sizeof(pj_rpid)); |
| pj_rpid.type = PJRPID_ELEMENT_TYPE_PERSON; |
| pj_rpid.activity = pres_st.activity; |
| pj_rpid.id = str2Pj(pres_st.rpidId); |
| pj_rpid.note = str2Pj(pres_st.note); |
| |
| PJSUA2_CHECK_EXPR( pjsua_acc_set_online_status2( |
| id, pres_st.status == PJSUA_BUDDY_STATUS_ONLINE, |
| &pj_rpid) ); |
| } |
| |
| void Account::setTransport(TransportId tp_id) throw(Error) |
| { |
| PJSUA2_CHECK_EXPR( pjsua_acc_set_transport(id, tp_id) ); |
| } |
| |
| void Account::presNotify(const PresNotifyParam &prm) throw(Error) |
| { |
| pj_str_t pj_state_str = str2Pj(prm.stateStr); |
| pj_str_t pj_reason = str2Pj(prm.reason); |
| pjsua_msg_data msg_data; |
| prm.txOption.toPj(msg_data); |
| |
| PJSUA2_CHECK_EXPR( pjsua_pres_notify(id, (pjsua_srv_pres*)prm.srvPres, |
| prm.state, &pj_state_str, |
| &pj_reason, prm.withBody, |
| &msg_data) ); |
| } |
| |
| const BuddyVector& Account::enumBuddies() const throw(Error) |
| { |
| return buddyList; |
| } |
| |
| Buddy* Account::findBuddy(string uri, FindBuddyMatch *buddy_match) const |
| throw(Error) |
| { |
| if (!buddy_match) { |
| static FindBuddyMatch def_bm; |
| buddy_match = &def_bm; |
| } |
| |
| for (unsigned i = 0; i < buddyList.size(); i++) { |
| if (buddy_match->match(uri, *buddyList[i])) |
| return buddyList[i]; |
| } |
| PJSUA2_RAISE_ERROR(PJ_ENOTFOUND); |
| } |
| |
| void Account::addBuddy(Buddy *buddy) |
| { |
| pj_assert(buddy); |
| |
| buddyList.push_back(buddy); |
| } |
| |
| void Account::removeBuddy(Buddy *buddy) |
| { |
| pj_assert(buddy); |
| |
| BuddyVector::iterator it; |
| for (it = buddyList.begin(); it != buddyList.end(); it++) { |
| if (*it == buddy) { |
| buddyList.erase(it); |
| return; |
| } |
| } |
| |
| pj_assert(!"Bug! Buddy to be removed is not in the buddy list!"); |
| } |