FreeSwitch Lua编程接口(1)dialplan里的配置

本文介绍如何在FreeSWITCH中使用Dialplan配置Lua脚本来处理SIP呼叫。详细解析了SIP消息到达后,系统如何通过一系列步骤找到对应的Lua脚本并执行的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Dialplan里的配置

可以为freeswitch配置一个或若干个号码,当其他的sip终端通过拨打此号码时,通过拨号路由,查找到此号码,从而执行lua脚本。在Dialplan里的配置如下:

       <extension name="1200">

        <condition field="destination_number" expression="^1200$">

          <action application="lua" data="test.lua"/>

        </condition>

</extension>

 

需要说明的是:

dialplan是通过xml寻找拨号规则的,具体流程为:

①sip信令到达,invite消息,抵达sip endpoint的回调机制,例如sofia终端,会到达sip_handle_sip_i_invite函数做相应处理。

②在sofia_handle_sip_i_invite函数中,建立一个新的session,并未session创建一个channel。在channel中,包含一个caller_profile,这是一个类型为switch_caller_profile_t的结构体,记录了当前呼叫的各种必要属性。Caller_profile里记录了当前的route方式为“XML”,这里明确指明了通过xml文件查询拨号规则。(见该函数里的switch_channel_set_caller_profile(channel, tech_pvt->caller_profile))

③除此之外,sofia_handle_sip_i_invite还根据sip消息设置channle和session的相关信息,其中包括remote_ip,sip_via_protocl等字段信息。

④设置完毕后,一个相对较完整的session和channle便存在了,这时,sofia_handle_i_invite会启动session的状态机,根据channel的状态来执行相应处理。

⑤于是,状态机启动,当执行到routing状态时(参见函数switch_core_session_run,switch_core_state_machine.c)。会执行标准的状态函数switch_core_standard_on_routing,在函数里,查询全局哈希表,得到名字为dpname的dialplan_interface:

108行dialplan_interface = switch_loadable_module_get_dialplan_interface(dpname)

dpname为“XML”,该dialplan_interface是在mod_dialplan_xml模块中加加载时插入全局哈希表的。

当然,要首先从channel中取得当前的caller_profile:

85行 caller_profile = switch_channel_get_caller_profile(session->channel)

当找到dialplan_interface时,会调用

dialplan_interface->hunt_function(session, dparg, NULL),实际调用的是

SWITCH_STANDARD_DIALPLAN(dialplan_hunt),定义在mod_dialplan_xml.c中,该函数会查找相应的xml文件,并返回一个switch_caller_extension_t结构,该结构代表了上面xml文件里的标签<extension>…</extension>里的内容。而子文档元素<action application="lua" data="test.lua"/>说明的是,将“lua”应用插入到switch_caller_extension_t结构中,在switch_caller_extension_t中由switch_caller_application_t *applications指针将当前channel需要执行的应用函数串成一个链表。于是,当channel在状态机中状态经过routing,转化为execute时,就会通过switch_core_standard_on_exev()函数一次调用所有应用。

⑥在这里,dialplan里只添加了一个extension,并且,只添加了一个应用接口,即为”lua”,所以当有拨打1200的sip消息到来时,将会在channel->state = on_execute时调用该应用。同样,会查询全局哈希表,找到application_interface,然后调用application_interface,调用流程如下:

switch_core_standard_on_execute(session)

switch_core_session_execute_application

//宏,实际为switch_core_session_execute_application_get_flags

switch_core_session_exec(session, application_interface, arg)//arg = “***.lua”

于是,就进入了lua的app应用接口

在mod_lua.cpp中得SWITCH_STANDARD_APP(lua_function)函数

 

Lua执行分析

App函数展开

SWITCH_STANDARD_APP(lua_function)展开后为:

lua_function(switch_core_session_t *session,const char *data);

这里传入的data即是“***.lua”即lua的文件名。

 

Lua_function主要工作

1.        调用lua_init()函数为当前执行脚本创建一个lua_State实例,并用lua_State *L指针指向。

2.        调用mod_lua_conjure_session(L, session, "session", 1),创建一个Session类,该类从freeswitch提供的CoreSession类公有继承而来。其中,实参session指向的便是在sip_handle_sip_i_invite里新创建的switch_core_session_t类型的实例。

3.        调用lua_parse_and_execute(L, mycmd)读取脚本文件并解释执行。mycmd=”***.lua”

 

具体的执行

具体执行是在lua_parse_and_execute(…)函数里用

174行 error = luaL_loadfile(L, file) || docall(L, 0, 1) 语句完成的。

luaL_loadfile函数负责读取文件,docall函数负责解释执行。

### FreeSWITCH 中使用 Lua 进行调用的实现方法 在 FreeSWITCH 配置中,通过定义特定扩展名并关联 Lua 脚本来处理来电请求。当电话号码匹配指定模式时触发相应的动作。 对于拨号方案配置,在 `/usr/local/freeswitch/conf/dialplan/default/` 下创建或编辑 XML 文件来设置新的 extension[^1]: ```xml <extension name="Simple_Lua_Test"> <condition field="destination_number" expression="^(9910)$"> <action application="lua" data="test3.lua"/> </condition> </extension> ``` 上述代码片段表示当目的地编号为 `9910` 的呼叫进入时,将会执行位于默认路径下的名为 `test3.lua` 的 Lua 脚本文件。 #### 创建 Lua 脚本 为了响应此事件,需编写对应的 Lua 脚本以操作 session 对象。假设我们将要编写的脚本保存为 `test3.lua` 并放置于适当位置以便被 FreeSWITCH 找到。下面是一个简单的例子展示如何利用 session 来控制通话流程: ```lua local session = freeswitch.Session() -- 初始化 Session 实例 if not session then freewswitch.consoleLog("ERR", "无法初始化会话\n") else session:answer() local stream = session:streamFile("/path/to/audio/file.wav") -- 播放音频 while true do event = session:waitForDigit(5000) -- 等待按键输入最长五秒 if event == "" or tonumber(event) ~= nil then break end end session:sayDigits(event, "en") -- 结束通话 end ``` 这段 Lua 代码展示了怎样接收来自用户的按鍵 (DTMF),以及如何根据这些输入采取行动。这还包含了基本的声音播放功能和结束通话的操作。 另外,还可以设定 API 挂断钩子,使得即使是在其他地方挂掉电话也能运行额外逻辑[^2]: ```xml <action application="set" data="api_hangup_hook=lua hook-test.lua"/> ``` 这允许开发者自定义更复杂的业务场景下所需的行为。 最后值得注意的是,除了被动等待入站呼叫外,也可以主动发起出站呼叫并通过编程方式管理整个过程[^3]: ```lua new_session = freeswitch.Session("sofia/gateway/gatewayname/xxxxx") ``` 以上就是有关 FreeSWITCH 使用 Lua 编程接口的一些基础介绍及其应用案例。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值