Codename Pineapple

Home page | Mailing list | Docs

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

Asterisk developer's documentation :: Codename Pineapple


sip3_subscribe.c File Reference


Detailed Description

Various SIP network interface 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_subscribe.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/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_subscribe.c:

Go to the source code of this file.

Functions

const struct cfsubscription_typesfind_subscription_type (enum subscriptiontype subtype)
 Find subscription type in array.
const char * subscription_type2str (enum subscriptiontype subtype)
 Show subscription type in string format.
GNURK int transmit_state_notify (struct sip_dialog *p, int state, int full, int timeout)
 Used in the SUBSCRIBE notification subsystem.

Variables

static const struct cfsubscription_types subscription_types []
 List of subscription event types for SUBSCRIBE requests.


Function Documentation

const struct cfsubscription_types* find_subscription_type enum subscriptiontype  subtype  ) 
 

Find subscription type in array.

Definition at line 119 of file sip3_subscribe.c.

References subscription_types, and type.

00120 {
00121    int i;
00122 
00123    for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) {
00124       if (subscription_types[i].type == subtype) {
00125          return &subscription_types[i];
00126       }
00127    }
00128    return &subscription_types[0];
00129 }

const char* subscription_type2str enum subscriptiontype  subtype  ) 
 

Show subscription type in string format.

sip3_subscribe.c

Definition at line 106 of file sip3_subscribe.c.

References subscription_types, and type.

00107 {
00108    int i;
00109 
00110    for (i = 1; (i < (sizeof(subscription_types) / sizeof(subscription_types[0]))); i++) {
00111       if (subscription_types[i].type == subtype) {
00112          return subscription_types[i].text;
00113       }
00114    }
00115    return subscription_types[0].text;
00116 }

GNURK int transmit_state_notify struct sip_dialog p,
int  state,
int  full,
int  timeout
 

Used in the SUBSCRIBE notification subsystem.

Definition at line 132 of file sip3_subscribe.c.

References add_header(), add_header_contentLength(), add_line(), ast_build_string(), ast_device_state(), AST_DEVICE_UNAVAILABLE, AST_EXTENSION_BUSY, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_INUSE, AST_EXTENSION_NOT_INUSE, AST_EXTENSION_ONHOLD, AST_EXTENSION_REMOVED, AST_EXTENSION_RINGING, AST_EXTENSION_UNAVAILABLE, ast_get_hint(), ast_log(), AST_MAX_EXTENSION, CPIM_PIDF_XML, DIALOG_INFO_XML, sip_dialog::dialogver, sip_dialog::expiry, find_subscription_type(), get_header(), get_in_brackets(), global, sip_dialog::initreq, LOG_WARNING, NONE, sip_globals::notifyringing, PIDF_XML, reqprep(), send_request(), SIP_MAX_PACKET, SIP_NOTIFY, sipnet, siprequest_alloc(), strsep(), sip_dialog::subscribed, TRUE, XMIT_RELIABLE, and XPIDF_XML.

00133 {
00134    char tmp[4000], from[256], to[256];
00135    char *t = tmp, *c, *mfrom, *mto;
00136    size_t maxbytes = sizeof(tmp);
00137    struct sip_request *req;
00138    char hint[AST_MAX_EXTENSION];
00139    char *statestring = "terminated";
00140    const struct cfsubscription_types *subscriptiontype;
00141    enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN;
00142    char *pidfstate = "--";
00143    char *pidfnote= "Ready";
00144 
00145    req = siprequest_alloc(SIP_MAX_PACKET, &sipnet);
00146 
00147    memset(from, 0, sizeof(from));
00148    memset(to, 0, sizeof(to));
00149    memset(tmp, 0, sizeof(tmp));
00150 
00151    switch (state) {
00152    case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE):
00153       statestring = (global.notifyringing) ? "early" : "confirmed";
00154       local_state = NOTIFY_INUSE;
00155       pidfstate = "busy";
00156       pidfnote = "Ringing";
00157       break;
00158    case AST_EXTENSION_RINGING:
00159       statestring = "early";
00160       local_state = NOTIFY_INUSE;
00161       pidfstate = "busy";
00162       pidfnote = "Ringing";
00163       break;
00164    case AST_EXTENSION_INUSE:
00165       statestring = "confirmed";
00166       local_state = NOTIFY_INUSE;
00167       pidfstate = "busy";
00168       pidfnote = "On the phone";
00169       break;
00170    case AST_EXTENSION_BUSY:
00171       statestring = "confirmed";
00172       local_state = NOTIFY_CLOSED;
00173       pidfstate = "busy";
00174       pidfnote = "On the phone";
00175       break;
00176    case AST_EXTENSION_UNAVAILABLE:
00177       statestring = "terminated";
00178       local_state = NOTIFY_CLOSED;
00179       pidfstate = "away";
00180       pidfnote = "Unavailable";
00181       break;
00182    case AST_EXTENSION_ONHOLD:
00183       statestring = "confirmed";
00184       local_state = NOTIFY_INUSE;
00185       pidfstate = "busy";
00186       pidfnote = "On hold";
00187       break;
00188    case AST_EXTENSION_NOT_INUSE:
00189    default:
00190       /* Default setting */
00191       break;
00192    }
00193 
00194    subscriptiontype = find_subscription_type(p->subscribed);
00195    
00196    /* Check which device/devices we are watching  and if they are registered */
00197    if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) {
00198       /* If they are not registered, we will override notification and show no availability */
00199       if (ast_device_state(hint) == AST_DEVICE_UNAVAILABLE) {
00200          local_state = NOTIFY_CLOSED;
00201          pidfstate = "away";
00202          pidfnote = "Not online";
00203       }
00204    }
00205 
00206    ast_copy_string(from, get_header(p->initreq, "From"), sizeof(from));
00207    c = get_in_brackets(from);
00208    if (strncmp(c, "sip:", 4)) {
00209       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
00210       return -1;
00211    }
00212    mfrom = strsep(&c, ";");   /* trim ; and beyond */
00213 
00214    ast_copy_string(to, get_header(p->initreq, "To"), sizeof(to));
00215    c = get_in_brackets(to);
00216    if (strncmp(c, "sip:", 4)) {
00217       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
00218       return -1;
00219    }
00220    mto = strsep(&c, ";");  /* trim ; and beyond */
00221 
00222    reqprep(req, p, SIP_NOTIFY, 0, TRUE);
00223 
00224    
00225    add_header(req, "Event", subscriptiontype->event);
00226    add_header(req, "Content-Type", subscriptiontype->mediatype);
00227    switch(state) {
00228    case AST_EXTENSION_DEACTIVATED:
00229       if (timeout)
00230          add_header(req, "Subscription-State", "terminated;reason=timeout");
00231       else {
00232          add_header(req, "Subscription-State", "terminated;reason=probation");
00233          add_header(req, "Retry-After", "60");
00234       }
00235       break;
00236    case AST_EXTENSION_REMOVED:
00237       add_header(req, "Subscription-State", "terminated;reason=noresource");
00238       break;
00239    default:
00240       if (p->expiry)
00241          add_header(req, "Subscription-State", "active");
00242       else  /* Expired */
00243          add_header(req, "Subscription-State", "terminated;reason=timeout");
00244    }
00245    switch (p->subscribed) {
00246    case XPIDF_XML:
00247    case CPIM_PIDF_XML:
00248       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n");
00249       ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n");
00250       ast_build_string(&t, &maxbytes, "<presence>\n");
00251       ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom);
00252       ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten);
00253       ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto);
00254       ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state ==  NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed");
00255       ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline");
00256       ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n");
00257       break;
00258    case PIDF_XML: /* Eyebeam supports this format */
00259       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
00260       ast_build_string(&t, &maxbytes, "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \nxmlns:pp=\"urn:ietf:params:xml:ns:pidf:person\"\nxmlns:es=\"urn:ietf:params:xml:ns:pidf:rpid:status:rpid-status\"\nxmlns:ep=\"urn:ietf:params:xml:ns:pidf:rpid:rpid-person\"\nentity=\"%s\">\n", mfrom);
00261       ast_build_string(&t, &maxbytes, "<pp:person><status>\n");
00262       if (pidfstate[0] != '-')
00263          ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate);
00264       ast_build_string(&t, &maxbytes, "</status></pp:person>\n");
00265       ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */
00266       ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */
00267       ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto);
00268       if (pidfstate[0] == 'b') /* Busy? Still open ... */
00269          ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n");
00270       else
00271          ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed");
00272       ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n");
00273       break;
00274    case DIALOG_INFO_XML: /* SNOM subscribes in this format */
00275       ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n");
00276       ast_build_string(&t, &maxbytes, "<dialog-info xmlns=\"urn:ietf:params:xml:ns:dialog-info\" version=\"%d\" state=\"%s\" entity=\"%s\">\n", p->dialogver++, full ? "full":"partial", mto);
00277       if ((state & AST_EXTENSION_RINGING) && global.notifyringing)
00278          ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten);
00279       else
00280          ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten);
00281       ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring);
00282       if (state == AST_EXTENSION_ONHOLD) {
00283          ast_build_string(&t, &maxbytes, "<local>\n<target uri=\"%s\">\n"
00284             "<param pname=\"+sip.rendering\" pvalue=\"no\">\n"
00285             "</target>\n</local>\n", mto);
00286       }
00287       ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n");
00288       break;
00289    case NONE:
00290    default:
00291       break;
00292    }
00293 
00294    if (t > tmp + sizeof(tmp))
00295       ast_log(LOG_WARNING, "Buffer overflow detected!!  (Please file a bug report)\n");
00296 
00297    add_header_contentLength(req, strlen(tmp));
00298    add_line(req, tmp);
00299 
00300    return send_request(p, req, XMIT_RELIABLE);
00301 }


Variable Documentation

const struct cfsubscription_types subscription_types[] [static]
 

List of subscription event types for SUBSCRIBE requests.

Definition at line 95 of file sip3_subscribe.c.


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