[asterisk-commits] branch oej/subscribemwi r9118 -
/team/oej/subscribemwi/channels/chan_sip.c
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Thu Feb 2 14:26:59 MST 2006
Author: oej
Date: Thu Feb 2 15:26:56 2006
New Revision: 9118
URL: http://svn.digium.com/view/asterisk?rev=9118&view=rev
Log:
Playing around with subscription of MWI notification to support AVM ATAs
Modified:
team/oej/subscribemwi/channels/chan_sip.c
Modified: team/oej/subscribemwi/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/oej/subscribemwi/channels/chan_sip.c?rev=9118&r1=9117&r2=9118&view=diff
==============================================================================
--- team/oej/subscribemwi/channels/chan_sip.c (original)
+++ team/oej/subscribemwi/channels/chan_sip.c Thu Feb 2 15:26:56 2006
@@ -177,7 +177,8 @@
XPIDF_XML,
DIALOG_INFO_XML,
CPIM_PIDF_XML,
- PIDF_XML
+ PIDF_XML,
+ MWI_NOTIFICATION
};
static const struct cfsubscription_types {
@@ -191,7 +192,8 @@
{ DIALOG_INFO_XML, "dialog", "application/dialog-info+xml", "dialog-info+xml" },
{ CPIM_PIDF_XML, "presence", "application/cpim-pidf+xml", "cpim-pidf+xml" }, /* RFC 3863 */
{ PIDF_XML, "presence", "application/pidf+xml", "pidf+xml" }, /* RFC 3863 */
- { XPIDF_XML, "presence", "application/xpidf+xml", "xpidf+xml" } /* Pre-RFC 3863 with MS additions */
+ { XPIDF_XML, "presence", "application/xpidf+xml", "xpidf+xml" }, /* Pre-RFC 3863 with MS additions */
+ { MWI_NOTIFICATION, "message-summary", "application/simple-message-summary", "mwi" } /* Mailbox notification */
};
enum sipmethod {
@@ -821,6 +823,7 @@
struct sockaddr_in defaddr; /*!< Default IP address, used until registration */
struct ast_ha *ha; /*!< Access control list */
struct ast_variable *chanvars; /*!< Variables to set for channel created by user */
+ struct sip_pvt *mwipvt; /*!< Subscription for MWI */
int lastmsg;
};
@@ -968,6 +971,7 @@
static int restart_monitor(void);
static void set_peer_defaults(struct sip_peer *peer);
static struct sip_peer *temp_peer(const char *name);
+static int sip_send_mwi_to_peer(struct sip_peer *peer);
/*----- RTP interface functions */
@@ -2161,7 +2165,6 @@
if (sip_debug_test_pvt(p) || option_debug > 2)
ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text);
-
if (dumphistory)
sip_dump_history(p);
@@ -7053,7 +7056,7 @@
\return 0 on success, -1 on failure, and 1 on challenge sent
-2 on authentication error from chedck_auth()
*/
-static int check_user_full(struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, int reliable, struct sockaddr_in *sin, int ignore, char *mailbox, int mailboxlen)
+static int check_user_full(struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, int reliable, struct sockaddr_in *sin, int ignore, struct sip_peer **authpeer)
{
struct sip_user *user = NULL;
struct sip_peer *peer;
@@ -7122,7 +7125,7 @@
if (ast_strlen_zero(of))
return 0;
- if (!mailbox) /* If it's a mailbox SUBSCRIBE, don't check users */
+ if (!authpeer) /* If we are looking for a peer, don't check the user objects (or realtime) */
user = find_user(of, 1);
/* Find user based on user name in the from header */
@@ -7207,7 +7210,7 @@
ast_verbose("Found user '%s'\n", user->name);
} else {
if (user) {
- if (!mailbox && debug)
+ if (!authpeer && debug)
ast_verbose("Found user '%s', but fails host access\n", user->name);
ASTOBJ_UNREF(user,sip_destroy_user);
}
@@ -7229,6 +7232,7 @@
if (peer) {
if (debug)
ast_verbose("Found peer '%s'\n", peer->name);
+
/* Take the peer */
ast_copy_flags(p, peer, SIP_FLAGS_TO_COPY);
@@ -7282,8 +7286,10 @@
p->chanvars = tmpvar;
}
}
- if (mailbox)
- snprintf(mailbox, mailboxlen, ",%s,", peer->mailbox);
+ if (authpeer) {
+ (*authpeer) = peer; /* We might want to add a ref to the object here, to keep it in memory a bit longer if it is realtime */
+ ASTOBJ_REF(peer); /* Any function that uses authpeer needs to ASTOBJ_UNREF */
+ }
if (!ast_strlen_zero(peer->username)) {
ast_string_field_set(p, username, peer->username);
/* Use the default username for authentication on outbound calls */
@@ -7348,7 +7354,7 @@
*/
static int check_user(struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, int reliable, struct sockaddr_in *sin, int ignore)
{
- return check_user_full(p, req, sipmethod, uri, reliable, sin, ignore, NULL, 0);
+ return check_user_full(p, req, sipmethod, uri, reliable, sin, ignore, NULL);
}
/*! \brief Get text out of a SIP MESSAGE packet */
@@ -10777,6 +10783,7 @@
int gotdest;
int res = 0;
int firststate = AST_EXTENSION_REMOVED;
+ struct sip_peer *authpeer = NULL;
if (p->initreq.headers) {
/* We already have a dialog */
@@ -10804,19 +10811,12 @@
ast_verbose("Ignoring this SUBSCRIBE request\n");
if (!p->lastinvite) {
- char mailboxbuf[256]="";
- char *mailbox = NULL;
- int mailboxsize = 0;
char *event = get_header(req, "Event"); /* Get Event package name */
char *accept = get_header(req, "Accept");
- if (!strcmp(event, "message-summary") && !strcmp(accept, "application/simple-message-summary")) {
- mailbox = mailboxbuf;
- mailboxsize = sizeof(mailboxbuf);
- }
/* Handle authentication if this is our first subscribe */
- res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, ignore, mailbox, mailboxsize);
+ res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, ignore, &authpeer);
if (res) {
if (res < 0) {
ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From"));
@@ -10879,9 +10879,11 @@
config section.
*/
- if (!ast_strlen_zero(mailbox)) {
+ if (authpeer && !ast_strlen_zero(authpeer->mailbox)) {
transmit_response(p, "200 OK", req);
- ast_set_flag(p, SIP_NEEDDESTROY);
+ p->subscribed = MWI_NOTIFICATION;
+ authpeer->mwipvt = p; /* Link from peer to pvt */
+ /* Do I need another the other way for destruction? */
} else {
transmit_response(p, "404 Not found", req);
ast_set_flag(p, SIP_NEEDDESTROY);
@@ -10917,47 +10919,56 @@
if (p->expiry > 0)
sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */
- if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) {
- ast_log(LOG_ERROR, "Got SUBSCRIBE for extensions without hint. Please add hint to %s in context %s\n", p->exten, p->context);
- transmit_response(p, "404 Not found", req);
- ast_set_flag(p, SIP_NEEDDESTROY);
- return 0;
+ if (p->subscribed == MWI_NOTIFICATION) {
+ if (authpeer) /* Send first notification */
+ ASTOBJ_WRLOCK(authpeer);
+ sip_send_mwi_to_peer(authpeer);
+ ASTOBJ_UNLOCK(authpeer);
} else {
- struct sip_pvt *p_old;
-
- transmit_response(p, "200 OK", req);
- transmit_state_notify(p, firststate, 1); /* Send first notification */
- append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate));
-
- /* remove any old subscription from this peer for the same exten/context,
- as the peer has obviously forgotten about it and it's wasteful to wait
- for it to expire and send NOTIFY messages to the peer only to have them
- ignored (or generate errors)
- */
- ast_mutex_lock(&iflock);
- for (p_old = iflist; p_old; p_old = p_old->next) {
- if (p_old == p)
- continue;
- if (p_old->initreq.method != SIP_SUBSCRIBE)
- continue;
- if (p_old->subscribed == NONE)
- continue;
- ast_mutex_lock(&p_old->lock);
- if (!strcmp(p_old->username, p->username)) {
- if (!strcmp(p_old->exten, p->exten) &&
- !strcmp(p_old->context, p->context)) {
- ast_set_flag(p_old, SIP_NEEDDESTROY);
- ast_mutex_unlock(&p_old->lock);
- break;
+ if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) {
+ ast_log(LOG_ERROR, "Got SUBSCRIBE for extensions without hint. Please add hint to %s in context %s\n", p->exten, p->context);
+ transmit_response(p, "404 Not found", req);
+ ast_set_flag(p, SIP_NEEDDESTROY);
+ return 0;
+ } else {
+ struct sip_pvt *p_old;
+
+ transmit_response(p, "200 OK", req);
+ transmit_state_notify(p, firststate, 1); /* Send first notification */
+ append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate));
+
+ /* remove any old subscription from this peer for the same exten/context,
+ as the peer has obviously forgotten about it and it's wasteful to wait
+ for it to expire and send NOTIFY messages to the peer only to have them
+ ignored (or generate errors)
+ */
+ ast_mutex_lock(&iflock);
+ for (p_old = iflist; p_old; p_old = p_old->next) {
+ if (p_old == p)
+ continue;
+ if (p_old->initreq.method != SIP_SUBSCRIBE)
+ continue;
+ if (p_old->subscribed == NONE)
+ continue;
+ ast_mutex_lock(&p_old->lock);
+ if (!strcmp(p_old->username, p->username)) {
+ if (!strcmp(p_old->exten, p->exten) &&
+ !strcmp(p_old->context, p->context)) {
+ ast_set_flag(p_old, SIP_NEEDDESTROY);
+ ast_mutex_unlock(&p_old->lock);
+ break;
+ }
}
+ ast_mutex_unlock(&p_old->lock);
}
- ast_mutex_unlock(&p_old->lock);
+ ast_mutex_unlock(&iflock);
}
- ast_mutex_unlock(&iflock);
}
if (!p->expiry)
ast_set_flag(p, SIP_NEEDDESTROY);
}
+ if (authpeer)
+ ASTOBJ_UNREF(authpeer, sip_destroy_peer);
return 1;
}
@@ -11289,20 +11300,25 @@
return 0;
}
- if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY)))
- return -1;
peer->lastmsgssent = ((newmsgs << 8) | (oldmsgs));
- if (create_addr_from_peer(p, peer)) {
- /* Maybe they're not registered, etc. */
- sip_destroy(p);
- return 0;
- }
- /* Recalculate our side, and recalculate Call ID */
- if (ast_sip_ouraddrfor(&p->sa.sin_addr,&p->ourip))
- memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
- build_via(p);
- build_callid_pvt(p);
+
+ if (!peer->mwipvt) {
+ if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY)))
+ return -1;
+ if (create_addr_from_peer(p, peer)) {
+ /* Maybe they're not registered, etc. */
+ sip_destroy(p);
+ return 0;
+ }
+ /* Recalculate our side, and recalculate Call ID */
+ if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
+ memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
+ build_via(p);
+ build_callid_pvt(p);
+ } else {
+ p = peer->mwipvt;
+ }
/* Send MWI */
ast_set_flag(p, SIP_OUTGOING);
transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten);
More information about the asterisk-commits
mailing list