[svn-commits] oej: branch group/pinana-publish-1.4 r296510 - /team/group/pinana-publish-1.4...
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Sun Nov 28 03:46:40 CST 2010
Author: oej
Date: Sun Nov 28 03:46:34 2010
New Revision: 296510
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=296510
Log:
Yahoo! We now have working status updates. Checkpoint #1 reached.
Modified:
team/group/pinana-publish-1.4/channels/chan_sip.c
Modified: team/group/pinana-publish-1.4/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/group/pinana-publish-1.4/channels/chan_sip.c?view=diff&rev=296510&r1=296509&r2=296510
==============================================================================
--- team/group/pinana-publish-1.4/channels/chan_sip.c (original)
+++ team/group/pinana-publish-1.4/channels/chan_sip.c Sun Nov 28 03:46:34 2010
@@ -15083,15 +15083,17 @@
/* Confirm that we received this packet */
transmit_response(p, "200 OK", req);
- } else if (!strcmp(event, "dialog")) {
+ } else if (!strcasecmp(event, "dialog")) {
res = sip_pres_notify_update(p, req);
} else {
/* We don't understand this event. */
+ if (option_debug > 1) {
+ ast_log(LOG_DEBUG, "Event ->%s<- \n", event);
+ }
/* Here's room to implement incoming voicemail notifications :-) */
transmit_response(p, "489 Bad event", req);
res = -1;
};
-
if (!p->lastinvite)
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
@@ -19118,12 +19120,14 @@
struct sip_subscription_pres {
ASTOBJ_COMPONENTS_FULL(struct sip_subscription_pres,1,1);
AST_DECLARE_STRING_FIELDS(
+ AST_STRING_FIELD(devicename); /*!< the full requested devicename in the hint */
AST_STRING_FIELD(uri); /*!< Who we are sending the subscription as */
AST_STRING_FIELD(domain); /*!< Domain or host we subscribe to */
);
//enum sip_transport transport; /*!< Transport to use */
struct sip_peer *peer; /*!< Peer to use for this subscription */
int resub; /*!< Sched ID of resubscription */
+ int state; /*!< Last known device state */
unsigned int subscribed:1; /*!< Whether we are currently subscribed or not */
unsigned int destruction:1; /*!< Whether we are currently being unsubscribed */
unsigned int fatalerror:1; /*!< We got a fatal error and can't do anything without a reload */
@@ -19136,7 +19140,7 @@
/* Forward decl (no doxygen here) */
static int __sip_subscribe_pres_do(struct sip_subscription_pres *pres);
-static int sip_subscribe_pres_do(const void *data);
+static int sip_subscribe_pres_do(void *data);
/*! \brief The MWI subscription list */
static struct ast_subscription_pres_list {
@@ -19169,6 +19173,7 @@
AST_SCHED_DEL(sched, pres->resub);
ast_string_field_free_memory(pres);
//XXX ast_dnsmgr_release(pres->dnsmgr);
+ /* XXX remove from sip_pres_sublist */
ast_free(pres);
}
@@ -19177,7 +19182,7 @@
{
struct sip_subscription_pres *pres;
char *domain;
- char buf[256] = "";
+ char buf[256];
/* We have a URI, much like in a dialstring. Just try to find where it leads us like a normal call.
the URI can point to a peer, a domain or a host. We can basically use the same logic as
@@ -19193,13 +19198,18 @@
}
ast_copy_string(buf, uri, sizeof(buf));
+ if (strncasecmp(buf, "sip:", 4)) {
+ ast_log(LOG_ERROR, "Currently, we only support sip: uri's - %s\n", buf);
+ return -1;
+ }
+ uri += 4; /* Skip sip: */
if ((domain = strrchr(uri, '@'))) {
- *domain++ = '\0';
+ domain++;
}
if (ast_strlen_zero(domain) || ast_strlen_zero(uri)) {
- ast_log(LOG_ERROR, "Format for SIP remote subscription in a hint is sipds:<username>@<domain/peer> \n");
+ ast_log(LOG_ERROR, "Format for SIP remote subscription in a hint is sipds:sip:<username>@<domain/peer> \n");
return -1;
}
@@ -19214,9 +19224,11 @@
}
ASTOBJ_INIT(pres);
- ast_string_field_set(pres, uri, uri);
+ ast_string_field_set(pres, uri, uri); /* Username part of URI */
ast_string_field_set(pres, domain, domain);
+ ast_string_field_set(pres, devicename, buf);
pres->resub = -1;
+
ASTOBJ_CONTAINER_LINK(&sip_pres_sublist, pres);
@@ -19231,10 +19243,10 @@
/*! \brief Send a subscription or resubscription for presence */
-static int sip_subscribe_pres_do(const void *data)
-{
- struct sip_subscription_pres *pres = (struct sip_subscription_pres*)data;
-
+static int sip_subscribe_pres_do(void *data)
+{
+ struct sip_subscription_pres *pres = (struct sip_subscription_pres *) data;
+
if (!pres) {
ast_log(LOG_DEBUG, "--- No subscription to start\n");
return -1;
@@ -19397,8 +19409,18 @@
static int sip_pres_notify_update(struct sip_pvt *dialog, struct sip_request *req)
{
char buf[SIPBUFSIZE * 8];
+ char uri[SIPBUFSIZE];
char *state;
+ int newstate=AST_EXTENSION_NOT_INUSE;
+
/* Example:
+ At this point we limit the code to support
+ Asterisk to Asterisk distribution of device states.
+ To support more complicated XML constructs we need
+ proper XML parsing. One Notify can have two or more
+ dialog represenations, in which case we currently
+ only read the state of the first.
+
NOTIFY sip:olle at 192.168.40.12 SIP/2.0
Via: SIP/2.0/UDP 192.168.20.200:5060;branch=z9hG4bK4d19eadc;rport
From: <sip:3000 at jarl.webway.se>;tag=as714765a1
@@ -19419,6 +19441,10 @@
<state>terminated</state>
</dialog>
</dialog-info>
+
+ <state> can have attributes
+ <state event="rejected" code="486">terminated</state>
+
*/
/* Check the content type */
if (strncasecmp(get_header(req, "Content-Type"), "application/dialog-info+xml", strlen("application/dialog-info+xml"))) {
@@ -19452,20 +19478,62 @@
return -1;
}
state += strlen("<state>");
- ast_log(LOG_DEBUG, "---------- State: ->%s<- \n", state);
+ state=ast_strip(state);
+ /* Translate dialog-info states to AST states */
+ if (!strcasecmp(state, "early")) {
+ newstate = AST_DEVICE_RINGING;
+ } else if (!strcasecmp(state, "confirmed")) {
+ newstate = AST_DEVICE_INUSE;
+ } else if (!strcasecmp(state, "terminated")) {
+ newstate = AST_DEVICE_NOT_INUSE;
+ }
/* Notify the device state system if there's a change */
/* Live long and prosper */
transmit_response(dialog, "200 OK", req);
+ if (!dialog->pres) {
+ ast_log(LOG_ERROR, "No presence subscription found for NOTIFY on subscription Call-ID %s\n", dialog->callid);
+ return 0;
+ }
+ dialog->pres->state = newstate;
+ ast_device_state_changed("sipds:%s", dialog->pres->devicename);
return 0;
}
-/*! \brief Callback for devicestate providers */
+/*! \brief Callback for devicestate providers
+ This is called everytime state changes.
+*/
static int sip_remote_devicestate(const char *data)
{
/* Data is the device to get state for, actually the SIP uri */
/* 1. Try to find the device in the list of subscriptions */
+ /* XXX Do we need to keep track of how many watchers we have? */
+ char buf[SIPBUFSIZE];
+ int foundit = FALSE;
+ int state = AST_DEVICE_UNKNOWN;
+
+ ast_log(LOG_DEBUG, "--- Looking for %s in subscriber list \n", data);
+ ASTOBJ_CONTAINER_TRAVERSE(&sip_pres_sublist, 1, do {
+ if (foundit) {
+ continue;
+ }
+ ASTOBJ_WRLOCK(iterator);
+ ast_log(LOG_DEBUG, "--- Comparing iterator->devicename %s with %s\n", iterator->devicename, data);
+ if (!strcasecmp(iterator->devicename, data)) {
+ foundit = TRUE;
+ state = iterator->state;
+ }
+ ASTOBJ_UNLOCK(iterator);
+ } while (0)
+ );
/* 2. If the device exists - get the last known state and return it */
+ if (foundit) {
+ if (option_debug > 2) {
+ ast_log(LOG_DEBUG, "Found device sipds:%s in subscription list\n", data);
+ }
+ return state;
+ }
+
/* 3. If the device does not exist in the list - set up a subscription */
/* When a dialplan is loaded, we get a first call to check state. In that call,
@@ -19473,7 +19541,6 @@
we'll update automatically with the initial state.
*/
sip_subscribe_pres(data, SUB_DIALOG_INFO);
-
return AST_DEVICE_UNKNOWN;
}
More information about the svn-commits
mailing list