3 from __future__
import print_function
9 from urllib.parse
import urlparse
11 from urlparse
import urlparse
13 import astconfigparser
24 """Finds a section based upon the given type, adding it if not found.""" 25 def __find_dict(mdicts, key, val):
26 """Given a list of multi-dicts, return the multi-dict that contains 27 the given key/value pair.""" 30 return key
in d
and val
in d[key]
33 return [d
for d
in mdicts
if found(d)][0]
35 raise LookupError(
"Dictionary not located for key = %s, value = %s" 39 return __find_dict(pjsip.section(section),
'type', type)
42 sect = pjsip.add_section(section)
47 def ignore(key=None, val=None, section=None, pjsip=None,
48 nmapped=None, type='endpoint'):
49 """Ignore a key and mark it as mapped""" 52 def set_value(key=None, val=None, section=None, pjsip=None,
53 nmapped=None, type='endpoint'):
54 """Sets the key to the value within the section in pjsip.conf""" 55 def _set_value(k, v, s, r, n):
56 set_value(key
if key
else k, v, s, r, n, type)
60 if not val
and not section:
65 val[0]
if isinstance(val, list)
else val
68 def merge_value(key=None, val=None, section=None, pjsip=None,
69 nmapped=None, type='endpoint', section_to=None,
71 """Merge values from the given section with those from the default.""" 72 def _merge_value(k, v, s, r, n):
73 merge_value(key
if key
else k, v, s, r, n, type, section_to, key_to)
77 if not val
and not section:
82 sect = sip.section(section)[0]
84 sect = sip.default(section)[0]
86 for i
in sect.get_merged(key):
88 section_to
if section_to
else section,
92 nmapped=None, type='endpoint', section_to=None,
94 """Merge values from allow/deny with those from the default. Special treatment for all""" 95 def _merge_codec_value(k, v, s, r, n):
100 if not val
and not section:
101 return _merge_codec_value
105 disallow = sip.get(section,
'disallow')[0]
106 if disallow ==
'all':
108 for i
in sip.get(section,
'allow'):
109 set_value(key, i, section, pjsip, nmapped, type)
111 merge_value(key, val, section, pjsip, nmapped, type, section_to, key_to)
113 print(
"lookup error", file=sys.stderr)
114 merge_value(key, val, section, pjsip, nmapped, type, section_to, key_to)
116 elif key ==
'disallow':
118 allow = sip.get(section,
'allow')[0]
121 for i
in sip.get(section,
'disallow'):
122 set_value(key, i, section, pjsip, nmapped, type)
124 merge_value(key, val, section, pjsip, nmapped, type, section_to, key_to)
126 merge_value(key, val, section, pjsip, nmapped, type, section_to, key_to)
129 merge_value(key, val, section, pjsip, nmapped, type, section_to, key_to)
133 """Write non-mapped sip.conf values to the non-mapped object""" 134 def _non_mapped(section, key, val):
135 """Writes a non-mapped value from sip.conf to the non-mapped object.""" 136 if section
not in nmapped:
138 if isinstance(val, list):
142 nmapped[section][0][key] = v
144 nmapped[section][0][key] = val
156 Sets the dtmfmode value. If value matches allowable option in pjsip 157 then map it, otherwise set it to none. 161 if val ==
'inband' or val ==
'info' or val ==
'auto':
162 set_value(key, val, section, pjsip, nmapped)
163 elif val ==
'rfc2833':
164 set_value(key,
'rfc4733', section, pjsip, nmapped)
166 nmapped(section, key, val +
" ; did not fully map - set to none")
167 set_value(key,
'none', section, pjsip, nmapped)
171 """Sets values from udptl into the appropriate pjsip.conf options.""" 173 val = sip.get(section,
't38pt_udptl')[0]
176 val = sip.get(
'general',
't38pt_udptl')[0]
182 set_value(
't38_udptl',
'yes', section, pjsip, nmapped)
184 set_value(
't38_udptl',
'no', section, pjsip, nmapped)
185 if 'redundancy' in val:
189 set_value(
't38_udptl_ec', ec, section, pjsip, nmapped)
192 """Sets values from nat into the appropriate pjsip.conf options.""" 196 set_value(
'rtp_symmetric',
'yes', section, pjsip, nmapped)
197 set_value(
'rewrite_contact',
'yes', section, pjsip, nmapped)
199 set_value(
'rtp_symmetric',
'yes', section, pjsip, nmapped)
200 if 'force_rport' in val:
201 set_value(
'force_rport',
'yes', section, pjsip, nmapped)
202 set_value(
'rewrite_contact',
'yes', section, pjsip, nmapped)
207 Sets the timers in pjsip.conf from the session-timers option 216 if val ==
'originate':
217 set_value(
'timers',
'always', section, pjsip, nmapped)
218 elif val ==
'refuse':
219 set_value(
'timers',
'no', section, pjsip, nmapped)
221 set_value(
'timers',
'yes', section, pjsip, nmapped)
226 Maps values from the sip.conf comma separated direct_media option 227 into pjsip.conf direct_media options. 230 set_value(
'direct_media',
'yes', section, pjsip, nmapped)
232 set_value(
'direct_media_method',
'update', section, pjsip, nmapped)
233 if 'outgoing' in val:
234 set_value(
'directed_media_glare_mitigation',
'outgoing', section,
237 set_value(
'disable_directed_media_on_nat',
'yes', section, pjsip,
240 set_value(
'direct_media',
'no', section, pjsip, nmapped)
244 """Sets the send_rpid/pai values in pjsip.conf.""" 245 if val ==
'yes' or val ==
'rpid':
246 set_value(
'send_rpid',
'yes', section, pjsip, nmapped)
248 set_value(
'send_pai',
'yes', section, pjsip, nmapped)
252 """Sets the media_encryption value in pjsip.conf""" 254 dtls = sip.get(section,
'dtlsenable')[0]
262 set_value(
'media_encryption',
'sdes', section, pjsip, nmapped)
267 If record on/off feature is set to automixmon then set 268 one_touch_recording, otherwise it can't be mapped. 270 set_value(
'one_touch_recording',
'yes', section, pjsip, nmapped)
271 set_value(key, val, section, pjsip, nmapped)
274 """Sets the record_on_feature in pjsip.conf""" 278 """Sets the record_off_feature in pjsip.conf""" 282 """Sets the inband_progress value in pjsip.conf""" 286 set_value(
'inband_progress', val, section, pjsip, nmapped)
289 def build_host(config, host, section='general', port_key=None):
291 Returns a string composed of a host:port. This assumes that the host 292 may have a port as part of the initial value. The port_key overrides 293 a port in host, see parameter 'bindport' in chan_sip. 296 socket.inet_pton(socket.AF_INET6, host)
297 if not host.startswith(
'['):
299 host =
'[' + host +
']' 305 url = urlparse(
'sip://' + host)
309 port = config.get(section, port_key)[0]
312 socket.inet_pton(socket.AF_INET6, host)
313 if not host.startswith(
'['):
315 host =
'[' + host +
']' 318 return host +
':' + port
329 Sets contact info in an AOR section in pjsip.conf using 'host' 330 and 'port' data from sip.conf 334 set_value(
'aors', section, section, pjsip, nmapped)
337 set_value(
'max_contacts', 1, section, pjsip, nmapped,
'aor')
349 user = sip.multi_get(section, [
'defaultuser',
'username'])[0]
355 result +=
build_host(sip, val, section,
'port')
357 set_value(
'contact', result, section, pjsip, nmapped,
'aor')
362 Determines whether a mailbox configured in sip.conf should map to 363 an endpoint or aor in pjsip.conf. If subscribemwi is true, then the 364 mailboxes are set on an aor. Otherwise the mailboxes are set on the 369 subscribemwi = sip.get(section,
'subscribemwi')[0]
374 set_value(
'mailboxes', val, section, pjsip, nmapped,
'aor' 375 if subscribemwi ==
'yes' else 'endpoint')
380 Sets up authentication information for a specific endpoint based on the 381 'secret' setting on a peer in sip.conf 383 set_value(
'username', section, section, pjsip, nmapped,
'auth')
391 set_value(
'password', val, section, pjsip, nmapped,
'auth')
393 set_value(
'md5_cred', val, section, pjsip, nmapped,
'auth')
394 set_value(
'auth_type',
'md5', section, pjsip, nmapped,
'auth')
398 auths = sip.get(
'authentication',
'auth')
400 user, at, realm = i.partition(
'@')
405 realm_str =
','.join(realms)
407 set_value(
'auth', section, section, pjsip, nmapped)
408 set_value(
'outbound_auth', realm_str, section, pjsip, nmapped)
413 Examines the 'type' field for a sip.conf peer and creates an identify 414 section if the type is either 'peer' or 'friend'. The identify section uses 415 either the host or defaultip field of the sip.conf peer. 417 if val !=
'peer' and val !=
'friend':
421 ip = sip.get(section,
'host')[0]
427 ip = sip.get(section,
'defaultip')[0]
431 set_value(
'endpoint', section, section, pjsip, nmapped,
'identify')
432 set_value(
'match', ip, section, pjsip, nmapped,
'identify')
436 """Sets the srtp_tag32 option based on sip.conf encryption_taglen""" 438 set_value(
'srtp_tag_32',
'yes', section, pjsip, nmapped)
442 """Optionally sets media_encryption=dtls based on sip.conf dtlsenable""" 444 set_value(
'media_encryption',
'dtls', section, pjsip, nmapped)
455 [
'context', set_value],
456 [
'dtmfmode', set_dtmfmode],
457 [
'disallow', merge_codec_value],
458 [
'allow', merge_codec_value],
461 [
'rtptimeout',
set_value(
'rtp_timeout')],
462 [
'icesupport',
set_value(
'ice_support')],
464 [
'outboundproxy',
set_value(
'outbound_proxy')],
465 [
'mohsuggest',
set_value(
'moh_suggest')],
466 [
'session-timers', set_timers],
467 [
'session-minse',
set_value(
'timers_min_se')],
468 [
'session-expires',
set_value(
'timers_sess_expires')],
470 [
'canreinvite', set_direct_media],
471 [
'directmedia', set_direct_media],
475 [
'callerid', set_value],
476 [
'callingpres',
set_value(
'callerid_privacy')],
478 [
'trustrpid',
set_value(
'trust_id_inbound')],
479 [
'sendrpid', from_sendrpid],
480 [
'send_diversion', set_value],
481 [
'encryption', set_media_encryption],
483 [
'recordonfeature', set_record_on_feature],
484 [
'recordofffeature', set_record_off_feature],
485 [
'progressinband', from_progressinband],
487 [
'pickupgroup',
set_value(
'pickup_group')],
488 [
'namedcallgroup',
set_value(
'named_call_group')],
489 [
'namedpickupgroup',
set_value(
'named_pickup_group')],
490 [
'allowtransfer',
set_value(
'allow_transfer')],
492 [
'fromdomain',
set_value(
'from_domain')],
494 [
'tos_audio', set_value],
495 [
'tos_video', set_value],
496 [
'cos_audio', set_value],
497 [
'cos_video', set_value],
499 [
'sdpsession',
set_value(
'sdp_session')],
501 [
'language', set_value],
502 [
'allowsubscribe',
set_value(
'allow_subscribe')],
503 [
'subscribecontext',
set_value(
'subscribe_context')],
504 [
'subminexpiry',
set_value(
'sub_min_expiry')],
505 [
'rtp_engine', set_value],
506 [
'mailbox', from_mailbox],
507 [
'busylevel',
set_value(
'device_state_busy_at')],
508 [
'secret', setup_auth],
509 [
'md5secret', setup_auth],
510 [
'type', setup_ident],
511 [
'dtlsenable', from_dtlsenable],
512 [
'dtlsverify',
set_value(
'dtls_verify')],
514 [
'dtlscertfile',
set_value(
'dtls_cert_file')],
515 [
'dtlsprivatekey',
set_value(
'dtls_private_key')],
516 [
'dtlscipher',
set_value(
'dtls_cipher')],
517 [
'dtlscafile',
set_value(
'dtls_ca_file')],
518 [
'dtlscapath',
set_value(
'dtls_ca_path')],
520 [
'encryption_taglen', from_encryption_taglen],
526 [
'qualifyfreq',
set_value(
'qualify_frequency', type=
'aor')],
527 [
'maxexpiry',
set_value(
'maximum_expiration', type=
'aor')],
528 [
'minexpiry',
set_value(
'minimum_expiration', type=
'aor')],
529 [
'defaultexpiry',
set_value(
'default_expiration', type=
'aor')],
541 [
'permit',
merge_value(type=
'acl', section_to=
'acl')],
542 [
'deny',
merge_value(type=
'acl', section_to=
'acl')],
543 [
'acl',
merge_value(type=
'acl', section_to=
'acl')],
544 [
'contactpermit',
merge_value(type=
'acl', section_to=
'acl', key_to=
'contact_permit')],
545 [
'contactdeny',
merge_value(type=
'acl', section_to=
'acl', key_to=
'contact_deny')],
546 [
'contactacl',
merge_value(type=
'acl', section_to=
'acl', key_to=
'contact_acl')],
592 Given an address in the form 'host:port' separate the host and port 594 Returns a two-tuple of strings, (host, port). If no port is present in the 595 string, then the port section of the tuple is None. 598 socket.inet_pton(socket.AF_INET6, addr)
599 if not addr.startswith(
'['):
606 url = urlparse(
'sip://' + addr)
608 return (url.hostname, url.port)
613 sip.conf has several global settings that in pjsip.conf apply to individual 614 transports. This function adds these global settings to each individual 617 The settings included are: 618 externaddr (or externip) 620 externtcpport for TCP 621 externtlsport for TLS 627 extern_addr = sip.multi_get(
'general', [
'externaddr',
'externip',
631 port = sip.get(
'general',
'extern' + protocol +
'port')[0]
634 set_value(
'external_media_address', host, section, pjsip,
635 nmapped,
'transport')
636 set_value(
'external_signaling_address', host, section, pjsip,
637 nmapped,
'transport')
639 set_value(
'external_signaling_port', port, section, pjsip,
640 nmapped,
'transport')
645 merge_value(
'localnet', sip.get(
'general',
'localnet')[0],
'general',
646 pjsip, nmapped,
'transport', section,
"local_net")
652 set_value(
'tos', sip.get(
'general',
'tos_sip')[0], section, pjsip,
653 nmapped,
'transport')
658 set_value(
'cos', sip.get(
'general',
'cos_sip')[0], section, pjsip,
659 nmapped,
'transport')
666 Given the protocol (udp, tcp, or tls), return 667 - the bind address, like [::] or 0.0.0.0 668 - name of the section to be created 670 section =
'transport-' + protocol
673 if protocol !=
'udp':
675 enabled = sip.get(
'general', protocol +
'enable')[0]
678 return (
None, section)
680 return (
None, section)
683 bind = pjsip.get(section,
'bind')[0]
686 return (
None, section)
691 bind = pjsip.get(section +
'6',
'bind')[0]
698 bind +=
':' +
str(port)
702 bind = sip.get(
'general', protocol +
'bindaddr')[0]
704 if protocol ==
'udp':
706 bind = sip.get(
'general',
'bindaddr')[0]
711 bind = pjsip.get(
'transport-udp6',
'bind')[0]
713 bind = pjsip.get(
'transport-udp',
'bind')[0]
715 if protocol ==
'tls':
721 if protocol ==
'udp':
722 host =
build_host(sip, bind,
'general',
'bindport')
726 return (host, section)
731 Creates a 'transport-udp' section in the pjsip.conf file based 732 on the following settings from sip.conf: 734 bindaddr (or udpbindaddr) 738 bind, section =
get_bind(sip, pjsip, protocol)
740 set_value(
'protocol', protocol, section, pjsip, nmapped,
'transport')
741 set_value(
'bind', bind, section, pjsip, nmapped,
'transport')
747 Creates a 'transport-tcp' section in the pjsip.conf file based 748 on the following settings from sip.conf: 751 tcpbindaddr (or bindaddr) 754 bind, section =
get_bind(sip, pjsip, protocol)
758 set_value(
'protocol', protocol, section, pjsip, nmapped,
'transport')
759 set_value(
'bind', bind, section, pjsip, nmapped,
'transport')
764 """Sets cert_file based on sip.conf tlscertfile""" 765 set_value(
'cert_file', val, section, pjsip, nmapped,
770 """Sets privkey_file based on sip.conf tlsprivatekey or sslprivatekey""" 771 set_value(
'priv_key_file', val, section, pjsip, nmapped,
776 """Sets cipher based on sip.conf tlscipher or sslcipher""" 779 print(
'chan_sip ciphers do not match 1:1 with PJSIP ciphers.' \
780 ' You should manually review and adjust this.', file=sys.stderr)
782 set_value(
'cipher', val, section, pjsip, nmapped,
'transport')
786 """Sets ca_list_file based on sip.conf tlscafile""" 787 set_value(
'ca_list_file', val, section, pjsip, nmapped,
792 """Sets ca_list_path based on sip.conf tlscapath""" 793 set_value(
'ca_list_path', val, section, pjsip, nmapped,
798 """Sets verify_client based on sip.conf tlsverifyclient""" 799 set_value(
'verify_client', val, section, pjsip, nmapped,
804 """Sets verify_server based on sip.conf tlsdontverifyserver""" 807 set_value(
'verify_server',
'yes', section, pjsip, nmapped,
810 set_value(
'verify_server',
'no', section, pjsip, nmapped,
816 Creates a 'transport-tls' section in pjsip.conf based on the following 817 settings from sip.conf: 819 tlsenable (or sslenable) 820 tlsbindaddr (or sslbindaddr or bindaddr) 821 tlsprivatekey (or sslprivatekey) 822 tlscipher (or sslcipher) 824 tlscapath (or tlscadir) 825 tlscertfile (or sslcert or tlscert) 828 tlsclientmethod (or sslclientmethod) 831 bind, section =
get_bind(sip, pjsip, protocol)
835 set_value(
'protocol', protocol, section, pjsip, nmapped,
'transport')
836 set_value(
'bind', bind, section, pjsip, nmapped,
'transport')
840 ([
'tlscertfile',
'sslcert',
'tlscert'], set_tls_cert_file),
841 ([
'tlsprivatekey',
'sslprivatekey'], set_tls_private_key),
842 ([
'tlscipher',
'sslcipher'], set_tls_cipher),
843 ([
'tlscafile'], set_tls_cafile),
844 ([
'tlscapath',
'tlscadir'], set_tls_capath),
845 ([
'tlsverifyclient'], set_tls_verifyclient),
846 ([
'tlsdontverifyserver'], set_tls_verifyserver)
851 i[1](sip.multi_get(
'general', i[0])[0], pjsip, section, nmapped)
856 method = sip.multi_get(
'general', [
'tlsclientmethod',
857 'sslclientmethod'])[0]
858 if section !=
'transport-' + protocol +
'6':
859 print(
'In chan_sip, you specified the TLS version. With chan_sip,' \
860 ' this was just for outbound client connections. In' \
861 ' chan_pjsip, this value is for client and server. Instead,' \
862 ' consider not to specify \'tlsclientmethod\' for chan_sip' \
863 ' and \'method = sslv23\' for chan_pjsip.', file=sys.stderr)
866 OpenSSL emerged during the 90s. SSLv2 and SSLv3 were the only 867 existing methods at that time. The OpenSSL project continued. And as 868 of today (OpenSSL 1.0.2) this does not start SSLv2 and SSLv3 anymore 869 but TLSv1.0 and v1.2. Or stated differently: This method should 870 have been called 'method = secure' or 'method = automatic' back in 871 the 90s. The PJProject did not realize this and uses 'tlsv1' as 872 default when unspecified, which disables TLSv1.2. chan_sip used 873 'sslv23' as default when unspecified, which gives TLSv1.0 and v1.2. 876 set_value(
'method', method, section, pjsip, nmapped,
'transport')
881 Finds options in sip.conf general section pertaining to 882 transport configuration and creates appropriate transport 883 configuration sections in pjsip.conf. 885 sip.conf only allows a single UDP transport, TCP transport, 886 and TLS transport for each IP version. As such, the mapping 887 into PJSIP can be made consistent by defining six sections: 896 To accommodate the default behaviors in sip.conf, we'll need to 897 create the UDP transports first, followed by the TCP and TLS transports. 914 Creates auth sections based on entries in the authentication section of 915 sip.conf. pjsip.conf section names consist of "auth_" followed by the name 919 auths = sip.get(
'authentication',
'auth')
924 creds, at, realm = i.partition(
'@')
925 if not at
and not realm:
928 user, colon, secret = creds.partition(
':')
930 user, sharp, md5 = creds.partition(
'#')
934 section =
"auth_" + realm
936 set_value(
'realm', realm, section, pjsip, nmapped,
'auth')
937 set_value(
'username', user, section, pjsip, nmapped,
'auth')
939 set_value(
'password', secret, section, pjsip, nmapped,
'auth')
941 set_value(
'md5_cred', md5, section, pjsip, nmapped,
'auth')
942 set_value(
'auth_type',
'md5', section, pjsip, nmapped,
'auth')
947 Class for parsing and storing information in a register line in sip.conf. 949 def __init__(self, line, retry_interval, max_attempts, outbound_proxy):
957 Initial parsing routine for register lines in sip.conf. 959 This splits the line into the part before the host, and the part 960 after the '@' symbol. These two parts are then passed to their 967 prehost, at, host_part = line.rpartition(
'@')
976 Parsing routine for the part after the final '@' in a register line. 977 The strategy is to use partition calls to peel away the data starting 978 from the right and working to the left. 980 pre_expiry, sep, expiry = host_part.partition(
'~')
981 pre_extension, sep, self.
extension = pre_expiry.partition(
'/')
982 self.host, sep, self.
port = pre_extension.partition(
':')
984 self.
expiry = expiry
if expiry
else '120' 988 Parsing routine for the part before the final '@' in a register line. 989 The only mandatory part of this line is the user portion. The strategy 990 here is to start by using partition calls to remove everything to 991 the right of the user, then finish by using rpartition calls to remove 992 everything to the left of the user. 996 protocols = [
'udp',
'tcp',
'tls']
997 for protocol
in protocols:
998 position = user_part.find(protocol +
'://')
1000 post_transport = user_part[position + 6:]
1001 self.
peer, sep, self.
protocol = user_part[:position + 3].rpartition(
'?')
1002 user_part = post_transport
1005 colons = user_part.count(
':')
1008 pre_auth, sep, port_auth = user_part.partition(
':')
1009 self.domainport, sep, auth = port_auth.partition(
':')
1013 pre_auth, sep, auth = user_part.partition(
':')
1017 pre_auth, sep, self.
secret = user_part.partition(
':')
1020 pre_auth = user_part
1025 self.user, sep, self.
domain = pre_auth.partition(
'@')
1029 Write parsed registration data into a section in pjsip.conf 1031 Most of the data in self will get written to a registration section. 1032 However, there will also need to be an auth section created if a 1033 secret or authuser is present. 1035 General mapping of values: 1036 A combination of self.host and self.port is server_uri 1037 A combination of self.user, self.domain, and self.domainport is 1039 self.expiry is expiration 1040 self.extension is contact_user 1041 self.protocol will map to one of the mapped transports 1042 self.secret and self.authuser will result in a new auth section, and 1043 outbound_auth will point to that section. 1044 XXX self.peer really doesn't map to anything :( 1047 section =
'reg_' + self.host
1050 nmapped,
'registration')
1061 set_value(
'transport',
'transport-udp', section, pjsip, nmapped,
1064 set_value(
'transport',
'transport-tcp', section, pjsip, nmapped,
1067 set_value(
'transport',
'transport-tls', section, pjsip, nmapped,
1070 auth_section =
'auth_reg_' + self.host
1072 if hasattr(self,
'secret')
and self.
secret:
1076 else self.user, auth_section, pjsip, nmapped,
'auth')
1077 set_value(
'outbound_auth', auth_section, section, pjsip, nmapped,
1080 client_uri =
"sip:%s@" % self.user
1082 client_uri += self.
domain 1084 client_uri += self.host
1086 if hasattr(self,
'domainport')
and self.domainport:
1087 client_uri +=
":" + self.domainport
1089 client_uri +=
":" + self.
port 1091 set_value(
'client_uri', client_uri, section, pjsip, nmapped,
1094 server_uri =
"sip:%s" % self.host
1096 server_uri +=
":" + self.
port 1098 set_value(
'server_uri', server_uri, section, pjsip, nmapped,
1103 nmapped,
'registration')
1108 Gathers all necessary outbound registration data in sip.conf and creates 1109 corresponding registration sections in pjsip.conf 1112 regs = sip.get(
'general',
'register')
1117 retry_interval = sip.get(
'general',
'registertimeout')[0]
1119 retry_interval =
'20' 1122 max_attempts = sip.get(
'general',
'registerattempts')[0]
1127 outbound_proxy = sip.get(
'general',
'outboundproxy')[0]
1132 reg =
Registration(i, retry_interval, max_attempts, outbound_proxy)
1133 reg.write(pjsip, nmapped)
1138 Map all setvar in peer section to the appropriate endpoint set_var 1141 setvars = sip.section(section)[0].get(
'setvar')
1145 for setvar
in setvars:
1146 set_value(
'set_var', setvar, section, pjsip, nmapped)
1151 Map the options from a peer section in sip.conf into the appropriate 1152 sections in pjsip.conf 1159 i[1](i[0], sip.get(section, i[0])[0], section, pjsip, nmapped)
1167 Determine sip.conf options that were not properly mapped to pjsip.conf 1170 for section, sect
in sections.iteritems():
1177 for key
in sect.keys(
True):
1182 nmapped(section, key, sect[key])
1192 user_agent = sip.get(
'general',
'useragent')[0]
1193 set_value(
'user_agent', user_agent,
'global', pjsip, nmapped,
'global')
1199 sipdebug = sip.get(
'general',
'sipdebug')[0]
1200 set_value(
'debug', sipdebug,
'global', pjsip, nmapped,
'global')
1205 useroption_parsing = sip.get(
'general',
'legacy_useroption_parsing')[0]
1206 set_value(
'ignore_uri_user_options', useroption_parsing,
'global', pjsip, nmapped,
'global')
1211 timer_t1 = sip.get(
'general',
'timert1')[0]
1212 set_value(
'timer_t1', timer_t1, section, pjsip, nmapped, type)
1217 timer_b = sip.get(
'general',
'timerb')[0]
1218 set_value(
'timer_b', timer_b, section, pjsip, nmapped, type)
1223 compact_headers = sip.get(
'general',
'compactheaders')[0]
1224 set_value(
'compact_headers', compact_headers, section, pjsip, nmapped, type)
1229 def convert(sip, filename, non_mappings, include):
1231 Entry point for configuration file conversion. This 1232 function will create a pjsip.conf object and begin to 1233 map specific sections from sip.conf into it. 1234 Returns the new pjsip.conf object once completed 1236 pjsip = sip.__class__()
1245 for section
in sip.sections():
1246 if section ==
'authentication':
1249 map_peer(sip, section, pjsip, nmapped)
1255 for key, val
in sip.includes().iteritems():
1256 pjsip.add_include(PREFIX + key,
convert(val, PREFIX + key,
1257 non_mappings,
True)[0])
1258 return pjsip, non_mappings
1263 Write pjsip.conf file to disk 1266 with open(filename,
'wt')
as fp:
1268 fp.write(
';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n')
1269 fp.write(
'Non mapped elements start\n')
1270 fp.write(
';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n')
1272 fp.write(
';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n')
1273 fp.write(
'Non mapped elements end\n')
1274 fp.write(
';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n')
1280 print(
"Could not open file " + filename +
" for writing", file=sys.stderr)
1287 Parse command line options and apply them. If invalid input is given, 1288 print usage information 1292 usage =
"usage: %prog [options] [input-file [output-file]]\n\n" \
1293 "Converts the chan_sip configuration input-file to the chan_pjsip output-file.\n" \
1294 "The input-file defaults to 'sip.conf'.\n" \
1295 "The output-file defaults to 'pjsip.conf'." 1296 parser = optparse.OptionParser(usage=usage)
1297 parser.add_option(
'-p',
'--prefix', dest=
'prefix', default=PREFIX,
1298 help=
'output prefix for include files')
1299 parser.add_option(
'-q',
'--quiet', dest=
'quiet', default=
False, action=
'store_true',
1300 help=
"don't print messages to stdout")
1302 options, args = parser.parse_args()
1303 PREFIX = options.prefix
1307 sip_filename = args[0]
if len(args)
else 'sip.conf' 1308 pjsip_filename = args[1]
if len(args) == 2
else 'pjsip.conf' 1310 return sip_filename, pjsip_filename
1319 if __name__ ==
"__main__":
1323 info(
'Please, report any issue at:')
1324 info(
' https://issues.asterisk.org/')
1325 info(
'Reading ' + sip_filename)
1326 sip.read(sip_filename)
1327 info(
'Converting to PJSIP...')
1328 pjsip, non_mappings =
convert(sip, pjsip_filename, dict(),
False)
1329 info(
'Writing ' + pjsip_filename)
def __init__(self, line, retry_interval, max_attempts, outbound_proxy)
def set_dtmfmode(key, val, section, pjsip, nmapped)
mapping functions - define f(key, val, section) where key/val are the key/value pair to write to give...
def set_tls_cipher(val, pjsip, section, nmapped)
def section_by_type(section, pjsip, type)
some utility functions
def from_progressinband(key, val, section, pjsip, nmapped)
def from_recordfeature(key, val, section, pjsip, nmapped)
def set_tls_private_key(val, pjsip, section, nmapped)
def set_value(key=None, val=None, section=None, pjsip=None, nmapped=None, type='endpoint')
def set_tls_capath(val, pjsip, section, nmapped)
def from_sendrpid(key, val, section, pjsip, nmapped)
def parse_host_part(self, host_part)
def set_timers(key, val, section, pjsip, nmapped)
def set_record_off_feature(key, val, section, pjsip, nmapped)
def create_tls(sip, pjsip, nmapped)
def map_peer(sip, section, pjsip, nmapped)
def from_mailbox(key, val, section, pjsip, nmapped)
def write(self, pjsip, nmapped)
def map_auth(sip, pjsip, nmapped)
def convert(sip, filename, non_mappings, include)
def map_system(sip, pjsip, nmapped)
def set_tls_cert_file(val, pjsip, section, nmapped)
def map_transports(sip, pjsip, nmapped)
def merge_value(key=None, val=None, section=None, pjsip=None, nmapped=None, type='endpoint', section_to=None, key_to=None)
def parse_user_part(self, user_part)
def write_pjsip(filename, pjsip, non_mappings)
def setup_auth(key, val, section, pjsip, nmapped)
def set_media_encryption(key, val, section, pjsip, nmapped)
def merge_codec_value(key=None, val=None, section=None, pjsip=None, nmapped=None, type='endpoint', section_to=None, key_to=None)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
def find_non_mapped(sections, nmapped)
def ignore(key=None, val=None, section=None, pjsip=None, nmapped=None, type='endpoint')
def map_setvars(sip, section, pjsip, nmapped)
def create_udp(sip, pjsip, nmapped)
def build_host(config, host, section='general', port_key=None)
def from_host(key, val, section, pjsip, nmapped)
def from_encryption_taglen(key, val, section, pjsip, nmapped)
def from_dtlsenable(key, val, section, pjsip, nmapped)
def set_direct_media(key, val, section, pjsip, nmapped)
def set_record_on_feature(key, val, section, pjsip, nmapped)
def map_registrations(sip, pjsip, nmapped)
def write_dicts(config_file, mdicts)
def setup_ident(key, val, section, pjsip, nmapped)
def set_tls_cafile(val, pjsip, section, nmapped)
def from_nat(key, val, section, pjsip, nmapped)
def set_tls_verifyclient(val, pjsip, section, nmapped)
def set_transport_common(section, sip, pjsip, protocol, nmapped)
def set_tls_verifyserver(val, pjsip, section, nmapped)
def setup_udptl(section, pjsip, nmapped)
def get_bind(sip, pjsip, protocol)
def create_tcp(sip, pjsip, nmapped)