dect
/
asterisk
Archived
13
0
Fork 0

Added a new module, res_phoneprov, which allows auto-provisioning of phones

based on configuration templates that use Asterisk dialplan function and
variable substitution.  It should be possible to create phone profiles and
templates that work for the majority of phones provisioned over http. It
is currently only intended to provision a single user account per phone.
An example profile and set of templates for Polycom phones is provided.
NOTE: Polycom firmware is not included, but should be placed in
AST_DATA_DIR/phoneprov/configs to match up with the included templates.



git-svn-id: http://svn.digium.com/svn/asterisk/trunk@97634 f38db490-d61c-443f-a65b-d21fe96a405b
This commit is contained in:
twilson 2008-01-09 21:37:26 +00:00
parent 34c07ddcaf
commit 11f6af8c7b
15 changed files with 1588 additions and 6 deletions

View File

@ -436,3 +436,11 @@ Miscellaneous
* Added a new codec translation module, codec_resample, which re-samples
signed linear audio between 8 kHz and 16 kHz to help support wideband
codecs.
* Added a new module, res_phoneprov, which allows auto-provisioning of phones
based on configuration templates that use Asterisk dialplan function and
variable substitution. It should be possible to create phone profiles and
templates that work for the majority of phones provisioned over http. It
is currently only intended to provision a single user account per phone.
An example profile and set of templates for Polycom phones is provided.
NOTE: Polycom firmware is not included, but should be placed in
AST_DATA_DIR/phoneprov/configs to match up with the included templates.

View File

@ -450,6 +450,10 @@ datafiles: _all
# Should static HTTP be installed during make samples or even with its own target ala
# webvoicemail? There are portions here that *could* be customized but might also be
# improved a lot. I'll put it here for now.
mkdir -p $(DESTDIR)$(ASTDATADIR)/phoneprov
for x in phoneprov/*; do \
$(INSTALL) -m 644 $$x $(DESTDIR)$(ASTDATADIR)/phoneprov ; \
done
mkdir -p $(DESTDIR)$(ASTDATADIR)/static-http
for x in static-http/*; do \
$(INSTALL) -m 644 $$x $(DESTDIR)$(ASTDATADIR)/static-http ; \

View File

@ -18,6 +18,9 @@ autoload=yes
;preload => res_odbc.so
;preload => res_config_odbc.so
;
; res_phoneprov requires func_strings.so to be loaded:
preload => func_strings.so
;
; Uncomment the following if you wish to use the Speech Recognition API
;preload => res_speech.so
;

View File

@ -0,0 +1,55 @@
[general]
;serveraddr=192.168.1.1 ; Address to send to the phone to use as server address.
serveriface=eth0 ; Same as above, except an ethernet interface.
; Useful for when the interface uses DHCP.
; There is no default for either of the above, and only one should be set.
serverport=5060 ; Port to send to the phone to use as server port. Default is 5060.
default_profile=polycom ; The default profile to use if none specified in users.conf
; You can define profiles for different phones specifying what files to register
; with the provisioning server. You can define either static files, or dynamically
; generated files that can have dynamic names and point to templates that variables
; can be substituted into. You can also set arbitrary variables for the profiles
; templates to have access to. Example:
;[example]
;mime_type => application/octet-stream
;static_file => example/firmware
;static_file => example/default.cfg,text/xml
;${TOUPPER(${MAC})}.cfg => templates/example-mac.cfg
;setvar => DB_CIDNAME=${ODBC_CID_NAME_LOOKUP(${USERNAME})}
; Dynamically generated files have a filename registered with variable substitution
; with variables obtained while reading users.conf.
; Built in variables and the options in users.conf that they come from
; MAC (macaddress)
; USERNAME (username)
; DISPLAY_NAME (fullname)
; SECRET (secret)
; LABEL (label)
; CALLERID (cid_number)
; VOCIEMAIL_EXTEN (vmexten)
; EXTENSION_LENGTH (localextenlength)
; Built-in variables and the options in phoneprov.conf that they come from
; SERVER (server)
; SERVER_PORT (serverport)
[polycom]
staticdir => configs/ ; Sub directory of AST_DATA_DIR/phoneprov that static files reside
; in. This allows a request to /phoneprov/sip.cfg to pull the file
; from /phoneprov/configs/sip.cfg
mime_type => text/xml ; Default mime type to use if one isn't specified or the
; extension isn't recognized
static_file => bootrom.ld,application/octet-stream ; Static files the phone will download
static_file => bootrom.ver,plain/text ; static_file => filename,mime-type
static_file => sip.ld,application/octet-stream
static_file => sip.ver,plain/text
static_file => sip.cfg
static_file => custom.cfg
${TOLOWER(${MAC})}.cfg => 000000000000.cfg ; Dynamically generated files.
${TOLOWER(${MAC})}-phone.cfg => 000000000000-phone.cfg ; (relative to AST_DATA_DIR/phoneprov)
config/${TOLOWER(${MAC})} => polycom.xml ; Dynamic Filename => template file
${TOLOWER(${MAC})}-directory.xml => 000000000000-directory.xml
setvar => CUSTOM_CONFIG=/var/lib/asterisk/phoneprov/configs/custom.cfg ; Custom variable

View File

@ -32,7 +32,7 @@
\author{Asterisk Development Team \\ Asterisk.org}
\title{Asterisk Reference Information \\ Version ASTERISKVERSION}
\title{Asterisk Reference Information \\ Version }
\begin{document}
\maketitle
@ -132,6 +132,9 @@ reference purposes.
\section{Queue Logs}
\input{queuelog.tex}
\chapter{Phone Provisioning}
\input{phoneprov.tex}
\chapter{Development}
\section{Backtrace}
\input{backtrace.tex}

301
doc/tex/phoneprov.tex Normal file
View File

@ -0,0 +1,301 @@
\section{Introduction}
Asterisk includes basic phone provisioning support through the res\_phoneprov module. The
current implementation is based on a templating system using Asterisk dialplan function
and variable substitution and obtains information to substitute into those templates from
\path{phoneprov.conf} and \path{users.conf}. A profile and set of templates is provided
for provisioning Polycom phones. Note that res\_phoneprov is currently limited to
provisioning a single user per device.
\section{Configuration of phoneprov.conf}
The configuration file, \path{phoneprov.conf}, is used to set up the built-in variables
SEVER and SERVER\_PORT, to define a default phone profile to use, and to define different
phone profiles available for provisioning.
\subsection{The [general] section}
Below is a sample of the general section of \path{phoneprov.conf}:
\begin{astlisting}
\begin{verbatim}
[general]
;serveriface=eth0
serveraddr=192.168.1.1
serverport=5060
default_profile=polycom
\end{verbatim}
\end{astlisting}
There are two choices for setting the SERVER variable. If the IP address of the server is
known, or the hostname resolvable by the phones, the appropriate \textbf{serveraddr}
value should be set. Alternatively, the network interface that the server listens on can
be set by specifying a \textbf{serveriface} and SERVER will be set to the IP address of
that interface. Only one of these options should be set.
The SERVER\_PORT variable is set by setting the \textbf{serverport}. If serverport is
not specified, it is set to a default value of 5060.
Any user set for auto-provisioning in users.conf without a specified profile will be
assumed to belong to the profile set with \textbf{default\_profile}.
\subsection{Creating phone profiles}
A phone profile is basically a list of files that a particular group of phones needs to
function. For most phone types there are files that are identical for all phones
(firmware, for instance) as well as a configuration file that is specific to individual
phones. res\_phoneprov breaks these two groups of files into static files and dynamic
files, respectively. A sample profile:
\begin{astlisting}
\begin{verbatim}
[polycom]
staticdir => configs/
mime_type => text/xml
setvar => CUSTOM_CONFIG=/var/lib/asterisk/phoneprov/configs/custom.cfg
static_file => bootrom.ld,application/octet-stream
static_file => bootrom.ver,plain/text
static_file => sip.ld,application/octet-stream
static_file => sip.ver,plain/text
static_file => sip.cfg
static_file => custom.cfg
${TOLOWER(${MAC})}.cfg => 000000000000.cfg
${TOLOWER(${MAC})}-phone.cfg => 000000000000-phone.cfg
config/${TOLOWER(${MAC})} => polycom.xml
${TOLOWER(${MAC})}-directory.xml => 000000000000-directory.xml
\end{verbatim}
\end{astlisting}
A \textbf{static\_file} is set by specifying the file name, relative to
\path{AST\_DATA\_DIR/phoneprov}. The mime-type of the file can optionally be specified
after a comma. If \textbf{staticdir} is set, all static files will be relative to the
subdirectory of AST\_DATA\_DIR/phoneprov specified.
Since phone-specific config files generally have file names based on phone-specifc data,
dynamic filenames in res\_phoneprov can be defined with Asterisk dialplan function and
variable substitution. In the above example, \$\{TOLOWER(\$\{MAC\})\}.cfg $\Rightarrow$
000000000000.cfg would define a relative URI to be served that matches the format of
MACADDRESS.cfg, all lower case. A request for that file would then point to the template
found at AST\_DATA\_DIR/phoneprov/000000000000.cfg. The template can be followed by a
comma and mime-type. Notice that the dynamic filename (URI) can contain contain
directories. Since these files are dynamically generated, the config file itself does not
reside on the filesystem--only the template. To view the generated config file, open it
in a web browser. If the config file is XML, Firefox should display it. Some browsers
will require viewing the source of the page requested.
A default mime-type for the profile can be defined by setting \textbf{mime-type}. If a
custom variable is required for a template, it can be specified with \textbf{setvar}.
Variable substitution on this value is done while building the route list, so
\$\{USERNAME\} would expand to the username of the users.conf user that registers the
dynamic filename.
NOTE: Any dialplan function that is used for generation of dynamic file names MUST be
loaded before res\_phoneprov. Add "preload $\Rightarrow$ modulename.so" to
\path{modules.conf} for required functions. In the example above, "preload $\Rightarrow$
func\_strings.so" would be required.
\section{Configuration of users.conf}
The asterisk-gui sets up extensions, SIP/IAX2 peers, and a host of other settings.
User-specific settings are stored in users.conf. If the asterisk-gui is not being used,
manual entries to users.conf can be made.
\subsection{The [general] section}
There are only two settings in the general section of \path{users.conf} that apply to
phone provisioning: localextenlength which maps to template variable EXTENSION\_LENGTH
and \textbf{vmexten} which maps to the VOICEMAIL\_EXTEN variable.
\subsection{Invdividual Users}
To enable auto-provisioning of a phone, the user in \path{users.conf} needs to have:
\begin{astlisting}
\begin{verbatim}
...
autoprov=yes
macaddress=deadbeef4dad
profile=polycom
\end{verbatim}
\end{astlisting}
The profile is optional if a \textbf{default\_profile} is set in \path{phoneprov.conf}.
The following is a sample users.conf entry, with the template variables commented next to
the settings:
\begin{astlisting}
\begin{verbatim}
[6001]
callwaiting = yes
context = numberplan-custom-1
hasagent = no
hasdirectory = yes
hasiax = no
hasmanager = no
hassip = yes
hasvoicemail = yes
host = dynamic
mailbox = 6001
threewaycalling = yes
deletevoicemail = no
autoprov = yes
profile = polycom
canreinvite = no
nat = no
fullname = User Two ; ${DISPLAY_NAME}
secret = test ; ${SECRET}
username = 6001 ; ${USERNAME}
macaddress = deadbeef4dad ; ${MAC}
label = 6001 ; ${LABEL}
cid_number = 6001 ; ${CALLERID}
\end{verbatim}
\end{astlisting}
The variables above, are the user-specfic variables that can be substituted into dynamic
filenames and config templates.
\section{Templates}
Configuration templates are a generic way to configure phones with text-based
configuration files. Templates can use any loaded dialplan function and all of the
variables created by \path{phoneprov.conf} and \path{users.conf}. A short example is the
included 000000000000.cfg Polycom template:
\begin{astlisting}
\begin{verbatim}
<?xml version="1.0" standalone="yes"?>
<APPLICATION
APP_FILE_PATH="sip.ld"
CONFIG_FILES="${IF($[${STAT(e|${CUSTOM_CONFIG})}] ? "custom.cfg,
")}config/${TOLOWER(${MAC})}, sip.cfg"
MISC_FILES="" LOG_FILE_DIRECTORY=""
/>
\end{verbatim}
\end{astlisting}
This template uses dialplan functions, expressions, and a couple of variables to generate
a config file to instruct the Polycom where to pull other needed config files. If a phone
with MAC address 0xDEADBEEF4DAD requests this config file, and the filename that is
stored in variable CUSTOM\_CONFIG does not exist, then the generated output would be:
\begin{astlisting}
\begin{verbatim}
<?xml version="1.0" standalone="yes"?>
<APPLICATION
APP_FILE_PATH="sip.ld"
CONFIG_FILES="config/deadbeef4dad, sip.cfg"
MISC_FILES="" LOG_FILE_DIRECTORY=""
/>
\end{verbatim}
\end{astlisting}
The Polycom phone would then download both sip.cfg (which would be registered in
\path{phoneprov.conf} as a static file) and config/deadbeef4dad (which would be
registered as a dynamic file pointing to another template, polycom.xml).
res\_phoneprov also registers its own dialplan function: PP\_EACH\_USER. This function
was designed to be able to print out a particular string for each user that
res\_phoneprov knows about. An example use of this function is the template for a Polycom
contact directory:
\begin{astlisting}
\begin{verbatim}
<?xml version="1.0" standalone="yes"?>
<directory>
<item_list>
${PP_EACH_USER(<item><fn>%{DISPLAY_NAME}</fn><ct>%{CALLERID}</ct><bw>1</bw></item>|${MAC})}
</item_list>
</directory>
\end{verbatim}
\end{astlisting}
PP\_EACH\_USER takes two arguments. The first is the string to be printed for each user.
Any variables that are to be substituted need to be in the format \%\{VARNAME\} so that
Asterisk doesn't try to substitute the variable immediately before it is passed to
PP\_EACH\_USER. The second, optional, argument is a MAC address to exclude from the list
iterated over (so, in this case, a phone won't be listed in its own contact directory).
\section{Putting it all together}
Make sure that \path{manager.conf} has:
\begin{astlisting}
\begin{verbatim}
[general]
enabled = yes
webenabled = yes
\end{verbatim}
\end{astlisting}
and that \path{http.conf} has:
\begin{astlisting}
\begin{verbatim}
[general]
enabled = yes
bindaddr = 192.168.1.1 ; Your IP here ;-)
bindport = 8088 ; Or port 80 if it is the only http server running on the machine
\end{verbatim}
\end{astlisting}
With \path{phoneprov.conf} and \path{users.conf} in place, start Astersik. From the CLI,
type "http show status". An example output:
\begin{astlisting}
\begin{verbatim}
HTTP Server Status:
Prefix: /asterisk
Server Enabled and Bound to 192.168.1.1:8088
Enabled URI's:
/asterisk/httpstatus => Asterisk HTTP General Status
/asterisk/phoneprov/... => Asterisk HTTP Phone Provisioning Tool
/asterisk/manager => HTML Manager Event Interface
/asterisk/rawman => Raw HTTP Manager Event Interface
/asterisk/static/... => Asterisk HTTP Static Delivery
/asterisk/mxml => XML Manager Event Interface
Enabled Redirects:
None.
POST mappings:
None.
\end{verbatim}
\end{astlisting}
There should be a phoneprov URI listed. Next, from the CLI, type "phoneprov show routes"
and verify that the information there is correct. An example output for Polycom phones
woud look like:
\begin{astlisting}
\begin{verbatim}
Static routes
Relative URI Physical location
sip.ver configs/sip.ver
sip.ld configs/sip.ld
bootrom.ver configs/bootrom.ver
sip.cfg configs/sip.cfg
bootrom.ld configs/bootrom.ld
custom.cfg configs/custom.cfg
Dynamic routes
Relative URI Template
deadbeef4dad.cfg 000000000000.cfg
deadbeef4dad-directory.xml 000000000000-directory.xml
deadbeef4dad-phone.cfg 000000000000-phone.cfg
config/deadbeef4dad polycom.xml
\end{verbatim}
\end{astlisting}
With the above examples, the phones would be pointed to
\url{http://192.168.1.1:8080/asterisk/phoneprov} for pulling config files. Templates
would all be placed in AST\_DATA\_DIR/phoneprov and static files would be placed in
AST\_DATA\_DIR/phoneprov/configs. Examples of valid URIs would be:
\begin{itemize}
\item http://192.168.1.1:8080/asterisk/phoneprov/sip.cfg
\item http://192.168.1.1:8080/asterisk/phoneprov/deadbeef4dad.cfg
\item http://192.168.1.1:8080/asterisk/phoneprov/config/deadbeef4dad
\end{itemize}

View File

@ -30,6 +30,7 @@
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include <regex.h>
#include <ctype.h>
#include "asterisk/module.h"
#include "asterisk/channel.h"
@ -800,6 +801,40 @@ static struct ast_custom_function keypadhash_function = {
.desc = "Example: ${KEYPADHASH(Les)} returns \"537\"\n",
};
static int string_toupper(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
{
char *bufptr = buf, *dataptr = data;
while ((bufptr < buf + len - 1) && (*bufptr++ = toupper(*dataptr++)));
return 0;
}
static struct ast_custom_function toupper_function = {
.name = "TOUPPER",
.synopsis = "Convert the string to upper case.",
.syntax = "TOUPPER(<string>)",
.read = string_toupper,
.desc = "Example: ${TOUPPER(Example)} returns \"EXAMPLE\"\n",
};
static int string_tolower(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
{
char *bufptr = buf, *dataptr = data;
while ((bufptr < buf + len - 1) && (*bufptr++ = tolower(*dataptr++)));
return 0;
}
static struct ast_custom_function tolower_function = {
.name = "TOLOWER",
.synopsis = "Convert the string to lower case.",
.syntax = "TOLOWER(<string>)",
.read = string_tolower,
.desc = "Example: ${TOLOWER(Example)} returns \"example\"\n",
};
static int unload_module(void)
{
int res = 0;
@ -818,6 +853,8 @@ static int unload_module(void)
res |= ast_custom_function_unregister(&hashkeys_function);
res |= ast_custom_function_unregister(&hash_function);
res |= ast_unregister_application(app_clearhash);
res |= ast_custom_function_unregister(&toupper_function);
res |= ast_custom_function_unregister(&tolower_function);
return res;
}
@ -840,6 +877,8 @@ static int load_module(void)
res |= ast_custom_function_register(&hashkeys_function);
res |= ast_custom_function_register(&hash_function);
res |= ast_register_application(app_clearhash, exec_clearhash, syn_clearhash, desc_clearhash);
res |= ast_custom_function_register(&toupper_function);
res |= ast_custom_function_register(&tolower_function);
return res;
}

View File

@ -41,6 +41,7 @@ struct ast_tm {
};
struct ast_tm *ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone);
void ast_get_dst_info(const time_t * const timep, int *dst_enabled, time_t *dst_start, time_t *dst_end, int *gmt_off, const char * const zone);
struct timeval ast_mktime(struct ast_tm * const tmp, const char *zone);
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm);

View File

@ -39,11 +39,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/lock.h"
#include "asterisk/srv.h"
struct my_ifreq {
char ifrn_name[IFNAMSIZ]; /* Interface name, e.g. "eth0", "ppp0", etc. */
struct sockaddr_in ifru_addr;
};
/* Free HA structure */
void ast_free_ha(struct ast_ha *ha)
{

View File

@ -1143,6 +1143,121 @@ struct ast_tm *ast_localtime(const struct timeval *timep, struct ast_tm *tmp, co
return sp ? localsub(timep, 0L, tmp, sp) : NULL;
}
/*
** This function provides informaton about daylight savings time
** for the given timezone. This includes whether it can determine
** if daylight savings is used for this timezone, the UTC times for
** when daylight savings transitions, and the offset in seconds from
** UTC.
*/
void ast_get_dst_info(const time_t * const timep, int *dst_enabled, time_t *dst_start, time_t *dst_end, int *gmt_off, const char * const zone)
{
int i;
int transition1 = -1;
int transition2 = -1;
time_t seconds;
int bounds_exceeded = 0;
time_t t = *timep;
const struct state *sp;
if (NULL == dst_enabled)
return;
*dst_enabled = 0;
if (NULL == dst_start || NULL == dst_end || NULL == gmt_off)
return;
*gmt_off = 0;
sp = ast_tzset(zone);
if (NULL == sp)
return;
/* If the desired time exceeds the bounds of the defined time transitions
* then give give up on determining DST info and simply look for gmt offset
* This requires that I adjust the given time using increments of Gregorian
* repeats to place the time within the defined time transitions in the
* timezone structure.
*/
if ((sp->goback && t < sp->ats[0]) ||
(sp->goahead && t > sp->ats[sp->timecnt - 1])) {
time_t tcycles;
int_fast64_t icycles;
if (t < sp->ats[0])
seconds = sp->ats[0] - t;
else seconds = t - sp->ats[sp->timecnt - 1];
--seconds;
tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR;
++tcycles;
icycles = tcycles;
if (tcycles - icycles >= 1 || icycles - tcycles >= 1)
return;
seconds = icycles;
seconds *= YEARSPERREPEAT;
seconds *= AVGSECSPERYEAR;
if (t < sp->ats[0])
t += seconds;
else
t -= seconds;
if (t < sp->ats[0] || t > sp->ats[sp->timecnt - 1])
return; /* "cannot happen" */
bounds_exceeded = 1;
}
if (sp->timecnt == 0 || t < sp->ats[0]) {
/* I have no transition times or I'm before time */
*dst_enabled = 0;
/* Find where I can get gmtoff */
i = 0;
while (sp->ttis[i].tt_isdst)
if (++i >= sp->typecnt) {
i = 0;
break;
}
*gmt_off = sp->ttis[i].tt_gmtoff;
return;
}
for (i = 1; i < sp->timecnt; ++i) {
if (t < sp->ats[i]) {
transition1 = sp->types[i - 1];
transition2 = sp->types[i];
break;
}
}
/* if I found transition times that do not bounded the given time and these correspond to
or the bounding zones do not reflect a changes in day light savings, then I do not have dst active */
if (i >= sp->timecnt || 0 > transition1 || 0 > transition2 ||
(sp->ttis[transition1].tt_isdst == sp->ttis[transition2].tt_isdst)) {
*dst_enabled = 0;
*gmt_off = sp->ttis[sp->types[sp->timecnt -1]].tt_gmtoff;
} else {
/* I have valid daylight savings information. */
if(sp->ttis[transition2].tt_isdst)
*gmt_off = sp->ttis[transition1].tt_gmtoff;
else
*gmt_off = sp->ttis[transition2].tt_gmtoff;
/* If I adjusted the time earlier, indicate that the dst is invalid */
if (!bounds_exceeded) {
*dst_enabled = 1;
/* Determine which of the bounds is the start of daylight savings and which is the end */
if(sp->ttis[transition2].tt_isdst) {
*dst_start = sp->ats[i];
*dst_end = sp->ats[i -1];
} else {
*dst_start = sp->ats[i -1];
*dst_end = sp->ats[i];
}
}
}
return;
}
/*
** gmtsub is to gmtime as localsub is to localtime.
*/

View File

@ -0,0 +1,6 @@
<?xml version="1.0" standalone="yes"?>
<directory>
<item_list>
${PP_EACH_USER(<item><fn>%{DISPLAY_NAME}</fn><ct>%{CALLERID}</ct><bw>1</bw></item>|${MAC})}
</item_list>
</directory>

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="yes"?>

View File

@ -0,0 +1,2 @@
<?xml version="1.0" standalone="yes"?>
<APPLICATION APP_FILE_PATH="sip.ld" CONFIG_FILES="${IF($[${STAT(e|${CUSTOM_CONFIG})}] ? "custom.cfg, ")}config/${TOLOWER(${MAC})}, sip.cfg" MISC_FILES="" LOG_FILE_DIRECTORY=""/>

37
phoneprov/polycom.xml Normal file
View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<phone1>
<reg reg.1.displayName="${DISPLAY_NAME}" reg.1.address="${USERNAME}" reg.1.label="${LABEL}" reg.1.type="private" reg.1.thirdPartyName="" reg.1.auth.userId="${USERNAME}" reg.1.auth.password="${SECRET}" reg.1.server.1.address="${SERVER}" reg.1.server.1.port="${SERVER_PORT}" reg.1.server.1.transport="DNSnaptr" reg.1.server.1.expires="300" reg.1.server.1.register="1" reg.1.server.1.retryTimeOut="" reg.1.server.1.retryMaxCount="" reg.1.server.1.expires.lineSeize="" reg.1.acd-login-logout="0" reg.1.acd-agent-available="0" reg.1.ringType="2" reg.1.lineKeys="2" reg.1.callsPerLineKey="1"/>
<call>
<donotdisturb call.donotdisturb.perReg="1" />
<autoOffHook call.autoOffHook.1.enabled="0" call.autoOffHook.1.contact="" call.autoOffHook.2.enabled="0" call.autoOffHook.2.contact="" call.autoOffHook.3.enabled="0" call.autoOffHook.3.contact="" call.autoOffHook.4.enabled="0" call.autoOffHook.4.contact="" call.autoOffHook.5.enabled="0" call.autoOffHook.5.contact="" call.autoOffHook.6.enabled="0" call.autoOffHook.6.contact=""/>
<serverMissedCall call.serverMissedCall.1.enabled="0" call.serverMissedCall.2.enabled="0" call.serverMissedCall.3.enabled="0" call.serverMissedCall.4.enabled="0" call.serverMissedCall.5.enabled="0" call.serverMissedCall.6.enabled="0"/>
</call>
<divert divert.1.contact="" divert.1.autoOnSpecificCaller="1" divert.1.sharedDisabled="1" divert.2.contact="" divert.2.autoOnSpecificCaller="1" divert.2.sharedDisabled="1" divert.3.contact="" divert.3.autoOnSpecificCaller="1" divert.3.sharedDisabled="1" divert.4.contact="" divert.4.autoOnSpecificCaller="1" divert.4.sharedDisabled="1" divert.5.contact="" divert.5.autoOnSpecificCaller="1" divert.5.sharedDisabled="1" divert.6.contact="" divert.6.autoOnSpecificCaller="1" divert.6.sharedDisabled="1">
<fwd divert.fwd.1.enabled="1" divert.fwd.2.enabled="1" divert.fwd.3.enabled="1" divert.fwd.4.enabled="1" divert.fwd.5.enabled="1" divert.fwd.6.enabled="1"/>
<busy divert.busy.1.enabled="1" divert.busy.1.contact="" divert.busy.2.enabled="1" divert.busy.2.contact="" divert.busy.3.enabled="1" divert.busy.3.contact="" divert.busy.4.enabled="1" divert.busy.4.contact="" divert.busy.5.enabled="1" divert.busy.5.contact="" divert.busy.6.enabled="1" divert.busy.6.contact=""/>
<noanswer divert.noanswer.1.enabled="1" divert.noanswer.1.timeout="60" divert.noanswer.1.contact="" divert.noanswer.2.enabled="1" divert.noanswer.2.timeout="60" divert.noanswer.2.contact="" divert.noanswer.3.enabled="1" divert.noanswer.3.timeout="60" divert.noanswer.3.contact="" divert.noanswer.4.enabled="1" divert.noanswer.4.timeout="60" divert.noanswer.4.contact="" divert.noanswer.5.enabled="1" divert.noanswer.5.timeout="60" divert.noanswer.5.contact="" divert.noanswer.6.enabled="1" divert.noanswer.6.timeout="60" divert.noanswer.6.contact=""/>
<dnd divert.dnd.1.enabled="0" divert.dnd.1.contact="" divert.dnd.2.enabled="0" divert.dnd.2.contact="" divert.dnd.3.enabled="0" divert.dnd.3.contact="" divert.dnd.4.enabled="0" divert.dnd.4.contact="" divert.dnd.5.enabled="0" divert.dnd.5.contact="" divert.dnd.6.enabled="0" divert.dnd.6.contact=""/>
</divert>
<dialplan
dialplan.1.impossibleMatchHandling="2" dialplan.1.removeEndOfDial="0"
/>
<digitmap
dialplan.1.digitmap="" dialplan.1.digitmap.timeOut="3"
/>
<routing>
<server dialplan.1.routing.server.1.address="" dialplan.1.routing.server.1.port="" dialplan.2.routing.server.1.address="" dialplan.2.routing.server.1.port="" dialplan.3.routing.server.1.address="" dialplan.3.routing.server.1.port="" dialplan.4.routing.server.1.address="" dialplan.4.routing.server.1.port="" dialplan.5.routing.server.1.address="" dialplan.5.routing.server.1.port="" dialplan.6.routing.server.1.address="" dialplan.6.routing.server.1.port=""/>
<emergency dialplan.1.routing.emergency.1.value="" dialplan.1.routing.emergency.1.server.1="" dialplan.2.routing.emergency.1.value="" dialplan.2.routing.emergency.1.server.1="" dialplan.3.routing.emergency.1.value="" dialplan.3.routing.emergency.1.server.1="" dialplan.4.routing.emergency.1.value="" dialplan.4.routing.emergency.1.server.1="" dialplan.5.routing.emergency.1.value="" dialplan.5.routing.emergency.1.server.1="" dialplan.6.routing.emergency.1.value="" dialplan.6.routing.emergency.1.server.1=""/>
</routing>
<msg msg.bypassInstantMessage="1">
<mwi msg.mwi.1.callBackMode="contact" msg.mwi.1.callBack="${VOICEMAIL_EXTEN}" />
</msg>
<nat nat.ip="" nat.signalPort="" nat.mediaPortStart=""/>
<user_preferences up.oneTouchVoiceMail="1" up.welcomeSoundEnabled="0" />
<volume voice.volume.persist.handset="1" voice.volume.persist.headset="1" />
<SNTP tcpIpApp.sntp.address="time" tcpIpApp.sntp.gmtOffset="-21600" />
<HTTPD httpd.enabled="1" />
<feature
feature.1.name="presence" feature.1.enabled="1"
feature.8.name="calllist-missed" feature.8.enabled="1"
/>
</phone1>

1012
res/res_phoneprov.c Normal file

File diff suppressed because it is too large Load Diff