From 1d895ace660869053830ed33302e0708efb6065e Mon Sep 17 00:00:00 2001 From: Ted Trask Date: Mon, 10 Oct 2011 19:34:59 +0000 Subject: Added in configuration files / scripts and cgi-bin scripts. --- config/acl.conf | 2 + config/delete_device.lua | 44 ++ config/determine_class.lua | 21 + config/lighttpd.sample.conf | 338 +++++++++++++ config/notify_device | 30 ++ config/templates/linksysata-template.lua | 839 +++++++++++++++++++++++++++++++ config/templates/polycom-template.lua | 346 +++++++++++++ config/templates/snom-template.lua | 95 ++++ config/update_device.lua | 14 + config/update_device_params.lua | 41 ++ 10 files changed, 1770 insertions(+) create mode 100644 config/acl.conf create mode 100644 config/delete_device.lua create mode 100644 config/determine_class.lua create mode 100644 config/lighttpd.sample.conf create mode 100755 config/notify_device create mode 100644 config/templates/linksysata-template.lua create mode 100644 config/templates/polycom-template.lua create mode 100644 config/templates/snom-template.lua create mode 100644 config/update_device.lua create mode 100644 config/update_device_params.lua (limited to 'config') diff --git a/config/acl.conf b/config/acl.conf new file mode 100644 index 0000000..9469c42 --- /dev/null +++ b/config/acl.conf @@ -0,0 +1,2 @@ +Linksys +Polycom diff --git a/config/delete_device.lua b/config/delete_device.lua new file mode 100644 index 0000000..ad908ed --- /dev/null +++ b/config/delete_device.lua @@ -0,0 +1,44 @@ +-- This is the script run after deleting a device (and all of its params) +local functions, olddevice, oldparams = ... + +local path = "PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin " + +APP.logevent("got to delete_device script") + +-- We'll handle the deleting of the device by handling the resulting changing of the params +-- First, have to create a new set of params (with blank extensions) +local duplicatestructure +duplicatestructure = function(value, saved) + saved = saved or {} + if type(value) == "table" then + if saved[value] then + return saved[value] + else + local output = {} + saved[value] = output + for k,v in pairs(value) do + output[k] = duplicatestructure(v, saved) + end + return output + end + else + return value + end +end + +local params = duplicatestructure(oldparams) +for name,val in pairs(params.value) do + if string.match(name, "^reg") then + params.value[name].value.extension.value = "" + end +end + +-- Then call the other script +local env = {} +setmetatable (env, {__index = _G}) +-- loadfile loads into the global environment +-- so we set env 0, not env 1 +setfenv (0, env) +local f = loadfile("/etc/provisioning/update_device_params.lua") +if (f) then f(functions, params, oldparams) end +setfenv (0, _G) diff --git a/config/determine_class.lua b/config/determine_class.lua new file mode 100644 index 0000000..df8f5c2 --- /dev/null +++ b/config/determine_class.lua @@ -0,0 +1,21 @@ +-- This is the script run to determine the device class from the HTTP user agent +local functions, agent, classes = ... + +APP.logevent("got to determine_class script") + +local manufacture, model + +if string.match(agent, "Polycom") then + manufacture = "Polycom" + model = string.match(agent, "Polycom[^%s%d]+(%d+)") +end + +APP.logevent("Found "..(manufacture or "").." model "..(model or "")) + +if manufacture and model then + for i,c in ipairs(classes.value) do + if string.match(c.label, manufacture) and string.match(c.label, model) then + return c.class_id + end + end +end diff --git a/config/lighttpd.sample.conf b/config/lighttpd.sample.conf new file mode 100644 index 0000000..23dbe0d --- /dev/null +++ b/config/lighttpd.sample.conf @@ -0,0 +1,338 @@ +############################################################################### +# Default lighttpd.conf for Gentoo. +# $Header: /var/cvsroot/gentoo-x86/www-servers/lighttpd/files/conf/lighttpd.conf,v 1.3 2005/09/01 14:22:35 ka0ttic Exp $ +############################################################################### + +server.reject-expect-100-with-417 = "disable" +debug.log-request-handling = "enable" +debug.log-file-not-found = "enable" +debug.log-request-header-on-error = "enable" + +# {{{ variables +var.basedir = "/var/www/provisioning" +var.logdir = "/var/log/lighttpd" +var.statedir = "/var/lib/lighttpd" +# }}} + +# {{{ modules +# At the very least, mod_access and mod_accesslog should be enabled. +# All other modules should only be loaded if necessary. +# NOTE: the order of modules is important. +server.modules = ( + "mod_rewrite", +# "mod_redirect", +# "mod_alias", + "mod_access", +# "mod_cml", +# "mod_trigger_b4_dl", +# "mod_auth", +# "mod_status", +# "mod_setenv", +# "mod_proxy", +# "mod_simple_vhost", +# "mod_evhost", +# "mod_userdir", +# "mod_compress", +# "mod_ssi", +# "mod_usertrack", +# "mod_expire", +# "mod_secdownload", +# "mod_rrdtool", +# "mod_webdav", + "mod_accesslog" +) +# }}} + +# {{{ includes +include "mime-types.conf" +# uncomment for cgi support +include "mod_cgi.conf" +# uncomment for php/fastcgi support +# include "mod_fastcgi.conf" +# }}} + +# {{{ server settings +server.username = "lighttpd" +server.groupname = "lighttpd" + +server.document-root = var.basedir + "/htdocs" +server.pid-file = "/var/run/lighttpd.pid" + +server.errorlog = var.logdir + "/error.log" +# log errors to syslog instead +# server.errorlog-use-syslog = "enable" + +server.indexfiles = ("index.php", "index.html", + "index.htm", "default.htm") + +# server.tag = "lighttpd" + +server.follow-symlink = "enable" + +# event handler (defaults to "poll") +# see performance.txt +# +# for >= linux-2.4 +# server.event-handler = "linux-rtsig" +# for >= linux-2.6 +# server.event-handler = "linux-sysepoll" +# for FreeBSD +# server.event-handler = "freebsd-kqueue" + +# chroot to directory (defaults to no chroot) +# server.chroot = "/" + +# bind to port (defaults to 80) +# server.port = 81 + +# bind to name (defaults to all interfaces) +# server.bind = "grisu.home.kneschke.de" + +# error-handler for status 404 +# server.error-handler-404 = "/error-handler.html" +# server.error-handler-404 = "/error-handler.php" +server.error-handler-404 = "/cgi-bin/provisioning.cgi" + +# Format: .html +# -> ..../status-404.html for 'File not found' +# server.errorfile-prefix = var.basedir + "/error/status-" + +# FAM support for caching stat() calls +# requires that lighttpd be built with USE=fam +# server.stat-cache-engine = "fam" +# }}} + +# {{{ mod_staticfile + +# which extensions should not be handled via static-file transfer +# (extensions that are usually handled by mod_cgi, mod_fastcgi, etc). +static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi") +# }}} + +# {{{ mod_accesslog +accesslog.filename = var.logdir + "/access.log" +# }}} + +# {{{ mod_dirlisting +# enable directory listings +# dir-listing.activate = "enable" +# +# don't list hidden files/directories +# dir-listing.hide-dotfiles = "enable" +# +# use a different css for directory listings +# dir-listing.external-css = "/path/to/dir-listing.css" +# +# list of regular expressions. files that match any of the +# specified regular expressions will be excluded from directory +# listings. +# dir-listing.exclude = ("^\.", "~$") +# }}} + +# {{{ mod_access +# see access.txt + +url.access-deny = ("~", ".inc") +# }}} + +# {{{ mod_userdir +# see userdir.txt +# +# userdir.path = "public_html" +# userdir.exclude-user = ("root") +# }}} + +# {{{ mod_ssi +# see ssi.txt +# +# ssi.extension = (".shtml") +# }}} + +# {{{ mod_ssl +# see ssl.txt +# +# ssl.engine = "enable" +# ssl.pemfile = "server.pem" +# }}} + +# {{{ mod_status +# see status.txt +# +# status.status-url = "/server-status" +# status.config-url = "/server-config" +# }}} + +# {{{ mod_simple_vhost +# see simple-vhost.txt +# +# If you want name-based virtual hosting add the next three settings and load +# mod_simple_vhost +# +# document-root = +# virtual-server-root + virtual-server-default-host + virtual-server-docroot +# or +# virtual-server-root + http-host + virtual-server-docroot +# +# simple-vhost.server-root = "/home/weigon/wwwroot/servers/" +# simple-vhost.default-host = "grisu.home.kneschke.de" +# simple-vhost.document-root = "/pages/" +# }}} + +# {{{ mod_compress +# see compress.txt +# +# compress.cache-dir = var.statedir + "/cache/compress" +# compress.filetype = ("text/plain", "text/html") +# }}} + +# {{{ mod_proxy +# see proxy.txt +# +# proxy.server = ( ".php" => +# ( "localhost" => +# ( +# "host" => "192.168.0.101", +# "port" => 80 +# ) +# ) +# ) +# }}} + +# {{{ mod_auth +# see authentication.txt +# +# auth.backend = "plain" +# auth.backend.plain.userfile = "lighttpd.user" +# auth.backend.plain.groupfile = "lighttpd.group" + +# auth.backend.ldap.hostname = "localhost" +# auth.backend.ldap.base-dn = "dc=my-domain,dc=com" +# auth.backend.ldap.filter = "(uid=$)" + +# auth.require = ( "/server-status" => +# ( +# "method" => "digest", +# "realm" => "download archiv", +# "require" => "user=jan" +# ), +# "/server-info" => +# ( +# "method" => "digest", +# "realm" => "download archiv", +# "require" => "valid-user" +# ) +# ) +# }}} + +# {{{ mod_rewrite +# see rewrite.txt +# +# url.rewrite = ( +# "^/$" => "/server-status" +# ) +# }}} + +# {{{ mod_redirect +# see redirect.txt +# +# url.redirect = ( +# "^/wishlist/(.+)" => "http://www.123.org/$1" +# ) +# }}} + +# {{{ mod_evhost +# define a pattern for the host url finding +# %% => % sign +# %0 => domain name + tld +# %1 => tld +# %2 => domain name without tld +# %3 => subdomain 1 name +# %4 => subdomain 2 name +# +# evhost.path-pattern = "/home/storage/dev/www/%3/htdocs/" +# }}} + +# {{{ mod_expire +# expire.url = ( +# "/buggy/" => "access 2 hours", +# "/asdhas/" => "access plus 1 seconds 2 minutes" +# ) +# }}} + +# {{{ mod_rrdtool +# see rrdtool.txt +# +# rrdtool.binary = "/usr/bin/rrdtool" +# rrdtool.db-name = var.statedir + "/lighttpd.rrd" +# }}} + +# {{{ mod_setenv +# see setenv.txt +# +# setenv.add-request-header = ( "TRAV_ENV" => "mysql://user@host/db" ) +# setenv.add-response-header = ( "X-Secret-Message" => "42" ) +# }}} + +# {{{ mod_trigger_b4_dl +# see trigger_b4_dl.txt +# +# trigger-before-download.gdbm-filename = "/home/weigon/testbase/trigger.db" +# trigger-before-download.memcache-hosts = ( "127.0.0.1:11211" ) +# trigger-before-download.trigger-url = "^/trigger/" +# trigger-before-download.download-url = "^/download/" +# trigger-before-download.deny-url = "http://127.0.0.1/index.html" +# trigger-before-download.trigger-timeout = 10 +# }}} + +# {{{ mod_cml +# see cml.txt +# +# don't forget to add index.cml to server.indexfiles +# cml.extension = ".cml" +# cml.memcache-hosts = ( "127.0.0.1:11211" ) +# }}} + +# {{{ mod_webdav +# see webdav.txt +# +# $HTTP["url"] =~ "^/dav($|/)" { +# webdav.activate = "enable" +# webdav.is-readonly = "enable" +# } +# }}} + +# {{{ extra rules +# +# set Content-Encoding and reset Content-Type for browsers that +# support decompressing on-thy-fly (requires mod_setenv) +# $HTTP["url"] =~ "\.gz$" { +# setenv.add-response-header = ("Content-Encoding" => "x-gzip") +# mimetype.assign = (".gz" => "text/plain") +# } + +# $HTTP["url"] =~ "\.bz2$" { +# setenv.add-response-header = ("Content-Encoding" => "x-bzip2") +# mimetype.assign = (".bz2" => "text/plain") +# } +# +# }}} + +# {{{ debug +# debug.log-request-header = "enable" +# debug.log-response-header = "enable" +# debug.log-request-handling = "enable" +# debug.log-file-not-found = "enable" +# }}} + +# vim: set ft=conf foldmethod=marker et : + +url.rewrite = ( + "^/?$" => "/cgi-bin/redirect.cgi", +) + +$HTTP["request-method"] =~ "^(PUT|DELETE)$" { +url.rewrite = ( + "^(.*)$" => "/cgi-bin/provisioning.cgi/$1" +) +} + diff --git a/config/notify_device b/config/notify_device new file mode 100755 index 0000000..7d5ff2a --- /dev/null +++ b/config/notify_device @@ -0,0 +1,30 @@ +#!/usr/bin/lua +require("socket") +require("validator") + +if not arg or #arg == 0 then + print("Error - IP Address must be specified") + return 1 +end + +local address = arg[1] +local user = arg[2] or "" +if not validator.is_ipv4(address) then + print("Error - Invalid IP Address") + return 1 +end + +local msg = "NOTIFY sip:"..user.."@"..address..":5060 SIP/2.0\n".. +"Via: SIP/2.0/UDP 127.0.0.1\n".. +"From: \n".. +"To: \n".. +"Event: check-sync\n".. +"Date: "..os.date().."\n".. +"Call-ID: "..os.time().."msgto0@"..address.."\n".. +"CSeq: 102 NOTIFY\n".. +"Contact: \n".. +"Content-Length: 0\n\n" + +local s = assert(socket.udp()) +assert(s:sendto(msg, address, 5060)) +s:close() diff --git a/config/templates/linksysata-template.lua b/config/templates/linksysata-template.lua new file mode 100644 index 0000000..ba71657 --- /dev/null +++ b/config/templates/linksysata-template.lua @@ -0,0 +1,839 @@ +<% +-- Linksys ATA Configuration File Template +local values = ... +server=values.device.registrar +web_server=string.gsub(ENV['HTTP_HOST'], ":[0-9]*$", "") +moh=values.device.musiconhold +dialpattern="( " .. values.device.digitmap .. " )" + +local cid +if values.reg1.callerid == "" then + cid = values.reg1.extension +else + cid = values.reg1.callerid +end +%> + +<% local values = ... %> + +<% + +local function yesno ( bool ) + if bool then + return "Yes" + else + return "No" + end +end +%> + + + + +Yes +80 +Yes + +<%= values.device.adminpassword %> + +<%= values.device.adminpassword %> + + + +Yes + + + + + + +<% io.write(values.reg1.extension) %> + + + + +DHCP,Manual +Sequential + +<%= web_server %> +<%= web_server %> +0 + + + + + + +Yes +Yes +<% -- Resync at a particular time of day, not periodically. (24-hour format hhmm) %> +0200 +<% -- Resync_Periodic is disabled because of using Resync_At instead %> + + +10 +900 +<% -- Do not resync during a call, unless the call lasts longer than 3 hours %> +10800 + +Yes +Yes + + + +No + + + + +http://<% io.write(web_server) %>/Linksys/$MA.xml + + + + + + + + + + +$PN $MAC -- Requesting resync $SCHEME://$SERVIP:$PORT$PATH +$PN $MAC -- Successful resync $SCHEME://$SERVIP:$PORT$PATH +$PN $MAC -- Resync failed: $ERR + + + + +Yes +7200 + + + + + + +(!5.1.6)?http://<% io.write(web_server) %>/pap2t-5-1-6.bin + + + +$PN $MAC -- Requesting upgrade $SCHEME://$SERVIP:$PORT$PATH +$PN $MAC -- Successful upgrade $SCHEME://$SERVIP:$PORT$PATH -- $ERR +$PN $MAC -- Upgrade failed: $ERR + + + +70 +5 +2 +$MAU $VERSION +$MAU $VERSION + + +application/dtmf-relay +application/hook-flash +No +No + + + +2 +32 +5 +6 +31 +32 +32 +32 +240 +30 +1 +7200 +60 +60 + + + + + + + + + + + + + +10050 +16384 +0 +5 + + + +100 +101 +98 +97 +96 +99 + +NSE +telephone-event +PCMU +PCMA +G726-16 +G726-24 +G726-32 +G726-40 +G729 +G729ab +G723 + + + +Yes +Yes +Yes +Yes +Yes +No +No +No + + + +15 + + + + + + + + +Yes + +No +<% io.write(moh) %> +30 +No + + +5060 + +No + +$NOTIFY +0x68 +$PROXY +0xb8 + + + + + +very high +disable +Yes +Yes +No +Yes + + +0 +No + + + + +<% io.write(server) %> + +No + +Yes + +Yes +No + +60 +Yes +Yes +Yes +3600 + + + + +<%= cid %> +<% io.write(values.reg1.extension) %> +<% io.write(values.reg1.password) %> +No + + + + + + +<%= yesno(values.services and values.services.callwaitingenable) %> +No +No +Yes +Yes +Yes +Yes +No +No +No +No +No +Yes +Yes +No +Yes +Yes +Yes +Yes +Yes +Yes +Yes +No +No +No +Yes + + + +G711u +No +Yes +medium +Yes +No +Yes +No +Yes +No +Yes +No +Yes +Yes +G711u +No +Yes +Auto +ReINVITE +None +Yes +No + + +<% io.write(dialpattern) %> + +No + + + +Forward +Forward +Forward + + +<% + if values.services and values.services.forwarding and values.reg1 then + local pg_t = values.reg1 + local fwddata = {} + + if pg_t.forwardallenable then + fwddata.all = pg_t.forwardall + else + fwddata.all = "" + end + if pg_t.forwardbusyenable then + fwddata.busy = pg_t.forwardbusy + else + fwddata.busy = "" + end + if pg_t.forwardnoanswerenable then + fwddata.noanswer = pg_t.forwardnoanswer + fwddata.noanswerdelay = "20" + else + fwddata.noanswer = "" + fwddata.noanswerdelay = "" + end +%> +<%= fwddata.all %> +<%= fwddata.busy %> +<%= fwddata.noanswer %> +<%= fwddata.noanswerdelay %> +<% + end +%> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +No +No +No +Yes +Yes +Yes +No + +No + + + + + + + + + + + + + + +1 +1 +8 + + +0 +0 +0 +New VM Available +No + + + + +No + +No + +30 +No + + +5060 + +Yes + +$NOTIFY +0x68 +$PROXY +0xb8 + + + + + + + +high +No +No +No +No + + +0 +No + + + + + + +No + +Yes + +Yes +No + +60 +Yes +No +No +3600 +2147483647 + + + + + + +No + + + + + + +Yes +Yes +No +Yes +No +No +No +No +No +No +No +No +Yes +Yes +No +Yes +Yes +Yes +Yes +Yes +Yes +Yes +No +No +No +Yes + + + +G711u +No +Yes +medium +Yes +Yes +Yes +No +Yes +No +Yes +No +Yes +Yes +G711u +No +Yes +Auto +ReINVITE +None +Yes +Yes + + + +(<:1123>[2-9]xxxxxxS0|<411:18003733411>|*xx|[369]11S0|0|00|011[2-9]x.|1xxx[2-9]xxxxxxS0|xxxxxxxxxxxx.) + +No + + + +Forward +Forward +Forward + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +No +No +No +Yes +Yes +Yes +No + + + + + + + + + + + + + + + + +1 +1 +8 + + +0 +0 +0 +New VM Available +No + + +1 +1 + +.020 + + +350@-19,440@-19;10(*/0/1+2) +350@-19,440@-19;10(*/0/1+2) +350@-19,440@-19;10(*/0/1+2) +350@-19,440@-19;10(*/0/1+2) +480@-19,620@-19;10(.5/.5/1+2) +480@-19,620@-19;10(.25/.25/1+2) +480@-10,620@0;10(.125/.125/1+2) +440@-19,480@-19;*(2/4/1+2) +600@-16;1(.25/.25/1) +985@-16,1428@-16,1777@-16;20(.380/0/1,.380/0/2,.380/0/3,0/4/0) +914@-16,1371@-16,1777@-16;20(.274/0/1,.274/0/2,.380/0/3,0/4/0) +914@-16,1371@-16,1777@-16;20(.380/0/1,.380/0/2,.380/0/3,0/4/0) +985@-16,1371@-16,1777@-16;20(.380/0/1,.274/0/2,.380/0/3,0/4/0) +350@-19,440@-19;2(.1/.1/1+2);10(*/0/1+2) +350@-19,440@-19;2(.2/.2/1+2);10(*/0/1+2) +600@-19;*(.1/.1/1,.1/.1/1,.1/9.5/1) +350@-19;20(.1/.1/1,.1/9.7/1) +397@-19,507@-19;15(0/2/0,.2/.1/1,.1/2.1/2) + + + +60(2/4) +60(.3/.2,1/.2,.3/4) +60(.8/.4,.8/4) +60(.4/.2,.3/.2,.8/4) +60(.2/.2,.2/.2,.2/.2,1/4) +60(.2/.4,.2/.4,.2/4) +60(.4/.2,.4/.2,.4/4) +60(0.25/9.75) + + + +30(.3/3.7) +30(.1/.1, .1/9.7) +30(.1/.1, .3/.1, .1/9.3) +30(.1/.1,.1/.1,.1/9.5) +30(.3/.1,.1/.1,.3/9.1) +30(.1/.1,.3/.2,.3/9.1) +30(.3/.1,.3/.1,.1/9.1) +2.3(.3/2) + + + +Bellcore-dr1 +Bellcore-dr2 +Bellcore-dr3 +Bellcore-dr4 +Bellcore-dr5 +Bellcore-dr6 +Bellcore-dr7 +Bellcore-dr8 + + + +Sinusoid +20 +90 +440@-10 +Yes + + + +.1 +1.0 +0 +0 +4500 +90 +2 +0 +8 +4 +2 +0 + + + + +*98 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +*99 + + + + + + + + +GMT-05:00 + + + +start=3/8/7/2:0:0;end=11/1/7/2:0:0;save=1 + + + +600 + +-6 +-3 +-16 +.1 +Yes +Yes +Bellcore(N.Amer,China) +5 + +Yes + +Yes + + + +<% +-- DEBUGGING +--require("session") +--io.write(session.serialize("values", values)) +%> diff --git a/config/templates/polycom-template.lua b/config/templates/polycom-template.lua new file mode 100644 index 0000000..5ed35a3 --- /dev/null +++ b/config/templates/polycom-template.lua @@ -0,0 +1,346 @@ + + +<% +-- Polycom Configuration File Template +-- We use single quotes to avoid escaping XML's double quotes + +-- It is important that the first line be the XML declaration + +--[[ + Implemented parameters: + values = { + device = { + adminpassword + digitmap + digitmaptimeout + homepage + musiconhold + pcportenable + registrar + sntpserver + timezone + urldialingenable + } + regX (where X is a number 1-34) = { + extension = EXTEN + password = string + forwardall = EXTEN + forwardallenable = boolean + forwardbusy = EXTEN (allow URI?) + forwardbusyenable = boolean + forwardnoanswer = EXTEN + forwardnoanswerenable = boolean + } + -- Assuming that services will not be nil + services = { + callhistoryenable = boolean + callwaitingenable = boolean + forwarding = boolean + hotlinedestination = string + hotlineenable = boolean + mailbox = string + speeddialenable = boolean + } +--]] +%> + + + +<% --- From features.cfg %> +<% --TODO: Do we want to enable locking? %> +<% --phoneLock.enabled="1" %> +<% --feature.autoLocalHold="1" -- trying default for now%> +feature.callPark.enabled="1" +feature.directedCallPickup.enabled="1" +feature.enhancedFeatureKeys.enabled="1" +feature.groupCallPickup.enabled="1" +feature.messaging.enabled="1" +<% -- Management of buddies, and own status %> +feature.presence.enabled="1" +<% -- Run-time downloading of ringers %> +feature.ringDownload.enabled="1" +<% -- Create DND softkey button except on SPIP650 %> +softkey.1.enable="1" +softkey.1.enable.SPIP650="0" +softkey.1.label="DND" +softkey.1.action="$FDoNotDisturb$" +softkey.1.use.idle="1" +softkey.1.use.active="1" +softkey.1.use.alerting="1" + +<% --- From sip-interop.cfg %> +<% -- Allow user to set Do Not Disturb (DND) per-registration %> +call.donotdisturb.perReg="1" +<% -- When a conference is put on hold, other parties continue to talk %> +call.localConferenceCallHold="1" +<% -- Disallow transfers during the proceeding state of a consultation call %> +voIpProt.SIP.allowTransferOnProceeding="0" +<% -- TODO needed???%> +<% --voIpProt.SIP.CID.sourcePreference="" %> +<% -- Send 486 (SIP Busy Here) when 'Reject' is pressed during a ringing call %> +voIpProt.SIP.use486forReject="1" +<% -- Set phone's requested registration period in seconds %> +voIpProt.server.1.expires="60" +voIpProt.server.2.expires="60" +<% -- Set RFC 2833 payload to 101 instead of 127 for interop. with Linksys ATA %> +tone.dtmf.rfc2833Payload="101" + + +<% --- From site.cfg %> +<% -- Allow the use of device.xxx options (Admin Guide A-30) %> +device.set="1" +<% -- Override default user password of '123' see Admin Guide 4-103 %> +<% -- only used for phone locking and to protect redundant 'Reboot' option %> +device.auth.localUserPassword="" +device.auth.localUserPassword.set="1" +<% -- Attempt to determine VLAN ID and negotiate power through LLDP %> +device.net.lldpEnabled="1" +<% -- Apply option configured in device.net.lldpEnabled (Admin Guide A-30) %> +device.net.lldpEnabled.set="1" +<% -- Phone should provide reorder tone when dialed digits do not match digit map %> +dialplan.impossibleMatchHandling="1" +<% -- Do not treat a trailing '#' as a 'Send' operation %> +dialplan.removeEndOfDial="0" +<% -- Automatic periodic polling of provisioning server for upgrades %> +prov.polling.enabled="1" +<% -- Polling time of day hh:mm. %> +prov.polling.time="02:00" +<% -- Do not reject RTP packets arriving from a non-SDP-negotiated IP address %> +<% -- Needed for some ATAs that do provide bad SDP in transfers to MOH %> +tcpIpApp.port.rtp.filterByIp="0" +<% -- Reject RTP packets arriving from a non-SDP-negotiated port %> +<% -- To provide some security despite disabling filterByIp above.t %> +tcpIpApp.port.rtp.filterByPort="1" +<% -- Headset preferred over speakerphone after first use, until disabled %> +up.headsetMode="1" +<% -- Intensity of LCD backlight when phone is idle. 0 = off. %> +up.backlight.idleIntensity="0" +<% -- Receive volume of handset remembered between calls %> +voice.volume.persist.handset="1" +<% -- Receive volume of headset remembered between calls %> +voice.volume.persist.headset="1" + + + + + +<% local values = ... %> + +<% +local function xml_attr (t, v) +if v ~= nil then + -- v could be a string, boolean, or a number + io.write(table.concat(t, '.') .. '="' .. tostring(v) .. '"\n') +end +end +%> + +<% + +xml_attr({ 'voIpProt.server.1.address' }, values.device.registrar) +xml_attr({ 'mb.main.home' }, values.device.homepage) +xml_attr({ 'voIpProt.SIP.musicOnHold.uri' }, values.device.musiconhold) +xml_attr({ 'dialplan.digitmap.timeOut' }, values.device.digitmaptimeout) +xml_attr({ 'feature.urlDialing.enabled' }, values.device.urldialingenable) + +if not values.device.pcportenable then + -- set mode to '-1' which disables it + xml_attr({ 'device.net.etherModePC' }, '-1') + -- apply settings in 'device' parameter above + xml_attr({ 'device.net.etherModePC.set' }, '1') +end + +-- Override the default admin password of '456' +if values.device.adminpassword then + xml_attr({ 'device.auth.localAdminPassword' }, values.device.adminpassword) + xml_attr({ 'device.auth.localAdminPassword.set' }, true) +end + +---[=[ +-- Handle SNTP and Time Zone parameters +-- See http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html +-- TZ variable, with no leading colon +-- Syntax: stdoffset[dst[offset][,start[/time],end[/time]]] +-- Examples: 'GMT0' 'EST5EDT,M3.2.0,M11.1.0' '5' + +-- we can assume that values.device is not nil +-- since values.device.template is this file +if values.device.sntpserver then + xml_attr({ 'tcpIpApp.sntp.address' }, values.device.sntpserver) +end + + +-- Parse time zone variable +require('posixtz') +local tz = posixtz.parse(values.device.timezone) + +if tz then + + -- convert POSIX sign (W of GMT is '+') to Polycom (E of GMT is '+') + xml_attr({'tcpIpApp.sntp.gmtOffset'}, -1 * tz.offset.total) + + + + local function dstrule ( pos ) + local dstprefix = 'tcpIpApp.sntp.daylightSavings' + local t = tz.dst[pos] + + -- Handle explicit hour for DST change + -- (Polycom doesn't implement explicit min or sec) + -- (Polycom DST implementation assumes DST change is 1 hour) + if t.hour then + xml_attr({ dstprefix, pos, 'time' }, t.hour) + end + + if t.day then + -- there may be two of next line, Polycom uses first + xml_attr({ dstprefix, 'fixedDayEnable' }, true) + xml_attr({ dstprefix, pos, 'month' }, t.month) + xml_attr({ dstprefix, pos, 'date' }, t.day) + else + + -- there may be two of next line, Polycom uses first + xml_attr({ dstprefix, 'fixedDayEnable' }, false) + xml_attr({ dstprefix, pos, 'month' }, t.month) + + -- POSIX weekday is between 0 (Sun) and 6 (Sat) + -- Polycom dayOfWeek is 1=Sun, 7=Sat + xml_attr({ dstprefix, pos, 'dayOfWeek' }, tonumber(t.weekday) + 1) + + -- POSIX week from 1 to 5, where 1st,2nd..4th, and 5=last + if t.week == '5' then + xml_attr({ dstprefix, pos, 'dayOfWeek.lastInMonth' }, true) + else + -- Polycom uses 1, 8, 15, 22 for 1st, 2nd... 4th + local d = 7 * ( tonumber(t.week) - 1 ) + 1 + xml_attr({ dstprefix, pos, 'date' }, d) + end + end + + end + + if tz.dst then + xml_attr({'tcpIpApp.sntp.daylightSavings.enable'}, true) + + dstrule('start') + dstrule('stop') + else + xml_attr({'tcpIpApp.sntp.daylightSavings.enable'}, false) + end +end + +--]=] + + +-- Check 'services' params +local enable = {} +enable.forwarding = false +enable.hotline = false + +if values.services then + -- set variables so that we don't have to test values.services again + if not values.services.callhistoryenable then + xml_attr({ 'feature.callList.enabled' }, '0') + end + if not values.services.callwaitingenable then + -- only allow one call per line key + xml_attr({ 'call.callsPerLineKey' }, '1' ) + end + if values.services.forwarding then + enable.forwarding = true + end + if values.services.hotlineenable then + enable.hotline = true + -- Set phone to replace any dialed digits with the hotline destination instead + xml_attr({ 'dialplan.digitmap' }, 'R[#*0123456789].R'..values.services.hotlinedestination..'R') + xml_attr({ 'dialplan.applyToUserDial' }, '1') + xml_attr({ 'dialplan.applyToUserSend' }, '1') + else + xml_attr({ 'dialplan.digitmap' }, values.device.digitmap) + end + if values.services.mailbox then + xml_attr({ 'msg.mwi.1.subscribe' }, values.services.mailbox) + xml_attr({ 'msg.mwi.1.callBackMode' }, "contact") + xml_attr({ 'msg.mwi.1.callBack' }, string.gsub(values.services.mailbox, "@.*", "")) + end + -- set local contact directory to be readonly or readwrite + if not values.services.speeddialenable then + xml_attr({ 'dir.local.contacts.maxNum' }, 0) + end +end + + +-- Loop through Parameter Groups looking for 'reg' params +for pg, pg_t in pairs(values) do + +-- Is it of the form regX ? +local num = string.match(pg, 'reg(%d+)') +if num then + + + -- set Hotline on all possible registrations if it is configured + if enable.hotline then + local d = values.services.hotlinedestination + if d then + xml_attr({ 'call.autoOffHook', num, 'enabled' }, '1') + xml_attr({ 'call.autoOffHook', num, 'protocol' }, 'SIP') + xml_attr({ 'call.autoOffHook', num, 'contact' }, d) + end + end + + -- user part of From URI + xml_attr({ 'reg', num, 'address' }, pg_t.extension) + -- SIP authentication parameters + xml_attr({ 'reg', num, 'auth.userId' }, pg_t.extension) + xml_attr({ 'reg', num, 'auth.password' }, pg_t.password) + -- Caller ID string + xml_attr({ 'reg', num, 'displayName' }, pg_t.callerid) + + + -- From Admin_Guide_UCS_v3.3.0: + -- "The phone has a flexible call forward/diversion feature for each registration. In all cases, a call will only be diverted if a non-Null contact has been configured." + if enable.forwarding then + -- Although not documented, + -- Polycom phones send special options for + -- 'forward all calls', namely: + -- reg.x.fwdContact and reg.x.fwdStatus + + -- set forwardall as defined + xml_attr({ 'reg', num, 'fwdStatus' }, pg_t.forwardallenable) + xml_attr({ 'reg', num, 'fwdContact' }, pg_t.forwardall) + + -- set forwardnoanswer as defined + xml_attr({ 'reg', num, 'fwd.noanswer.status' }, pg_t.forwardnoanswerenable) + xml_attr({ 'reg', num, 'fwd.noanswer.contact' }, pg_t.forwardnoanswer) + xml_attr({ 'reg', num, 'fwd.noanswer.ringCount' }, '3') + -- we do not use 'divert.noanswer.x.timeout', + -- because it limits maximum rings *even when* forward-on-noanswer disabled + + -- set forwardbusy on DND and on busy, as defined + xml_attr({ 'reg', num, 'fwd.busy.status' }, pg_t.forwardbusyenable) + xml_attr({ 'divert.dnd', num, 'enabled' }, pg_t.forwardbusyenable) + xml_attr({ 'reg', num, 'fwd.busy.contact' }, pg_t.forwardbusy) + xml_attr({ 'divert.dnd', num, 'contact' }, pg_t.forwardbusy) + + else -- forwarding is not enabled + -- disable the soft-key menu for forwarding + xml_attr({ 'divert.fwd', num, 'enabled' }, '0') + end + + +end + +end + +%> + +/> + +<% +-- DEBUGGING +--require("session") +--local log, err = io.open("/root/polycom-template.log", "a") +--log:write(session.serialize("values", values)) +%> diff --git a/config/templates/snom-template.lua b/config/templates/snom-template.lua new file mode 100644 index 0000000..7ac4542 --- /dev/null +++ b/config/templates/snom-template.lua @@ -0,0 +1,95 @@ +<% +local values = ... + +local function xml_elem(t,v,p,i) + local elem = t + if i == nil then + if v == true then + io.write('<'..elem..' perm="'..p..'">on\n') + elseif v == false then + io.write('<'..elem..' perm="'..p..'">off\n') + else + io.write('<'..elem..' perm="'..p..'">'..tostring(v)..'\n') + end + else + if v == true then + io.write('<'..elem..' idx="'..i..'" perm="'..p..'">on\n') + elseif v == false then + io.write('<'..elem..' idx="'..i..'" perm="'..p..'">off\n') + else + io.write('<'..elem..' idx="'..i..'" perm="'..p..'">'..tostring(v)..'\n') + end + end +end +%> + + + + + <% io.write(values.device.adminpassword) %> + 184 + <% if values.device.dateformat == string.lower("mm/dd/yyyy") then + io.write('on') + else + io.write('off') + end %> + on + 60 + <% xml_elem('eth_pc',values.device.pcportenable,'R') %> + <% io.write(values.device.adminpassword) %> + admin + on + <% xml_elem('language',values.device.uilanguage,'RW') %> + <% io.write(values.device.sntpserver) %> + off + on + 7200 + 184 + <% xml_elem('time_24_format',values.device.timeformat24h,'RW') %> + + + auto_update + off + <% +for pg, pg_t in pairs(values) do + + -- Is it of the form regX ? + local num = string.match(pg, 'reg(%d+)') + if num then + if pg_t.extension ~= "" then + xml_elem('record_dialed_calls', pg_t.callhistoryenable, 'R', num) + xml_elem('record_missed_calls', pg_t.callhistoryenable, 'R', num) + xml_elem('record_received_calls', pg_t.callhistoryenable, 'R', num) + -- SNOMs do not support per-line forwarding + xml_elem('redirect_allways',pg_t.forwardallenable,'RW') + xml_elem('redirect_number',pg_t.forwardall,'RW') + xml_elem('redirect_on_busy',pg_t.forwardbusyenable,'RW') + xml_elem('redirect_busy_number',pg_t.forwardbusy,'RW') + xml_elem('redirect_on_timeout',pg_t.forwardnoanswerenable,'RW') + xml_elem('redirect_time_number',pg_t.forwardnoanswer,'RW') + xml_elem('redirect_time','20','RW') + xml_elem('retry_after_failed_subscribe', '30', 'R', num) + xml_elem('user_active', 'on', 'RW', num ) + xml_elem('user_host', values.device.registrar, 'R', num ) + xml_elem('user_hold_inactive', 'off', 'R', num) + xml_elem('user_moh', values.device.musiconhold, 'R', num) + xml_elem('user_name', pg_t.extension, 'R', num) + xml_elem('user_outbound', values.device.registrar, 'R', num) + xml_elem('user_pass', pg_t.password, 'R', num) + xml_elem('user_publish_presence_bootup', 'off', 'R', num) + xml_elem('user_ringer', 'Ringer'..pg_t.ringtone, '!', num) + xml_elem('user_shared_line',pg_t.sharedlineenable, 'R', num) + xml_elem('user_srtp', 'off', 'R', num) + xml_elem('user_subscription_expiry', '120', 'R', num) -- by default SNOMs re-register after *half* of this time have passed + -- Caller ID string + if string.len(pg_t.callerid) == 0 then + xml_elem( 'user_realname', pg_t.extension,'R', num) + else + xml_elem( 'user_realname', pg_t.callerid,'R', num) + end + end + end +end + %> + + diff --git a/config/update_device.lua b/config/update_device.lua new file mode 100644 index 0000000..90f5340 --- /dev/null +++ b/config/update_device.lua @@ -0,0 +1,14 @@ +-- This is the script run after editing a device - the label, classes +local functions, device, olddevice, params, oldparams = ... + +APP.logevent("got to update_device script") + +-- We'll handle the changing of the device by handling the resulting changing of the params +local env = {} +setmetatable (env, {__index = _G}) +-- loadfile loads into the global environment +-- so we set env 0, not env 1 +setfenv (0, env) +local f = loadfile("/etc/provisioning/update_device_params.lua") +if (f) then f(functions, params, oldparams) end +setfenv (0, _G) diff --git a/config/update_device_params.lua b/config/update_device_params.lua new file mode 100644 index 0000000..974f339 --- /dev/null +++ b/config/update_device_params.lua @@ -0,0 +1,41 @@ +-- This is the script run after editing device params +local functions, params, oldparams = ... + +APP.logevent("got to update_device_params script") + +local function findip(mac) + if not mac or mac == "" then + return nil + end + local ipaddr = functions.getselectresponse("SELECT ip FROM provisioning_requests WHERE mac~*'"..mac.."'") + if ipaddr and ipaddr[1] then + return ipaddr[1].ip + end +end + +local notify_device = function(mac, extension) + local ipaddr = findip(mac) + if ipaddr then + APP.logevent("Notifying "..ipaddr.." to update for "..(mac or "")) + os.execute("/etc/provisioning/notify_device "..ipaddr.." "..extension) + addfuturenotify(ipaddr, extension) + else + APP.logevent("Warning - could not find IP address for "..(mac or "")) + end +end + +-- Notify the phone to pull it's config +-- Try to get a valid extension currently on the device +local oldexten = "" +for name,val in pairs(oldparams.value) do + if string.match(name, "^reg") and val.value.extension and val.value.extension.value ~= "" then + oldexten = val.value.extension.value + break + end +end +if params.value.device and params.value.device.value.mac and params.value.device.value.mac.value ~= "" then + notify_device(params.value.device.value.mac.value, oldexten) +end +if oldparams.value.device and oldparams.value.device.value.mac and oldparams.value.device.value.mac.value ~= "" then + notify_device(oldparams.value.device.value.mac.value, oldexten) +end -- cgit v1.2.3