[asterisk-commits] oej: branch oej/codename-pineapple r48189 - in
/team/oej/codename-pineapple: ...
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Fri Dec 1 15:01:56 MST 2006
Author: oej
Date: Fri Dec 1 16:01:56 2006
New Revision: 48189
URL: http://svn.digium.com/view/asterisk?view=rev&rev=48189
Log:
Giving the monitor a new home for Christmas
Added:
team/oej/codename-pineapple/channels/sip3/sip3_monitor.c (with props)
Modified:
team/oej/codename-pineapple/channels/Makefile
team/oej/codename-pineapple/channels/chan_sip.c
team/oej/codename-pineapple/channels/chan_sip3.c
team/oej/codename-pineapple/channels/sip3/Makefile
team/oej/codename-pineapple/channels/sip3/sip3.h
team/oej/codename-pineapple/channels/sip3/sip3_cliami.c
team/oej/codename-pineapple/channels/sip3/sip3_config.c
team/oej/codename-pineapple/channels/sip3/sip3_dialog.c
team/oej/codename-pineapple/channels/sip3/sip3_network.c
team/oej/codename-pineapple/channels/sip3/sip3funcs.h
team/oej/codename-pineapple/main/channel.c
Modified: team/oej/codename-pineapple/channels/Makefile
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/Makefile?view=diff&rev=48189&r1=48188&r2=48189
==============================================================================
--- team/oej/codename-pineapple/channels/Makefile (original)
+++ team/oej/codename-pineapple/channels/Makefile Fri Dec 1 16:01:56 2006
@@ -16,7 +16,7 @@
SIP3_MODULES=chan_sip3.o sip3/sip3_network.o sip3/sip3_subscribe.o sip3/sip3_refer.o sip3/sip3_domain.o \
sip3/sip3_callerid.o sip3/sip3_auth.o sip3/sip3_sdprtp.o sip3/sip3_config.o \
sip3/sip3_cliami.o sip3/sip3_dialog.o sip3/sip3_services.o sip3/sip3_compose.o \
- sip3/sip3_parse.o sip3/sip3_utils.o sip3/sip3_pokedevice.o
+ sip3/sip3_parse.o sip3/sip3_utils.o sip3/sip3_pokedevice.o sip3/sip3_monitor.o
ifeq ($(OSARCH),OpenBSD)
PTLIB=-lpt_OpenBSD_x86_r
Modified: team/oej/codename-pineapple/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/chan_sip.c?view=diff&rev=48189&r1=48188&r2=48189
==============================================================================
--- team/oej/codename-pineapple/channels/chan_sip.c (original)
+++ team/oej/codename-pineapple/channels/chan_sip.c Fri Dec 1 16:01:56 2006
@@ -1333,7 +1333,7 @@
static int sip_do_reload(enum channelreloadreason reason);
static int reload_config(enum channelreloadreason reason);
static int expire_register(void *data);
-static void *do_monitor(void *data);
+static void *do_sip_monitor(void *data);
static int restart_monitor(void);
static int sip_send_mwi_to_peer(struct sip_peer *peer);
static void sip_destroy(struct sip_pvt *p);
@@ -14970,7 +14970,7 @@
\note This thread monitors all the SIP sessions and peers that needs notification of mwi
(and thus do not have a separate thread) indefinitely
*/
-static void *do_monitor(void *data)
+static void *do_sip_monitor(void *data)
{
int res;
struct sip_pvt *sip;
@@ -15091,7 +15091,7 @@
pthread_kill(monitor_thread, SIGURG);
} else {
/* Start a new monitor */
- if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
+ if (ast_pthread_create_background(&monitor_thread, NULL, do_sip_monitor, NULL) < 0) {
ast_mutex_unlock(&monlock);
ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
return -1;
Modified: team/oej/codename-pineapple/channels/chan_sip3.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/chan_sip3.c?view=diff&rev=48189&r1=48188&r2=48189
==============================================================================
--- team/oej/codename-pineapple/channels/chan_sip3.c (original)
+++ team/oej/codename-pineapple/channels/chan_sip3.c Fri Dec 1 16:01:56 2006
@@ -415,18 +415,10 @@
struct sip_globals global;
/* Object counters */
-struct channel_counters sipcounters = { 0, 0, 0, 0, 0, 0, 0};
-
-/*! \brief Protect the monitoring thread, so only one process can kill or start it, and not
- when it's doing something critical. */
-AST_MUTEX_DEFINE_STATIC(monlock);
+struct channel_counters sipcounters = { 0, 0, 0, 0, 0, 0, 0, 0};
/*! \brief Make sure we don't reload twice at the same time */
AST_MUTEX_DEFINE_STATIC(sip_reload_lock);
-
-/*! \brief This is the thread for the monitor which checks for input on the channels
- which are not currently in use. */
-static pthread_t monitor_thread = AST_PTHREADT_NULL;
static int sip_reloading = FALSE; /*!< Flag for avoiding multiple reloads at the same time */
static enum channelreloadreason sip_reloadreason; /*!< Reason for last reload/load of configuration */
@@ -470,8 +462,6 @@
static int transmit_refer(struct sip_dialog *p, const char *dest);
static int transmit_notify_with_mwi(struct sip_dialog *p, int newmsgs, int oldmsgs, char *vmexten);
static void receive_message(struct sip_dialog *p, struct sip_request *req);
-static int sip_send_mwi_to_peer(struct sip_peer *peer);
-static int does_peer_need_mwi(struct sip_peer *peer);
/*--- Dialog management */
static int auto_congest(void *nothing);
@@ -492,11 +482,7 @@
static int check_user(struct sip_dialog *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin);
/*--- Misc functions */
-static int sip_do_reload(enum channelreloadreason reason);
static int sip_sipredirect(struct sip_dialog *p, const char *dest);
-static void *do_monitor(void *data);
-static int restart_monitor(void);
-static int sip_send_mwi_to_peer(struct sip_peer *peer);
static int sip_addrcmp(char *name, struct sockaddr_in *sin); /* Support for peer matching */
/*--- Device monitoring and Device/extension state handling */
@@ -510,7 +496,6 @@
static int function_sipchaninfo_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len);
static int sip_dtmfmode(struct ast_channel *chan, void *data);
static int sip_addheader(struct ast_channel *chan, void *data);
-static int sip_do_reload(enum channelreloadreason reason);
/*--- Debugging
Functions for enabling debug per IP or fully, or enabling history logging for
@@ -1505,7 +1490,6 @@
static int sip_write(struct ast_channel *ast, struct ast_frame *frame)
{
struct sip_dialog *p = ast->tech_pvt;
- struct ast_rtp *mediartp = NULL;
int res = 0;
switch (frame->frametype) {
@@ -6333,7 +6317,7 @@
}
/*! \brief Send message waiting indication to alert peer that they've got voicemail */
-static int sip_send_mwi_to_peer(struct sip_peer *peer)
+GNURK int sip_send_mwi_to_peer(struct sip_peer *peer)
{
/* Called with devicelist lock, but releases it */
struct sip_dialog *p;
@@ -6375,213 +6359,6 @@
/* Send MWI */
ast_set_flag(&p->flags[0], SIP_OUTGOING);
transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten);
- 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 = time(NULL);
-
- if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) &&
- !peer->mwipvt) { /* We don't have a subscription */
- peer->lastmsgcheck = t; /* Reset timer */
- return FALSE;
- }
-
- if (!ast_strlen_zero(peer->mailbox) && (t - peer->lastmsgcheck) > global.mwitime)
- return TRUE;
-
- return FALSE;
-}
-
-
-/*! \brief Check if we need to send RTP keepalive or hangup, due to RTP timers */
-static void check_rtp_timeout(struct sip_dialog *sip, time_t t)
-{
- /* Do we have a channel that is UP and do we handle RTP inside the box? */
- if (!(sip->rtp && sip->owner && (sip->owner->_state == AST_STATE_UP) &&
- !sip->redirip.sin_addr.s_addr) )
- return;
-
- /* Do we need to sent RTP keepalive ? */
- if (sip->lastrtptx && sip->rtpkeepalive &&
- (t > sip->lastrtptx + sip->rtpkeepalive)) {
- /* Need to send an empty RTP packet */
- sip->lastrtptx = time(NULL);
- ast_rtp_sendcng(sip->rtp, 0);
- }
-
- if (sip->lastrtprx && (sip->rtptimeout || sip->rtpholdtimeout) &&
- (t > sip->lastrtprx + sip->rtptimeout)) {
- /* Might be a timeout now -- see if we're on hold */
- struct sockaddr_in sin;
- ast_rtp_get_peer(sip->rtp, &sin);
- if (sin.sin_addr.s_addr ||
- (sip->rtpholdtimeout && (t > sip->lastrtprx + sip->rtpholdtimeout))) {
- /* Needs a hangup */
- if (!sip->rtptimeout)
- return;
- while (sip->owner && ast_channel_trylock(sip->owner)) {
- dialog_lock(sip, FALSE);
- usleep(1);
- dialog_lock(sip, TRUE);
- }
- if (!sip->owner)
- return;
-
- if (ast_rtp_get_bridged(sip->rtp))
- ast_log(LOG_NOTICE, "'%s' will not be disconnected in %ld seconds because it is directly bridged to another RTP stream\n", sip->owner->name, (long) (t - sip->lastrtprx));
- else {
- ast_log(LOG_NOTICE, "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n",
- sip->owner->name,
- (long) (t - sip->lastrtprx));
- /* Issue a softhangup */
- ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV);
- }
- ast_channel_unlock(sip->owner);
- /* forget the timeouts for this call, since a hangup
- has already been requested and we don't want to
- repeatedly request hangups
- */
- sip->rtptimeout = 0;
- sip->rtpholdtimeout = 0;
- }
- }
-}
-
-/*! \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
-*/
-static void *do_monitor(void *data)
-{
- int res;
- struct sip_dialog *sip;
- struct sip_peer *peer = NULL;
- time_t t;
- int fastrestart = FALSE;
- int lastpeernum = -1;
- int curpeernum;
- int reloading;
-
- /* Add an I/O event to our SIP UDP socket */
- if (sipsocket_initialized())
- sipnet.read_id = ast_io_add(io, sipnet.sipsock, sipsock_read, AST_IO_IN, NULL);
-
- /* From here on out, we die whenever asked */
- for(;;) {
- /* Check for a reload request */
- ast_mutex_lock(&sip_reload_lock);
- reloading = sip_reloading;
- sip_reloading = FALSE;
- ast_mutex_unlock(&sip_reload_lock);
- if (reloading) {
- if (option_verbose > 0)
- ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n");
- sip_do_reload(sip_reloadreason);
-
- /* Change the I/O fd of our UDP socket */
- if (sipsocket_initialized())
- sipnet.read_id = ast_io_change(io, sipnet.read_id, sipnet.sipsock, NULL, 0, NULL);
- }
- /* Check for interfaces needing to be killed */
- dialoglist_lock();
-restartsearch:
- t = time(NULL);
- /* don't scan the interface list if it hasn't been a reasonable period
- of time since the last time we did it (when MWI is being sent, we can
- get back to this point every millisecond or less)
- */
- for (sip = dialoglist; !fastrestart && sip; sip = sip->next) {
- dialog_lock(sip, TRUE);
- /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */
- check_rtp_timeout(sip, t);
- /* If we have sessions that needs to be destroyed, do it now */
- if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets &&
- !sip->owner) {
- dialog_lock(sip, FALSE);
- __sip_destroy(sip, TRUE, FALSE);
- goto restartsearch;
- }
- dialog_lock(sip, FALSE);
- }
- dialoglist_unlock();
-
- pthread_testcancel();
- /* Wait for sched or io */
- res = ast_sched_wait(sched);
- if ((res < 0) || (res > 1000))
- res = 1000;
- /* If we might need to send more mailboxes, don't wait long at all.*/
- if (fastrestart)
- res = 1;
- res = ast_io_wait(io, res);
- if (option_debug && res > 20)
- ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res);
- ast_mutex_lock(&monlock);
- if (res >= 0) {
- res = ast_sched_runq(sched);
- if (option_debug && res >= 20)
- ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res);
- }
-
- /* Send MWI notifications to peers - static and cached realtime peers */
- t = time(NULL);
- fastrestart = FALSE;
- curpeernum = 0;
- peer = NULL;
- /* Find next peer that needs mwi */
- ASTOBJ_CONTAINER_TRAVERSE(&devicelist, !peer, do {
- if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) {
- fastrestart = TRUE;
- lastpeernum = curpeernum;
- peer = ASTOBJ_REF(iterator);
- };
- curpeernum++;
- } while (0)
- );
- /* Send MWI to the peer */
- if (peer) {
- ASTOBJ_WRLOCK(peer);
- sip_send_mwi_to_peer(peer);
- ASTOBJ_UNLOCK(peer);
- ASTOBJ_UNREF(peer,sip_destroy_device);
- } else {
- /* Reset where we come from */
- lastpeernum = -1;
- }
- ast_mutex_unlock(&monlock);
- }
- /* Never reached */
- return NULL;
-
-}
-
-/*! \brief Start the channel monitor thread */
-static int restart_monitor(void)
-{
- /* If we're supposed to be stopped -- stay stopped */
- if (monitor_thread == AST_PTHREADT_STOP)
- return 0;
- ast_mutex_lock(&monlock);
- if (monitor_thread == pthread_self()) {
- ast_mutex_unlock(&monlock);
- ast_log(LOG_WARNING, "Cannot kill myself\n");
- return -1;
- }
- if (monitor_thread != AST_PTHREADT_NULL) {
- /* Wake up the thread */
- pthread_kill(monitor_thread, SIGURG);
- } else {
- /* Start a new monitor */
- if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
- ast_mutex_unlock(&monlock);
- ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
- return -1;
- }
- }
- ast_mutex_unlock(&monlock);
return 0;
}
@@ -6740,7 +6517,7 @@
if (!tmpc)
sip_destroy(p);
ast_update_use_count();
- restart_monitor();
+ restart_monitor(); /* Make sure we have monitor up and running */
return tmpc;
}
@@ -7000,7 +6777,7 @@
}
/*! \brief Reload module */
-GNURK int sip_do_reload(enum channelreloadreason reason)
+GNURK int sip_do_reload()
{
if (option_debug > 3)
ast_log(LOG_DEBUG, "--------------- SIP reload started\n");
@@ -7027,7 +6804,7 @@
if (option_debug > 3)
ast_log(LOG_DEBUG, "--------------- Done destroying registry list\n");
ASTOBJ_CONTAINER_MARKALL(&devicelist);
- reload_config(reason);
+ reload_config(sip_reloadreason);
/* Prune peers who still are supposed to be deleted */
ASTOBJ_CONTAINER_PRUNE_MARKED(&devicelist, sip_destroy_device);
@@ -7045,6 +6822,20 @@
return 0;
}
+
+
+/*! Check for a reload request */
+int sip_reload_check()
+{
+ int reloading;
+
+ ast_mutex_lock(&sip_reload_lock);
+ reloading = sip_reloading;
+ ast_mutex_unlock(&sip_reload_lock);
+ sip_reloading = FALSE;
+ return reloading;
+}
+
/*! \brief Force reload of module from cli */
GNURK int sip_reload(int fd)
@@ -7061,7 +6852,7 @@
sip_reloadreason = CHANNEL_MODULE_RELOAD;
}
ast_mutex_unlock(&sip_reload_lock);
- restart_monitor();
+ restart_monitor(); /* Time to wake up our monitor thread */
return 0;
}
@@ -7136,7 +6927,8 @@
logdebug(4, "SIP3 :: Scheduled registration of services\n");
/* And start the monitor for the first time */
- restart_monitor();
+ restart_monitor();
+
logdebug(4, "SIP3 :: Monitor started. Ready for rock'n'roll! ---------------------------\n");
return AST_MODULE_LOAD_SUCCESS;
@@ -7172,14 +6964,7 @@
dialoglist_unlock();
/* Kill the monitor thread */
- ast_mutex_lock(&monlock);
- if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP)) {
- pthread_cancel(monitor_thread);
- pthread_kill(monitor_thread, SIGURG);
- pthread_join(monitor_thread, NULL);
- }
- monitor_thread = AST_PTHREADT_STOP;
- ast_mutex_unlock(&monlock);
+ kill_monitor();
/* Destroy all the dialogs and free their memory */
dialoglist_lock();
Modified: team/oej/codename-pineapple/channels/sip3/Makefile
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/Makefile?view=diff&rev=48189&r1=48188&r2=48189
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/Makefile (original)
+++ team/oej/codename-pineapple/channels/sip3/Makefile Fri Dec 1 16:01:56 2006
@@ -3,7 +3,7 @@
#
all: sip3_refer.o sip3_subscribe.o sip3_network.o sip3_domain.o sip3_callerid.o sip3_auth.o \
sip3_sdprtp.o sip3_config.o sip3_cliami.o sip3_dialog.o sip3_services.o \
- sip3_compose.o sip3_parse.o sip3_utils.o sip3_pokedevice.o
+ sip3_compose.o sip3_parse.o sip3_utils.o sip3_pokedevice.o sip3_monitor.o
%.o: %.c sip3funcs.h sip3.h
$(CC) $(CFLAGS) -c -o $@ $<
Modified: team/oej/codename-pineapple/channels/sip3/sip3.h
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3.h?view=diff&rev=48189&r1=48188&r2=48189
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3.h (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3.h Fri Dec 1 16:01:56 2006
@@ -1038,20 +1038,24 @@
int autocreated_peers;
int registry_objects;
int dialog_objects;
-};
-
-extern struct sip_network sipnet; /*!< Sockets and networking */
-extern struct expiry_times expiry; /*!< Various expiration times */
-extern struct ast_config *notify_types; /*!< Notification types */
-extern const char notify_config[]; /*!< Configuration file for notifications */
-extern const struct cfsip_methods sip_methods[]; /*!< sip3_parse.c: SIP method table */
-extern struct sip_globals global; /* Defined in chan_sip3.c */
-extern struct sched_context *sched; /*!< The scheduling context */
-extern struct io_context *io; /*!< The IO context */
+ int peers_with_mwi;
+};
+
+/*! @name External objects */
+/*! @{ */
+extern struct sip_network sipnet; /*!< Sockets and networking */
+extern struct expiry_times expiry; /*!< Various expiration times */
+extern struct ast_config *notify_types; /*!< Notification types */
+extern const char notify_config[]; /*!< Configuration file for notifications */
+extern const struct cfsip_methods sip_methods[]; /*!< sip3_parse.c: SIP method table */
+extern struct sip_globals global; /* Defined in chan_sip3.c */
+extern struct sched_context *sched; /*!< The scheduling context */
+extern struct io_context *io; /*!< The IO context */
extern struct channel_counters sipcounters; /*!< Various object counters */
extern struct sip_device_list devicelist; /*!< Device list */
extern struct sip_register_list regl; /*!< Registration list */
extern struct sip_auth *authl; /*!< Realm authentications */
extern struct sip_dialog *dialoglist;
+/*! @} */
#endif
Modified: team/oej/codename-pineapple/channels/sip3/sip3_cliami.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3_cliami.c?view=diff&rev=48189&r1=48188&r2=48189
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_cliami.c (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3_cliami.c Fri Dec 1 16:01:56 2006
@@ -982,6 +982,7 @@
else
ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox");
for (; cur; cur = cur->next) {
+ dialoglist_unlock();
referstatus = "";
if (cur->refer) { /* SIP transfer in progress */
referstatus = referstatus2str(cur->refer->status);
@@ -1011,6 +1012,7 @@
);
numchans++;
}
+ dialoglist_lock();
}
dialoglist_unlock();
if (!subscriptions)
Modified: team/oej/codename-pineapple/channels/sip3/sip3_config.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3_config.c?view=diff&rev=48189&r1=48188&r2=48189
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_config.c (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3_config.c Fri Dec 1 16:01:56 2006
@@ -481,6 +481,7 @@
ast_copy_string(device->mohsuggest, v->value, sizeof(device->mohsuggest));
} else if (!strcasecmp(v->name, "mailbox")) {
ast_copy_string(device->mailbox, v->value, sizeof(device->mailbox));
+ sipcounters.peers_with_mwi++;
} else if (!strcasecmp(v->name, "subscribemwi")) {
ast_set2_flag(&device->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY);
} else if (!strcasecmp(v->name, "vmexten")) {
@@ -709,6 +710,7 @@
global->relaxdtmf = FALSE;
global->callevents = FALSE;
global->t1min = DEFAULT_T1MIN;
+ sipcounters.peers_with_mwi = 0; /* Reset counter for mwi peers */
}
/*! \brief Re-read SIP.conf config file
Modified: team/oej/codename-pineapple/channels/sip3/sip3_dialog.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3_dialog.c?view=diff&rev=48189&r1=48188&r2=48189
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_dialog.c (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3_dialog.c Fri Dec 1 16:01:56 2006
@@ -123,7 +123,13 @@
/*! \brief Lock list of active SIP dialogs */
void dialoglist_lock(void)
{
- ast_mutex_lock(&dialoglock);
+ int counter = 0;
+ while (ast_mutex_trylock(&dialoglock) && counter < 100) {
+ if (option_debug > 4)
+ ast_log(LOG_DEBUG, "---Trying to lock dialoglist -- %d \n", ++counter);
+ }
+ if (counter == 100)
+ ast_mutex_lock(&dialoglock);
if (sipdebug && option_debug > 4)
ast_log(LOG_DEBUG, "=== SIP dialog list: LOCKED\n");
}
@@ -227,8 +233,6 @@
void __sip_ack(struct sip_dialog *dialog, int seqno, int resp, int sipmethod, int reset)
{
struct sip_request *cur, *prev = NULL;
-
- /* Just in case... */
int res = FALSE;
dialog_lock(dialog, TRUE);
@@ -1002,7 +1006,6 @@
ast_log(LOG_DEBUG, "= Looking for Call ID: %s (Checking %s) --From tag %s --To-tag %s \n", req->callid, req->method==SIP_RESPONSE ? "To" : "From", fromtag, totag);
find_via_branch(req, branch, sizeof(branch));
- dialoglist_lock();
for (cur = dialoglist; cur; cur = cur->next) {
/* we do not want packets with bad syntax to be connected to a PVT */
int found = FALSE;
Added: team/oej/codename-pineapple/channels/sip3/sip3_monitor.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3_monitor.c?view=auto&rev=48189
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_monitor.c (added)
+++ team/oej/codename-pineapple/channels/sip3/sip3_monitor.c Fri Dec 1 16:01:56 2006
@@ -1,0 +1,343 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2006, Digium, Inc.
+ * and Edvina AB, Sollentuna, Sweden (chan_sip3 changes/additions)
+ *
+ * Mark Spencer <markster at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file
+ * \brief The SIP monitor thread
+ * Version 3 of chan_sip
+ *
+ * \author Mark Spencer <markster at digium.com>
+ * \author Olle E. Johansson <oej at edvina.net> (all the chan_sip3 changes)
+ *
+ * See Also:
+ * \arg \ref AstCREDITS
+ *
+ */
+
+/*! \page SIP3_monitor Chan_sip3:: The monitor thread
+ *
+ * The monitor thread is a background process that takes care of maintenance of the
+ * SIP channel
+ * - Destruction of SIP dialogs at timeout
+ * - Scheduled items, like retransmits, registrations that expire etc
+ * - Voicemail notifications
+*/
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision: 47624 $")
+
+#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/lock.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/acl.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"
+
+/*! \brief This is the thread for the monitor which checks for input on the channels
+ which are not currently in use. */
+static pthread_t monitor_thread = AST_PTHREADT_NULL;
+
+
+/*! \brief Protect the monitoring thread, so only one process can kill or start it, and not
+ when it's doing something critical. */
+AST_MUTEX_DEFINE_STATIC(monlock);
+
+/*! \brief kill monitor thread (only at module unload) */
+void kill_monitor(void)
+{
+ /* Kill the monitor thread */
+ ast_mutex_lock(&monlock);
+ if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP)) {
+ pthread_cancel(monitor_thread);
+ pthread_kill(monitor_thread, SIGURG);
+ pthread_join(monitor_thread, NULL);
+ }
+ monitor_thread = AST_PTHREADT_STOP;
+ ast_mutex_unlock(&monlock);
+}
+
+
+/*! \brief Start the channel monitor thread */
+int restart_monitor(void)
+{
+ /* If we're supposed to be stopped -- stay stopped */
+ if (monitor_thread == AST_PTHREADT_STOP)
+ return 0;
+ /* Lock the monitor lock to keep the new monitor thread under control */
+ ast_mutex_lock(&monlock);
+ if (monitor_thread == pthread_self()) {
+ ast_mutex_unlock(&monlock);
+ ast_log(LOG_WARNING, "Cannot kill myself\n");
+ return -1;
+ }
+ if (monitor_thread != AST_PTHREADT_NULL) {
+ /* Wake up the thread */
+ pthread_kill(monitor_thread, SIGURG);
+ } else {
+ /* Start a new monitor */
+ if (ast_pthread_create_background(&monitor_thread, NULL, do_sip_monitor, NULL) < 0) {
+ ast_mutex_unlock(&monlock);
+ ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
+ return -1;
+ }
+ }
+
+ /* Let the monitor run by itself now */
+ ast_mutex_unlock(&monlock);
+ return 0;
+}
+
+
+/*! \brief Check if we need to send RTP keepalive or hangup, due to RTP timers */
+static void check_rtp_timeout(struct sip_dialog *sip, time_t t)
+{
+ /* Do we have a channel that is UP and do we handle RTP inside the box? */
+ if (!(sip->rtp && sip->owner && (sip->owner->_state == AST_STATE_UP) &&
+ !sip->redirip.sin_addr.s_addr) )
+ return;
+
+ /* Do we need to sent RTP keepalive ? */
+ if (sip->lastrtptx && sip->rtpkeepalive &&
+ (t > sip->lastrtptx + sip->rtpkeepalive)) {
+ /* Need to send an empty RTP packet */
+ sip->lastrtptx = time(NULL);
+ ast_rtp_sendcng(sip->rtp, 0);
+ }
+
+ if (sip->lastrtprx && (sip->rtptimeout || sip->rtpholdtimeout) &&
+ (t > sip->lastrtprx + sip->rtptimeout)) {
+ /* Might be a timeout now -- see if we're on hold */
+ struct sockaddr_in sin;
+ ast_rtp_get_peer(sip->rtp, &sin);
+ if (sin.sin_addr.s_addr ||
+ (sip->rtpholdtimeout && (t > sip->lastrtprx + sip->rtpholdtimeout))) {
+ /* Needs a hangup */
+ if (!sip->rtptimeout)
+ return;
+ while (sip->owner && ast_channel_trylock(sip->owner)) {
+ dialog_lock(sip, FALSE);
+ usleep(1);
+ dialog_lock(sip, TRUE);
+ }
+ if (!sip->owner)
+ return;
+
+ if (ast_rtp_get_bridged(sip->rtp))
+ ast_log(LOG_NOTICE, "'%s' will not be disconnected in %ld seconds because it is directly bridged to another RTP stream\n", sip->owner->name, (long) (t - sip->lastrtprx));
+ else {
+ ast_log(LOG_NOTICE, "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n",
+ sip->owner->name,
+ (long) (t - sip->lastrtprx));
+ /* Issue a softhangup */
+ ast_softhangup_nolock(sip->owner, AST_SOFTHANGUP_DEV);
+ }
+ ast_channel_unlock(sip->owner);
+ /* forget the timeouts for this call, since a hangup
+ has already been requested and we don't want to
+ repeatedly request hangups
+ */
+ sip->rtptimeout = 0;
+ sip->rtpholdtimeout = 0;
+ }
+ }
+}
+
+/*! \brief Check whether peer needs a new MWI notification check */
+static int does_peer_need_mwi(struct sip_peer *peer)
+{
+ time_t t = time(NULL);
+
+ if (ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) &&
+ !peer->mwipvt) { /* We don't have a subscription */
+ peer->lastmsgcheck = t; /* Reset timer */
+ return FALSE;
+ }
+
+ 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
+*/
+void *do_sip_monitor(void *data)
+{
+ int res;
+ struct sip_dialog *sip;
+ struct sip_peer *peer = NULL;
+ time_t t;
+ int fastrestart = FALSE;
+ int lastpeernum = -1;
+ int curpeernum;
+ int reloading;
+
+ /* Add an I/O event to our SIP UDP socket */
+ if (sipsocket_initialized())
+ sipnet.read_id = ast_io_add(io, sipnet.sipsock, sipsock_read, AST_IO_IN, NULL);
+
+ /* From here on out, we die whenever asked */
+ for(;;) {
+ /*------ Check for a reload request */
+ if (sip_reload_check()) {
+ if (option_verbose > 0)
+ ast_verbose(VERBOSE_PREFIX_1 "Reloading SIP\n");
+ sip_do_reload();
+
+ /* Change the I/O fd of our UDP socket */
+ if (sipsocket_initialized())
+ sipnet.read_id = ast_io_change(io, sipnet.read_id, sipnet.sipsock, NULL, 0, NULL);
+ }
+
+ /*----- Check for interfaces needing to be killed */
+ if (dialoglist != NULL) {
+ ast_log(LOG_DEBUG, ":: MONITOR :: Walking dialog list.\n");
+ dialoglist_lock();
+restartsearch:
+ t = time(NULL);
+ /* don't scan the interface list if it hasn't been a reasonable period
+ of time since the last time we did it (when MWI is being sent, we can
+ get back to this point every millisecond or less)
+ */
+ for (sip = dialoglist; !fastrestart && sip; sip = sip->next) {
+ dialog_lock(sip, TRUE);
+ /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP or RTCP */
+ check_rtp_timeout(sip, t);
+ /* If we have sessions that needs to be destroyed, do it now */
+ if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets && !sip->owner) {
+ dialog_lock(sip, FALSE);
+ __sip_destroy(sip, TRUE, FALSE);
+ goto restartsearch;
+ }
+ dialog_lock(sip, FALSE);
+ }
+ dialoglist_unlock();
+ } else if (sipdebug && option_debug > 4) {
+ ast_log(LOG_DEBUG, ":: MONITOR :: Empty dialog list. No walk today \n");
+ }
+
+ pthread_testcancel();
+
+ /*------ Wait for sched or io */
+ res = ast_sched_wait(sched);
+
+ if ((res < 0) || (res > 1000))
+ res = 1000;
+ /* If we might need to send more mailboxes, don't wait long at all.*/
+ if (fastrestart)
+ res = 1;
+
+ res = ast_io_wait(io, res);
+ if (option_debug && res > 20)
+ ast_log(LOG_DEBUG, "chan_sip: ast_io_wait ran %d all at once\n", res);
+ ast_mutex_lock(&monlock);
+ if (res >= 0) {
+ res = ast_sched_runq(sched); /* Check for scheduled items, like retransmits */
+ if (option_debug && res >= 20)
+ ast_log(LOG_DEBUG, "chan_sip: ast_sched_runq ran %d all at once\n", res);
+ }
+
+ /*----- Send MWI notifications to peers - static and cached realtime peers */
+ if (sipcounters.peers_with_mwi > 0 ) {
+ t = time(NULL);
+ fastrestart = FALSE;
+ curpeernum = 0;
+ peer = NULL;
+ /* Find next peer that needs mwi */
+ ASTOBJ_CONTAINER_TRAVERSE(&devicelist, !peer, do {
+ if ((curpeernum > lastpeernum) && does_peer_need_mwi(iterator)) {
+ fastrestart = TRUE;
+ lastpeernum = curpeernum;
+ peer = ASTOBJ_REF(iterator);
+ };
+ curpeernum++;
+ } while (0)
+ );
+ /* Send MWI to the peer */
+ if (peer) {
+ ASTOBJ_WRLOCK(peer);
+ sip_send_mwi_to_peer(peer);
+ ASTOBJ_UNLOCK(peer);
+ ASTOBJ_UNREF(peer,sip_destroy_device);
+ } else {
+ /* Reset where we come from */
+ lastpeernum = -1;
+ }
+ }
+ ast_mutex_unlock(&monlock);
+ }
+ /* Never reached */
+ return NULL;
+
+}
+
Propchange: team/oej/codename-pineapple/channels/sip3/sip3_monitor.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/oej/codename-pineapple/channels/sip3/sip3_monitor.c
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Propchange: team/oej/codename-pineapple/channels/sip3/sip3_monitor.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: team/oej/codename-pineapple/channels/sip3/sip3_network.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3_network.c?view=diff&rev=48189&r1=48188&r2=48189
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_network.c (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3_network.c Fri Dec 1 16:01:56 2006
@@ -346,6 +346,10 @@
struct sip_request *pkt = data, *prev, *cur = NULL;
int reschedule = DEFAULT_RETRANS;
+ if (!pkt->dialog) {
+ ast_log(LOG_WARNING, "Trying to retransmit packet without dialog owner... id #%d:%s (Method %d) (No timer T1)\n", pkt->retransid, sip_method2txt(pkt->method), pkt->method);
+ return 0;
+ }
/* Lock channel PVT */
dialog_lock(pkt->dialog, TRUE);
@@ -431,6 +435,8 @@
else
pkt->dialog->packets = cur->next;
dialog_lock(pkt->dialog, FALSE);
+ if (option_debug > 3)
+ ast_log(LOG_DEBUG, "Deleting packet from dialog list...%s\n", pkt->dialog->callid);
free(cur);
pkt = NULL;
} else
Modified: team/oej/codename-pineapple/channels/sip3/sip3funcs.h
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3funcs.h?view=diff&rev=48189&r1=48188&r2=48189
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3funcs.h (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3funcs.h Fri Dec 1 16:01:56 2006
@@ -55,7 +55,7 @@
GNURK void destroy_association(struct sip_peer *peer);
GNURK void reg_source_db(struct sip_peer *peer);
GNURK int expire_register(void *data);
-GNURK int sip_do_relaod(enum channelreloadreason reason);
+GNURK int sip_do_reload(void);
GNURK void parse_request(struct sip_request *req);
GNURK int transmit_response(struct sip_dialog *p, const char *msg, const struct sip_request *req);
GNURK void parse_copy(struct sip_request *dst, const struct sip_request *src);
@@ -80,6 +80,8 @@
GNURK void free_old_route(struct sip_route *route);
GNURK void find_via_branch(struct sip_request *req, char *viabuf, size_t vialen);
GNURK int update_call_counter(struct sip_dialog *fup, int event);
+GNURK int sip_reload_check(void);
+GNURK int sip_send_mwi_to_peer(struct sip_peer *peer);
/*! sip3_refer.c */
GNURK const char *referstatus2str(enum referstatus rstatus) attribute_pure;
@@ -251,5 +253,9 @@
int sip_poke_peer(struct sip_peer *peer);
void handle_response_peerpoke(struct sip_dialog *p, int resp, struct sip_request *req);
+/* sip3_monitor.c - the monitor thread */
+void *do_sip_monitor(void *data);
+void kill_monitor(void);
+int restart_monitor(void);
#endif
Modified: team/oej/codename-pineapple/main/channel.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/main/channel.c?view=diff&rev=48189&r1=48188&r2=48189
==============================================================================
--- team/oej/codename-pineapple/main/channel.c (original)
+++ team/oej/codename-pineapple/main/channel.c Fri Dec 1 16:01:56 2006
@@ -4593,9 +4593,9 @@
if (option_debug)
ast_log(LOG_DEBUG, "::::==== Channel %s was locked\n", chan->name);
if (res == EDEADLK) {
- /* We had no lock, so okey any way */
- if (option_debug > 3)
- ast_log(LOG_DEBUG, "::::==== Channel %s was not locked by us. Lock would cause deadlock.\n", chan->name);
+ /* We had no lock, so okey any way */
+ if (option_debug > 3)
+ ast_log(LOG_DEBUG, "::::==== Channel %s was not locked by us. Lock would cause deadlock.\n", chan->name);
}
if (res == EINVAL) {
if (option_debug > 3)
More information about the asterisk-commits
mailing list