Codename Pineapple

Home page | Mailing list | Docs

Last updated: Sat Feb 3 05:01:51 2007

Asterisk developer's documentation :: Codename Pineapple


sip3_config.c File Reference


Detailed Description

Various SIP configuration functions Version 3 of chan_sip.

Author:
Mark Spencer <markster@digium.com>

Olle E. Johansson <oej@edvina.net> (all the chan_sip3 changes)

See Also:

Definition in file sip3_config.c.

#include "asterisk.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <netdb.h>
#include <signal.h>
#include <sys/signal.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <regex.h>
#include "asterisk/channel.h"
#include "asterisk/cli.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/lock.h"
#include "asterisk/acl.h"
#include "asterisk/callerid.h"
#include "asterisk/musiconhold.h"
#include "asterisk/manager.h"
#include "asterisk/dsp.h"
#include "asterisk/rtp.h"
#include "asterisk/srv.h"
#include "asterisk/causes.h"
#include "asterisk/utils.h"
#include "asterisk/file.h"
#include "asterisk/astobj.h"
#include "asterisk/dnsmgr.h"
#include "asterisk/linkedlists.h"
#include "asterisk/stringfields.h"
#include "asterisk/monitor.h"
#include "asterisk/localtime.h"
#include "asterisk/compiler.h"
#include "asterisk/version.h"
#include "sip3.h"
#include "sip3funcs.h"

Include dependency graph for sip3_config.c:

Go to the source code of this file.

Functions

static struct ast_variableadd_var (const char *buf, struct ast_variable *list)
 * implement the servar config line
static struct sip_devicebuild_device (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
 Build peer from configuration (file or realtime static/dynamic).
static void cleanup_stale_contexts (char *new, char *old)
 Destroy disused contexts between reloads Only used in reload_config so the code for regcontext doesn't get ugly.
sip_devicedevice_ref (struct sip_device *device)
 Add reference for device.
void device_unref (struct sip_device *device)
 Remove reference for device. When we reach 0, device is removed from memory.
static int handle_common_options (enum sip_config_options option, struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v)
 Handle flag-type options common to configuration of devices - users and peers.
sip_devicerealtime_peer (const char *newpeername, struct sockaddr_in *sin)
 realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf
int reload_config (enum channelreloadreason reason)
 Re-read SIP.conf config file.
static void reset_global_settings (struct sip_globals *global)
 Reset settings of global settings structure Codecs that we support by default:.
static int set_device_acl (struct sip_device *device, struct ast_variable *v)
 Add ACL entry (permit/deny) to device.
static void set_device_cid (struct sip_device *device, enum sip_config_options option, struct ast_variable *v)
 Set Caller ID for phone or service.
void set_device_defaults (struct sip_device *device)
 Set peer defaults before configuring specific configurations.
static void set_device_host (struct sip_device *device, struct ast_variable *v, int found, enum sip_config_objects object)
 Configure Host= setting for device.
static enum sip_config_options sip_config_parse (char *label, enum sip_config_objects object)
 Parse configuration file label, check if it's valid in this object context and return label.
static void sip_listconfighelper (int fd, enum sip_config_objects object)
 List configuration options for specific object.
int sip_listconfigs (int fd)
 List all configuration options in sip.conf.

Variables

static const char config [] = "sip3.conf"
static struct ast_jb_conf default_jbconf
 Global jitterbuffer configuration - by default, jb is disabled.
const char notify_config [] = "sip3_notify.conf"
static struct sip_config_struct sip_config []
 The configuration matrix.


Function Documentation

static struct ast_variable* add_var const char *  buf,
struct ast_variable list
[static]
 

* implement the servar config line

Definition at line 467 of file sip3_config.c.

References ast_strdupa, ast_variable_new(), and ast_variable::next.

00468 {
00469    struct ast_variable *tmpvar = NULL;
00470    char *varname = ast_strdupa(buf), *varval = NULL;
00471    
00472    if ((varval = strchr(varname,'='))) {
00473       *varval++ = '\0';
00474       if ((tmpvar = ast_variable_new(varname, varval))) {
00475          tmpvar->next = list;
00476          list = tmpvar;
00477       }
00478    }
00479    return list;
00480 }

static struct sip_device* build_device const char *  name,
struct ast_variable v,
struct ast_variable alt,
int  realtime
[static]
 

Build peer from configuration (file or realtime static/dynamic).

Definition at line 763 of file sip3_config.c.

References sip_device_extra::accountcode, add_realm_authentication(), add_var(), sip_device::addr, sip_globals::allowsubscribe, sip_device::allowtransfer, sip_device_extra::amaflags, ast_calloc, ast_cdr_amaflags2int(), ast_copy_flags, ast_false(), ast_free_ha(), ast_get_group(), ast_get_ip(), ast_get_time_t(), ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), ast_set2_flag, ast_set_flag, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variables_destroy(), ASTOBJ_CONTAINER_FIND_UNLINK_FULL, ASTOBJ_FLAG_MARKED, ASTOBJ_INIT, ASTOBJ_UNMARK, ASTOBJ_UNREF, sip_device::auth, sip_device::autoframing, sip_device::call_limit, sip_device::callgroup, sip_device::callingpres, sip_device::capability, sip_device::chanvars, context, sip_device::defaddr, sip_globals::default_maxcallbitrate, DEFAULT_QUALIFY_MAXMS, destroy_association(), devicelist, sip_device::domain, error(), sip_device::extra, FALSE, sip_globals::flags, ast_flags::flags, sip_device::flags, format, free, global, sip_device::ha, handle_common_options(), sip_device::language, sip_mwi_mailbox::lastmsgssent, ast_variable::lineno, LOG_DEBUG, LOG_ERROR, LOG_WARNING, mailbox, sip_device::mailbox, sip_device::maxcallbitrate, sip_device::maxms, sip_device_extra::mohinterpret, sip_device_extra::mohsuggest, ast_variable::name, ast_variable::next, option_debug, channel_counters::peers_with_mwi, sip_device::pickupgroup, sip_device::prefs, channel_counters::realtime_peers, reg_source_db(), rtptimers::rtpholdtimeout, rtptimers::rtpkeepalive, rtptimers::rtptimeout, sip_globals::rtptimer, sip_device::rtptimer, secret, set_device_acl(), set_device_cid(), set_device_defaults(), set_device_host(), SIP_CONF_ALLOW, SIP_CONF_ALLOWOVERLAP, SIP_CONF_ALLOWSUBSCRIBE, SIP_CONF_ALLOWTRANSFER, SIP_CONF_AUTH, SIP_CONF_AUTHUSER, SIP_CONF_AUTOFRAMING, SIP_CONF_CALL_LIMIT, SIP_CONF_CALLERID, SIP_CONF_CALLERPRES, SIP_CONF_CALLGROUP, SIP_CONF_CANREINVITE, SIP_CONF_CDR_ACCOUNTCODE, SIP_CONF_CDR_AMAFLAGS, SIP_CONF_CHANVAR, SIP_CONF_CID_NAME, SIP_CONF_CID_NUMBER, SIP_CONF_COMPACTHEADERS, SIP_CONF_DEFAULTIP, SIP_CONF_DEFAULTPORT, SIP_CONF_DEFAULTUSER, SIP_CONF_DEFCONTEXT, SIP_CONF_DENY, SIP_CONF_DISALLOW, SIP_CONF_DOMAIN, SIP_CONF_DTMFMODE, SIP_CONF_EXPIRYMAX, SIP_CONF_G726NONSTANDARD, SIP_CONF_GROUPDESC, SIP_CONF_GROUPVAR, SIP_CONF_HOST, SIP_CONF_IGNOREREGEXPIRE, SIP_CONF_INSECURE, SIP_CONF_LANGUAGE, SIP_CONF_LOCALNET, SIP_CONF_MAXCALLBITRATE, SIP_CONF_MD5SECRET, SIP_CONF_MOHINTERPRET, SIP_CONF_MOHSUGGEST, SIP_CONF_MWISUBSCRIBE, SIP_CONF_NAT, SIP_CONF_NONE, SIP_CONF_NOT_FOUND, SIP_CONF_NOT_VALID_FOR_OBJECT, SIP_CONF_OBPROXYPORT, SIP_CONF_OUTBOUNDPROXY, SIP_CONF_PERMIT, SIP_CONF_PICKUPGROUP, SIP_CONF_PORT, SIP_CONF_PROGRESSINBAND, SIP_CONF_PROMISCREDIR, SIP_CONF_PROXY, SIP_CONF_PROXYPORT, SIP_CONF_QUALIFY, SIP_CONF_REGEXTEN, SIP_CONF_REGISTER, SIP_CONF_REGISTERTIMEOUT, SIP_CONF_RFC2833COMPENSATE, SIP_CONF_RTAUTOCLEAR, SIP_CONF_RTFULLCONTACT, SIP_CONF_RTIPADDR, SIP_CONF_RTNAME, SIP_CONF_RTPHOLDTIMEOUT, SIP_CONF_RTPKEEPALIVE, SIP_CONF_RTPTIMEOUT, SIP_CONF_RTREGSECONDS, SIP_CONF_SECRET, SIP_CONF_SENDRPID, SIP_CONF_SETVAR, SIP_CONF_SUBSCRIBECONTEXT, SIP_CONF_T1DEFAULT, SIP_CONF_T1MIN, SIP_CONF_T38PT_UDPTL, SIP_CONF_TRUSTRPID, SIP_CONF_TYPE, SIP_CONF_USECLIENTCODE, SIP_CONF_USEREQPHONE, SIP_CONF_VIDEOSUPPORT, SIP_CONF_VMAILBOX, SIP_CONF_VMEXTEN, sip_config_parse(), SIP_CONFOBJ_PHONE, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DYNAMIC, SIP_PAGE2_IGNOREREGEXPIRE, SIP_PAGE2_RT_FROMCONTACT, SIP_PAGE2_SERVICE, SIP_PAGE2_SUBSCRIBEMWIONLY, SIP_PEER, SIP_REALTIME, sip_register(), sip_registry_destroy(), SIP_USEREQPHONE, sipcounters, channel_counters::static_peers, TRANSFER_CLOSED, TRANSFER_OPENFORALL, TRUE, sip_device::type, and ast_variable::value.

00764 {
00765    struct sip_device *device = NULL;
00766    struct ast_ha *oldha = NULL;
00767    int found = 0;
00768    int firstpass = 1;
00769    int format = 0;      /* Ama flags */
00770    time_t regseconds = 0;
00771    struct ast_flags peerflags[2] = {{(0)}};
00772    struct ast_flags mask[2] = {{(0)}};
00773    int register_lineno = 0;
00774    int error = 0;
00775 
00776    if (!realtime)
00777       /* Note we do NOT use find_peer here, to avoid realtime recursion */
00778       /* We also use a case-sensitive comparison (unlike find_peer) so
00779          that case changes made to the peer name will be properly handled
00780          during reload
00781       */
00782       device = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&devicelist, name, name, 0, 0, strcmp);
00783 
00784    if (device) {
00785       /* Already in the list, remove it and it will be added back (or FREE'd)  */
00786       found++;
00787       if (!(device->objflags & ASTOBJ_FLAG_MARKED))
00788          firstpass = 0;
00789    } else {
00790       if (!(device = ast_calloc(1, sizeof(*device))))
00791          return NULL;
00792 
00793       if (ast_string_field_init(device, 512)) { /* Initialize string field buffer */
00794          free(device);
00795          return NULL;
00796       }
00797       if (ast_string_field_init(&device->mailbox, 512)) {   /* Initialize string field buffer */
00798          free(device);
00799          return NULL;
00800       }
00801       if (ast_string_field_init(&device->extra, 512)) {  /* Initialize string field buffer */
00802          free(device);
00803          return NULL;
00804       }
00805 
00806       if (realtime)
00807          sipcounters.realtime_peers++;
00808       else
00809          sipcounters.static_peers++;
00810       ASTOBJ_INIT(device);
00811    }
00812    device->type &= SIP_PEER;
00813 
00814    /* Note that our peer HAS had its reference count incrased */
00815 
00816    if (firstpass) {
00817       device->mailbox.lastmsgssent = -1;
00818       oldha = device->ha;
00819       device->ha = NULL;
00820       set_device_defaults(device);  /* Set peer defaults */
00821    }
00822    if (!found && name)
00823       ast_copy_string(device->name, name, sizeof(device->name));
00824 
00825    /* If we have channel variables, remove them (reload) */
00826    if (device->chanvars) {
00827       ast_variables_destroy(device->chanvars);
00828       device->chanvars = NULL;
00829       /* XXX should unregister ? */
00830    }
00831    for (; v || ((v = alt) && !(alt=NULL)); v = v->next) {
00832       enum sip_config_options option = sip_config_parse(v->name, SIP_CONFOBJ_PHONE);
00833       switch (option) {
00834       case SIP_CONF_TYPE:
00835          /* Ignore this, it's already parsed */
00836          break;
00837       case SIP_CONF_TRUSTRPID:
00838       case SIP_CONF_SENDRPID:
00839       case SIP_CONF_G726NONSTANDARD:
00840       case SIP_CONF_USECLIENTCODE:
00841       case SIP_CONF_DTMFMODE:
00842       case SIP_CONF_NAT:
00843       case SIP_CONF_CANREINVITE:
00844       case SIP_CONF_INSECURE:
00845       case SIP_CONF_PROGRESSINBAND:
00846       case SIP_CONF_PROMISCREDIR:
00847       case SIP_CONF_VIDEOSUPPORT:
00848       case SIP_CONF_ALLOWOVERLAP:
00849       case SIP_CONF_ALLOWSUBSCRIBE:
00850       case SIP_CONF_T38PT_UDPTL:
00851       case SIP_CONF_RFC2833COMPENSATE:
00852       case SIP_CONF_COMPACTHEADERS:
00853          error += handle_common_options(option, &peerflags[0], &mask[0], v);
00854          break;
00855       case SIP_CONF_ALLOW:
00856          error += ast_parse_allow_disallow(&device->prefs, &device->capability, v->value, 1);
00857          break;
00858       case SIP_CONF_ALLOWTRANSFER:
00859          device->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
00860          break;
00861       case SIP_CONF_AUTH:
00862          device->auth = add_realm_authentication(device->auth, v->value, v->lineno);
00863          break;
00864       case SIP_CONF_AUTHUSER:
00865          ast_string_field_set(device, authuser, v->value);
00866          break;
00867       case SIP_CONF_AUTOFRAMING:
00868          device->autoframing = ast_true(v->value);
00869          break;
00870       case SIP_CONF_CALLERID:
00871       case SIP_CONF_CID_NAME:
00872       case SIP_CONF_CID_NUMBER:
00873          set_device_cid(device, option, v);
00874          break;
00875       case SIP_CONF_CALLERPRES:
00876          device->callingpres = ast_parse_caller_presentation(v->value);
00877          if (device->callingpres == -1)
00878             device->callingpres = atoi(v->value);
00879          break;
00880       case SIP_CONF_CALLGROUP:
00881          device->callgroup = ast_get_group(v->value);
00882          break;
00883       case SIP_CONF_CALL_LIMIT:
00884          device->call_limit = atoi(v->value);
00885          if (device->call_limit < 0)
00886             device->call_limit = 0;
00887          break;
00888       case SIP_CONF_CDR_ACCOUNTCODE:
00889          ast_copy_string(device->extra.accountcode, v->value, sizeof(device->extra.accountcode));
00890          break;
00891       case SIP_CONF_CDR_AMAFLAGS:
00892          format = ast_cdr_amaflags2int(v->value);
00893          if (format < 0) {
00894             ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno);
00895             error++;
00896          } else 
00897             device->extra.amaflags = format;
00898          break;
00899       case SIP_CONF_CHANVAR:
00900          break;
00901       case SIP_CONF_DEFAULTIP:
00902          if (ast_get_ip(&device->defaddr, v->value))  {
00903             ast_log(LOG_WARNING, "Default IP ignored, bad/unparseable value: %s\n", v->value);
00904             error++;
00905          }
00906          break;
00907       case SIP_CONF_DEFAULTUSER:
00908          ast_string_field_set(device, defaultuser, v->value);
00909          break;
00910       case SIP_CONF_DEFAULTPORT:
00911          device->defaddr.sin_port = htons(atoi(v->value));
00912          break;
00913       case SIP_CONF_DEFCONTEXT:
00914          ast_string_field_set(&device->extra, context, v->value);
00915          break;
00916       case SIP_CONF_DENY:
00917          if(set_device_acl(device, v) != 0) {
00918             ast_log(LOG_WARNING, "Bad DENY setting in sip.conf line %d : %s\n", v->lineno, v->value);
00919             error++;
00920          }
00921          break;
00922       case SIP_CONF_DISALLOW:
00923          error += ast_parse_allow_disallow(&device->prefs, &device->capability, v->value, FALSE);
00924          break;
00925       case SIP_CONF_DOMAIN:
00926          ast_copy_string(device->domain, v->value, sizeof(device->domain));
00927          break;
00928       case SIP_CONF_GROUPDESC:
00929          break;
00930       case SIP_CONF_GROUPVAR:
00931          break;
00932       case SIP_CONF_HOST:
00933          set_device_host(device, v, found, SIP_CONFOBJ_PHONE);
00934          break;
00935       case SIP_CONF_LANGUAGE:
00936          ast_copy_string(device->language, v->value, sizeof(device->language));
00937          break;
00938       case SIP_CONF_LOCALNET:
00939          break;
00940       case SIP_CONF_MAXCALLBITRATE:
00941          device->maxcallbitrate = atoi(v->value);
00942          if (device->maxcallbitrate < 0) {
00943             device->maxcallbitrate = global.default_maxcallbitrate;
00944             ast_log(LOG_WARNING, "Max call bitrate setting of device '%s' out of bonds (line %d)\n", device->name, v->lineno);
00945             error++;
00946          }
00947          break;
00948       case SIP_CONF_EXPIRYMAX:
00949          break;
00950       case SIP_CONF_MD5SECRET:
00951          ast_string_field_set(device, md5secret, v->value);
00952          break;
00953       case SIP_CONF_MOHINTERPRET:
00954          ast_copy_string(device->extra.mohinterpret, v->value, sizeof(device->extra.mohinterpret));
00955          break;
00956       case SIP_CONF_MOHSUGGEST:
00957          ast_copy_string(device->extra.mohsuggest, v->value, sizeof(device->extra.mohsuggest));
00958          break;
00959       case SIP_CONF_OUTBOUNDPROXY:
00960          break;
00961       case SIP_CONF_OBPROXYPORT:
00962          break;
00963       case SIP_CONF_PERMIT:
00964          if(set_device_acl(device, v) != 0) {
00965             ast_log(LOG_WARNING, "Bad PERMIT setting in sip.conf line %d : %s\n", v->lineno, v->value);
00966             error++;
00967          }
00968          break;
00969       case SIP_CONF_PICKUPGROUP:
00970          device->pickupgroup = ast_get_group(v->value);
00971          break;
00972       case SIP_CONF_PORT:
00973          device->addr.sin_port = htons(atoi(v->value));
00974          break;
00975       case SIP_CONF_PROXY:
00976          break;
00977       case SIP_CONF_PROXYPORT:
00978          break;
00979       case SIP_CONF_QUALIFY:
00980          if (!strcasecmp(v->value, "no")) {
00981             device->maxms = 0;
00982          } else if (!strcasecmp(v->value, "yes")) {
00983             device->maxms = DEFAULT_QUALIFY_MAXMS;
00984          } else if (sscanf(v->value, "%d", &device->maxms) != 1) {
00985             ast_log(LOG_WARNING, "Qualification of device '%s' should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", device->name, v->lineno);
00986             error++;
00987             device->maxms = 0;
00988          }
00989          break;
00990       case SIP_CONF_REGEXTEN:
00991          ast_string_field_set(device, extra.regexten, v->value);
00992          break;
00993       case SIP_CONF_REGISTER:
00994          if (ast_true(v->value)) {
00995             if (realtime) {
00996                ast_log(LOG_ERROR, "register=yes is not supported for realtime.\n");
00997             } else {
00998                ast_set_flag(&device->flags[1], SIP_PAGE2_SERVICE);
00999                register_lineno = v->lineno;
01000             }
01001          } else if (!ast_false(v->value)) {
01002             ast_log(LOG_ERROR, "Bad value for register= in line %d, device %s\n", v->lineno, device->name);
01003             error++;
01004          }
01005          break;
01006       case SIP_CONF_REGISTERTIMEOUT:
01007          break;
01008       case SIP_CONF_RTAUTOCLEAR:
01009          break;
01010       case SIP_CONF_IGNOREREGEXPIRE:
01011          break;
01012       case SIP_CONF_RTIPADDR:    /* Realtime only */
01013          if(realtime && !ast_strlen_zero(v->value)) 
01014             inet_aton(v->value, &(device->addr.sin_addr));
01015          break;
01016       case SIP_CONF_RTNAME:      /* Realtime only */
01017          if(realtime && !ast_strlen_zero(v->value)) 
01018             ast_copy_string(device->name, v->value, sizeof(device->name));
01019          break;
01020       case SIP_CONF_RTREGSECONDS:   /* REALTIME */
01021          ast_get_time_t(v->value, &regseconds, 0, NULL);
01022          break;
01023       case SIP_CONF_RTPHOLDTIMEOUT:
01024          if ((sscanf(v->value, "%d", &device->rtptimer.rtpholdtimeout) != 1) || (device->rtptimer.rtpholdtimeout < 0)) {
01025             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
01026             device->rtptimer.rtpholdtimeout = global.rtptimer.rtpholdtimeout;
01027             error++;
01028          }
01029          break;
01030       case SIP_CONF_RTPKEEPALIVE:
01031          if ((sscanf(v->value, "%d", &device->rtptimer.rtpkeepalive) != 1) || (device->rtptimer.rtpkeepalive < 0)) {
01032             ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d.  Using default.\n", v->value, v->lineno);
01033             device->rtptimer.rtpkeepalive = global.rtptimer.rtpkeepalive;
01034             error++;
01035          } 
01036          break;
01037       case SIP_CONF_RTFULLCONTACT:  /* Realtime only */
01038          if (realtime) {
01039             ast_string_field_set(device, fullcontact, v->value);
01040             ast_set_flag(&device->flags[1], SIP_PAGE2_RT_FROMCONTACT);
01041          } else {
01042             ast_log(LOG_WARNING, "'%s' is not a valid configuration option (line %d, device %s).\n", v->value, v->lineno, device->name);
01043             error++;
01044          }
01045          break;
01046       case SIP_CONF_RTPTIMEOUT:
01047          if ((sscanf(v->value, "%d", &device->rtptimer.rtptimeout) != 1) || (device->rtptimer.rtptimeout < 0)) {
01048             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
01049             error++;
01050             device->rtptimer.rtptimeout = global.rtptimer.rtptimeout;
01051          }
01052          break;
01053       case SIP_CONF_SECRET:
01054          ast_string_field_set(device, secret, v->value);
01055          break;
01056       case SIP_CONF_SETVAR:
01057          device->chanvars = add_var(v->value, device->chanvars);
01058          break;
01059       case SIP_CONF_SUBSCRIBECONTEXT:
01060          ast_string_field_set(&device->extra, subscribecontext, v->value);
01061          break;
01062       case SIP_CONF_MWISUBSCRIBE:
01063          ast_set2_flag(&device->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY);
01064          break;
01065       case SIP_CONF_T1MIN:
01066          break;
01067       case SIP_CONF_T1DEFAULT:
01068          break;
01069       case SIP_CONF_USEREQPHONE:
01070          ast_set2_flag(&device->flags[0], ast_true(v->value), SIP_USEREQPHONE);
01071          break;
01072       case SIP_CONF_VMAILBOX:
01073          ast_string_field_set(device, mailbox.mailbox, v->value);
01074          sipcounters.peers_with_mwi++;
01075          break;
01076       case SIP_CONF_VMEXTEN:
01077          ast_string_field_set(device, mailbox.vmexten, v->value);
01078          break;
01079       case SIP_CONF_NONE:
01080       case SIP_CONF_NOT_VALID_FOR_OBJECT:
01081       case SIP_CONF_NOT_FOUND:
01082          ast_log(LOG_ERROR, "Bad configuration entry in line %d: %s = %s\n", v->lineno, v->name, v->value);
01083          error++;
01084          break;
01085       default: 
01086          ast_log(LOG_ERROR, "This error message should not happen. Bad config error: %d\n", option);
01087          break;
01088       }
01089 
01090 /*---------------------
01091    SERVICE CONFIGS
01092       } else if (!strcasecmp(v->name, "fromdomain")) {
01093          ast_string_field_set(device, extra.fromdomain, v->value);
01094          //ast_copy_string(device->fromdomain, v->value, sizeof(device->fromdomain));
01095       } else if (!strcasecmp(v->name, "fromuser")) {
01096          ast_string_field_set(device, extra.fromuser, v->value);
01097          //ast_copy_string(device->fromuser, v->value, sizeof(device->fromuser));
01098 ----------*/
01099    }
01100    if (error) 
01101       ast_log(LOG_WARNING, "Errors found in phone config: %s = %d\n", device->name, error);
01102 
01103    /* Set flags from handle_common_options */
01104    ast_copy_flags(&device->flags[0], &peerflags[0], mask[0].flags);
01105    ast_copy_flags(&device->flags[1], &peerflags[1], mask[1].flags);
01106 
01107    /* If not realtime and dynamic - check if we have a current registration */
01108    if (!found && ast_test_flag(&device->flags[1], SIP_PAGE2_DYNAMIC) && !ast_test_flag(&device->flags[0], SIP_REALTIME))
01109       reg_source_db(device);
01110    
01111 
01112    /* If dynamic and realtime, check registration expiry - it might have
01113       expired already */
01114    if (!ast_test_flag(&global.flags[1], SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&device->flags[1], SIP_PAGE2_DYNAMIC) && realtime) {
01115       time_t nowtime = time(NULL);
01116 
01117       if ((nowtime - regseconds) > 0) {
01118          destroy_association(device);
01119          memset(&device->addr, 0, sizeof(device->addr));
01120          if (option_debug)
01121             ast_log(LOG_DEBUG, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
01122       }
01123    }
01124 
01125    /* If we have an allowsubscribe, enable it */
01126    if (ast_test_flag(&device->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE))
01127       global.allowsubscribe = TRUE; /* No global ban any more */
01128 
01129    ASTOBJ_UNMARK(device);
01130    /* Delete the old ACL list */
01131    ast_free_ha(oldha);
01132 
01133    /* Start registration if needed */
01134    if (ast_test_flag(&device->flags[1], SIP_PAGE2_SERVICE)) {
01135       sip_register(NULL, register_lineno, device); /* XXX How do we handle this at reload?? */
01136    } else if (device->registry) {
01137       /* We have a registry entry for a peer that no longer wished to be registered */
01138       ASTOBJ_UNREF(device->registry,sip_registry_destroy);
01139       device->registry = NULL;
01140    }
01141    return device;
01142 }

static void cleanup_stale_contexts char *  new,
char *  old
[static]
 

Destroy disused contexts between reloads Only used in reload_config so the code for regcontext doesn't get ugly.

Definition at line 484 of file sip3_config.c.

References ast_context_destroy(), ast_context_find(), AST_MAX_CONTEXT, and strsep().

00485 {
00486    char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT];
00487 
00488    while ((oldcontext = strsep(&old, "&"))) {
00489       stalecontext = '\0';
00490       ast_copy_string(newlist, new, sizeof(newlist));
00491       stringp = newlist;
00492       while ((newcontext = strsep(&stringp, "&"))) {
00493          if (strcmp(newcontext, oldcontext) == 0) {
00494             /* This is not the context you're looking for */
00495             stalecontext = '\0';
00496             break;
00497          } else if (strcmp(newcontext, oldcontext)) {
00498             stalecontext = oldcontext;
00499          }
00500          
00501       }
00502       if (stalecontext)
00503          ast_context_destroy(ast_context_find(stalecontext), "SIP");
00504    }
00505 }

struct sip_device* device_ref struct sip_device device  ) 
 

Add reference for device.

Definition at line 436 of file sip3_config.c.

References ast_log(), ASTOBJ_REF, LOG_DEBUG, option_debug, and sipdebug.

00437 {
00438    ASTOBJ_REF(device);
00439    if (option_debug > 3 && sipdebug)
00440       ast_log(LOG_DEBUG, "/// Adding reference to device %s - refcount now %d\n", device->name, device->refcount);
00441    return device;
00442 }

void device_unref struct sip_device device  ) 
 

Remove reference for device. When we reach 0, device is removed from memory.

Definition at line 425 of file sip3_config.c.

References ast_log(), ASTOBJ_UNREF, LOG_DEBUG, option_debug, sip_destroy_device(), and sipdebug.

Referenced by __sip_autodestruct(), _sip_show_device(), check_user_full(), create_addr(), expire_register(), function_sippeer(), handle_request_subscribe(), register_verify(), sip_devicestate(), sip_do_debug_device(), and update_call_counter().

00426 {
00427    if (!device)
00428       return;
00429 
00430    if (option_debug > 3 && sipdebug)
00431       ast_log(LOG_DEBUG, "/// Removing reference from device %s - refcount now %d\n", device->name, device->refcount - 1);
00432    ASTOBJ_UNREF(device, sip_destroy_device);
00433 }

static int handle_common_options enum sip_config_options  option,
struct ast_flags flags,
struct ast_flags mask,
struct ast_variable v
[static]
 

Handle flag-type options common to configuration of devices - users and peers.

Parameters:
flags array of two struct ast_flags
mask array of two struct ast_flags
v linked list of config variables to process
Returns:
non-zero if any config options were handled, zero otherwise

Definition at line 514 of file sip3_config.c.

References ast_clear_flag, ast_false(), ast_log(), ast_set2_flag, ast_set_flag, ast_true(), error(), ast_variable::lineno, LOG_WARNING, ast_variable::next, SIP_CAN_REINVITE, SIP_CAN_REINVITE_NAT, SIP_CONF_ALLOWOVERLAP, SIP_CONF_ALLOWSUBSCRIBE, SIP_CONF_CANREINVITE, SIP_CONF_COMPACTHEADERS, SIP_CONF_DTMFMODE, SIP_CONF_G726NONSTANDARD, SIP_CONF_INSECURE, SIP_CONF_NAT, SIP_CONF_PROGRESSINBAND, SIP_CONF_PROMISCREDIR, SIP_CONF_RFC2833COMPENSATE, SIP_CONF_SENDRPID, SIP_CONF_T38PT_RTP, SIP_CONF_T38PT_TCP, SIP_CONF_T38PT_UDPTL, SIP_CONF_TRUSTRPID, SIP_CONF_USECLIENTCODE, SIP_CONF_VIDEOSUPPORT, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, SIP_G726_NONSTANDARD, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, SIP_NAT, SIP_NAT_ALWAYS, SIP_NAT_NEVER, SIP_NAT_RFC3581, SIP_NAT_ROUTE, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_COMPACTHEADERS, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT_RTP, SIP_PAGE2_T38SUPPORT_TCP, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_VIDEOSUPPORT, SIP_PROG_INBAND, SIP_PROG_INBAND_NO, SIP_PROG_INBAND_YES, SIP_PROMISCREDIR, SIP_REINVITE, SIP_REINVITE_UPDATE, SIP_SENDRPID, SIP_TRUSTRPID, SIP_USECLIENTCODE, strsep(), and ast_variable::value.

00515 {
00516    int error = 0; /* Number of errors */
00517 
00518    switch (option) {
00519    case SIP_CONF_TRUSTRPID:
00520       ast_set_flag(&mask[0], SIP_TRUSTRPID);
00521       ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID);
00522       break;
00523    case SIP_CONF_SENDRPID:
00524       ast_set_flag(&mask[0], SIP_SENDRPID);
00525       ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID);
00526       break;
00527    case SIP_CONF_G726NONSTANDARD:
00528       ast_set_flag(&mask[0], SIP_G726_NONSTANDARD);
00529       ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD);
00530       break;
00531    case SIP_CONF_USECLIENTCODE:
00532       ast_set_flag(&mask[0], SIP_USECLIENTCODE);
00533       ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE);
00534       break;
00535    case SIP_CONF_DTMFMODE:
00536       ast_set_flag(&mask[0], SIP_DTMF);
00537       ast_clear_flag(&flags[0], SIP_DTMF);
00538       if (!strcasecmp(v->value, "inband"))
00539          ast_set_flag(&flags[0], SIP_DTMF_INBAND);
00540       else if (!strcasecmp(v->value, "rfc2833"))
00541          ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
00542       else if (!strcasecmp(v->value, "info"))
00543          ast_set_flag(&flags[0], SIP_DTMF_INFO);
00544       else if (!strcasecmp(v->value, "auto"))
00545          ast_set_flag(&flags[0], SIP_DTMF_AUTO);
00546       else {
00547          ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno);
00548          error++;
00549          ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
00550       }
00551       break;
00552    case SIP_CONF_NAT:
00553       ast_set_flag(&mask[0],