Skip to content

Commit

Permalink
Add Session.execute()
Browse files Browse the repository at this point in the history
Deprecate `Session.broadcast()` as the FS core behaviour is unreliable.
Add `execute()` support and use throughout the session API for all
FS core app commands.

Resolves #52
  • Loading branch information
Tyler Goodlet committed Dec 4, 2017
1 parent 49681fd commit 27490ae
Showing 1 changed file with 36 additions and 20 deletions.
56 changes: 36 additions & 20 deletions switchio/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import multiprocessing as mp
from concurrent import futures
from pprint import pprint
import warnings
from . import utils


Expand Down Expand Up @@ -229,7 +230,7 @@ def getvar(self, var):
def setvar(self, var, value):
"""Set variable to value
"""
self.broadcast("set::{}={}".format(var, value))
self.execute('set', '='.join((var, value)))

def setvars(self, params):
"""Set all variables in map `params` with a single command
Expand All @@ -241,7 +242,7 @@ def setvars(self, params):
def unsetvar(self, var):
"""Unset a channel var.
"""
self.broadcast("unset::{}".format(var))
return self.execute("unset", var)

def answer(self):
self.con.api("uuid_answer {}".format(self.uuid))
Expand Down Expand Up @@ -302,15 +303,12 @@ def playback(self, args, start_sample=None, endless=False,
else: # set a stream file delimiter
self.setvar('playback_delimiter', delim)

self.broadcast(
'{app}::{varset}{streams}{start} {leg}'.format(
app=app,
varset = '{{{vars}}}'.format(','.join(pairs)) if pairs else ''
args = '{streams}{start}'.format(
streams=delim.join(args),
start='@@{}'.format(start_sample) if start_sample else '',
leg=leg,
varset='{{{vars}}}'.format(','.join(pairs)) if pairs else '',
)
)
self.execute(app, args, params=varset)

def start_record(self, path, rx_only=False, stereo=False, rate=16000):
'''Record audio from this session to a local file on the slave filesystem
Expand All @@ -326,7 +324,7 @@ def start_record(self, path, rx_only=False, stereo=False, rate=16000):
self.setvar('RECORD_STEREO', 'true')

self.setvar('record_sample_rate', '{}'.format(rate))
self.broadcast('record_session::{}'.format(path))
self.execute('record_session', path)

def stop_record(self, path='all', delay=0):
'''Stop recording audio from this session to a local file on the slave
Expand All @@ -336,13 +334,13 @@ def stop_record(self, path='all', delay=0):
https://freeswitch.org/confluence/display/FREESWITCH/mod_dptools%3A+stop_record_session
'''
if delay:
self.con.api(
"sched_api +{delay} none uuid_broadcast {sessid} "
"stop_record_session::{path}".
format(sessid=self.uuid, delay=delay, path=path)
self.execute(
"sched_api",
"+{delay} none stop_record_session {path}".
format(delay=delay, path=path)
)
else:
self.broadcast('stop_record_session::{}'.format(path))
self.execute('stop_record_session', path)

def record(self, action, path, rx_only=True):
'''Record audio from this session to a local file on the slave filesystem
Expand All @@ -356,9 +354,9 @@ def record(self, action, path, rx_only=True):
self.con.api('uuid_record {} {} {}'.format(self.uuid, action, path))

def echo(self):
'''Echo back all audio recieved
'''Echo back all audio recieved.
'''
self.broadcast('echo::')
self.execute('echo')

def bypass_media(self, state):
'''Re-invite a bridged node out of the media path for this session
Expand All @@ -383,6 +381,12 @@ def park(self):
self.con.api('uuid_park {}'.format(self.uuid))
return self.recv('CHANNEL_PARK')

def execute(self, cmd, arg='', params='', loops=1):
"""Execute an application async.
"""
return self.con.execute(
self.uuid, cmd, arg, params=params, loops=loops)

def broadcast(self, path, leg='', delay=None, hangup_cause=None):
"""Execute an application async on a chosen leg(s) with optional hangup
afterwards. If provided tell FS to schedule the app ``delay`` seconds
Expand All @@ -394,6 +398,11 @@ def broadcast(self, path, leg='', delay=None, hangup_cause=None):
.. _sched_broadcast:
https://freeswitch.org/confluence/display/FREESWITCH/mod_commands#mod_commands-sched_broadcast
"""
warnings.warn((
"`Session.broadcast()` has been deprecated due to unreliable\
`uuid_broadcast` behaviour in FreeSWITCH core. Use\
`Session.execute()` instead."),
DeprecationWarning)
if not delay:
return self.con.api(
'uuid_broadcast {} {} {}'.format(self.uuid, path, leg))
Expand All @@ -414,8 +423,9 @@ def bridge(self, dest_url=None, profile=None, gateway=None, proxy=None,
if gateway:
profile = 'gateway/{}'.format(gateway)

self.broadcast(
"bridge::{{{varset}}}sofia/{}/{}{dest}".format(
self.execute(
'bridge',
"{{{varset}}}sofia/{}/{}{dest}".format(
profile if profile else self['variable_sofia_profile_name'],
dest_url if dest_url else self['variable_sip_req_uri'],
varset=','.join(pairs),
Expand Down Expand Up @@ -455,7 +465,7 @@ def respond(self, response):
.. _respond:
https://freeswitch.org/confluence/display/FREESWITCH/mod_dptools%3A+respond
"""
self.broadcast('respond::{}'.format(response))
self.execute('respond', response)

def deflect(self, uri):
"""Send a refer to the client.
Expand All @@ -464,7 +474,13 @@ def deflect(self, uri):
<action application="deflect" data="sip:someone@somewhere.com" />
"""
self.broadcast("deflect::{}".format(uri))
self.execute("deflect", uri)

def speak(self, text, engine='flite', voice='kal', timer_name=''):
"""Speak, young switch (alpha).
"""
return self.execute(
'speak', '|'.join((engine, voice, text, timer_name)))

def is_inbound(self):
"""Return bool indicating whether this is an inbound session
Expand Down

0 comments on commit 27490ae

Please sign in to comment.