3from __future__
import print_function
9 from urllib.parse
import urlparse
11 from urlparse
import urlparse
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)
47def ignore(key=None, val=None, section=None, pjsip=None,
48 nmapped=None, type='endpoint'):
49 """Ignore a key and mark it as mapped"""
52def 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
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)
289def 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
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)
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
1319if __name__ ==
"__main__":
1323 info(
'Please, report any issue at:')
1324 info(
' https://github.com/asterisk/asterisk/issues/')
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 parse_host_part(self, host_part)
def write(self, pjsip, nmapped)
def __init__(self, line, retry_interval, max_attempts, outbound_proxy)
def parse_user_part(self, user_part)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
def write_dicts(config_file, mdicts)
def setup_ident(key, val, section, pjsip, nmapped)
def convert(sip, filename, non_mappings, include)
def map_auth(sip, pjsip, nmapped)
def ignore(key=None, val=None, section=None, pjsip=None, nmapped=None, type='endpoint')
def build_host(config, host, section='general', port_key=None)
def map_transports(sip, pjsip, nmapped)
def set_tls_verifyserver(val, pjsip, section, nmapped)
def setup_udptl(section, pjsip, nmapped)
def set_tls_cert_file(val, pjsip, section, nmapped)
def map_peer(sip, section, pjsip, nmapped)
def set_tls_cafile(val, pjsip, section, nmapped)
def set_tls_cipher(val, pjsip, section, nmapped)
def set_tls_private_key(val, pjsip, section, nmapped)
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_record_off_feature(key, val, section, pjsip, nmapped)
def set_value(key=None, val=None, section=None, pjsip=None, nmapped=None, type='endpoint')
def setup_auth(key, val, section, pjsip, nmapped)
def from_mailbox(key, val, section, pjsip, nmapped)
def set_timers(key, val, section, pjsip, nmapped)
def create_tcp(sip, pjsip, nmapped)
def from_host(key, val, section, pjsip, nmapped)
def merge_value(key=None, val=None, section=None, pjsip=None, nmapped=None, type='endpoint', section_to=None, key_to=None)
def from_dtlsenable(key, val, section, pjsip, nmapped)
def from_encryption_taglen(key, val, section, pjsip, nmapped)
def create_tls(sip, pjsip, nmapped)
def from_nat(key, val, section, pjsip, nmapped)
def set_record_on_feature(key, val, section, pjsip, nmapped)
def map_registrations(sip, pjsip, nmapped)
def write_pjsip(filename, pjsip, non_mappings)
def set_direct_media(key, val, section, pjsip, nmapped)
def set_transport_common(section, sip, pjsip, protocol, nmapped)
def map_setvars(sip, section, pjsip, nmapped)
def section_by_type(section, pjsip, type)
some utility functions
def merge_codec_value(key=None, val=None, section=None, pjsip=None, nmapped=None, type='endpoint', section_to=None, key_to=None)
def set_tls_capath(val, pjsip, section, nmapped)
def from_progressinband(key, val, section, pjsip, nmapped)
def set_media_encryption(key, val, section, pjsip, nmapped)
def from_sendrpid(key, val, section, pjsip, nmapped)
def map_system(sip, pjsip, nmapped)
def get_bind(sip, pjsip, protocol)
def set_tls_verifyclient(val, pjsip, section, nmapped)
def create_udp(sip, pjsip, nmapped)
def from_recordfeature(key, val, section, pjsip, nmapped)
def find_non_mapped(sections, nmapped)