Codename Pineapple

Home page | Mailing list | Docs

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

Asterisk developer's documentation :: Codename Pineapple


sip3_objects.c File Reference


Detailed Description

Various SIP object handling functions (phones, trunks, services) 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_objects.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/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp.h"
#include "asterisk/udptl.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/dsp.h"
#include "asterisk/features.h"
#include "asterisk/srv.h"
#include "asterisk/astdb.h"
#include "asterisk/causes.h"
#include "asterisk/utils.h"
#include "asterisk/file.h"
#include "asterisk/astobj.h"
#include "asterisk/dnsmgr.h"
#include "asterisk/devicestate.h"
#include "asterisk/linkedlists.h"
#include "asterisk/stringfields.h"
#include "asterisk/monitor.h"
#include "asterisk/localtime.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/compiler.h"
#include "sip3.h"
#include "sip3funcs.h"

Include dependency graph for sip3_objects.c:

Go to the source code of this file.

Functions

GNURK void destroy_association (struct sip_device *device)
 Remove registration data from realtime database or AST/DB when registration expires.
GNURK int expire_register (void *data)
 Expire registration of SIP peer.
GNURK struct sip_devicefind_device (const char *device, struct sockaddr_in *sin, int realtime)
 Locate peer by name or ip address This is used on incoming SIP message to find matching peer on ip or outgoing message to find matching peer on name.
GNURK void realtime_update_peer (const char *peername, struct sockaddr_in *sin, const char *username, const char *fullcontact, int expiry)
 Update peer object in realtime storage If the Asterisk system name is set in asterisk.conf, we will use that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups.
GNURK void register_peer_exten (struct sip_device *device, int onoff)
 Automatically add peer extension to dial plan.
static int sip_addrcmp (char *name, struct sockaddr_in *sin)
 Support routine for find_device.
GNURK void sip_destroy_device (struct sip_device *device)
 Destroy device object from memory.
GNURK struct sip_devicetemp_device (const char *name)
 Create temporary peer (used in autocreatepeer mode).
GNURK void update_peer (struct sip_device *device, int expiry)
 Update peer data in database (if used).

Variables

sip_device_list devicelist


Function Documentation

GNURK void destroy_association struct sip_device device  ) 
 

Remove registration data from realtime database or AST/DB when registration expires.

Definition at line 380 of file sip3_objects.c.

References ast_db_del(), ast_test_flag, ast_update_realtime(), sip_globals::flags, sip_device::flags, global, SIP_PAGE2_IGNOREREGEXPIRE, and SIP_PAGE2_RT_FROMCONTACT.

00381 {
00382    if (!ast_test_flag(&global.flags[1], SIP_PAGE2_IGNOREREGEXPIRE)) {
00383       if (ast_test_flag(&device->flags[1], SIP_PAGE2_RT_FROMCONTACT))
00384          ast_update_realtime("sippeers", "name", device->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "defaultuser", "", "regserver", "", NULL);
00385       else 
00386          ast_db_del("SIP3-Registry", device->name);
00387    }
00388 }

int expire_register void *  data  ) 
 

Expire registration of SIP peer.

Definition at line 391 of file sip3_objects.c.

References sip_device::addr, ast_device_state_changed(), ast_test_flag, ASTOBJ_CONTAINER_UNLINK, destroy_association(), device_unref(), devicelist, EVENT_FLAG_SYSTEM, sip_device::expire, FALSE, sip_device::flags, manager_event, register_peer_exten(), SIP_PAGE2_RTAUTOCLEAR, and SIP_PAGE2_SELFDESTRUCT.

00392 {
00393    struct sip_device *device = data;
00394    
00395    if (!device)      /* Hmmm. We have no peer. Weird. */
00396       return 0;
00397 
00398    memset(&device->addr, 0, sizeof(device->addr));
00399 
00400    destroy_association(device);  /* remove registration data from storage */
00401    
00402    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", device->name);
00403    register_peer_exten(device, FALSE); /* Remove regexten */
00404    device->expire = -1;
00405    ast_device_state_changed("SIP/%s", device->name);
00406 
00407    /* Do we need to release this peer from memory? 
00408       Only for realtime peers and autocreated peers
00409    */
00410    if (ast_test_flag(&device->flags[1], SIP_PAGE2_SELFDESTRUCT) ||
00411        ast_test_flag(&device->flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
00412       device = ASTOBJ_CONTAINER_UNLINK(&devicelist, device);   /* Remove from peer list */
00413       device_unref(device);
00414    }
00415 
00416    return 0;
00417 }

GNURK struct sip_device* find_device const char *  peer,
struct sockaddr_in *  sin,
int  realtime
 

Locate peer by name or ip address This is used on incoming SIP message to find matching peer on ip or outgoing message to find matching peer on name.

sip3_objects.c

Definition at line 242 of file sip3_objects.c.

References ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, devicelist, name, realtime_peer(), and sip_addrcmp().

Referenced by _sip_show_device(), check_user_full(), create_addr(), function_sippeer(), register_verify(), sip_devicestate(), sip_do_debug_device(), sip_peer_hold(), and update_call_counter().

00243 {
00244    struct sip_device *peer = NULL;
00245 
00246    if (device)
00247       peer = ASTOBJ_CONTAINER_FIND(&devicelist, device);
00248    else
00249       peer = ASTOBJ_CONTAINER_FIND_FULL(&devicelist, sin, name, sip_addr_hashfunc, 1, sip_addrcmp);
00250 
00251    if (!peer && realtime)
00252       peer = realtime_peer(device, sin);
00253 
00254    return peer;
00255 }

GNURK void realtime_update_peer const char *  peername,
struct sockaddr_in *  sin,
const char *  username,
const char *  fullcontact,
int  expiry
 

Update peer object in realtime storage If the Asterisk system name is set in asterisk.conf, we will use that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups.

Definition at line 112 of file sip3_objects.c.

References ast_config_AST_SYSTEM_NAME, ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, ast_update_realtime(), sip_globals::flags, global, ipaddr, and SIP_PAGE2_RTSAVE_SYSNAME.

00113 {
00114    char port[10];
00115    char ipaddr[INET_ADDRSTRLEN];
00116    char regseconds[20];
00117 
00118    char *sysname = ast_config_AST_SYSTEM_NAME;
00119    char *syslabel = NULL;
00120 
00121    time_t nowtime = time(NULL) + expiry;
00122    const char *fc = fullcontact ? "fullcontact" : NULL;
00123    
00124    snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime);  /* Expiration time */
00125    ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr));
00126    snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
00127    
00128    if (ast_strlen_zero(sysname)) /* No system name, disable this */
00129       sysname = NULL;
00130    else if (ast_test_flag(&global.flags[1], SIP_PAGE2_RTSAVE_SYSNAME))
00131       syslabel = "regserver";
00132 
00133    if (fc)
00134       ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr,
00135          "port", port, "regseconds", regseconds,
00136          "defaultuser", username, fc, fullcontact, syslabel, sysname, NULL); /* note fc and syslabel _can_ be NULL */
00137    else
00138       ast_update_realtime("sippeers", "name", peername, "ipaddr", ipaddr,
00139          "port", port, "regseconds", regseconds,
00140          "defaultuser", username, syslabel, sysname, NULL); /* note syslabel _can_ be NULL */
00141 }

GNURK void register_peer_exten struct sip_device device,
int  onoff
 

Automatically add peer extension to dial plan.

Definition at line 144 of file sip3_objects.c.

References ast_add_extension(), ast_context_find(), ast_context_remove_extension(), ast_free, ast_log(), ast_strdup, ast_strlen_zero(), context, ext, sip_device::extra, global, LOG_WARNING, sip_globals::regcontext, S_OR, and strsep().

00145 {
00146    char multi[256];
00147    char *stringp, *ext, *context;
00148 
00149    /* XXX note that global.regcontext is both a global 'enable' flag and
00150     * the name of the global regexten context, if not specified
00151     * individually.
00152     */
00153    if (ast_strlen_zero(global.regcontext))
00154       return;
00155 
00156    ast_copy_string(multi, S_OR(device->extra.regexten, device->name), sizeof(multi));
00157    stringp = multi;
00158    while ((ext = strsep(&stringp, "&"))) {
00159       if ((context = strchr(ext, '@'))) {
00160          *context++ = '\0';   /* split ext@context */
00161          if (!ast_context_find(context)) {
00162             ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context);
00163             continue;
00164          }
00165       } else {
00166          context = global.regcontext;
00167       }
00168       if (onoff)
00169          ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop",
00170              ast_strdup(device->name), ast_free, "SIP");
00171       else
00172          ast_context_remove_extension(context, ext, 1, NULL);
00173    }
00174 }

static int sip_addrcmp char *  name,
struct sockaddr_in *  sin
[static]
 

Support routine for find_device.

Definition at line 97 of file sip3_objects.c.

References sip_device::addr, ast_test_flag, sip_device::flags, inaddrcmp(), and SIP_INSECURE_PORT.

00098 {
00099    /* We know name is the first field, so we can cast */
00100    struct sip_device *peer = (struct sip_device *) name;
00101    return   !(!inaddrcmp(&peer->addr, sin) || 
00102                (ast_test_flag(&peer->flags[0], SIP_INSECURE_PORT) &&
00103                (peer->addr.sin_addr.s_addr == sin->sin_addr.s_addr)));
00104 }

GNURK void sip_destroy_device struct sip_device device  ) 
 

Destroy device object from memory.

Definition at line 177 of file sip3_objects.c.

References ast_dnsmgr_release(), ast_free_ha(), ast_sched_del(), ast_string_field_free_pools, ast_test_flag, ast_variables_destroy(), ASTOBJ_UNREF, channel_counters::autocreated_peers, sip_device::call, sip_device::chanvars, clear_realm_authentication(), sip_device::dnsmgr, sip_device::expire, FALSE, sip_device::flags, free, sip_device::ha, logdebug(), sip_device::mailbox, sip_mwi_mailbox::mwipvt, sip_registry::peer, sip_device::pokeexpire, channel_counters::realtime_peers, channel_counters::realtime_users, register_peer_exten(), sip_device::registry, sip_destroy(), SIP_PAGE2_SELFDESTRUCT, SIP_PEER, SIP_REALTIME, sip_registry_destroy(), SIP_USER, sipcounters, channel_counters::static_peers, channel_counters::static_users, and sip_device::type.

Referenced by device_unref().

00178 {
00179    logdebug(3, "Destroying SIP device %s\n", device->name);
00180    //if (option_debug > 2)
00181       //ast_log(LOG_DEBUG, "Destroying SIP %s %s\n", device->type & SIP_USER ? "user" : "peer", device->name);
00182 
00183    /* Delete it, it needs to disappear */
00184    if (device->call)
00185       sip_destroy(device->call);
00186    if (device->chanvars) {
00187       ast_variables_destroy(device->chanvars);
00188       device->chanvars = NULL;
00189    }
00190 
00191    if (device->mailbox.mwipvt)      /* We have an active subscription, delete it */
00192       sip_destroy(device->mailbox.mwipvt);
00193 
00194    if (device->expire > -1)
00195       ast_sched_del(sched, device->expire);
00196    if (device->pokeexpire > -1)
00197       ast_sched_del(sched, device->pokeexpire);
00198    ast_free_ha(device->ha);
00199 
00200    if (device->type & SIP_PEER) {
00201       register_peer_exten(device, FALSE);
00202       clear_realm_authentication(device->auth);
00203       device->auth = (struct sip_auth *) NULL;
00204       if (ast_test_flag((&device->flags[1]), SIP_PAGE2_SELFDESTRUCT))
00205          sipcounters.autocreated_peers--;
00206       else if (ast_test_flag(&device->flags[0], SIP_REALTIME))
00207          sipcounters.realtime_peers--;
00208       else
00209          sipcounters.static_peers--;
00210    } 
00211    if (device->type & SIP_USER) {   /* SIP_USER */
00212       if (ast_test_flag(&device->flags[0], SIP_REALTIME))
00213          sipcounters.realtime_users--;
00214       else
00215          sipcounters.static_users--;
00216    }
00217    if (device->dnsmgr)
00218       ast_dnsmgr_release(device->dnsmgr);
00219    if (device->registry) {
00220       device->registry->peer = NULL;
00221       ASTOBJ_UNREF(device->registry,sip_registry_destroy);
00222    }
00223 
00224    /* Free the stringfield pool */
00225    ast_string_field_free_pools(device);
00226    free(device);
00227 }

GNURK struct sip_device* temp_device const char *  name  ) 
 

Create temporary peer (used in autocreatepeer mode).

Definition at line 258 of file sip3_objects.c.

References ast_calloc, ast_set_flag, ASTOBJ_INIT, channel_counters::autocreated_peers, sip_globals::default_prefs, global, reg_source_db(), set_device_defaults(), SIP_PAGE2_DYNAMIC, SIP_PAGE2_SELFDESTRUCT, SIP_PEER, and sipcounters.

Referenced by register_verify().

00259 {
00260    struct sip_device *peer;
00261 
00262    if (!(peer = ast_calloc(1, sizeof(*peer))))
00263       return NULL;
00264 
00265    sipcounters.autocreated_peers++;
00266    ASTOBJ_INIT(peer);
00267    peer->type = SIP_PEER;
00268    set_device_defaults(peer);
00269 
00270    ast_copy_string(peer->name, name, sizeof(peer->name));
00271 
00272    ast_set_flag(&peer->flags[1], SIP_PAGE2_SELFDESTRUCT);
00273    ast_set_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC);
00274    peer->prefs = global.default_prefs;
00275    reg_source_db(peer);
00276 
00277    return peer;
00278 }

GNURK void update_peer struct sip_device device,
int  expiry
 

Update peer data in database (if used).

Definition at line 230 of file sip3_objects.c.

References sip_device::addr, ast_test_flag, sip_device::flags, sip_globals::flags, global, realtime_update_peer(), SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_RTUPDATE, and SIP_REALTIME.

00231 {
00232    int rtcachefriends = ast_test_flag(&device->flags[1], SIP_PAGE2_RTCACHEFRIENDS);
00233    if (ast_test_flag(&global.flags[1], SIP_PAGE2_RTUPDATE) &&
00234        (ast_test_flag(&device->flags[0], SIP_REALTIME) || rtcachefriends)) {
00235       realtime_update_peer(device->name, &device->addr, device->defaultuser, rtcachefriends ? device->fullcontact : NULL, expiry);
00236    }
00237 }


Variable Documentation

struct sip_device_list devicelist
 

The device list

Definition at line 94 of file sip3_objects.c.

Referenced by _sip_show_devices(), build_device(), complete_sip_device(), expire_register(), find_device(), load_module(), register_verify(), sip_poke_all_peers(), sip_prune_realtime(), sip_show_inuse(), and sip_show_objects().


Asterisk is a trademark for Digium, inc.. | Edvina.net | Asterisk.org | This documentation was generated with Doxygen