summaryrefslogtreecommitdiff
path: root/contrib/scripts/sip_to_res_sip
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/scripts/sip_to_res_sip')
-rw-r--r--contrib/scripts/sip_to_res_sip/astconfigparser.py394
-rw-r--r--contrib/scripts/sip_to_res_sip/astdicts.py298
-rwxr-xr-xcontrib/scripts/sip_to_res_sip/sip_to_res_sip.py392
3 files changed, 0 insertions, 1084 deletions
diff --git a/contrib/scripts/sip_to_res_sip/astconfigparser.py b/contrib/scripts/sip_to_res_sip/astconfigparser.py
deleted file mode 100644
index 4a324e2ec..000000000
--- a/contrib/scripts/sip_to_res_sip/astconfigparser.py
+++ /dev/null
@@ -1,394 +0,0 @@
-import re
-
-from astdicts import OrderedDict
-from astdicts import MultiOrderedDict
-
-def merge_values(left, right, key):
- """Merges values from right into left."""
- if isinstance(left, list):
- vals0 = left
- else: # assume dictionary
- vals0 = left[key] if key in left else []
- vals1 = right[key] if key in right else []
-
- return vals0 + [i for i in vals1 if i not in vals0]
-
-###############################################################################
-
-class Section(MultiOrderedDict):
- """A Section is a MultiOrderedDict itself that maintains a list of
- key/value options. However, in the case of an Asterisk config
- file a section may have other defaults sections that is can pull
- data from (i.e. templates). So when an option is looked up by key
- it first checks the base section and if not found looks in the
- added default sections. If not found at that point then a 'KeyError'
- exception is raised.
- """
- count = 0
-
- def __init__(self, defaults=None, templates=None):
- MultiOrderedDict.__init__(self)
- # track an ordered id of sections
- Section.count += 1
- self.id = Section.count
- self._defaults = [] if defaults is None else defaults
- self._templates = [] if templates is None else templates
-
- def __cmp__(self, other):
- return cmp(self.id, other.id)
-
- def get(self, key, from_self=True, from_templates=True, from_defaults=True):
- if from_self and key in self:
- return MultiOrderedDict.__getitem__(self, key)
-
- if from_templates:
- if self in self._templates:
- return []
- for t in self._templates:
- try:
- # fail if not found on the search - doing it this way
- # allows template's templates to be searched.
- return t.get(key, True, from_templates, from_defaults)
- except KeyError:
- pass
-
- if from_defaults:
- for d in self._defaults:
- try:
- return d.get(key, True, from_templates, from_defaults)
- except KeyError:
- pass
-
- raise KeyError(key)
-
- def __getitem__(self, key):
- """Get the value for the given key. If it is not found in the 'self'
- then check inside templates and defaults before declaring raising
- a KeyError exception.
- """
- return self.get(key)
-
- def keys(self, self_only=False):
- res = MultiOrderedDict.keys(self)
- if self_only:
- return res
-
- for d in self._templates:
- for key in d.keys():
- if key not in res:
- res.append(key)
-
- for d in self._defaults:
- for key in d.keys():
- if key not in res:
- res.append(key)
- return res
-
- def add_defaults(self, defaults):
- defaults.sort()
- for i in defaults:
- self._defaults.insert(0, i)
-
- def add_templates(self, templates):
- templates.sort(reverse=True);
- self._templates.extend(templates)
-
- def get_merged(self, key):
- """Return a list of values for a given key merged from default(s)"""
- # first merge key/values from defaults together
- merged = []
- for i in reversed(self._defaults):
- if not merged:
- merged = i
- continue
- merged = merge_values(merged, i, key)
-
- for i in reversed(self._templates):
- if not merged:
- merged = i
- continue
- merged = merge_values(merged, i, key)
-
- # then merge self in
- return merge_values(merged, self, key)
-
-###############################################################################
-
-COMMENT = ';'
-COMMENT_START = ';--'
-COMMENT_END = '--;'
-
-DEFAULTSECT = 'general'
-
-def remove_comment(line, is_comment):
- """Remove any commented elements from the line."""
- if not line: return line, is_comment
-
- if is_comment:
- part = line.partition(COMMENT_END)
- if part[1]:
- # found multi-line comment end check string after it
- return remove_comment(part[2], False)
- return "", True
-
- part = line.partition(COMMENT_START)
- if part[1]:
- # found multi-line comment start check string before
- # it to make sure there wasn't an eol comment in it
- has_comment = part[0].partition(COMMENT)
- if has_comment[1]:
- # eol comment found return anything before it
- return has_comment[0], False
-
- # check string after it to see if the comment ends
- line, is_comment = remove_comment(part[2], True)
- if is_comment:
- # return possible string data before comment
- return part[0].strip(), True
-
- # otherwise it was an embedded comment so combine
- return ''.join([part[0].strip(), ' ', line]).rstrip(), False
-
- # check for eol comment
- return line.partition(COMMENT)[0].strip(), False
-
-def try_include(line):
- """Checks to see if the given line is an include. If so return the
- included filename, otherwise None.
- """
- if not line.startswith('#'):
- return None
-
- # it is an include - get file name
- try:
- return line[line.index('"') + 1:line.rindex('"')]
- except ValueError:
- print "Invalid include - could not parse filename."
- return None
-
-def try_section(line):
- """Checks to see if the given line is a section. If so return the section
- name, otherwise return 'None'.
- """
- # leading spaces were stripped when checking for comments
- if not line.startswith('['):
- return None, False, []
-
- section, delim, templates = line.partition(']')
- if not templates:
- return section[1:], False, []
-
- # strip out the parens and parse into an array
- templates = templates.replace('(', "").replace(')', "").split(',')
- # go ahead and remove extra whitespace
- templates = [i.strip() for i in templates]
- try:
- templates.remove('!')
- return section[1:], True, templates
- except:
- return section[1:], False, templates
-
-def try_option(line):
- """Parses the line as an option, returning the key/value pair."""
- data = re.split('=>?', line)
- # should split in two (key/val), but either way use first two elements
- return data[0].rstrip(), data[1].lstrip()
-
-###############################################################################
-
-def find_value(sections, key):
- """Given a list of sections, try to find value(s) for the given key."""
- # always start looking in the last one added
- sections.sort(reverse=True);
- for s in sections:
- try:
- # try to find in section and section's templates
- return s.get(key, from_defaults=False)
- except KeyError:
- pass
-
- # wasn't found in sections or a section's templates so check in defaults
- for s in sections:
- try:
- # try to find in section's defaultsects
- return s.get(key, from_self=False, from_templates=False)
- except KeyError:
- pass
-
- raise KeyError(key)
-
-def find_dict(mdicts, key, val):
- """Given a list of mult-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))
-
-def get_sections(parser, key, attr='_sections', searched=None):
- if searched is None:
- searched = []
- if parser is None or parser in searched:
- return []
-
- try:
- sections = getattr(parser, attr)
- res = sections[key] if key in sections else []
- searched.append(parser)
- return res + get_sections(parser._includes, key, attr, searched) \
- + get_sections(parser._parent, key, attr, searched)
- except:
- # assume ordereddict of parsers
- res = []
- for p in parser.itervalues():
- res.extend(get_sections(p, key, attr, searched))
- return res
-
-def get_defaults(parser, key):
- return get_sections(parser, key, '_defaults')
-
-def write_dicts(file, mdicts):
- for section, sect_list in mdicts.iteritems():
- # every section contains a list of dictionaries
- for sect in sect_list:
- file.write("[%s]\n" % section)
- for key, val_list in sect.iteritems():
- # every value is also a list
- for v in val_list:
- key_val = key
- if v is not None:
- key_val += " = " + str(v)
- file.write("%s\n" % (key_val))
- file.write("\n")
-
-###############################################################################
-
-class MultiOrderedConfigParser:
- def __init__(self, parent=None):
- self._parent = parent
- self._defaults = MultiOrderedDict()
- self._sections = MultiOrderedDict()
- self._includes = OrderedDict()
-
- def defaults(self):
- return self._defaults
-
- def default(self, key):
- """Retrieves a list of dictionaries for a default section."""
- return get_defaults(self, key)
-
- def add_default(self, key, template_keys=None):
- """Adds a default section to defaults, returning the
- default Section object.
- """
- if template_keys is None:
- template_keys = []
- return self.add_section(key, template_keys, self._defaults)
-
- def sections(self):
- return self._sections
-
- def section(self, key):
- """Retrieves a list of dictionaries for a section."""
- return get_sections(self, key)
-
- def add_section(self, key, template_keys=None, mdicts=None):
- if template_keys is None:
- template_keys = []
- if mdicts is None:
- mdicts = self._sections
- res = Section()
- for t in template_keys:
- res.add_templates(get_defaults(self, t))
- res.add_defaults(get_defaults(self, DEFAULTSECT))
- mdicts.insert(0, key, res)
- return res
-
- def includes(self):
- return self._includes
-
- def add_include(self, filename, parser=None):
- if filename in self._includes:
- return self._includes[filename]
-
- self._includes[filename] = res = \
- MultiOrderedConfigParser(self) if parser is None else parser
- return res;
-
- def get(self, section, key):
- """Retrieves the list of values from a section for a key."""
- try:
- # search for the value in the list of sections
- return find_value(self.section(section), key)
- except KeyError:
- pass
-
- try:
- # section may be a default section so, search
- # for the value in the list of defaults
- return find_value(self.default(section), key)
- except KeyError:
- raise LookupError("key %r not found for section %r"
- % (key, section))
-
- def set(self, section, key, val):
- """Sets an option in the given section."""
- # TODO - set in multiple sections? (for now set in first)
- # TODO - set in both sections and defaults?
- if section in self._sections:
- self.section(section)[0][key] = val
- else:
- self.defaults(section)[0][key] = val
-
- def read(self, filename):
- try:
- with open(filename, 'rt') as file:
- self._read(file, filename)
- except IOError:
- print "Could not open file ", filename, " for reading"
-
- def _read(self, file, filename):
- is_comment = False # used for multi-lined comments
- for line in file:
- line, is_comment = remove_comment(line, is_comment)
- if not line:
- # line was empty or was a comment
- continue
-
- include_name = try_include(line)
- if include_name:
- parser = self.add_include(include_name)
- parser.read(include_name)
- continue
-
- section, is_template, templates = try_section(line)
- if section:
- if section == DEFAULTSECT or is_template:
- sect = self.add_default(section, templates)
- else:
- sect = self.add_section(section, templates)
- continue
-
- key, val = try_option(line)
- sect[key] = val
-
- def write(self, f):
- try:
- for key, val in self._includes.iteritems():
- val.write(key)
- f.write('#include "%s"\n' % key)
-
- f.write('\n')
- write_dicts(f, self._defaults)
- write_dicts(f, self._sections)
- except:
- try:
- with open(f, 'wt') as fp:
- self.write(fp)
- except IOError:
- print "Could not open file ", f, " for writing"
diff --git a/contrib/scripts/sip_to_res_sip/astdicts.py b/contrib/scripts/sip_to_res_sip/astdicts.py
deleted file mode 100644
index ae630755d..000000000
--- a/contrib/scripts/sip_to_res_sip/astdicts.py
+++ /dev/null
@@ -1,298 +0,0 @@
-# Backport of OrderedDict() class that runs on Python 2.4, 2.5, 2.6, 2.7 and pypy.
-# Passes Python2.7's test suite and incorporates all the latest updates.
-# copied from http://code.activestate.com/recipes/576693/
-
-try:
- from thread import get_ident as _get_ident
-except ImportError:
- from dummy_thread import get_ident as _get_ident
-
-try:
- from _abcoll import KeysView, ValuesView, ItemsView
-except ImportError:
- pass
-
-
-class OrderedDict(dict):
- 'Dictionary that remembers insertion order'
- # An inherited dict maps keys to values.
- # The inherited dict provides __getitem__, __len__, __contains__, and get.
- # The remaining methods are order-aware.
- # Big-O running times for all methods are the same as for regular dictionaries.
-
- # The internal self.__map dictionary maps keys to links in a doubly linked list.
- # The circular doubly linked list starts and ends with a sentinel element.
- # The sentinel element never gets deleted (this simplifies the algorithm).
- # Each link is stored as a list of length three: [PREV, NEXT, KEY].
-
- def __init__(self, *args, **kwds):
- '''Initialize an ordered dictionary. Signature is the same as for
- regular dictionaries, but keyword arguments are not recommended
- because their insertion order is arbitrary.
-
- '''
- if len(args) > 1:
- raise TypeError('expected at most 1 arguments, got %d' % len(args))
- try:
- self.__root
- except AttributeError:
- self.__root = root = [] # sentinel node
- root[:] = [root, root, None]
- self.__map = {}
- self.__update(*args, **kwds)
-
- def __setitem__(self, key, value, dict_setitem=dict.__setitem__):
- 'od.__setitem__(i, y) <==> od[i]=y'
- # Setting a new item creates a new link which goes at the end of the linked
- # list, and the inherited dictionary is updated with the new key/value pair.
- if key not in self:
- root = self.__root
- last = root[0]
- last[1] = root[0] = self.__map[key] = [last, root, key]
- dict_setitem(self, key, value)
-
- def __delitem__(self, key, dict_delitem=dict.__delitem__):
- 'od.__delitem__(y) <==> del od[y]'
- # Deleting an existing item uses self.__map to find the link which is
- # then removed by updating the links in the predecessor and successor nodes.
- dict_delitem(self, key)
- link_prev, link_next, key = self.__map.pop(key)
- link_prev[1] = link_next
- link_next[0] = link_prev
-
- def __iter__(self):
- 'od.__iter__() <==> iter(od)'
- root = self.__root
- curr = root[1]
- while curr is not root:
- yield curr[2]
- curr = curr[1]
-
- def __reversed__(self):
- 'od.__reversed__() <==> reversed(od)'
- root = self.__root
- curr = root[0]
- while curr is not root:
- yield curr[2]
- curr = curr[0]
-
- def clear(self):
- 'od.clear() -> None. Remove all items from od.'
- try:
- for node in self.__map.itervalues():
- del node[:]
- root = self.__root
- root[:] = [root, root, None]
- self.__map.clear()
- except AttributeError:
- pass
- dict.clear(self)
-
- def popitem(self, last=True):
- '''od.popitem() -> (k, v), return and remove a (key, value) pair.
- Pairs are returned in LIFO order if last is true or FIFO order if false.
-
- '''
- if not self:
- raise KeyError('dictionary is empty')
- root = self.__root
- if last:
- link = root[0]
- link_prev = link[0]
- link_prev[1] = root
- root[0] = link_prev
- else:
- link = root[1]
- link_next = link[1]
- root[1] = link_next
- link_next[0] = root
- key = link[2]
- del self.__map[key]
- value = dict.pop(self, key)
- return key, value
-
- # -- the following methods do not depend on the internal structure --
-
- def keys(self):
- 'od.keys() -> list of keys in od'
- return list(self)
-
- def values(self):
- 'od.values() -> list of values in od'
- return [self[key] for key in self]
-
- def items(self):
- 'od.items() -> list of (key, value) pairs in od'
- return [(key, self[key]) for key in self]
-
- def iterkeys(self):
- 'od.iterkeys() -> an iterator over the keys in od'
- return iter(self)
-
- def itervalues(self):
- 'od.itervalues -> an iterator over the values in od'
- for k in self:
- yield self[k]
-
- def iteritems(self):
- 'od.iteritems -> an iterator over the (key, value) items in od'
- for k in self:
- yield (k, self[k])
-
- def update(*args, **kwds):
- '''od.update(E, **F) -> None. Update od from dict/iterable E and F.
-
- If E is a dict instance, does: for k in E: od[k] = E[k]
- If E has a .keys() method, does: for k in E.keys(): od[k] = E[k]
- Or if E is an iterable of items, does: for k, v in E: od[k] = v
- In either case, this is followed by: for k, v in F.items(): od[k] = v
-
- '''
- if len(args) > 2:
- raise TypeError('update() takes at most 2 positional '
- 'arguments (%d given)' % (len(args),))
- elif not args:
- raise TypeError('update() takes at least 1 argument (0 given)')
- self = args[0]
- # Make progressively weaker assumptions about "other"
- other = ()
- if len(args) == 2:
- other = args[1]
- if isinstance(other, dict):
- for key in other:
- self[key] = other[key]
- elif hasattr(other, 'keys'):
- for key in other.keys():
- self[key] = other[key]
- else:
- for key, value in other:
- self[key] = value
- for key, value in kwds.items():
- self[key] = value
-
- __update = update # let subclasses override update without breaking __init__
-
- __marker = object()
-
- def pop(self, key, default=__marker):
- '''od.pop(k[,d]) -> v, remove specified key and return the corresponding value.
- If key is not found, d is returned if given, otherwise KeyError is raised.
-
- '''
- if key in self:
- result = self[key]
- del self[key]
- return result
- if default is self.__marker:
- raise KeyError(key)
- return default
-
- def setdefault(self, key, default=None):
- 'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od'
- if key in self:
- return self[key]
- self[key] = default
- return default
-
- def __repr__(self, _repr_running={}):
- 'od.__repr__() <==> repr(od)'
- call_key = id(self), _get_ident()
- if call_key in _repr_running:
- return '...'
- _repr_running[call_key] = 1
- try:
- if not self:
- return '%s()' % (self.__class__.__name__,)
- return '%s(%r)' % (self.__class__.__name__, self.items())
- finally:
- del _repr_running[call_key]
-
- def __reduce__(self):
- 'Return state information for pickling'
- items = [[k, self[k]] for k in self]
- inst_dict = vars(self).copy()
- for k in vars(OrderedDict()):
- inst_dict.pop(k, None)
- if inst_dict:
- return (self.__class__, (items,), inst_dict)
- return self.__class__, (items,)
-
- def copy(self):
- 'od.copy() -> a shallow copy of od'
- return self.__class__(self)
-
- @classmethod
- def fromkeys(cls, iterable, value=None):
- '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S
- and values equal to v (which defaults to None).
-
- '''
- d = cls()
- for key in iterable:
- d[key] = value
- return d
-
- def __eq__(self, other):
- '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive
- while comparison to a regular mapping is order-insensitive.
-
- '''
- if isinstance(other, OrderedDict):
- return len(self)==len(other) and self.items() == other.items()
- return dict.__eq__(self, other)
-
- def __ne__(self, other):
- return not self == other
-
- # -- the following methods are only used in Python 2.7 --
-
- def viewkeys(self):
- "od.viewkeys() -> a set-like object providing a view on od's keys"
- return KeysView(self)
-
- def viewvalues(self):
- "od.viewvalues() -> an object providing a view on od's values"
- return ValuesView(self)
-
- def viewitems(self):
- "od.viewitems() -> a set-like object providing a view on od's items"
- return ItemsView(self)
-
-###############################################################################
-### MultiOrderedDict
-###############################################################################
-class MultiOrderedDict(OrderedDict):
- def __init__(self, *args, **kwds):
- OrderedDict.__init__(self, *args, **kwds)
-
- def __setitem__(self, key, val, i=None):
- if key not in self:
-# print "__setitem__ key = ", key, " val = ", val
- OrderedDict.__setitem__(
- self, key, val if isinstance(val, list) else [val])
- return
-# print "inserting key = ", key, " val = ", val
- vals = self[key]
- if i is None:
- i = len(vals)
-
- if not isinstance(val, list):
- if val not in vals:
- vals.insert(i, val)
- else:
- for j in val.reverse():
- if j not in vals:
- vals.insert(i, j)
-
-
- def insert(self, i, key, val):
- self.__setitem__(key, val, i)
-
- def copy(self):
- # TODO - find out why for some reason copies
- # the [] as an [[]], so do manually
- c = MultiOrderedDict() #self.__class__(self)
- for key, val in self.iteritems():
- for v in val:
- c[key] = v
- return c
diff --git a/contrib/scripts/sip_to_res_sip/sip_to_res_sip.py b/contrib/scripts/sip_to_res_sip/sip_to_res_sip.py
deleted file mode 100755
index ca253bdd0..000000000
--- a/contrib/scripts/sip_to_res_sip/sip_to_res_sip.py
+++ /dev/null
@@ -1,392 +0,0 @@
-#!/usr/bin/python
-
-###############################################################################
-# TODO:
-# (1) There is more work to do here, at least for the sip.conf items that
-# aren't currently parsed. An issue will be created for that.
-# (2) All of the scripts should probably be passed through pylint and have
-# as many PEP8 issues fixed as possible
-# (3) A public review is probably warranted at that point of the entire script
-###############################################################################
-
-import optparse
-import astdicts
-import astconfigparser
-
-PREFIX = 'res_sip_'
-
-###############################################################################
-### some utility functions
-###############################################################################
-def section_by_type(section, res_sip, type):
- """Finds a section based upon the given type, adding it if not found."""
- try:
- return astconfigparser.find_dict(
- res_sip.section(section), 'type', type)
- except LookupError:
- # section for type doesn't exist, so add
- sect = res_sip.add_section(section)
- sect['type'] = type
- return sect
-
-def set_value(key=None, val=None, section=None, res_sip=None,
- nmapped=None, type='endpoint'):
- """Sets the key to the value within the section in res_sip.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, res_sip, type)[key] = \
- val[0] if isinstance(val, list) else val
-
-def merge_value(key=None, val=None, section=None, res_sip=None,
- nmapped=None, type='endpoint', section_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)
-
- # 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
- sect = sip.section(section)[0]
- # for each merged value add it to res_sip.conf
- for i in sect.get_merged(key):
- set_value(key, i, section_to if section_to else section,
- res_sip, nmapped, type)
-
-def is_in(s, sub):
- """Returns true if 'sub' is in 's'"""
- return s.find(sub) != -1
-
-def non_mapped(nmapped):
- 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 res_sip.conf
-###############################################################################
-
-def set_dtmfmode(key, val, section, res_sip, nmapped):
- """Sets the dtmfmode value. If value matches allowable option in res_sip
- then map it, otherwise set it to none.
- """
- # available res_sip.conf values: frc4733, inband, info, none
- if val != 'inband' or val != 'info':
- nmapped(section, key, val + " ; did not fully map - set to none")
- val = 'none'
- set_value(key, val, section, res_sip, nmapped)
-
-def from_nat(key, val, section, res_sip, nmapped):
- """Sets values from nat into the appropriate res_sip.conf options."""
- # nat from sip.conf can be comma separated list of values:
- # yes/no, [auto_]force_rport, [auto_]comedia
- if is_in(val, 'yes'):
- set_value('rtp_symmetric', 'yes', section, res_sip, nmapped)
- set_value('rewrite_contact', 'yes', section, res_sip, nmapped)
- if is_in(val, 'comedia'):
- set_value('rtp_symmetric', 'yes', section, res_sip, nmapped)
- if is_in(val, 'force_rport'):
- set_value('force_rport', 'yes', section, res_sip, nmapped)
- set_value('rewrite_contact', 'yes', section, res_sip, nmapped)
-
-def set_timers(key, val, section, res_sip, nmapped):
- """Sets the timers in res_sip.conf from the session-timers option
- found in sip.conf.
- """
- # res_sip.conf values can be yes/no, required, always
- if val == 'originate':
- set_value('timers', 'always', section, res_sip, nmapped)
- elif val == 'accept':
- set_value('timers', 'required', section, res_sip, nmapped)
- elif val == 'never':
- set_value('timers', 'no', section, res_sip, nmapped)
- else:
- set_value('timers', 'yes', section, res_sip, nmapped)
-
-def set_direct_media(key, val, section, res_sip, nmapped):
- """Maps values from the sip.conf comma separated direct_media option
- into res_sip.conf direct_media options.
- """
- if is_in(val, 'yes'):
- set_value('direct_media', 'yes', section, res_sip, nmapped)
- if is_in(val, 'update'):
- set_value('direct_media_method', 'update', section, res_sip, nmapped)
- if is_in(val, 'outgoing'):
- set_value('directed_media_glare_mitigation', 'outgoing', section, res_sip, nmapped)
- if is_in(val, 'nonat'):
- set_value('disable_directed_media_on_nat','yes', section, res_sip, nmapped)
- if (val == 'no'):
- set_value('direct_media', 'no', section, res_sip, nmapped)
-
-def from_sendrpid(key, val, section, res_sip, nmapped):
- """Sets the send_rpid/pai values in res_sip.conf."""
- if val == 'yes' or val == 'rpid':
- set_value('send_rpid', 'yes', section, res_sip, nmapped)
- elif val == 'pai':
- set_value('send_pai', 'yes', section, res_sip, nmapped)
-
-def set_media_encryption(key, val, section, res_sip, nmapped):
- """Sets the media_encryption value in res_sip.conf"""
- if val == 'yes':
- set_value('media_encryption', 'sdes', section, res_sip, nmapped)
-
-def from_recordfeature(key, val, section, res_sip, nmapped):
- """If record on/off feature is set to automixmon then set
- one_touch_recording, otherwise it can't be mapped.
- """
- if val == 'automixmon':
- set_value('one_touch_recording', 'yes', section, res_sip, nmapped)
- else:
- nmapped(section, key, val + " ; could not be fully mapped")
-
-def from_progressinband(key, val, section, res_sip, nmapped):
- """Sets the inband_progress value in res_sip.conf"""
- # progressinband can = yes/no/never
- if val == 'never':
- val = 'no'
- set_value('inband_progress', val, section, res_sip, nmapped)
-
-def from_host(key, val, section, res_sip, nmapped):
- """Sets contact info in an AOR section in in res_sip.conf using 'host'
- data from sip.conf
- """
- # all aors have the same name as the endpoint so makes
- # it easy to endpoint's 'aors' value
- set_value('aors', section, section, res_sip, nmapped)
- if val != 'dynamic':
- set_value('contact', val, section, res_sip, nmapped, 'aor')
- else:
- set_value('max_contacts', 1, section, res_sip, nmapped, 'aor')
-
-def from_subscribemwi(key, val, section, res_sip, nmapped):
- """Checks the subscribemwi value in sip.conf. If yes places the
- mailbox value in mailboxes within the endpoint, otherwise puts
- it in the aor.
- """
- mailboxes = sip.get('mailbox', section, res_sip)
- type = 'endpoint' if val == 'yes' else 'aor'
- set_value('mailboxes', mailboxes, section, res_sip, nmapped, type)
-
-###############################################################################
-
-# options in res_sip.conf on an endpoint that have no sip.conf equivalent:
-# type, rtp_ipv6, 100rel, trust_id_outbound, aggregate_mwi,
-# connected_line_method
-
-# known sip.conf peer keys that can be mapped to a res_sip.conf section/key
-peer_map = [
- # sip.conf option mapping function res_sip.conf option(s)
- ###########################################################################
- ['context', set_value],
- ['dtmfmode', set_dtmfmode],
- ['disallow', merge_value],
- ['allow', merge_value],
- ['nat', from_nat], # rtp_symmetric, force_rport,
- # rewrite_contact
- ['icesupport', set_value('ice_support')],
- ['autoframing', set_value('use_ptime')],
- ['outboundproxy', set_value('outbound_proxy')],
- ['mohsuggest', set_value],
- ['session-timers', set_timers], # timers
- ['session-minse', set_value('timers_min_se')],
- ['session-expires', set_value('timers_sess_expires')],
- ['externip', set_value('external_media_address')],
- ['externhost', set_value('external_media_address')],
- # identify_by ?
- ['directmedia', set_direct_media], # direct_media
- # direct_media_method
- # directed_media_glare_mitigation
- # disable_directed_media_on_nat
- ['callerid', set_value], # callerid
- ['callingpres', set_value('callerid_privacy')],
- ['cid_tag', set_value('callerid_tag')],
- ['trustpid', set_value('trust_id_inbound')],
- ['sendrpid', from_sendrpid], # send_pai, send_rpid
- ['send_diversion', set_value],
- ['encrpytion', set_media_encryption],
- ['use_avpf', set_value],
- ['recordonfeature', from_recordfeature], # automixon
- ['recordofffeature', from_recordfeature], # automixon
- ['progressinband', from_progressinband], # in_band_progress
- ['callgroup', set_value],
- ['pickupgroup', set_value],
- ['namedcallgroup', set_value],
- ['namedpickupgroup', set_value],
- ['busylevel', set_value('devicestate_busy_at')],
-
-############################ maps to an aor ###################################
-
- ['host', from_host], # contact, max_contacts
- ['subscribemwi', from_subscribemwi], # mailboxes
- ['qualifyfreq', set_value('qualify_frequency', type='aor')],
-
-############################# maps to auth#####################################
-# type = auth
-# username
-# password
-# md5_cred
-# realm
-# nonce_lifetime
-# auth_type
-######################### maps to acl/security ################################
-
- ['permit', merge_value(type='security', section_to='acl')],
- ['deny', merge_value(type='security', section_to='acl')],
- ['acl', merge_value(type='security', section_to='acl')],
- ['contactpermit', merge_value(type='security', section_to='acl')],
- ['contactdeny', merge_value(type='security', section_to='acl')],
- ['contactacl', merge_value(type='security', section_to='acl')],
-
-########################### maps to transport #################################
-# type = transport
-# protocol
-# bind
-# async_operations
-# ca_list_file
-# cert_file
-# privkey_file
-# password
-# external_signaling_address - externip & externhost
-# external_signaling_port
-# external_media_address
-# domain
-# verify_server
-# verify_client
-# require_client_cert
-# method
-# cipher
-# localnet
-######################### maps to domain_alias ################################
-# type = domain_alias
-# domain
-######################### maps to registration ################################
-# type = registration
-# server_uri
-# client_uri
-# contact_user
-# transport
-# outbound_proxy
-# expiration
-# retry_interval
-# max_retries
-# auth_rejection_permanent
-# outbound_auth
-########################### maps to identify ##################################
-# type = identify
-# endpoint
-# match
-]
-
-def map_peer(sip, section, res_sip, nmapped):
- for i in peer_map:
- try:
- # coming from sip.conf the values should mostly be a list with a
- # single value. In the few cases that they are not a specialized
- # function (see merge_value) is used to retrieve the values.
- i[1](i[0], sip.get(section, i[0])[0], section, res_sip, nmapped)
- except LookupError:
- pass # key not found in sip.conf
-
-def find_non_mapped(sections, nmapped):
- for section, sect in sections.iteritems():
- try:
- # since we are pulling from sip.conf this should always
- # be a single value list
- sect = sect[0]
- # loop through the section and store any values that were not mapped
- for key in sect.keys(True):
- for i in peer_map:
- if i[0] == key:
- break;
- else:
- nmapped(section, key, sect[key])
- except LookupError:
- pass
-
-def convert(sip, filename, non_mappings):
- res_sip = astconfigparser.MultiOrderedConfigParser()
- non_mappings[filename] = astdicts.MultiOrderedDict()
- nmapped = non_mapped(non_mappings[filename])
- for section in sip.sections():
- if section == 'authentication':
- pass
- else:
- map_peer(sip, section, res_sip, nmapped)
-
- find_non_mapped(sip.defaults(), nmapped)
- find_non_mapped(sip.sections(), nmapped)
-
- for key, val in sip.includes().iteritems():
- res_sip.add_include(PREFIX + key, convert(val, PREFIX + key, non_mappings)[0])
- return res_sip, non_mappings
-
-def write_res_sip(filename, res_sip, non_mappings):
- try:
- with open(filename, 'wt') as fp:
- fp.write(';--\n')
- fp.write(';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n')
- fp.write('Non mapped elements start\n')
- fp.write(';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n')
- astconfigparser.write_dicts(fp, non_mappings[filename])
- fp.write(';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n')
- fp.write('Non mapped elements end\n')
- fp.write(';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n')
- fp.write('--;\n\n')
- # write out include file(s)
- for key, val in res_sip.includes().iteritems():
- write_res_sip(key, val, non_mappings)
- fp.write('#include "%s"\n' % key)
- fp.write('\n')
- # write out mapped data elements
- astconfigparser.write_dicts(fp, res_sip.defaults())
- astconfigparser.write_dicts(fp, res_sip.sections())
-
- except IOError:
- print "Could not open file ", filename, " for writing"
-
-###############################################################################
-
-def cli_options():
- global PREFIX
- usage = "usage: %prog [options] [input-file [output-file]]\n\n" \
- "input-file defaults to 'sip.conf'\n" \
- "output-file defaults to 'res_sip.conf'"
- parser = optparse.OptionParser(usage=usage)
- parser.add_option('-p', '--prefix', dest='prefix', default=PREFIX,
- help='output prefix for include files')
-
- options, args = parser.parse_args()
- PREFIX = options.prefix
-
- sip_filename = args[0] if len(args) else 'sip.conf'
- res_sip_filename = args[1] if len(args) == 2 else 'res_sip.conf'
-
- return sip_filename, res_sip_filename
-
-if __name__ == "__main__":
- sip_filename, res_sip_filename = cli_options()
- # configuration parser for sip.conf
- sip = astconfigparser.MultiOrderedConfigParser()
- sip.read(sip_filename)
- res_sip, non_mappings = convert(sip, res_sip_filename, dict())
- write_res_sip(res_sip_filename, res_sip, non_mappings)