Skip to content
Snippets Groups Projects
sip_to_pjsip.py 46.6 KiB
Newer Older
#!/usr/bin/env python
try:
    from urllib.parse import urlparse
except ImportError:
    from urlparse import urlparse # Python 2.7 required for Literal IPv6 Addresses
import astdicts
import astconfigparser

PREFIX = 'pjsip_'

###############################################################################
### some utility functions
###############################################################################


def section_by_type(section, pjsip, type):
    """Finds a section based upon the given type, adding it if not found."""
    def __find_dict(mdicts, key, val):
        """Given a list of multi-dicts, return the multi-dict that contains
           the given key/value pair."""

        def found(d):
            return key in d and val in d[key]

        try:
            return [d for d in mdicts if found(d)][0]
        except IndexError:
            raise LookupError("Dictionary not located for key = %s, value = %s"
                              % (key, val))

    try:
        return __find_dict(pjsip.section(section), 'type', type)
    except LookupError:
        # section for type doesn't exist, so add
        sect = pjsip.add_section(section)
        sect['type'] = type
        return sect


def ignore(key=None, val=None, section=None, pjsip=None,
           nmapped=None, type='endpoint'):
    """Ignore a key and mark it as mapped"""


def set_value(key=None, val=None, section=None, pjsip=None,
              nmapped=None, type='endpoint'):
    """Sets the key to the value within the section in pjsip.conf"""
    def _set_value(k, v, s, r, n):
        set_value(key if key else k, v, s, r, n, type)

    # if no value or section return the set_value
    # function with the enclosed key and type
    if not val and not section:
        return _set_value

    # otherwise try to set the value
    section_by_type(section, pjsip, type)[key] = \
        val[0] if isinstance(val, list) else val


def merge_value(key=None, val=None, section=None, pjsip=None,
                nmapped=None, type='endpoint', section_to=None,
                key_to=None):
    """Merge values from the given section with those from the default."""
    def _merge_value(k, v, s, r, n):
        merge_value(key if key else k, v, s, r, n, type, section_to, key_to)

    # if no value or section return the merge_value
    # function with the enclosed key and type
    if not val and not section:
        return _merge_value

    # should return a single value section list
    try:
        sect = sip.section(section)[0]
    except LookupError:
        sect = sip.default(section)[0]
    # for each merged value add it to pjsip.conf
    for i in sect.get_merged(key):
        set_value(key_to if key_to else key, i,
                  section_to if section_to else section,
def merge_codec_value(key=None, val=None, section=None, pjsip=None,
                nmapped=None, type='endpoint', section_to=None,
                key_to=None):
    """Merge values from allow/deny with those from the default. Special treatment for all"""
    def _merge_codec_value(k, v, s, r, n):
        merge_codec_value(key if key else k, v, s, r, n, type, section_to, key_to)

    # if no value or section return the merge_codec_value
    # function with the enclosed key and type
    if not val and not section:
        return _merge_codec_value

    if key == 'allow':
        try:
            disallow = sip.get(section, 'disallow')[0]
            if disallow == 'all':
                #don't inherit
                for i in sip.get(section, 'allow'):
                    set_value(key, i, section, pjsip, nmapped, type)
            else:
                merge_value(key, val, section, pjsip, nmapped, type, section_to, key_to)
        except LookupError:
            print("lookup error")
            merge_value(key, val, section, pjsip, nmapped, type, section_to, key_to)
            return
        try:
            allow = sip.get(section, 'allow')[0]
            if allow == 'all':
                #don't inherit
                for i in sip.get(section, 'disallow'):
                    set_value(key, i, section, pjsip, nmapped, type)
            else:
                merge_value(key, val, section, pjsip, nmapped, type, section_to, key_to)
        except LookupError:
            merge_value(key, val, section, pjsip, nmapped, type, section_to, key_to)
            return
        merge_value(key, val, section, pjsip, nmapped, type, section_to, key_to)

def non_mapped(nmapped):
    """Write non-mapped sip.conf values to the non-mapped object"""
    def _non_mapped(section, key, val):
        """Writes a non-mapped value from sip.conf to the non-mapped object."""
        if section not in nmapped:
            nmapped[section] = astconfigparser.Section()
            if isinstance(val, list):
                for v in val:
                    # since coming from sip.conf we can assume
                    # single section lists
                    nmapped[section][0][key] = v
            else:
                nmapped[section][0][key] = val
    return _non_mapped

###############################################################################
### mapping functions -
###      define f(key, val, section) where key/val are the key/value pair to
###      write to given section in pjsip.conf
###############################################################################


def set_dtmfmode(key, val, section, pjsip, nmapped):
    """
    Sets the dtmfmode value.  If value matches allowable option in pjsip
    then map it, otherwise set it to none.
    """
    # available pjsip.conf values: rfc4733, inband, info, none
    if val == 'inband' or val == 'info':
        set_value(key, val, section, pjsip, nmapped)
    elif val == 'rfc2833':
        set_value(key, 'rfc4733', section, pjsip, nmapped)
    else:
        nmapped(section, key, val + " ; did not fully map - set to none")
        set_value(key, 'none', section, pjsip, nmapped)


def setup_udptl(section, pjsip, nmapped):
    """Sets values from udptl into the appropriate pjsip.conf options."""
    try:
        val = sip.get(section, 't38pt_udptl')[0]
    except LookupError:
        try:
            val = sip.get('general', 't38pt_udptl')[0]

    ec = 'none'
    if 'yes' in val:
        set_value('t38_udptl', 'yes', section, pjsip, nmapped)
    if 'no' in val:
        set_value('t38_udptl', 'no', section, pjsip, nmapped)
    if 'redundancy' in val:
        ec = 'redundancy'
    if 'fec' in val:
        ec = 'fec'
    set_value('t38_udptl_ec', ec, section, pjsip, nmapped)

def from_nat(key, val, section, pjsip, nmapped):
    """Sets values from nat into the appropriate pjsip.conf options."""
    # nat from sip.conf can be comma separated list of values:
    # yes/no, [auto_]force_rport, [auto_]comedia
    if 'yes' in val:
        set_value('rtp_symmetric', 'yes', section, pjsip, nmapped)
        set_value('rewrite_contact', 'yes', section, pjsip, nmapped)
    if 'comedia' in val:
        set_value('rtp_symmetric', 'yes', section, pjsip, nmapped)
    if 'force_rport' in val:
        set_value('force_rport', 'yes', section, pjsip, nmapped)
        set_value('rewrite_contact', 'yes', section, pjsip, nmapped)


Loading
Loading full blame...