blob: cca0ad51156d670b13721bb493dfa637b35e873d [file] [log] [blame]
Alexandre Lision0e143012014-01-22 11:02:46 -05001/* $Id: account.cpp 4704 2014-01-16 05:30:46Z ming $ */
2/*
3 * Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19#include <pjsua2/account.hpp>
20#include <pjsua2/endpoint.hpp>
21#include <pjsua2/presence.hpp>
22#include <pj/ctype.h>
23#include "util.hpp"
24
25using namespace pj;
26using namespace std;
27
28#define THIS_FILE "account.cpp"
29
30///////////////////////////////////////////////////////////////////////////////
31
32void AccountRegConfig::readObject(const ContainerNode &node) throw(Error)
33{
34 ContainerNode this_node = node.readContainer("AccountRegConfig");
35
36 NODE_READ_STRING (this_node, registrarUri);
37 NODE_READ_BOOL (this_node, registerOnAdd);
38 NODE_READ_UNSIGNED (this_node, timeoutSec);
39 NODE_READ_UNSIGNED (this_node, retryIntervalSec);
40 NODE_READ_UNSIGNED (this_node, firstRetryIntervalSec);
41 NODE_READ_UNSIGNED (this_node, delayBeforeRefreshSec);
42 NODE_READ_BOOL (this_node, dropCallsOnFail);
43 NODE_READ_UNSIGNED (this_node, unregWaitSec);
44 NODE_READ_UNSIGNED (this_node, proxyUse);
45
46 readSipHeaders(this_node, "headers", headers);
47}
48
49void AccountRegConfig::writeObject(ContainerNode &node) const throw(Error)
50{
51 ContainerNode this_node = node.writeNewContainer("AccountRegConfig");
52
53 NODE_WRITE_STRING (this_node, registrarUri);
54 NODE_WRITE_BOOL (this_node, registerOnAdd);
55 NODE_WRITE_UNSIGNED (this_node, timeoutSec);
56 NODE_WRITE_UNSIGNED (this_node, retryIntervalSec);
57 NODE_WRITE_UNSIGNED (this_node, firstRetryIntervalSec);
58 NODE_WRITE_UNSIGNED (this_node, delayBeforeRefreshSec);
59 NODE_WRITE_BOOL (this_node, dropCallsOnFail);
60 NODE_WRITE_UNSIGNED (this_node, unregWaitSec);
61 NODE_WRITE_UNSIGNED (this_node, proxyUse);
62
63 writeSipHeaders(this_node, "headers", headers);
64}
65
66///////////////////////////////////////////////////////////////////////////////
67
68void AccountSipConfig::readObject(const ContainerNode &node) throw(Error)
69{
70 ContainerNode this_node = node.readContainer("AccountSipConfig");
71
72 NODE_READ_STRINGV (this_node, proxies);
73 NODE_READ_STRING (this_node, contactForced);
74 NODE_READ_STRING (this_node, contactParams);
75 NODE_READ_STRING (this_node, contactUriParams);
76 NODE_READ_BOOL (this_node, authInitialEmpty);
77 NODE_READ_STRING (this_node, authInitialAlgorithm);
78 NODE_READ_INT (this_node, transportId);
79
80 ContainerNode creds_node = this_node.readArray("authCreds");
81 authCreds.resize(0);
82 while (creds_node.hasUnread()) {
83 AuthCredInfo cred;
84 cred.readObject(creds_node);
85 authCreds.push_back(cred);
86 }
87}
88
89void AccountSipConfig::writeObject(ContainerNode &node) const throw(Error)
90{
91 ContainerNode this_node = node.writeNewContainer("AccountSipConfig");
92
93 NODE_WRITE_STRINGV (this_node, proxies);
94 NODE_WRITE_STRING (this_node, contactForced);
95 NODE_WRITE_STRING (this_node, contactParams);
96 NODE_WRITE_STRING (this_node, contactUriParams);
97 NODE_WRITE_BOOL (this_node, authInitialEmpty);
98 NODE_WRITE_STRING (this_node, authInitialAlgorithm);
99 NODE_WRITE_INT (this_node, transportId);
100
101 ContainerNode creds_node = this_node.writeNewArray("authCreds");
102 for (unsigned i=0; i<authCreds.size(); ++i) {
103 authCreds[i].writeObject(creds_node);
104 }
105}
106
107///////////////////////////////////////////////////////////////////////////////
108
109void AccountCallConfig::readObject(const ContainerNode &node) throw(Error)
110{
111 ContainerNode this_node = node.readContainer("AccountCallConfig");
112
113 NODE_READ_NUM_T ( this_node, pjsua_call_hold_type, holdType);
114 NODE_READ_NUM_T ( this_node, pjsua_100rel_use, prackUse);
115 NODE_READ_NUM_T ( this_node, pjsua_sip_timer_use, timerUse);
116 NODE_READ_UNSIGNED( this_node, timerMinSESec);
117 NODE_READ_UNSIGNED( this_node, timerSessExpiresSec);
118}
119
120void AccountCallConfig::writeObject(ContainerNode &node) const throw(Error)
121{
122 ContainerNode this_node = node.writeNewContainer("AccountCallConfig");
123
124 NODE_WRITE_NUM_T ( this_node, pjsua_call_hold_type, holdType);
125 NODE_WRITE_NUM_T ( this_node, pjsua_100rel_use, prackUse);
126 NODE_WRITE_NUM_T ( this_node, pjsua_sip_timer_use, timerUse);
127 NODE_WRITE_UNSIGNED( this_node, timerMinSESec);
128 NODE_WRITE_UNSIGNED( this_node, timerSessExpiresSec);
129}
130
131///////////////////////////////////////////////////////////////////////////////
132
133void AccountPresConfig::readObject(const ContainerNode &node) throw(Error)
134{
135 ContainerNode this_node = node.readContainer("AccountPresConfig");
136
137 NODE_READ_BOOL ( this_node, publishEnabled);
138 NODE_READ_BOOL ( this_node, publishQueue);
139 NODE_READ_UNSIGNED( this_node, publishShutdownWaitMsec);
140 NODE_READ_STRING ( this_node, pidfTupleId);
141
142 readSipHeaders(this_node, "headers", headers);
143}
144
145void AccountPresConfig::writeObject(ContainerNode &node) const throw(Error)
146{
147 ContainerNode this_node = node.writeNewContainer("AccountPresConfig");
148
149 NODE_WRITE_BOOL ( this_node, publishEnabled);
150 NODE_WRITE_BOOL ( this_node, publishQueue);
151 NODE_WRITE_UNSIGNED( this_node, publishShutdownWaitMsec);
152 NODE_WRITE_STRING ( this_node, pidfTupleId);
153
154 writeSipHeaders(this_node, "headers", headers);
155}
156
157///////////////////////////////////////////////////////////////////////////////
158
159void AccountMwiConfig::readObject(const ContainerNode &node) throw(Error)
160{
161 ContainerNode this_node = node.readContainer("AccountMwiConfig");
162
163 NODE_READ_BOOL ( this_node, enabled);
164 NODE_READ_UNSIGNED( this_node, expirationSec);
165}
166
167void AccountMwiConfig::writeObject(ContainerNode &node) const throw(Error)
168{
169 ContainerNode this_node = node.writeNewContainer("AccountMwiConfig");
170
171 NODE_WRITE_BOOL ( this_node, enabled);
172 NODE_WRITE_UNSIGNED( this_node, expirationSec);
173}
174
175///////////////////////////////////////////////////////////////////////////////
176
177void AccountNatConfig::readObject(const ContainerNode &node) throw(Error)
178{
179 ContainerNode this_node = node.readContainer("AccountNatConfig");
180
181 NODE_READ_NUM_T ( this_node, pjsua_stun_use, sipStunUse);
182 NODE_READ_NUM_T ( this_node, pjsua_stun_use, mediaStunUse);
183 NODE_READ_BOOL ( this_node, iceEnabled);
184 NODE_READ_INT ( this_node, iceMaxHostCands);
185 NODE_READ_BOOL ( this_node, iceAggressiveNomination);
186 NODE_READ_UNSIGNED( this_node, iceNominatedCheckDelayMsec);
187 NODE_READ_INT ( this_node, iceWaitNominationTimeoutMsec);
188 NODE_READ_BOOL ( this_node, iceNoRtcp);
189 NODE_READ_BOOL ( this_node, iceAlwaysUpdate);
190 NODE_READ_BOOL ( this_node, turnEnabled);
191 NODE_READ_STRING ( this_node, turnServer);
192 NODE_READ_NUM_T ( this_node, pj_turn_tp_type, turnConnType);
193 NODE_READ_STRING ( this_node, turnUserName);
194 NODE_READ_INT ( this_node, turnPasswordType);
195 NODE_READ_STRING ( this_node, turnPassword);
196 NODE_READ_INT ( this_node, contactRewriteUse);
197 NODE_READ_INT ( this_node, contactRewriteMethod);
198 NODE_READ_INT ( this_node, viaRewriteUse);
199 NODE_READ_INT ( this_node, sdpNatRewriteUse);
200 NODE_READ_INT ( this_node, sipOutboundUse);
201 NODE_READ_STRING ( this_node, sipOutboundInstanceId);
202 NODE_READ_STRING ( this_node, sipOutboundRegId);
203 NODE_READ_UNSIGNED( this_node, udpKaIntervalSec);
204 NODE_READ_STRING ( this_node, udpKaData);
205}
206
207void AccountNatConfig::writeObject(ContainerNode &node) const throw(Error)
208{
209 ContainerNode this_node = node.writeNewContainer("AccountNatConfig");
210
211 NODE_WRITE_NUM_T ( this_node, pjsua_stun_use, sipStunUse);
212 NODE_WRITE_NUM_T ( this_node, pjsua_stun_use, mediaStunUse);
213 NODE_WRITE_BOOL ( this_node, iceEnabled);
214 NODE_WRITE_INT ( this_node, iceMaxHostCands);
215 NODE_WRITE_BOOL ( this_node, iceAggressiveNomination);
216 NODE_WRITE_UNSIGNED( this_node, iceNominatedCheckDelayMsec);
217 NODE_WRITE_INT ( this_node, iceWaitNominationTimeoutMsec);
218 NODE_WRITE_BOOL ( this_node, iceNoRtcp);
219 NODE_WRITE_BOOL ( this_node, iceAlwaysUpdate);
220 NODE_WRITE_BOOL ( this_node, turnEnabled);
221 NODE_WRITE_STRING ( this_node, turnServer);
222 NODE_WRITE_NUM_T ( this_node, pj_turn_tp_type, turnConnType);
223 NODE_WRITE_STRING ( this_node, turnUserName);
224 NODE_WRITE_INT ( this_node, turnPasswordType);
225 NODE_WRITE_STRING ( this_node, turnPassword);
226 NODE_WRITE_INT ( this_node, contactRewriteUse);
227 NODE_WRITE_INT ( this_node, contactRewriteMethod);
228 NODE_WRITE_INT ( this_node, viaRewriteUse);
229 NODE_WRITE_INT ( this_node, sdpNatRewriteUse);
230 NODE_WRITE_INT ( this_node, sipOutboundUse);
231 NODE_WRITE_STRING ( this_node, sipOutboundInstanceId);
232 NODE_WRITE_STRING ( this_node, sipOutboundRegId);
233 NODE_WRITE_UNSIGNED( this_node, udpKaIntervalSec);
234 NODE_WRITE_STRING ( this_node, udpKaData);
235}
236
237///////////////////////////////////////////////////////////////////////////////
238
239void AccountMediaConfig::readObject(const ContainerNode &node) throw(Error)
240{
241 ContainerNode this_node = node.readContainer("AccountMediaConfig");
242
243 NODE_READ_BOOL ( this_node, lockCodecEnabled);
244 NODE_READ_BOOL ( this_node, streamKaEnabled);
245 NODE_READ_NUM_T ( this_node, pjmedia_srtp_use, srtpUse);
246 NODE_READ_INT ( this_node, srtpSecureSignaling);
247 NODE_READ_NUM_T ( this_node, pjsua_ipv6_use, ipv6Use);
248 NODE_READ_OBJ ( this_node, transportConfig);
249}
250
251void AccountMediaConfig::writeObject(ContainerNode &node) const throw(Error)
252{
253 ContainerNode this_node = node.writeNewContainer("AccountMediaConfig");
254
255 NODE_WRITE_BOOL ( this_node, lockCodecEnabled);
256 NODE_WRITE_BOOL ( this_node, streamKaEnabled);
257 NODE_WRITE_NUM_T ( this_node, pjmedia_srtp_use, srtpUse);
258 NODE_WRITE_INT ( this_node, srtpSecureSignaling);
259 NODE_WRITE_NUM_T ( this_node, pjsua_ipv6_use, ipv6Use);
260 NODE_WRITE_OBJ ( this_node, transportConfig);
261}
262
263///////////////////////////////////////////////////////////////////////////////
264
265void AccountVideoConfig::readObject(const ContainerNode &node) throw(Error)
266{
267 ContainerNode this_node = node.readContainer("AccountVideoConfig");
268
269 NODE_READ_BOOL ( this_node, autoShowIncoming);
270 NODE_READ_BOOL ( this_node, autoTransmitOutgoing);
271 NODE_READ_UNSIGNED( this_node, windowFlags);
272 NODE_READ_NUM_T ( this_node, pjmedia_vid_dev_index, defaultCaptureDevice);
273 NODE_READ_NUM_T ( this_node, pjmedia_vid_dev_index, defaultRenderDevice);
274 NODE_READ_NUM_T ( this_node, pjmedia_vid_stream_rc_method, rateControlMethod);
275 NODE_READ_UNSIGNED( this_node, rateControlBandwidth);
276}
277
278void AccountVideoConfig::writeObject(ContainerNode &node) const throw(Error)
279{
280 ContainerNode this_node = node.writeNewContainer("AccountVideoConfig");
281
282 NODE_WRITE_BOOL ( this_node, autoShowIncoming);
283 NODE_WRITE_BOOL ( this_node, autoTransmitOutgoing);
284 NODE_WRITE_UNSIGNED( this_node, windowFlags);
285 NODE_WRITE_NUM_T ( this_node, pjmedia_vid_dev_index, defaultCaptureDevice);
286 NODE_WRITE_NUM_T ( this_node, pjmedia_vid_dev_index, defaultRenderDevice);
287 NODE_WRITE_NUM_T ( this_node, pjmedia_vid_stream_rc_method, rateControlMethod);
288 NODE_WRITE_UNSIGNED( this_node, rateControlBandwidth);
289}
290
291///////////////////////////////////////////////////////////////////////////////
292
293AccountConfig::AccountConfig()
294{
295 pjsua_acc_config acc_cfg;
296 pjsua_acc_config_default(&acc_cfg);
297 pjsua_media_config med_cfg;
298 pjsua_media_config_default(&med_cfg);
299 fromPj(acc_cfg, &med_cfg);
300}
301
302/* Convert to pjsip. */
303void AccountConfig::toPj(pjsua_acc_config &ret) const
304{
305 unsigned i;
306
307 pjsua_acc_config_default(&ret);
308
309 // Global
310 ret.priority = priority;
311 ret.id = str2Pj(idUri);
312
313 // AccountRegConfig
314 ret.reg_uri = str2Pj(regConfig.registrarUri);
315 ret.register_on_acc_add = regConfig.registerOnAdd;
316 ret.reg_timeout = regConfig.timeoutSec;
317 ret.reg_retry_interval = regConfig.retryIntervalSec;
318 ret.reg_first_retry_interval= regConfig.firstRetryIntervalSec;
319 ret.reg_delay_before_refresh= regConfig.delayBeforeRefreshSec;
320 ret.drop_calls_on_reg_fail = regConfig.dropCallsOnFail;
321 ret.unreg_timeout = regConfig.unregWaitSec;
322 ret.reg_use_proxy = regConfig.proxyUse;
323 for (i=0; i<regConfig.headers.size(); ++i) {
324 pj_list_push_back(&ret.reg_hdr_list, &regConfig.headers[i].toPj());
325 }
326
327 // AccountSipConfig
328 ret.cred_count = 0;
329 if (sipConfig.authCreds.size() > PJ_ARRAY_SIZE(ret.cred_info))
330 PJSUA2_RAISE_ERROR(PJ_ETOOMANY);
331 for (i=0; i<sipConfig.authCreds.size(); ++i) {
332 const AuthCredInfo &src = sipConfig.authCreds[i];
333 pjsip_cred_info *dst = &ret.cred_info[i];
334
335 dst->realm = str2Pj(src.realm);
336 dst->scheme = str2Pj(src.scheme);
337 dst->username = str2Pj(src.username);
338 dst->data_type = src.dataType;
339 dst->data = str2Pj(src.data);
340 dst->ext.aka.k = str2Pj(src.akaK);
341 dst->ext.aka.op = str2Pj(src.akaOp);
342 dst->ext.aka.amf= str2Pj(src.akaAmf);
343
344 ret.cred_count++;
345 }
346 ret.proxy_cnt = 0;
347 if (sipConfig.proxies.size() > PJ_ARRAY_SIZE(ret.proxy))
348 PJSUA2_RAISE_ERROR(PJ_ETOOMANY);
349 for (i=0; i<sipConfig.proxies.size(); ++i) {
350 ret.proxy[ret.proxy_cnt++] = str2Pj(sipConfig.proxies[i]);
351 }
352 ret.force_contact = str2Pj(sipConfig.contactForced);
353 ret.contact_params = str2Pj(sipConfig.contactParams);
354 ret.contact_uri_params = str2Pj(sipConfig.contactUriParams);
355 ret.auth_pref.initial_auth = sipConfig.authInitialEmpty;
356 ret.auth_pref.algorithm = str2Pj(sipConfig.authInitialAlgorithm);
357 ret.transport_id = sipConfig.transportId;
358
359 // AccountCallConfig
360 ret.call_hold_type = callConfig.holdType;
361 ret.require_100rel = callConfig.prackUse;
362 ret.use_timer = callConfig.timerUse;
363 ret.timer_setting.min_se = callConfig.timerMinSESec;
364 ret.timer_setting.sess_expires = callConfig.timerSessExpiresSec;
365
366 // AccountPresConfig
367 for (i=0; i<presConfig.headers.size(); ++i) {
368 pj_list_push_back(&ret.sub_hdr_list, &presConfig.headers[i].toPj());
369 }
370 ret.publish_enabled = presConfig.publishEnabled;
371 ret.publish_opt.queue_request= presConfig.publishQueue;
372 ret.unpublish_max_wait_time_msec = presConfig.publishShutdownWaitMsec;
373 ret.pidf_tuple_id = str2Pj(presConfig.pidfTupleId);
374
375 // AccountNatConfig
376 ret.sip_stun_use = natConfig.sipStunUse;
377 ret.media_stun_use = natConfig.mediaStunUse;
378 ret.ice_cfg_use = PJSUA_ICE_CONFIG_USE_CUSTOM;
379 ret.ice_cfg.enable_ice = natConfig.iceEnabled;
380 ret.ice_cfg.ice_max_host_cands = natConfig.iceMaxHostCands;
381 ret.ice_cfg.ice_opt.aggressive = natConfig.iceAggressiveNomination;
382 ret.ice_cfg.ice_opt.nominated_check_delay = natConfig.iceNominatedCheckDelayMsec;
383 ret.ice_cfg.ice_opt.controlled_agent_want_nom_timeout = natConfig.iceWaitNominationTimeoutMsec;
384 ret.ice_cfg.ice_no_rtcp = natConfig.iceNoRtcp;
385 ret.ice_cfg.ice_always_update = natConfig.iceAlwaysUpdate;
386
387 ret.turn_cfg_use = PJSUA_TURN_CONFIG_USE_CUSTOM;
388 ret.turn_cfg.enable_turn = natConfig.turnEnabled;
389 ret.turn_cfg.turn_server = str2Pj(natConfig.turnServer);
390 ret.turn_cfg.turn_conn_type = natConfig.turnConnType;
391 ret.turn_cfg.turn_auth_cred.type = PJ_STUN_AUTH_CRED_STATIC;
392 ret.turn_cfg.turn_auth_cred.data.static_cred.username = str2Pj(natConfig.turnUserName);
393 ret.turn_cfg.turn_auth_cred.data.static_cred.data_type = (pj_stun_passwd_type)natConfig.turnPasswordType;
394 ret.turn_cfg.turn_auth_cred.data.static_cred.data = str2Pj(natConfig.turnPassword);
395 ret.turn_cfg.turn_auth_cred.data.static_cred.realm = pj_str((char*)"");
396 ret.turn_cfg.turn_auth_cred.data.static_cred.nonce = pj_str((char*)"");
397
398 ret.allow_contact_rewrite = natConfig.contactRewriteUse;
399 ret.contact_rewrite_method = natConfig.contactRewriteMethod;
400 ret.allow_via_rewrite = natConfig.viaRewriteUse;
401 ret.allow_sdp_nat_rewrite = natConfig.sdpNatRewriteUse;
402 ret.use_rfc5626 = natConfig.sipOutboundUse;
403 ret.rfc5626_instance_id = str2Pj(natConfig.sipOutboundInstanceId);
404 ret.rfc5626_reg_id = str2Pj(natConfig.sipOutboundRegId);
405 ret.ka_interval = natConfig.udpKaIntervalSec;
406 ret.ka_data = str2Pj(natConfig.udpKaData);
407
408 // AccountMediaConfig
409 ret.rtp_cfg = mediaConfig.transportConfig.toPj();
410 ret.lock_codec = mediaConfig.lockCodecEnabled;
411#if defined(PJMEDIA_STREAM_ENABLE_KA) && (PJMEDIA_STREAM_ENABLE_KA != 0)
412 ret.use_stream_ka = mediaConfig.streamKaEnabled;
413#endif
414 ret.use_srtp = mediaConfig.srtpUse;
415 ret.srtp_secure_signaling = mediaConfig.srtpSecureSignaling;
416 ret.ipv6_media_use = mediaConfig.ipv6Use;
417
418 // AccountVideoConfig
419 ret.vid_in_auto_show = videoConfig.autoShowIncoming;
420 ret.vid_out_auto_transmit = videoConfig.autoTransmitOutgoing;
421 ret.vid_wnd_flags = videoConfig.windowFlags;
422 ret.vid_cap_dev = videoConfig.defaultCaptureDevice;
423 ret.vid_rend_dev = videoConfig.defaultRenderDevice;
424 ret.vid_stream_rc_cfg.method= videoConfig.rateControlMethod;
425 ret.vid_stream_rc_cfg.bandwidth = videoConfig.rateControlBandwidth;
426}
427
428/* Initialize from pjsip. */
429void AccountConfig::fromPj(const pjsua_acc_config &prm,
430 const pjsua_media_config *mcfg)
431{
432 const pjsip_hdr *hdr;
433 unsigned i;
434
435 // Global
436 priority = prm.priority;
437 idUri = pj2Str(prm.id);
438
439 // AccountRegConfig
440 regConfig.registrarUri = pj2Str(prm.reg_uri);
441 regConfig.registerOnAdd = (prm.register_on_acc_add != 0);
442 regConfig.timeoutSec = prm.reg_timeout;
443 regConfig.retryIntervalSec = prm.reg_retry_interval;
444 regConfig.firstRetryIntervalSec = prm.reg_first_retry_interval;
445 regConfig.delayBeforeRefreshSec = prm.reg_delay_before_refresh;
446 regConfig.dropCallsOnFail = PJ2BOOL(prm.drop_calls_on_reg_fail);
447 regConfig.unregWaitSec = prm.unreg_timeout;
448 regConfig.proxyUse = prm.reg_use_proxy;
449 regConfig.headers.clear();
450 hdr = prm.reg_hdr_list.next;
451 while (hdr != &prm.reg_hdr_list) {
452 SipHeader new_hdr;
453 new_hdr.fromPj(hdr);
454
455 regConfig.headers.push_back(new_hdr);
456
457 hdr = hdr->next;
458 }
459
460 // AccountSipConfig
461 sipConfig.authCreds.clear();
462 for (i=0; i<prm.cred_count; ++i) {
463 AuthCredInfo cred;
464 const pjsip_cred_info &src = prm.cred_info[i];
465
466 cred.realm = pj2Str(src.realm);
467 cred.scheme = pj2Str(src.scheme);
468 cred.username = pj2Str(src.username);
469 cred.dataType = src.data_type;
470 cred.data = pj2Str(src.data);
471 cred.akaK = pj2Str(src.ext.aka.k);
472 cred.akaOp = pj2Str(src.ext.aka.op);
473 cred.akaAmf = pj2Str(src.ext.aka.amf);
474
475 sipConfig.authCreds.push_back(cred);
476 }
477 sipConfig.proxies.clear();
478 for (i=0; i<prm.proxy_cnt; ++i) {
479 sipConfig.proxies.push_back(pj2Str(prm.proxy[i]));
480 }
481 sipConfig.contactForced = pj2Str(prm.force_contact);
482 sipConfig.contactParams = pj2Str(prm.contact_params);
483 sipConfig.contactUriParams = pj2Str(prm.contact_uri_params);
484 sipConfig.authInitialEmpty = PJ2BOOL(prm.auth_pref.initial_auth);
485 sipConfig.authInitialAlgorithm = pj2Str(prm.auth_pref.algorithm);
486 sipConfig.transportId = prm.transport_id;
487
488 // AccountCallConfig
489 callConfig.holdType = prm.call_hold_type;
490 callConfig.prackUse = prm.require_100rel;
491 callConfig.timerUse = prm.use_timer;
492 callConfig.timerMinSESec = prm.timer_setting.min_se;
493 callConfig.timerSessExpiresSec = prm.timer_setting.sess_expires;
494
495 // AccountPresConfig
496 presConfig.headers.clear();
497 hdr = prm.sub_hdr_list.next;
498 while (hdr != &prm.sub_hdr_list) {
499 SipHeader new_hdr;
500 new_hdr.fromPj(hdr);
501 presConfig.headers.push_back(new_hdr);
502 hdr = hdr->next;
503 }
504 presConfig.publishEnabled = PJ2BOOL(prm.publish_enabled);
505 presConfig.publishQueue = PJ2BOOL(prm.publish_opt.queue_request);
506 presConfig.publishShutdownWaitMsec = prm.unpublish_max_wait_time_msec;
507 presConfig.pidfTupleId = pj2Str(prm.pidf_tuple_id);
508
509 // AccountMwiConfig
510 mwiConfig.enabled = PJ2BOOL(prm.mwi_enabled);
511 mwiConfig.expirationSec = prm.mwi_expires;
512
513 // AccountNatConfig
514 natConfig.sipStunUse = prm.sip_stun_use;
515 natConfig.mediaStunUse = prm.media_stun_use;
516 if (prm.ice_cfg_use == PJSUA_ICE_CONFIG_USE_CUSTOM) {
517 natConfig.iceEnabled = PJ2BOOL(prm.ice_cfg.enable_ice);
518 natConfig.iceMaxHostCands = prm.ice_cfg.ice_max_host_cands;
519 natConfig.iceAggressiveNomination = PJ2BOOL(prm.ice_cfg.ice_opt.aggressive);
520 natConfig.iceNominatedCheckDelayMsec = prm.ice_cfg.ice_opt.nominated_check_delay;
521 natConfig.iceWaitNominationTimeoutMsec = prm.ice_cfg.ice_opt.controlled_agent_want_nom_timeout;
522 natConfig.iceNoRtcp = PJ2BOOL(prm.ice_cfg.ice_no_rtcp);
523 natConfig.iceAlwaysUpdate = PJ2BOOL(prm.ice_cfg.ice_always_update);
524 } else {
525 pjsua_media_config default_mcfg;
526 if (!mcfg) {
527 pjsua_media_config_default(&default_mcfg);
528 mcfg = &default_mcfg;
529 }
530 natConfig.iceEnabled = PJ2BOOL(mcfg->enable_ice);
531 natConfig.iceMaxHostCands= mcfg->ice_max_host_cands;
532 natConfig.iceAggressiveNomination = PJ2BOOL(mcfg->ice_opt.aggressive);
533 natConfig.iceNominatedCheckDelayMsec = mcfg->ice_opt.nominated_check_delay;
534 natConfig.iceWaitNominationTimeoutMsec = mcfg->ice_opt.controlled_agent_want_nom_timeout;
535 natConfig.iceNoRtcp = PJ2BOOL(mcfg->ice_no_rtcp);
536 natConfig.iceAlwaysUpdate = PJ2BOOL(mcfg->ice_always_update);
537 }
538
539 if (prm.turn_cfg_use == PJSUA_TURN_CONFIG_USE_CUSTOM) {
540 natConfig.turnEnabled = PJ2BOOL(prm.turn_cfg.enable_turn);
541 natConfig.turnServer = pj2Str(prm.turn_cfg.turn_server);
542 natConfig.turnConnType = prm.turn_cfg.turn_conn_type;
543 natConfig.turnUserName = pj2Str(prm.turn_cfg.turn_auth_cred.data.static_cred.username);
544 natConfig.turnPasswordType = prm.turn_cfg.turn_auth_cred.data.static_cred.data_type;
545 natConfig.turnPassword = pj2Str(prm.turn_cfg.turn_auth_cred.data.static_cred.data);
546 } else {
547 pjsua_media_config default_mcfg;
548 if (!mcfg) {
549 pjsua_media_config_default(&default_mcfg);
550 mcfg = &default_mcfg;
551 }
552 natConfig.turnEnabled = PJ2BOOL(mcfg->enable_turn);
553 natConfig.turnServer = pj2Str(mcfg->turn_server);
554 natConfig.turnConnType = mcfg->turn_conn_type;
555 natConfig.turnUserName = pj2Str(mcfg->turn_auth_cred.data.static_cred.username);
556 natConfig.turnPasswordType = mcfg->turn_auth_cred.data.static_cred.data_type;
557 natConfig.turnPassword = pj2Str(mcfg->turn_auth_cred.data.static_cred.data);
558 }
559 natConfig.contactRewriteUse = prm.allow_contact_rewrite;
560 natConfig.contactRewriteMethod = prm.contact_rewrite_method;
561 natConfig.viaRewriteUse = prm.allow_via_rewrite;
562 natConfig.sdpNatRewriteUse = prm.allow_sdp_nat_rewrite;
563 natConfig.sipOutboundUse = prm.use_rfc5626;
564 natConfig.sipOutboundInstanceId = pj2Str(prm.rfc5626_instance_id);
565 natConfig.sipOutboundRegId = pj2Str(prm.rfc5626_reg_id);
566 natConfig.udpKaIntervalSec = prm.ka_interval;
567 natConfig.udpKaData = pj2Str(prm.ka_data);
568
569 // AccountMediaConfig
570 mediaConfig.transportConfig.fromPj(prm.rtp_cfg);
571 mediaConfig.lockCodecEnabled= PJ2BOOL(prm.lock_codec);
572#if defined(PJMEDIA_STREAM_ENABLE_KA) && (PJMEDIA_STREAM_ENABLE_KA != 0)
573 mediaConfig.streamKaEnabled = PJ2BOOL(prm.use_stream_ka);
574#else
575 mediaConfig.streamKaEnabled = false;
576#endif
577 mediaConfig.srtpUse = prm.use_srtp;
578 mediaConfig.srtpSecureSignaling = prm.srtp_secure_signaling;
579 mediaConfig.ipv6Use = prm.ipv6_media_use;
580
581 // AccountVideoConfig
582 videoConfig.autoShowIncoming = PJ2BOOL(prm.vid_in_auto_show);
583 videoConfig.autoTransmitOutgoing = PJ2BOOL(prm.vid_out_auto_transmit);
584 videoConfig.windowFlags = prm.vid_wnd_flags;
585 videoConfig.defaultCaptureDevice = prm.vid_cap_dev;
586 videoConfig.defaultRenderDevice = prm.vid_rend_dev;
587 videoConfig.rateControlMethod = prm.vid_stream_rc_cfg.method;
588 videoConfig.rateControlBandwidth = prm.vid_stream_rc_cfg.bandwidth;
589}
590
591void AccountConfig::readObject(const ContainerNode &node) throw(Error)
592{
593 ContainerNode this_node = node.readContainer("AccountConfig");
594
595 NODE_READ_INT ( this_node, priority);
596 NODE_READ_STRING ( this_node, idUri);
597 NODE_READ_OBJ ( this_node, regConfig);
598 NODE_READ_OBJ ( this_node, sipConfig);
599 NODE_READ_OBJ ( this_node, callConfig);
600 NODE_READ_OBJ ( this_node, presConfig);
601 NODE_READ_OBJ ( this_node, mwiConfig);
602 NODE_READ_OBJ ( this_node, natConfig);
603 NODE_READ_OBJ ( this_node, mediaConfig);
604 NODE_READ_OBJ ( this_node, videoConfig);
605}
606
607void AccountConfig::writeObject(ContainerNode &node) const throw(Error)
608{
609 ContainerNode this_node = node.writeNewContainer("AccountConfig");
610
611 NODE_WRITE_INT ( this_node, priority);
612 NODE_WRITE_STRING ( this_node, idUri);
613 NODE_WRITE_OBJ ( this_node, regConfig);
614 NODE_WRITE_OBJ ( this_node, sipConfig);
615 NODE_WRITE_OBJ ( this_node, callConfig);
616 NODE_WRITE_OBJ ( this_node, presConfig);
617 NODE_WRITE_OBJ ( this_node, mwiConfig);
618 NODE_WRITE_OBJ ( this_node, natConfig);
619 NODE_WRITE_OBJ ( this_node, mediaConfig);
620 NODE_WRITE_OBJ ( this_node, videoConfig);
621}
622
623
624///////////////////////////////////////////////////////////////////////////////
625
626void AccountInfo::fromPj(const pjsua_acc_info &pai)
627{
628 id = pai.id;
629 isDefault = pai.is_default != 0;
630 uri = pj2Str(pai.acc_uri);
631 regIsConfigured = pai.has_registration != 0;
632 regIsActive = pai.has_registration && pai.expires > 0 &&
633 (pai.status / 100 == 2);
634 regExpiresSec = pai.expires;
635 regStatus = pai.status;
636 regStatusText = pj2Str(pai.status_text);
637 regLastErr = pai.reg_last_err;
638 onlineStatus = pai.online_status != 0;
639 onlineStatusText = pj2Str(pai.online_status_text);
640}
641
642///////////////////////////////////////////////////////////////////////////////
643
644Account::Account()
645: id(PJSUA_INVALID_ID)
646{
647}
648
649Account::~Account()
650{
651 /* If this instance is deleted, also delete the corresponding account in
652 * PJSUA library.
653 */
654 if (isValid() && pjsua_get_state() < PJSUA_STATE_CLOSING) {
655 // Cleanup buddies in the buddy list
656 while(buddyList.size() > 0) {
657 Buddy *b = buddyList[0];
658 delete b; /* this will remove itself from the list */
659 }
660
661 pjsua_acc_set_user_data(id, NULL);
662 pjsua_acc_del(id);
663 }
664}
665
666void Account::create(const AccountConfig &acc_cfg,
667 bool make_default) throw(Error)
668{
669 pjsua_acc_config pj_acc_cfg;
670
671 acc_cfg.toPj(pj_acc_cfg);
672 pj_acc_cfg.user_data = (void*)this;
673 PJSUA2_CHECK_EXPR( pjsua_acc_add(&pj_acc_cfg, make_default, &id) );
674}
675
676void Account::modify(const AccountConfig &acc_cfg) throw(Error)
677{
678 pjsua_acc_config pj_acc_cfg;
679
680 acc_cfg.toPj(pj_acc_cfg);
681 pj_acc_cfg.user_data = (void*)this;
682 PJSUA2_CHECK_EXPR( pjsua_acc_modify(id, &pj_acc_cfg) );
683}
684
685bool Account::isValid() const
686{
687 return pjsua_acc_is_valid(id) != 0;
688}
689
690void Account::setDefault() throw(Error)
691{
692 PJSUA2_CHECK_EXPR( pjsua_acc_set_default(id) );
693}
694
695bool Account::isDefault() const
696{
697 return pjsua_acc_get_default() == id;
698}
699
700int Account::getId() const
701{
702 return id;
703}
704
705Account *Account::lookup(int acc_id)
706{
707 return (Account*)pjsua_acc_get_user_data(acc_id);
708}
709
710AccountInfo Account::getInfo() const throw(Error)
711{
712 pjsua_acc_info pj_ai;
713 AccountInfo ai;
714
715 PJSUA2_CHECK_EXPR( pjsua_acc_get_info(id, &pj_ai) );
716 ai.fromPj(pj_ai);
717 return ai;
718}
719
720void Account::setRegistration(bool renew) throw(Error)
721{
722 PJSUA2_CHECK_EXPR( pjsua_acc_set_registration(id, renew) );
723}
724
725void
726Account::setOnlineStatus(const PresenceStatus &pres_st) throw(Error)
727{
728 pjrpid_element pj_rpid;
729
730 pj_bzero(&pj_rpid, sizeof(pj_rpid));
731 pj_rpid.type = PJRPID_ELEMENT_TYPE_PERSON;
732 pj_rpid.activity = pres_st.activity;
733 pj_rpid.id = str2Pj(pres_st.rpidId);
734 pj_rpid.note = str2Pj(pres_st.note);
735
736 PJSUA2_CHECK_EXPR( pjsua_acc_set_online_status2(
737 id, pres_st.status == PJSUA_BUDDY_STATUS_ONLINE,
738 &pj_rpid) );
739}
740
741void Account::setTransport(TransportId tp_id) throw(Error)
742{
743 PJSUA2_CHECK_EXPR( pjsua_acc_set_transport(id, tp_id) );
744}
745
746void Account::presNotify(const PresNotifyParam &prm) throw(Error)
747{
748 pj_str_t pj_state_str = str2Pj(prm.stateStr);
749 pj_str_t pj_reason = str2Pj(prm.reason);
750 pjsua_msg_data msg_data;
751 prm.txOption.toPj(msg_data);
752
753 PJSUA2_CHECK_EXPR( pjsua_pres_notify(id, (pjsua_srv_pres*)prm.srvPres,
754 prm.state, &pj_state_str,
755 &pj_reason, prm.withBody,
756 &msg_data) );
757}
758
759const BuddyVector& Account::enumBuddies() const throw(Error)
760{
761 return buddyList;
762}
763
764Buddy* Account::findBuddy(string uri, FindBuddyMatch *buddy_match) const
765 throw(Error)
766{
767 if (!buddy_match) {
768 static FindBuddyMatch def_bm;
769 buddy_match = &def_bm;
770 }
771
772 for (unsigned i = 0; i < buddyList.size(); i++) {
773 if (buddy_match->match(uri, *buddyList[i]))
774 return buddyList[i];
775 }
776 PJSUA2_RAISE_ERROR(PJ_ENOTFOUND);
777}
778
779void Account::addBuddy(Buddy *buddy)
780{
781 pj_assert(buddy);
782
783 buddyList.push_back(buddy);
784}
785
786void Account::removeBuddy(Buddy *buddy)
787{
788 pj_assert(buddy);
789
790 BuddyVector::iterator it;
791 for (it = buddyList.begin(); it != buddyList.end(); it++) {
792 if (*it == buddy) {
793 buddyList.erase(it);
794 return;
795 }
796 }
797
798 pj_assert(!"Bug! Buddy to be removed is not in the buddy list!");
799}