실행되는 기본 함수

Freeswitch 에서 Python 스크립트를 호출할 때, 호출하는 주체가 어디냐에 따라 자동으로 실행되는 Default 함수가 달라진다.

 

– Dialplan 내에서 <action application=”python” data=”mod_fstest.python_example”/> 와 같은 형식으로 호출되는 경우.

호출되는 스크립트 내, handler() 함수가 호출된다.

handler() 함수의 모습은

# APPLICATION
#
# default name for apps is "handler" it can be overridden with <modname>::<function>
# session is a session object
# args is all the args passed after the module name
def handler(session, args):

	consoleLog('info', 'Answering call from Python.n')

처럼 되어야 한다.

 

– fs_cli 등에서 python 명령으로 호출되는 스크립트의 경우.
호출되는 스크립트 내의 fsapi() 함수가 호출된다.

fsapi() 함수의 모습은

# FSAPI CALL FROM CLI, DP HTTP etc
#
# default name for python FSAPI is "fsapi" it can be overridden with <modname>::<function>
# stream is a switch_stream, anything written with stream.write() is returned to the caller
# env is a switch_event
# args is all the args passed after the module name
# session is a session object when called from the dial plan or the string "na" when not.
def fsapi(session, stream, env, args):

	stream.write("w00t!n" + env.serialize())

처럼 되어야 한다.

 

– fs_cli 등에서 pyrun 명령으로 호출되는 스크립트의 경우,

호출되는 스크립트 내의 runtime() 함수가 호출된다.

runtime() 함수의 모습은

# RUN A FUNCTION IN A THREAD
#
# default name for pyrun is "runtime" it can be overridden with <modname>::<function>
# args is all the args passed after the module name
def runtime(args):

	print args + "n"

처럼 되어야 한다.

 

지원 API

mod_python 모듈을 이용하여 스크립트 작성시, freeswitch 에서 제공하는 여러가지 API 들을 이용하여 편리하게 프로그래밍을 할 수 있다.
지원하는 API 내용은 mod_lua 와 똑같은 내용의 API 를 지원하며 자세한 기능 및 API 일람은 아래의 링크에서 확인할 수 있다.

mod_lua API 목록: https://wiki.freeswitch.org/wiki/Mod_lua

 

예제 python Script

예제로 사용한 python script 이다. 원본은 https://wiki.freeswitch.org/wiki/Mod_python#Sample_Python_Scripts 에서 구할 수 있다.

import os
from freeswitch import *

# HANGUP HOOK
#
# session is a session object
# what is "hangup" or "transfer"
# if you pass an extra arg to setInputCallback then append 'arg' to get that value
# def hangup_hook(session, what, arg):
def hangup_hook(session, what):

	consoleLog("info","hangup hook for %s!!nn" % what)
	return


# INPUT CALLBACK
#
# session is a session object
# what is "dtmf" or "event"
# obj is a dtmf object or an event object depending on the 'what' var.
# if you pass an extra arg to setInputCallback then append 'arg' to get that value
# def input_callback(session, what, obj, arg):
def input_callback(session, what, obj):

	if (what == "dtmf"):
		consoleLog("info", what + " " + obj.digit + "n")
	else:
		consoleLog("info", what + " " + obj.serialize() + "n")		
	return "pause"

# APPLICATION
#
# default name for apps is "handler" it can be overridden with <modname>::<function>
# session is a session object
# args is all the args passed after the module name
def handler(session, args):

	consoleLog('info', 'Answering call from Python.n')
	consoleLog('info', 'Arguments: %sn' % args)

	session.answer()
	session.setHangupHook(hangup_hook)
	session.setInputCallback(input_callback)
	session.execute("playback", session.getVariable("hold_music"))

# FSAPI CALL FROM CLI, DP HTTP etc
#
# default name for python FSAPI is "fsapi" it can be overridden with <modname>::<function>
# stream is a switch_stream, anything written with stream.write() is returned to the caller
# env is a switch_event
# args is all the args passed after the module name
# session is a session object when called from the dial plan or the string "na" when not.
def fsapi(session, stream, env, args):

	stream.write("w00t!n" + env.serialize())
	

# RUN A FUNCTION IN A THREAD
#
# default name for pyrun is "runtime" it can be overridden with <modname>::<function>
# args is all the args passed after the module name
def runtime(args):

	print args + "n"

# BIND TO AN XML LOOKUP
#
# default name for binding to an XML lookup is "xml_fetch" it can be overridden with <modname>::<function>
# params a switch_event with all the relevant data about what is being searched for in the XML registry.
#
def xml_fetch(params):

	xml = '''
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="freeswitch/xml">
  <section name="dialplan" description="RE Dial Plan For FreeSWITCH">
    <context name="default">
      <extension name="generated">
        <condition>
         <action application="answer"/>
         <action application="playback" data="${hold_music}"/>
        </condition>
      </extension>
    </context>
  </section>
</document>
'''

	return xml

 

예제로 사용한 dialplan 이다. “5555555”로 전화를 걸면 스크립트가 사용된다.

<include>
  <extension name="python_test">
    <condition field="destination_number" expression="^(5555555)$">
      <!--
      If you're hosting multiple domains you will want to set the
      target_domain on these calls so they hit the proper domain after you
      transfer the caller into the default context. 
      
      $${domain} is the default domain set from vars.xml but you can set it
      to any domain you have setup in your user directory.

      -->
      <action application="info"/>
      <action application="python" data="mod_fstest.python_example"/>
      <!--<action application="set" data="domain_name=$${domain}"/>-->
      <!-- This example maps the DID 5551212 to ring 1000 in the default context -->
      <!--<action application="transfer" data="1000 XML default"/>-->
    </condition>
  </extension>
</include>

 

작성한 Python 스크립트를 dialplan 에서 호출하기 위해서는, 당연하겠지만 Dialplan 내에서 어떤 스크립트를 호출할지를 지정해 주어야 한다.

<action application=”python” data=”foo.bar”/>

위에 입력한 foo.bar 는 foo package 에 있는 bar 모듈을 호출한다는 설정이다. 뒤에 확장자 .py 를 붙이지 않도록 주의하자.
이 경우, 사용하게 되는 함수는 ‘handler’ 함수이다.

2014-05-06 17:55:40.838121 [NOTICE] mod_python.c:212 Invoking py module: mod_fstest.python_example
2014-05-06 17:55:40.838121 [DEBUG] mod_python.c:281 Call python script 
2014-05-06 17:55:40.838121 [INFO] switch_cpp.cpp:1293 Answering call from Python.
2014-05-06 17:55:40.838121 [INFO] switch_cpp.cpp:1293 Arguments:

handler 함수.

# APPLICATION
#
# default name for apps is "handler" it can be overridden with <modname>::<function>
# session is a session object
# args is all the args passed after the module name
def handler(session, args):

	consoleLog('info', 'Answering call from Python.n')
	consoleLog('info', 'Arguments: %sn' % args)

	session.answer()
	session.setHangupHook(hangup_hook)
	session.setInputCallback(input_callback)
	session.execute("playback", session.getVariable("hold_music"))

인자 값으로 session 과 args 를 입력받는다.
session 은 python 스크립트 내에서 사용되는 freeswitch interface 객체이며, args 는 모듈 호출시 넘겨지는 인자값들이다.

 

또한, fs_cli 에서 바로 작성한 python 스크립트를 호출할 수 있다. 이 경우, 사용한 명령어에 따라 호출되는 함수가 달라지는데, python 명령으로 호출할 경우, 스크립트 내, ‘fsapi’ 함수가 바로 호출이 된다.

freeswitch@192.168.200.10@internal> python mod_fstest.python_example
w00t!
'Event-Name: API
Core-UUID: 86d48a48-6f22-475c-89ac-146e6d0217d9
FreeSWITCH-Hostname: MyDebian
FreeSWITCH-Switchname: MyDebian
FreeSWITCH-IPv4: 10.0.2.10
FreeSWITCH-IPv6: %3A%3A1
Event-Date-Local: 2014-05-06%2017%3A43%3A01
Event-Date-GMT: Tue,%2006%20May%202014%2015%3A43%3A01%20GMT
Event-Date-Timestamp: 1399390981818146
Event-Calling-File: switch_loadable_module.c
Event-Calling-Function: switch_api_execute
Event-Calling-Line-Number: 2406
Event-Sequence: 4158
API-Command: python
API-Command-Argument: mod_fstest.python_example

'
2014-05-06 17:43:01.818146 [NOTICE] mod_python.c:212 Invoking py module: mod_fstest.python_example
2014-05-06 17:43:01.818146 [DEBUG] mod_python.c:281 Call python script 
2014-05-06 17:43:01.818146 [DEBUG] mod_python.c:284 Finished calling python script

 

참조 : https://wiki.freeswitch.org/wiki/Mod_python#Sample_Python_Scripts

 

 

Tags: ,

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.