Default LuaAutostarters.xml in FW 1.4

LuaAutostarters.xml
  1. <?xml version="1.0" encoding="utf-8"?><!--
  2. --><luaAutoStarters><!--
  3. --><luaScript name="ActionUrlReporting"><!--
  4. --><code><![CDATA[
  5. local stringx = require "pl.stringx"
  6. local SERVER_SETTING_PATH = "remoteAccess/actionUrlServer"
  7. local mServer = ""
  8. function settingChanged(path)
  9. mServer = config.get(SERVER_SETTING_PATH)
  10. if #mServer > 0 and not stringx.startswith(string.lower(mServer), "http") then
  11. mServer = "http://"..mServer
  12. end
  13. end
  14. config.register(SERVER_SETTING_PATH, settingChanged)
  15. settingChanged(SERVER_SETTING_PATH)
  16. function callListChanged(event, call1, call2)
  17. if event == nil or call1 == nil then
  18. debug.log("invalid parameters at callListChanged("..tostring(event).." ,"..tostring(call1)..")", "w")
  19. return
  20. end
  21. if event == "add" then onCallAdded(call1)
  22. elseif event == "remove" then onCallRemoved(call1)
  23. elseif event == "state_changed" then onStateChanged(call1)
  24. elseif event == "remote_update" then onRemoteChanged(call1)
  25. elseif event == "transferred" then onTransferred(call1)
  26. elseif event == "conferenced" then onConferenced(call1, call2)
  27. elseif event == "unconferenced" then onUnconferenced(call1, call2)
  28. elseif event == "transfer_initiated" or event == "transfer_failed" or event == "transfer_done" then
  29. onTransferAway(call1, call2, event)
  30. else debug.log("unknown call-event: "..event, "w")
  31. end
  32. end
  33. function informServer(query)
  34. if #mServer > 0 then
  35. http.get(mServer..query)
  36. end
  37. end
  38. function onCallAdded(call)
  39. local mac = phoneInfo.getMacAddress()
  40. local regId = call:getIdentityIndex()
  41. local callId = call:getId()
  42. local state = call:getState()
  43. local incoming = call:isIncoming()
  44. local event = "outgoing"
  45. if incoming then
  46. event = "incoming"
  47. end
  48. debug.log("call added: "..callId..", reg="..regId..", state="..state..", event="..event..", "..getRemoteParameters(call), "i")
  49. informServer("?event="..event.."&mac="..mac.."&callId="..callId.."&accountId="..regId..getRemoteParameters(call))
  50. end
  51. function onCallRemoved(call)
  52. local mac = phoneInfo.getMacAddress()
  53. local callId = call:getId()
  54. debug.log("call removed: "..callId, "i")
  55. informServer("?event=disconnected&callId="..callId.."&mac="..mac)
  56. end
  57. function onStateChanged(call)
  58. local mac = phoneInfo.getMacAddress()
  59. local callId = call:getId()
  60. local state = call:getState()
  61. local event = "unknown"
  62. debug.log("call state changed: "..callId..", state="..state, "i")
  63. if state == "holding" then
  64. event = "holding"
  65. elseif state == "active" then
  66. event = "connected"
  67. else
  68. debug.log("call state changed ignored cause neither hold nor connected", "i")
  69. return
  70. end
  71. informServer("?event="..event.."&mac="..mac.."&callId="..callId)
  72. end
  73. function onRemoteChanged(call)
  74. local mac = phoneInfo.getMacAddress()
  75. local callId = call:getId()
  76. debug.log("remote updated: "..callId..", "..getRemoteParameters(call), "i")
  77. informServer("?event=remoteUpdate&mac="..mac.."&callId="..callId..getRemoteParameters(call))
  78. end
  79. function onTransferred(call)
  80. local mac = phoneInfo.getMacAddress()
  81. local callId = call:getId()
  82. local state = call:getState()
  83. if state == "active" then
  84. state = "connected"
  85. end
  86. debug.log("remote changed: "..callId..", "..getRemoteParameters(call), "i")
  87. informServer("?event=transferred&mac="..mac.."&callId="..callId.."&state="..state..getRemoteParameters(call))
  88. end
  89. function onTransferAway(call, target, evtType)
  90. local mac = phoneInfo.getMacAddress()
  91. local callId = call:getId()
  92. local targetParam = ""
  93. if type(target) == "string" then
  94. targetParam = "&number="..target
  95. else
  96. targetParam = "&callId2="..target:getId()
  97. end
  98. debug.log(evtType ..": "..callId..", "..targetParam, "i")
  99. informServer("?event="..evtType.."&mac="..mac.."&callId="..callId..targetParam)
  100. end
  101. function onUnconferenced(call1, call2)
  102. local mac = phoneInfo.getMacAddress()
  103. local callId1 = call1:getId()
  104. local callId2 = call2:getId()
  105. debug.log("conference disolved: "..callId1.." and "..callId2, "i")
  106. informServer("?event=unconferenced&mac="..mac.."&callId="..callId1.."&callId2="..callId2)
  107. end
  108. function onConferenced(call1, call2)
  109. local mac = phoneInfo.getMacAddress()
  110. local callId1 = call1:getId()
  111. local callId2 = call2:getId()
  112. debug.log("conferenced: "..callId1.." and "..callId2, "i")
  113. informServer("?event=conferenced&mac="..mac.."&callId="..callId1.."&callId2="..callId2)
  114. end
  115. function getRemoteParameters(call)
  116. local number, name = call:getRemote()
  117. -- TODO: enclose number and name in "" once we figure out how to make http.get(..) not encode it to %22
  118. if name == nil then
  119. return "&number="..number.."&name="
  120. else
  121. return "&number="..number.."&name="..tostring(name)..""
  122. end
  123. end
  124. callsCb = sip.calls.listen(callListChanged)--]]></code><!--
  125. --></luaScript><!--
  126. --><luaScript name="ActionUrlAccepting"><!--
  127. --><code><![CDATA[
  128. local pretty = require "pl.pretty"
  129. local stringx = require "pl.stringx"
  130. local tablex = require "pl.tablex"
  131. local SETTING_PATH = "remoteAccess/allowCallManipulationViaHttp"
  132. local PRINT_HLP_ERROR = "printHelp"
  133. local mEnable = false
  134. function settingChanged(path)
  135. local newEnable = config.get(SETTING_PATH) == "true"
  136. if newEnable ~= mEnable then
  137. mEnable = newEnable
  138. if mEnable then
  139. listenForCallCmds()
  140. else
  141. stopListeningToCallCmds()
  142. end
  143. end
  144. end
  145. local cmdMap = {}
  146. cmdMap.accept = { executeMe=sip.calls.accept, strParams = { callid="call", callid1="call" }, boolParams = { fireandforget="!returnHttpResult"} }
  147. cmdMap.call = { executeMe=sip.calls.make, strParams = { number="uri", accountid="line" }, boolParams = { fireandforget="!returnHttpResult"} }
  148. cmdMap.terminate =
  149. { executeMe=sip.calls.terminate, strParams = { callid="call", callid1="call", callid2="call2" }, boolParams = { fireandforget="!returnHttpResult"} }
  150. cmdMap.dtmf = { executeMe=sip.calls.dtmf, strParams = { callid="call", callid1="call", number="dtmf" }, boolParams = { fireandforget="!returnHttpResult"} }
  151. cmdMap.hold = { executeMe=sip.calls.hold, strParams = { callid="call", callid1="call", callid2="call2" }, boolParams = { fireandforget="!returnHttpResult"} }
  152. cmdMap.resume = { executeMe=sip.calls.resume, strParams = { callid="call", callid1="call", callid2="call2" }, boolParams = { fireandforget="!returnHttpResult"} }
  153. cmdMap.conference =
  154. { executeMe=sip.calls.conference, strParams = { callid="call", callid1="call", callid2="call2" }, boolParams = { fireandforget="!returnHttpResult"} }
  155. cmdMap.join = { executeMe=sip.calls.join, strParams = { callid="call", callid1="call", callid2="call2" }, boolParams = { fireandforget="!returnHttpResult"} }
  156. cmdMap.transfer =
  157. { executeMe=sip.calls.transfer, strParams = { callid="call", callid1="call", number="number" }, boolParams = { fireandforget="!returnHttpResult"} }
  158. cmdMap.log = { executeMe=debug.log, strParams = { text="message", level="debug_level"}, boolParams = { fireandforget="!returnHttpResult"} }
  159. cmdMap.show = { executeMe=system.toast, strParams = { text="text"}, boolParams = { fireandforget="!returnHttpResult"} }
  160. -- aliases:
  161. cmdMap.offhook = { duplicates="accept" }
  162. cmdMap.hangup = { duplicates="terminate" }
  163. local uniqueCmds = {}
  164. for action, details in pairs(cmdMap) do
  165. if details.duplicates == nil then
  166. uniqueCmds[action] = details
  167. end
  168. end
  169. function onActionUrl(url, body, headers, vars)
  170. debug.log(url, "d")
  171. debug.log(pretty.write(vars.query_map), "d")
  172. local query = vars.query_map
  173. local action = query.action
  174. query.action = nil -- remove so it won't get interpreted as parameter
  175. if action == nil then
  176. if query.help ~= nil then
  177. return 200, getCmdList()
  178. end
  179. debug.log("unknown action in request -> ignoring: ?"..tostring(vars.query_string))
  180. return 400, "missing action=...\n\n"..getCmdList()
  181. end
  182. -- find action within our mapping, what should be done?:
  183. action = string.lower(tostring(action))
  184. if cmdMap[action] == nil then
  185. if action == "help" then
  186. return 200, getCmdList()
  187. else
  188. return 404, "unknown action '"..action.."'\n\n"..getCmdList()
  189. end
  190. end
  191. command = cmdMap[action]
  192. if command.duplicates ~= nil then
  193. command = cmdMap[command.duplicates]
  194. end
  195. -- interpret the query-parameters, how do they get passed on to the system-function?:
  196. local paramMap, error = createParamMap(query, command)
  197. if error ~= nil then
  198. if error == PRINT_HLP_ERROR then
  199. return 200, "action: "..action.." - parameters: "..getCmdHelp(command)
  200. else
  201. return 400, error.."\n\nexpected: "..getCmdHelp(command)
  202. end
  203. end
  204. -- finally, do it:
  205. return command.executeMe(paramMap)
  206. end
  207. -- return 2 results:
  208. -- first one is the parameter-map (query parameters converted into dict for lua-function)
  209. -- when query contains any none-mapped parameters, then 2nd result is that parameter
  210. function createParamMap(query, details)
  211. local result = {}
  212. local queryKeys = {}
  213. -- find the real map-keys [i.e. all but the array-indexes] .. also check for special help-param
  214. for key, val in pairs(query) do
  215. if type(key) ~= 'number' or key < 1 or key > #query then
  216. queryKeys[#queryKeys+1]=key
  217. elseif val == "help" then
  218. return result, PRINT_HLP_ERROR
  219. end
  220. end
  221. if details.boolParams then
  222. for i, queryParam in ipairs(query) do
  223. -- iterating through all query-params that dont have a value. These are interpreted as bool
  224. -- these bools represent a true by just being in the query - false when mapped-param starts with !
  225. local destination = details.boolParams[queryParam:lower()]
  226. if destination == nil then
  227. destination = details.strParams and details.strParams[queryParam:lower()]
  228. if destination == nil then
  229. return result, "unknown parameter: "..queryParam
  230. end
  231. return result, queryParam.." is missing an assigned value."
  232. end
  233. local value = true
  234. if destination:sub(1, 1) == "!" then
  235. destination = destination:sub(2)
  236. value = false
  237. end
  238. result[destination] = value
  239. end
  240. else -- no bool-params expected, report error if we received any
  241. for i, queryParam in ipairs(query) do
  242. return result, "unknown parameter: "..queryParam
  243. end
  244. end
  245. if details.strParams then
  246. for _, key in ipairs(queryKeys) do
  247. local value = query[key]
  248. debug.log(tostring(key).." -> "..tostring(value), "d")
  249. local destination = details.strParams[key:lower()]
  250. if destination == nil then
  251. destination = details.boolParams and details.boolParams[key:lower()]
  252. if destination == nil then
  253. return result, "unknown parameter: "..key
  254. end
  255. -- so its a bool param -> convert str-value:
  256. value = (value:lower() == "true" or value:lower() == "on")
  257. if destination:sub(1, 1) == "!" then
  258. destination = destination:sub(2)
  259. value = not value
  260. end
  261. end
  262. result[destination] = value
  263. end
  264. end
  265. if details.boolParams then
  266. -- now set all boolean values that were not part of the query:
  267. for _, boolParam in pairs(details.boolParams) do
  268. local value = false -- wasn't added to query thus false
  269. if boolParam:sub(1, 1) == "!" then
  270. boolParam = boolParam:sub(2)
  271. value = not value
  272. end
  273. if result[boolParam] == nil then
  274. result[boolParam] = value
  275. end
  276. end
  277. end
  278. return result
  279. end
  280. function getCmdHelp(cmd)
  281. local result = ""
  282. if cmd.strParams and cmd.boolParams then
  283. result = stringx.join(", ", tablex.keys(tablex.union(cmd.strParams, cmd.boolParams))).."\n"
  284. elseif cmd.strParams then
  285. result = stringx.join(", ", tablex.keys(cmd.strParams)).."\n"
  286. elseif cmd.boolParams then
  287. result = stringx.join(", ", tablex.keys(cmd.boolParams)).."\n"
  288. else
  289. result = "[no parameters]"
  290. end
  291. local conversion = ""
  292. if cmd.strParams then
  293. for query, param in pairs(cmd.strParams) do
  294. if query ~= param then
  295. conversion = conversion.." "..query.." -> "..param.."\n"
  296. end
  297. end
  298. end
  299. if cmd.boolParams then
  300. for query, param in pairs(cmd.boolParams) do
  301. if query ~= param then
  302. conversion = conversion.." "..query.." -> "..param.."\n"
  303. end
  304. end
  305. end
  306. if #conversion > 0 then
  307. result = result.."\nMapping of query-parameters to function-parameters:\n"
  308. result = result..conversion
  309. end
  310. result = result.."\n"..debug.getDocu(cmd.executeMe)
  311.  
  312. return result
  313. end
  314. function getCmdList()
  315. local result = "choose one of the following actions: help, "..stringx.join(", ", tablex.keys(uniqueCmds))
  316. result = result.."\n\nYou can get detailed help for an action by adding 'help' as parameter, e.g.: ..?action=call&help\n"
  317. return result
  318. end
  319. local mCommandListener = nil
  320. function stopListeningToCallCmds()
  321. http.stop_listen(mCommandListener)
  322. mCommandListener = nil
  323. debug.log("no longer listening to incoming ActionUrl's")
  324. end
  325. function listenForCallCmds()
  326. mCommandListener = http.listen("command", onActionUrl, true)
  327. debug.log("listening for commands on https://" .. getIp() .. "/api/v1/exec/command?action=...")
  328. end
  329. function getIp()
  330. local ips = phoneInfo.getIPs()
  331. if #ips > 0 then
  332. return ips[1]
  333. end
  334. return "[phoneIp]"
  335. end
  336. config.register(SETTING_PATH, settingChanged)
  337. settingChanged(SETTING_PATH)--]]></code><!--
  338. --></luaScript><!--
  339. --></luaAutoStarters>
  • en/products/comfortel-d-series/d-100-200/developer/provisioning/settings/luaautostarters/default1.4.txt
  • Last modified: 17.03.2020 16:29
  • (external edit)