support subscription-based MWI, and use proper Call-ID on NOTIFY messages (issue #6390)

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@15476 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Kevin P. Fleming
2006-03-28 04:21:21 +00:00
parent 0b5f2a5d3f
commit 8410e0d681
2 changed files with 235 additions and 167 deletions

View File

@@ -186,7 +186,8 @@ enum subscriptiontype {
XPIDF_XML,
DIALOG_INFO_XML,
CPIM_PIDF_XML,
PIDF_XML
PIDF_XML,
MWI_NOTIFICATION
};
static const struct cfsubscription_types {
@@ -200,7 +201,8 @@ static const struct cfsubscription_types {
{ 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 {
@@ -408,7 +410,7 @@ static int global_reg_timeout;
static int global_regattempts_max; /*!< Registration attempts before giving up */
static int global_allowguest; /*!< allow unauthenticated users/peers to connect? */
static int global_allowsubscribe; /*!< Flag for disabling ALL subscriptions, this is FALSE only if all peers are FALSE
the global setting is in globals_flag_page2 */
the global setting is in globals_flags[1] */
static int global_mwitime; /*!< Time between MWI checks for peers */
static int global_tos_sip; /*!< IP type of service for SIP packets */
static int global_tos_audio; /*!< IP type of service for audio RTP packets */
@@ -616,6 +618,7 @@ struct sip_auth {
#define SIP_PAGE2_VIDEOSUPPORT (1 << 9)
#define SIP_PAGE2_ALLOWSUBSCRIBE (1 << 10) /*!< Allow subscriptions from this peer? */
#define SIP_PAGE2_ALLOWOVERLAP (1 << 11) /*!< Allow overlap dialing ? */
#define SIP_PAGE2_SUBSCRIBEMWIONLY (1 << 12) /*!< Only issue MWI notification if subscribed to */
#define SIP_PAGE2_FLAGS_TO_COPY \
@@ -732,7 +735,8 @@ static struct sip_pvt {
struct ast_dsp *vad; /*!< Voice Activation Detection dsp */
struct sip_peer *peerpoke; /*!< If this dialog is to poke a peer, which one */
struct sip_peer *relatedpeer; /*!< If this dialog is related to a peer, which one
Used in peerpoke, mwi subscriptions */
struct sip_registry *registry; /*!< If this is a REGISTER dialog, to which registry */
struct ast_rtp *rtp; /*!< RTP Session */
struct ast_rtp *vrtp; /*!< Video RTP session */
@@ -843,6 +847,7 @@ struct sip_peer {
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;
};
@@ -980,6 +985,8 @@ static char *gettag(struct sip_request *req, char *header, char *tagbuf, int tag
static int find_sip_method(char *msg);
static unsigned int parse_sip_options(struct sip_pvt *pvt, char *supported);
static void sip_destroy(struct sip_pvt *p);
static void sip_destroy_peer(struct sip_peer *peer);
static void sip_destroy_user(struct sip_user *user);
static void parse_request(struct sip_request *req);
static char *get_header(struct sip_request *req, const char *name);
static void copy_request(struct sip_request *dst,struct sip_request *src);
@@ -990,6 +997,8 @@ static int __sip_do_register(struct sip_registry *r);
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);
static int sip_scheddestroy(struct sip_pvt *p, int ms);
/*----- RTP interface functions */
@@ -1707,6 +1716,11 @@ static void sip_destroy_peer(struct sip_peer *peer)
/* Delete it, it needs to disappear */
if (peer->call)
sip_destroy(peer->call);
if (peer->mwipvt) { /* We have an active subscription, delete it */
sip_destroy(peer->mwipvt);
}
if (peer->chanvars) {
ast_variables_destroy(peer->chanvars);
peer->chanvars = NULL;
@@ -2195,6 +2209,10 @@ static void __sip_destroy(struct sip_pvt *p, int lockowner)
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);
/* Remove link from peer to subscription of MWI */
if (p->relatedpeer && p->relatedpeer->mwipvt)
p->relatedpeer->mwipvt = (struct sip_pvt *) NULL;
if (dumphistory)
sip_dump_history(p);
@@ -5283,7 +5301,6 @@ static int transmit_state_notify(struct sip_pvt *p, int state, int full)
case AST_EXTENSION_REMOVED:
add_header(&req, "Subscription-State", "terminated;reason=noresource");
break;
break;
default:
if (p->expiry)
add_header(&req, "Subscription-State", "active");
@@ -5364,6 +5381,12 @@ static int transmit_notify_with_mwi(struct sip_pvt *p, int newmsgs, int oldmsgs,
ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no");
ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n", !ast_strlen_zero(vmexten) ? vmexten : default_vmexten, ast_strlen_zero(p->fromdomain) ? ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip) : p->fromdomain);
ast_build_string(&t, &maxbytes, "Voice-Message: %d/%d (0/0)\r\n", newmsgs, oldmsgs);
if (p->subscribed) {
if (p->expiry)
add_header(&req, "Subscription-State", "active");
else /* Expired */
add_header(&req, "Subscription-State", "terminated;reason=timeout");
}
if (t > tmp + sizeof(tmp))
ast_log(LOG_WARNING, "Buffer overflow detected!! (Please file a bug report)\n");
@@ -6608,6 +6631,7 @@ static int register_verify(struct sip_pvt *p, struct sockaddr_in *sin, struct si
update_peer(peer, p->expiry);
/* Say OK and ask subsystem to retransmit msg counter */
transmit_response_with_date(p, "200 OK", req);
if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY))
peer->lastmsgssent = -1;
res = 0;
break;
@@ -7145,7 +7169,7 @@ static int get_rpid_num(char *input,char *output, int maxlen)
\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, enum xmittype 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, enum xmittype reliable, struct sockaddr_in *sin, int ignore, struct sip_peer **authpeer)
{
struct sip_user *user = NULL;
struct sip_peer *peer;
@@ -7215,7 +7239,7 @@ static int check_user_full(struct sip_pvt *p, struct sip_request *req, int sipme
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 */
@@ -7311,7 +7335,7 @@ static int check_user_full(struct sip_pvt *p, struct sip_request *req, int sipme
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);
}
@@ -7333,6 +7357,7 @@ static int check_user_full(struct sip_pvt *p, struct sip_request *req, int sipme
if (peer) {
if (debug)
ast_verbose("Found peer '%s'\n", peer->name);
/* Take the peer */
ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
@@ -7389,8 +7414,10 @@ static int check_user_full(struct sip_pvt *p, struct sip_request *req, int sipme
p->chanvars = tmpvar;
}
}
if (mailbox)
snprintf(mailbox, mailboxlen, ",%s,", peer->mailbox);
if (authpeer) {
(*authpeer) = ASTOBJ_REF(peer); /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */
}
if (!ast_strlen_zero(peer->username)) {
ast_string_field_set(p, username, peer->username);
/* Use the default username for authentication on outbound calls */
@@ -7461,7 +7488,7 @@ static int check_user_full(struct sip_pvt *p, struct sip_request *req, int sipme
*/
static int check_user(struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype 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 */
@@ -8554,7 +8581,7 @@ static int sip_show_subscriptions(int fd, int argc, char *argv[])
static int __sip_show_channels(int fd, int argc, char *argv[], int subscriptions)
{
#define FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s\n"
#define FORMAT3 "%-15.15s %-10.10s %-11.11s %-15.15s %-13.13s %-15.15s %-10.10s\n"
#define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-4.4s %-7.7s %-15.15s\n"
#define FORMAT "%-15.15s %-10.10s %-11.11s %5.5d/%5.5d %-4.4s %-3.3s %-3.3s %-15.15s\n"
struct sip_pvt *cur;
@@ -8567,7 +8594,7 @@ static int __sip_show_channels(int fd, int argc, char *argv[], int subscriptions
if (!subscriptions)
ast_cli(fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Seq (Tx/Rx)", "Format", "Hold", "Last Message");
else
ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type");
ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox");
while (cur) {
if (cur->subscribed == NONE && !subscriptions) {
ast_cli(fd, FORMAT, ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr),
@@ -8583,8 +8610,12 @@ static int __sip_show_channels(int fd, int argc, char *argv[], int subscriptions
if (cur->subscribed != NONE && subscriptions) {
ast_cli(fd, FORMAT3, ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr),
ast_strlen_zero(cur->username) ? ( ast_strlen_zero(cur->cid_num) ? "(None)" : cur->cid_num ) : cur->username,
cur->callid, cur->exten, ast_extension_state2str(cur->laststate),
subscription_type2str(cur->subscribed));
cur->callid,
cur->subscribed == MWI_NOTIFICATION ? "--" : cur->exten,
cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate),
subscription_type2str(cur->subscribed),
cur->subscribed == MWI_NOTIFICATION ? (cur->relatedpeer ? cur->relatedpeer->mailbox : "<none>") : "<none>"
);
numchans++;
}
cur = cur->next;
@@ -9964,7 +9995,7 @@ static int handle_response_peerpoke(struct sip_pvt *p, int resp, char *rest, str
if (resp != 100) {
int statechanged = 0;
int newstate = 0;
peer = p->peerpoke;
peer = p->relatedpeer;
gettimeofday(&tv, NULL);
pingtime = ast_tvdiff_ms(tv, peer->ps);
if (pingtime < 1)
@@ -10044,7 +10075,7 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_
gettag(req, "To", tag, sizeof(tag));
ast_string_field_set(p, theirtag, tag);
}
if (p->peerpoke) {
if (p->relatedpeer && p->method == SIP_OPTIONS) {
/* We don't really care what the response is, just that it replied back.
Well, as long as it's not a 100 response... since we might
need to hang around for something more "definitive" */
@@ -10933,6 +10964,10 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req,
int gotdest;
int res = 0;
int firststate = AST_EXTENSION_REMOVED;
struct sip_peer *authpeer = NULL;
char *event = get_header(req, "Event"); /* Get Event package name */
char *accept = get_header(req, "Accept");
char *eventparam;
if (p->initreq.headers) {
/* We already have a dialog */
@@ -10943,9 +10978,11 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req,
/* Do not destroy session, since we will break the call if we do */
ast_log(LOG_DEBUG, "Got a subscription within the context of another call, can't handle that - %s (Method %s)\n", p->callid, sip_methods[p->initreq.method].text);
return 0;
} else {
if (debug)
} else if (debug) {
if (p->subscribed != NONE)
ast_log(LOG_DEBUG, "Got a re-subscribe on existing subscription %s\n", p->callid);
else
ast_log(LOG_DEBUG, "Got a new subscription %s (possibly with auth)\n", p->callid);
}
}
@@ -10958,10 +10995,11 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req,
return 0;
}
if (!ignore && !p->initreq.headers) {
if (!ignore && !p->initreq.headers) { /* Set up dialog, new subscription */
/* Use this as the basis */
if (debug)
ast_verbose("Using latest SUBSCRIBE request as basis request\n");
ast_verbose("Creating new subscription\n");
/* This call is no longer outgoing if it ever was */
ast_clear_flag(&p->flags[0], SIP_OUTGOING);
copy_request(&p->initreq, req);
@@ -10969,28 +11007,14 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req,
} else if (debug && ignore)
ast_verbose("Ignoring this SUBSCRIBE request\n");
if (!p->lastinvite) {
char mailboxbuf[256]="";
char *mailbox = NULL;
int mailboxsize = 0;
char *eventparam;
char *event = get_header(req, "Event"); /* Get Event package name */
char *accept = get_header(req, "Accept");
/* Find parameters to Event: header value and remove them for now */
eventparam = strchr(event, ';');
if (eventparam) {
*eventparam = '\0';
eventparam++;
}
if ((eventparam = strchr(event, ';')))
*eventparam++ = '\0';
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, XMIT_UNRELIABLE, 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"));
@@ -11000,7 +11024,7 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req,
}
/* Check if this user/peer is allowed to subscribe at all */
if (! ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) {
if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) {
transmit_response(p, "403 Forbidden (policy)", req);
ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
return 0;
@@ -11011,12 +11035,14 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req,
ast_string_field_set(p, context, p->subscribecontext);
else if (ast_strlen_zero(p->context))
ast_string_field_set(p, context, default_context);
/* Get destination right away */
gotdest = get_destination(p, NULL);
build_contact(p);
if (gotdest) {
transmit_response(p, "404 Not Found", req);
ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
return 0;
} else {
/* Initialize tag for new subscriptions */
@@ -11044,28 +11070,24 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req,
return 0;
}
} else if (!strcmp(event, "message-summary") && !strcmp(accept, "application/simple-message-summary")) {
/* Looks like they actually want a mailbox status */
/* At this point, we should check if they subscribe to a mailbox that
has the same extension as the peer or the mailbox id. If we configure
the context to be the same as a SIP domain, we could check mailbox
context as well. To be able to securely accept subscribes on mailbox
IDs, not extensions, we need to check the digest auth user to make
sure that the user has access to the mailbox.
Since we do not act on this subscribe anyway, we might as well
accept any authenticated peer with a mailbox definition in their
config section.
/* Looks like they actually want a mailbox status
This version of Asterisk supports mailbox subscriptions
The subscribed URI needs to exist in the dial plan
In most devices, this is configurable to the voicemailmain extension you use
*/
if (!ast_strlen_zero(mailbox)) {
transmit_response(p, "200 OK", req);
if (!authpeer || ast_strlen_zero(authpeer->mailbox)) {
transmit_response(p, "404 Not found (no mailbox)", req);
ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
} else {
transmit_response(p, "404 Not found", req);
ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
}
ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name);
return 0;
}
p->subscribed = MWI_NOTIFICATION;
if (authpeer->mwipvt && authpeer->mwipvt != p) /* Destroy old PVT if this is a new one */
/* We only allow one subscription per peer */
sip_destroy(authpeer->mwipvt);
authpeer->mwipvt = p; /* Link from peer to pvt */
p->relatedpeer = authpeer; /* Link from pvt to peer */
} else { /* At this point, Asterisk does not understand the specified event */
transmit_response(p, "489 Bad Event", req);
if (option_debug > 1)
@@ -11073,10 +11095,9 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req,
ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
return 0;
}
if (p->subscribed != NONE)
if (p->subscribed != MWI_NOTIFICATION)
p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, p);
}
}
if (!ignore && p)
p->lastinvite = seqno;
@@ -11089,15 +11110,27 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req,
if (p->expiry < min_expiry && p->expiry > 0)
p->expiry = min_expiry;
if (sipdebug || option_debug > 1)
if (sipdebug || option_debug > 1) {
if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer)
ast_log(LOG_DEBUG, "Adding subscription for mailbox notification - peer %s Mailbox %s\n", p->relatedpeer->name, p->relatedpeer->mailbox);
else
ast_log(LOG_DEBUG, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username);
}
if (p->autokillid > -1)
sip_cancel_destroy(p); /* Remove subscription expiry for renewals */
if (p->expiry > 0)
sip_scheddestroy(p, (p->expiry + 10) * 1000); /* Set timer for destruction of call at expiration */
if (p->subscribed == MWI_NOTIFICATION) {
transmit_response(p, "200 OK", req);
if (p->relatedpeer) { /* Send first notification */
ASTOBJ_WRLOCK(p->relatedpeer);
sip_send_mwi_to_peer(p->relatedpeer);
ASTOBJ_UNLOCK(p->relatedpeer);
}
} else {
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);
ast_log(LOG_ERROR, "Got SUBSCRIBE for extension 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->flags[0], SIP_NEEDDESTROY);
return 0;
@@ -11134,9 +11167,12 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req,
}
ast_mutex_unlock(&iflock);
}
}
if (!p->expiry)
ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
}
if (authpeer)
ASTOBJ_UNREF(authpeer, sip_destroy_peer);
return 1;
}
@@ -11471,27 +11507,55 @@ static int sip_send_mwi_to_peer(struct sip_peer *peer)
return 0;
}
if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY)))
return -1;
peer->lastmsgssent = ((newmsgs << 8) | (oldmsgs));
if (peer->mwipvt) {
/* Base message on subscription */
p = peer->mwipvt;
} else {
/* Build temporary dialog for this message */
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))
if (ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
memcpy(&p->ourip, &__ourip, sizeof(p->ourip));
build_via(p);
build_callid_pvt(p);
/* Destroy this session after 32 secs */
sip_scheddestroy(p, 32000);
}
/* Send MWI */
ast_set_flag(&p->flags[0], SIP_OUTGOING);
transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten);
sip_scheddestroy(p, 15000);
return 0;
}
/*! \brief Check whether peer needs a new MWI notification check */
static int does_peer_need_mwi(struct sip_peer *peer)
{
time_t t;
if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) &&
!peer->mwipvt) { /* We don't have a subscription */
time(&peer->lastmsgcheck); /* Reset timer */
return FALSE;
}
time(&t);
if (!ast_strlen_zero(peer->mailbox) && ((t - peer->lastmsgcheck) > global_mwitime))
return TRUE;
return FALSE;
}
/*! \brief The SIP monitoring thread
\note This thread monitors all the SIP sessions and peers that needs notification of mwi
(and thus do not have a separate thread) indefinitely
@@ -11594,7 +11658,7 @@ restartsearch:
curpeernum = 0;
peer = NULL;
ASTOBJ_CONTAINER_TRAVERSE(&peerl, !peer, do {
if ((curpeernum > lastpeernum) && !ast_strlen_zero(iterator->mailbox) && ((t - iterator->lastmsgcheck) > global_mwitime)) {
if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) {
fastrestart = TRUE;
lastpeernum = curpeernum;
peer = ASTOBJ_REF(iterator);
@@ -11719,7 +11783,7 @@ static int sip_poke_peer(struct sip_peer *peer)
if (peer->pokeexpire > -1)
ast_sched_del(sched, peer->pokeexpire);
p->peerpoke = peer;
p->relatedpeer = peer;
ast_set_flag(&p->flags[0], SIP_OUTGOING);
#ifdef VOCAL_DATA_HACK
ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username));
@@ -12471,6 +12535,8 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int
ast_copy_string(peer->musicclass, v->value, sizeof(peer->musicclass));
} else if (!strcasecmp(v->name, "mailbox")) {
ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox));
} else if (!strcasecmp(v->name, "subscribemwi")) {
ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY);
} else if (!strcasecmp(v->name, "vmexten")) {
ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten));
} else if (!strcasecmp(v->name, "callgroup")) {

View File

@@ -430,6 +430,8 @@ srvlookup=yes ; Enable DNS SRV lookups on outbound calls
;dtmfmode=inband ; Choices are inband, rfc2833, or info
;defaultip=192.168.0.59 ; IP used until peer registers
;mailbox=1234@context,2345 ; Mailbox(-es) for message waiting indicator
;subscribemwi=yes ; Only send notifications if this phone
; subscribes for mailbox notification
;vmexten=voicemail ; dialplan extension to reach mailbox
; sets the Message-Account in the MWI notify message
; defaults to global vmexten which defaults to "asterisk"