application/luci-asterisk:
authorJo-Philipp Wich <jow@openwrt.org>
Sun, 11 Jan 2009 23:37:21 +0000 (23:37 +0000)
committerJo-Philipp Wich <jow@openwrt.org>
Sun, 11 Jan 2009 23:37:21 +0000 (23:37 +0000)
- implement initial sip client management
- improve trunk and client handling
- implement more options

applications/luci-asterisk/luasrc/controller/asterisk.lua
applications/luci-asterisk/luasrc/model/cbi/asterisk/phone_sip.lua [new file with mode: 0644]
applications/luci-asterisk/luasrc/model/cbi/asterisk/phones.lua [new file with mode: 0644]
applications/luci-asterisk/luasrc/model/cbi/asterisk/trunk_sip.lua
applications/luci-asterisk/luasrc/model/cbi/asterisk/trunks.lua

index 8200ce2e5c666ed4342972f2b17c7da8ac14fc28..bf0b36bef4cc61a91c9208a221f34be0f5faff22 100644 (file)
@@ -40,9 +40,14 @@ function index()
                cbi("asterisk-mod-res-feature"), "Feature Module Configuration", 9 )
 
 
                cbi("asterisk-mod-res-feature"), "Feature Module Configuration", 9 )
 
 
-       entry({"admin", "asterisk"},                   cbi("asterisk/main"),       "Asterisk", 99).i18n = "asterisk"
-       entry({"admin", "asterisk", "trunks"},         cbi("asterisk/trunks"),     "Trunks",    1)
-       entry({"admin", "asterisk", "trunks", "sip"},  cbi("asterisk/trunk_sip"),  "SIP",       1).leaf = true
+       entry({"admin", "asterisk"},                    cbi("asterisk/main"),        "Asterisk",  99).i18n = "asterisk"
+
+       entry({"admin", "asterisk", "phones"},          cbi("asterisk/phones"),      "Phones",     1)
+       entry({"admin", "asterisk", "phones", "sip"},   cbi("asterisk/phone_sip"),   nil,          1).leaf = true
+       entry({"admin", "asterisk", "phones", "exten"}, cbi("asterisk/phone_exten"), "Extensions", 2).leaf = true
+
+       entry({"admin", "asterisk", "trunks"},          cbi("asterisk/trunks"),      "Trunks",     2)
+       entry({"admin", "asterisk", "trunks", "sip"},   cbi("asterisk/trunk_sip"),   nil,          1).leaf = true
 
 
 end
 
 
 end
diff --git a/applications/luci-asterisk/luasrc/model/cbi/asterisk/phone_sip.lua b/applications/luci-asterisk/luasrc/model/cbi/asterisk/phone_sip.lua
new file mode 100644 (file)
index 0000000..29286c1
--- /dev/null
@@ -0,0 +1,113 @@
+--[[
+LuCI - Lua Configuration Interface
+
+Copyright 2008 Jo-Philipp Wich <xm@subsignal.org>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+$Id$
+
+]]--
+
+local ast = require("luci.asterisk")
+
+--
+-- SIP phone info
+--
+if arg[2] == "info" then
+       form = SimpleForm("asterisk", "SIP Phone Information")
+       form.reset  = false
+       form.submit = "Back to overview"
+
+       local info, keys = ast.sip.peer(arg[1])
+       local data = { }
+
+       for _, key in ipairs(keys) do
+               data[#data+1] = {
+                       key = key,
+                       val = type(info[key]) == "boolean"
+                               and ( info[key] and "yes" or "no" )
+                               or  ( info[key] == nil or #info[key] == 0 )
+                                       and "(none)"
+                                       or  tostring(info[key])
+               }
+       end
+
+       itbl = form:section(Table, data, "SIP Phone %q" % arg[1])
+       itbl:option(DummyValue, "key", "Key")
+       itbl:option(DummyValue, "val", "Value")
+
+       function itbl.parse(...)
+               luci.http.redirect(
+                       luci.dispatcher.build_url("admin", "asterisk", "phones")
+               )
+       end
+
+       return form
+
+--
+-- SIP phone configuration
+--
+elseif arg[1] then
+       cbimap = Map("asterisk", "Edit SIP Client")
+
+       peer = cbimap:section(NamedSection, arg[1])
+       peer.hidden = {
+               type        = "friend",
+               qualify     = "yes",
+               host        = "dynamic",
+               nat         = "no",
+               canreinvite = "no"
+       }
+
+       back = peer:option(DummyValue, "_overview", "Back to phone overview")
+       back.value = ""
+       back.titleref = luci.dispatcher.build_url("admin", "asterisk", "phones")
+
+       exten = peer:option(Value, "extension", "Extension Number")
+       cbimap.uci:foreach("asterisk", "dialplanexten",
+               function(s)
+                       exten:value(
+                               s.extension,
+                               "%s (via %s/%s)" %{ s.extension, s.type:upper(), s.target }
+                       )
+               end)
+
+       display = peer:option(Value, "callerid", "Display Name")
+
+       username  = peer:option(Value, "username", "Authorization ID")
+       password  = peer:option(Value, "secret", "Authorization Password")
+       password.password = true
+
+       active = peer:option(Flag, "disable", "Active")
+       active.enabled  = "yes"
+       active.disabled = "no"
+       function active.cfgvalue(...)
+               return AbstractValue.cfgvalue(...) or "yes"
+       end
+
+       regtimeout = peer:option(Value, "registertimeout", "Registration Time Value")
+       function regtimeout.cfgvalue(...)
+               return AbstractValue.cfgvalue(...) or "60"
+       end
+
+       sipport = peer:option(Value, "port", "SIP Port")
+       function sipport.cfgvalue(...)
+               return AbstractValue.cfgvalue(...) or "5060"
+       end
+
+       linekey = peer:option(ListValue, "_linekey", "Linekey Mode (broken)")
+       linekey:value("", "Off")
+       linekey:value("trunk", "Trunk Appearance")
+       linekey:value("call", "Call Appearance")
+
+       dialplan = peer:option(ListValue, "context", "Dialplan Context")
+       cbimap.uci:foreach("asterisk", "dialplan",
+               function(s) dialplan:value(s['.name']) end)
+
+       return cbimap
+end
diff --git a/applications/luci-asterisk/luasrc/model/cbi/asterisk/phones.lua b/applications/luci-asterisk/luasrc/model/cbi/asterisk/phones.lua
new file mode 100644 (file)
index 0000000..7831824
--- /dev/null
@@ -0,0 +1,119 @@
+--[[
+LuCI - Lua Configuration Interface
+
+Copyright 2008 Jo-Philipp Wich <xm@subsignal.org>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+$Id$
+
+]]--
+
+local ast = require("luci.asterisk")
+
+cbimap = Map("asterisk", "Registered Phones")
+cbimap.pageaction = false
+
+local sip_peers = { }
+cbimap.uci:foreach("asterisk", "sip",
+       function(s)
+               if s.type ~= "peer" then
+                       s.name = s['.name']
+                       s.info = ast.sip.peer(s.name)
+                       sip_peers[s.name] = s
+               end
+       end)
+
+
+sip_table = cbimap:section(TypedSection, "sip", "SIP Phones")
+sip_table.template  = "cbi/tblsection"
+sip_table.extedit   = luci.dispatcher.build_url("admin", "asterisk", "phones", "sip", "%s")
+sip_table.addremove = true
+
+sip_table.hidden = {
+       type        = "friend",
+       qualify     = "yes",
+       host        = "dynamic",
+       nat         = "no",
+       canreinvite = "no"
+}
+
+function sip_table.filter(self, s)
+       return s and cbimap.uci:get("asterisk", s, "type") ~= "peer"
+end
+
+function sip_table.create(self, section)
+       if TypedSection.create(self, section) then
+               created = section
+       else
+               self.invalid_cts = true
+       end
+end
+
+function sip_table.parse(self, ...)
+       TypedSection.parse(self, ...)
+       if created then
+               cbimap.uci:save("asterisk")
+               luci.http.redirect(luci.dispatcher.build_url(
+                       "admin", "asterisk", "phones", "sip", created
+               ))
+       end
+end
+
+
+user = sip_table:option(DummyValue, "username")
+function user.cfgvalue(self, s)
+       return sip_peers[s] and sip_peers[s].callerid or
+               AbstractValue.cfgvalue(self, s)
+end
+
+host = sip_table:option(DummyValue, "host")
+function host.cfgvalue(self, s)
+       if sip_peers[s] and sip_peers[s].info.address then
+               return "%s:%i" %{ sip_peers[s].info.address, sip_peers[s].info.port }
+       else
+               return "n/a"
+       end
+end
+
+context = sip_table:option(DummyValue, "context")
+context.href = luci.dispatcher.build_url("admin", "asterisk", "dialplan")
+
+nat = sip_table:option(DummyValue, "nat")
+function nat.cfgvalue(self, s)
+       return sip_peers[s] and sip_peers[s].info.Nat or "none"
+end
+
+online = sip_table:option(DummyValue, "online")
+function online.cfgvalue(self, s)
+       if sip_peers[s] and sip_peers[s].info.online == nil then
+               return "n/a"
+       else
+               return sip_peers[s] and sip_peers[s].info.online
+                       and "yes" or "no (%s)" % {
+                               sip_peers[s] and sip_peers[s].info.Status:lower() or "unknown"
+                       }
+       end
+end
+
+delay = sip_table:option(DummyValue, "delay")
+function delay.cfgvalue(self, s)
+       if sip_peers[s] and sip_peers[s].info.online then
+               return "%i ms" % sip_peers[s].info.delay
+       else
+               return "n/a"
+       end
+end
+
+info = sip_table:option(Button, "_info", "Info")
+function info.write(self, s)
+       luci.http.redirect(luci.dispatcher.build_url(
+               "admin", "asterisk", "phones", "sip", s, "info"
+       ))
+end
+
+return cbimap
index 28be40561268b7ff200cbd934d7657dc622ef5e0..900ff516a48cdee3c4f6fac246ad845b369d27c0 100644 (file)
@@ -16,19 +16,54 @@ $Id$
 local ast = require("luci.asterisk")
 
 --
 local ast = require("luci.asterisk")
 
 --
--- Specific SIP trunk
+-- SIP trunk info
 --
 --
-if arg[1] then
+if arg[2] == "info" then
+       form = SimpleForm("asterisk", "SIP Trunk Information")
+       form.reset  = false
+       form.submit = "Back to overview"
+
+       local info, keys = ast.sip.peer(arg[1])
+       local data = { }
+
+       for _, key in ipairs(keys) do
+               data[#data+1] = {
+                       key = key,
+                       val = type(info[key]) == "boolean"
+                               and ( info[key] and "yes" or "no" )
+                               or  ( info[key] == nil or #info[key] == 0 )
+                                       and "(none)"
+                                       or  tostring(info[key])
+               }
+       end
+
+       itbl = form:section(Table, data, "SIP Trunk %q" % arg[1])
+       itbl:option(DummyValue, "key", "Key")
+       itbl:option(DummyValue, "val", "Value")
+
+       function itbl.parse(...)
+               luci.http.redirect(
+                       luci.dispatcher.build_url("admin", "asterisk", "trunks")
+               )
+       end
+
+       return form
+
+--
+-- SIP trunk config
+--
+elseif arg[1] then
        cbimap = Map("asterisk", "Edit SIP Trunk")
 
        peer = cbimap:section(NamedSection, arg[1])
        peer.hidden = {
        cbimap = Map("asterisk", "Edit SIP Trunk")
 
        peer = cbimap:section(NamedSection, arg[1])
        peer.hidden = {
-               type = "peer"
+               type    = "peer",
+               qualify = "yes",
        }
 
        back = peer:option(DummyValue, "_overview", "Back to trunk overview")
        back.value = ""
        }
 
        back = peer:option(DummyValue, "_overview", "Back to trunk overview")
        back.value = ""
-       back.titleref = luci.dispatcher.build_url("admin", "asterisk", "trunks", "sip")
+       back.titleref = luci.dispatcher.build_url("admin", "asterisk", "trunks")
 
        sipdomain = peer:option(Value, "host", "SIP Domain")
        sipport   = peer:option(Value, "port", "SIP Port")
 
        sipdomain = peer:option(Value, "host", "SIP Domain")
        sipport   = peer:option(Value, "port", "SIP Port")
@@ -42,6 +77,9 @@ if arg[1] then
        password  = peer:option(Value, "secret", "Authorization Password")
        password.password = true
 
        password  = peer:option(Value, "secret", "Authorization Password")
        password.password = true
 
+       outboundproxy = peer:option(Value, "outboundproxy", "Outbound Proxy")
+       outboundport  = peer:option(Value, "outboundproxyport", "Outbound Proxy Port")
+
        register = peer:option(Flag, "register", "Register with peer")
        register.enabled  = "yes"
        register.disabled = "no"
        register = peer:option(Flag, "register", "Register with peer")
        register.enabled  = "yes"
        register.disabled = "no"
@@ -50,69 +88,13 @@ if arg[1] then
        regext:depends({register="yes"})
 
        didval = peer:option(ListValue, "_did", "Number of assigned DID numbers")
        regext:depends({register="yes"})
 
        didval = peer:option(ListValue, "_did", "Number of assigned DID numbers")
+       didval:value("", "(none)")
        for i=1,24 do didval:value(i) end
 
        for i=1,24 do didval:value(i) end
 
-       return cbimap
-
---
--- Trunk overview
---
-else
-       cbimap = Map("asterisk", "asterisk", "")
-
-       local sip_peers = { }
-       cbimap.uci:foreach("asterisk", "sip",
-               function(s)
-                       if s.type == "peer" then
-                               s.name = s['.name']
-                               s.info = ast.sip.peer(s.name)
-                               sip_peers[s.name] = s
-                       end
-               end)
-
-
-       sip_table = cbimap:section(Table, sip_peers, "SIP Trunks")
-       sip_table.template = "cbi/tblsection"
-       sip_table.extedit  = luci.dispatcher.build_url("admin", "asterisk", "trunks", "sip", "%s")
-
-       name = sip_table:option(DummyValue, "name")
-       user = sip_table:option(DummyValue, "username")
-
-       host = sip_table:option(DummyValue, "host")
-       function host.cfgvalue(self, s)
-               if sip_peers[s].info.address then
-                       return "%s:%i" %{ sip_peers[s].info.address, sip_peers[s].info.port }
-               else
-                       return "n/a"
-               end
-       end
-
-       context = sip_table:option(DummyValue, "context")
-       context.href = luci.dispatcher.build_url("admin", "asterisk", "dialplan")
-
-       nat = sip_table:option(DummyValue, "nat")
-       function nat.cfgvalue(self, s)
-               return sip_peers[s].info.Nat or "none"
-       end
-
-       online = sip_table:option(DummyValue, "online")
-       function online.cfgvalue(self, s)
-               if sip_peers[s].info.online == nil then
-                       return "n/a"
-               else
-                       return sip_peers[s].info.online
-                               and "yes" or "no (%s)" % sip_peers[s].info.Status:lower()
-               end
-       end
-
-       delay = sip_table:option(DummyValue, "delay")
-       function delay.cfgvalue(self, s)
-               if sip_peers[s].info.online then
-                       return "%i ms" % sip_peers[s].info.delay
-               else
-                       return "n/a"
-               end
-       end
+       dialplan = peer:option(ListValue, "context", "Dialplan Context")
+       dialplan:value("", "(default)")
+       cbimap.uci:foreach("asterisk", "dialplan",
+               function(s) dialplan:value(s['.name']) end)
 
        return cbimap
 end
 
        return cbimap
 end
index af992989c49ff34fbc27c063f7a27c96672eb479..02576b55939a88a98698814ee4931591b812e993 100644 (file)
@@ -15,7 +15,8 @@ $Id$
 
 local ast = require("luci.asterisk")
 
 
 local ast = require("luci.asterisk")
 
-cbimap = Map("asterisk", "asterisk", "")
+cbimap = Map("asterisk", "Registered Trunks")
+cbimap.pageaction = false
 
 local sip_peers = { }
 cbimap.uci:foreach("asterisk", "sip",
 
 local sip_peers = { }
 cbimap.uci:foreach("asterisk", "sip",
@@ -28,16 +29,47 @@ cbimap.uci:foreach("asterisk", "sip",
        end)
 
 
        end)
 
 
-sip_table = cbimap:section(Table, sip_peers, "SIP Trunks")
-sip_table.template = "cbi/tblsection"
-sip_table.extedit  = luci.dispatcher.build_url("admin", "asterisk", "trunks", "sip", "%s")
+sip_table = cbimap:section(TypedSection, "sip", "SIP Trunks")
+sip_table.template  = "cbi/tblsection"
+sip_table.extedit   = luci.dispatcher.build_url("admin", "asterisk", "trunks", "sip", "%s")
+sip_table.addremove = true
+
+sip_table.hidden = {
+       type    = "peer",
+       qualify = "yes"
+}
+
+function sip_table.filter(self, s)
+       return s and (
+               cbimap.uci:get("asterisk", s, "type") == "peer" or
+               cbimap.uci:get("asterisk", s, "type") == nil
+       )
+end
+
+function sip_table.create(self, section)
+       if TypedSection.create(self, section) then
+               created = section
+       else
+               self.invalid_cts = true
+       end
+end
+
+function sip_table.parse(self, ...)
+       TypedSection.parse(self, ...)
+       if created then
+               cbimap.uci:save("asterisk")
+               luci.http.redirect(luci.dispatcher.build_url(
+                       "admin", "asterisk", "trunks", "sip", created
+               ))
+       end
+end
+
 
 
-name = sip_table:option(DummyValue, "name")
 user = sip_table:option(DummyValue, "username")
 
 host = sip_table:option(DummyValue, "host")
 function host.cfgvalue(self, s)
 user = sip_table:option(DummyValue, "username")
 
 host = sip_table:option(DummyValue, "host")
 function host.cfgvalue(self, s)
-       if sip_peers[s].info.address then
+       if sip_peers[s] and sip_peers[s].info.address then
                return "%s:%i" %{ sip_peers[s].info.address, sip_peers[s].info.port }
        else
                return "n/a"
                return "%s:%i" %{ sip_peers[s].info.address, sip_peers[s].info.port }
        else
                return "n/a"
@@ -46,29 +78,41 @@ end
 
 context = sip_table:option(DummyValue, "context")
 context.href = luci.dispatcher.build_url("admin", "asterisk", "dialplan")
 
 context = sip_table:option(DummyValue, "context")
 context.href = luci.dispatcher.build_url("admin", "asterisk", "dialplan")
+function context.cfgvalue(...)
+       return AbstractValue.cfgvalue(...) or "(default)"
+end
 
 nat = sip_table:option(DummyValue, "nat")
 function nat.cfgvalue(self, s)
 
 nat = sip_table:option(DummyValue, "nat")
 function nat.cfgvalue(self, s)
-       return sip_peers[s].info.Nat or "none"
+       return sip_peers[s] and sip_peers[s].info.Nat or "none"
 end
 
 online = sip_table:option(DummyValue, "online")
 function online.cfgvalue(self, s)
 end
 
 online = sip_table:option(DummyValue, "online")
 function online.cfgvalue(self, s)
-       if sip_peers[s].info.online == nil then
+       if sip_peers[s] and sip_peers[s].info.online == nil then
                return "n/a"
        else
                return "n/a"
        else
-               return sip_peers[s].info.online
-                       and "yes" or "no (%s)" % sip_peers[s].info.Status:lower()
+               return sip_peers[s] and sip_peers[s].info.online
+                       and "yes" or "no (%s)" %{
+                               sip_peers[s] and sip_peers[s].info.Status:lower() or "unknown"
+                       }
        end
 end
 
 delay = sip_table:option(DummyValue, "delay")
 function delay.cfgvalue(self, s)
        end
 end
 
 delay = sip_table:option(DummyValue, "delay")
 function delay.cfgvalue(self, s)
-       if sip_peers[s].info.online then
+       if sip_peers[s] and sip_peers[s].info.online then
                return "%i ms" % sip_peers[s].info.delay
        else
                return "n/a"
        end
 end
 
                return "%i ms" % sip_peers[s].info.delay
        else
                return "n/a"
        end
 end
 
+info = sip_table:option(Button, "_info", "Info")
+function info.write(self, s)
+       luci.http.redirect(luci.dispatcher.build_url(
+               "admin", "asterisk", "trunks", "sip", s, "info"
+       ))
+end
+
 return cbimap
 return cbimap