Merged revisions 41768,41827,41830,41880,41882,41989,42014,42054 via svnmerge from

https://origsvn.digium.com/svn/asterisk/branches/1.2

........
r41768 | file | 2006-09-01 18:49:07 -0400 (Fri, 01 Sep 2006) | 2 lines

Only wipe the redirected audio & video IP/port if it's specified, and trigger a reinvite.

........
r41827 | bweschke | 2006-09-03 10:16:08 -0400 (Sun, 03 Sep 2006) | 3 lines

 Setting a retry of 0 is generally not a good idea and shouldn't be allowed. (#7574 - reported by regin)


........
r41830 | bweschke | 2006-09-03 10:50:59 -0400 (Sun, 03 Sep 2006) | 3 lines

 Let's NOT spy on Zap/psuedo channels, mmmmmmmmk? 


........
r41880 | bweschke | 2006-09-03 13:13:38 -0400 (Sun, 03 Sep 2006) | 3 lines

 Don't keep trying the same member in certain strategies when members of the queue are unavailable (#7278 - diLLec reported and patched) - This should have been patched here first and then merged into /trunk. My bad!


........
r41882 | bweschke | 2006-09-03 13:38:22 -0400 (Sun, 03 Sep 2006) | 3 lines

 Make sure the forwarded channel inherits variables appropriately when we receive a call forward in the queue. (#7867 - raarts reported and patched)


........
r41989 | oej | 2006-09-04 11:46:07 -0400 (Mon, 04 Sep 2006) | 2 lines

Don't kill the pvt before we have sent ACK on CANCEL (needs more testing before making a release)

........
r42014 | qwell | 2006-09-05 12:27:46 -0400 (Tue, 05 Sep 2006) | 4 lines

Small typo in zapata.conf.sample

Reported by ppyy in 7881

........
r42054 | file | 2006-09-05 16:02:48 -0400 (Tue, 05 Sep 2006) | 2 lines

Merge in last round of spy fixes. This should hopefully eliminate all the issues people have been seeing by distinctly separating what each component (core/spy) is responsible for. Core is responsible for adding a spy to a channel, feeding frames to the spy, removing the spy from a channel, and telling the spy to stop. Spy is responsible for reading frames in, and cleaning up after itself.

........


git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.2-netsec@42081 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.2-netsec
Joshua Colp 19 years ago
parent e9cce1551a
commit 6480d28862

@ -131,7 +131,7 @@ static struct ast_channel *local_get_channel_begin_name(char *name)
ast_mutex_lock(&modlock);
chan = local_channel_walk(NULL);
while (chan) {
if (!strncmp(chan->name, name, strlen(name))) {
if (!strncmp(chan->name, name, strlen(name)) && strncmp(chan->name, "Zap/pseudo", 10)) {
ret = chan;
break;
}
@ -207,21 +207,6 @@ static int start_spying(struct ast_channel *chan, struct ast_channel *spychan, s
return res;
}
static void stop_spying(struct ast_channel *chan, struct ast_channel_spy *spy)
{
/* If our status has changed to DONE, then the channel we're spying on is gone....
DON'T TOUCH IT!!! RUN AWAY!!! */
if (spy->status == CHANSPY_DONE)
return;
if (!chan)
return;
ast_mutex_lock(&chan->lock);
ast_channel_spy_remove(chan, spy);
ast_mutex_unlock(&chan->lock);
};
/* Map 'volume' levels from -4 through +4 into
decibel (dB) settings for channel drivers
*/
@ -338,7 +323,13 @@ static int channel_spy(struct ast_channel *chan, struct ast_channel *spyee, int
}
}
ast_deactivate_generator(chan);
stop_spying(spyee, &csth.spy);
if (csth.spy.chan) {
csth.spy.status = CHANSPY_DONE;
ast_mutex_lock(&csth.spy.chan->lock);
ast_channel_spy_remove(csth.spy.chan, &csth.spy);
ast_mutex_unlock(&csth.spy.chan->lock);
}
if (option_verbose >= 2) {
ast_verbose(VERBOSE_PREFIX_2 "Done Spying on channel %s\n", name);
@ -347,7 +338,7 @@ static int channel_spy(struct ast_channel *chan, struct ast_channel *spyee, int
running = 0;
}
ast_mutex_destroy(&csth.spy.lock);
ast_channel_spy_free(&csth.spy);
return running;
}

@ -109,23 +109,6 @@ AST_APP_OPTIONS(mixmonitor_opts, {
AST_APP_OPTION_ARG('W', MUXFLAG_VOLUME, OPT_ARG_VOLUME),
});
static void stopmon(struct ast_channel_spy *spy)
{
struct ast_channel *chan = spy->chan;
/* If our status has changed to DONE, then the channel we're spying on is gone....
DON'T TOUCH IT!!! RUN AWAY!!! */
if (spy->status == CHANSPY_DONE)
return;
if (!chan)
return;
ast_mutex_lock(&chan->lock);
ast_channel_spy_remove(chan, spy);
ast_mutex_unlock(&chan->lock);
}
static int startmon(struct ast_channel *chan, struct ast_channel_spy *spy)
{
struct ast_channel *peer;
@ -164,9 +147,8 @@ static void *mixmonitor_thread(void *obj)
ast_channel_spy_trigger_wait(&mixmonitor->spy);
if (!mixmonitor->spy.chan || mixmonitor->spy.status != CHANSPY_RUNNING) {
if (!mixmonitor->spy.chan || mixmonitor->spy.status != CHANSPY_RUNNING)
break;
}
while (1) {
if (!(f = ast_channel_spy_read_frame(&mixmonitor->spy, SAMPLES_PER_FRAME)))
@ -189,7 +171,7 @@ static void *mixmonitor_thread(void *obj)
ast_mutex_unlock(&mixmonitor->spy.lock);
stopmon(&mixmonitor->spy);
ast_channel_spy_free(&mixmonitor->spy);
if (option_verbose > 1)
ast_verbose(VERBOSE_PREFIX_2 "End MixMonitor Recording %s\n", mixmonitor->name);
@ -200,8 +182,6 @@ static void *mixmonitor_thread(void *obj)
ast_safe_system(mixmonitor->post_process);
}
ast_mutex_destroy(&mixmonitor->spy.lock);
ast_closestream(mixmonitor->fs);
free(mixmonitor);

@ -777,7 +777,7 @@ static void queue_set_param(struct call_queue *q, const char *param, const char
q->periodicannouncefrequency = atoi(val);
} else if (!strcasecmp(param, "retry")) {
q->retry = atoi(val);
if (q->retry < 0)
if (q->retry <= 0)
q->retry = DEFAULT_RETRY;
} else if (!strcasecmp(param, "wrapuptime")) {
q->wrapuptime = atoi(val);
@ -1518,6 +1518,11 @@ static int ring_entry(struct queue_ent *qe, struct localuser *tmp, int *busies)
ast_cdr_busy(qe->chan->cdr);
tmp->stillgoing = 0;
update_dial_status(qe->parent, tmp->member, status);
ast_mutex_lock(&qe->parent->lock);
qe->parent->rrpos++;
ast_mutex_unlock(&qe->parent->lock);
(*busies)++;
return 0;
} else if (status != tmp->oldstatus)
@ -1824,6 +1829,7 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser
o->stillgoing = 0;
numnochan++;
} else {
ast_channel_inherit_variables(in, o->chan);
if (o->chan->cid.cid_num)
free(o->chan->cid.cid_num);
o->chan->cid.cid_num = NULL;

@ -1017,22 +1017,59 @@ int ast_channel_spy_add(struct ast_channel *chan, struct ast_channel_spy *spy)
return 0;
}
/* Clean up a channel's spy information */
static void spy_cleanup(struct ast_channel *chan)
{
if (AST_LIST_EMPTY(&chan->spies->list))
return;
if (chan->spies->read_translator.path)
ast_translator_free_path(chan->spies->read_translator.path);
if (chan->spies->write_translator.path)
ast_translator_free_path(chan->spies->write_translator.path);
free(chan->spies);
chan->spies = NULL;
return;
}
/* Detach a spy from it's channel */
static void spy_detach(struct ast_channel_spy *spy, struct ast_channel *chan)
{
ast_mutex_lock(&spy->lock);
/* We only need to poke them if they aren't already done */
if (spy->status != CHANSPY_DONE) {
spy->status = CHANSPY_STOP;
spy->chan = NULL;
if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE)
ast_cond_signal(&spy->trigger);
}
/* Print it out while we still have a lock so the structure can't go away (if signalled above) */
ast_log(LOG_DEBUG, "Spy %s removed from channel %s\n", spy->type, chan->name);
ast_mutex_unlock(&spy->lock);
return;
}
void ast_channel_spy_stop_by_type(struct ast_channel *chan, const char *type)
{
struct ast_channel_spy *spy;
struct ast_channel_spy *spy = NULL;
if (!chan->spies)
return;
AST_LIST_TRAVERSE(&chan->spies->list, spy, list) {
AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->spies->list, spy, list) {
ast_mutex_lock(&spy->lock);
if ((spy->type == type) && (spy->status == CHANSPY_RUNNING)) {
spy->status = CHANSPY_STOP;
if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE)
ast_cond_signal(&spy->trigger);
}
ast_mutex_unlock(&spy->lock);
ast_mutex_unlock(&spy->lock);
AST_LIST_REMOVE_CURRENT(&chan->spies->list, list);
spy_detach(spy, chan);
} else
ast_mutex_unlock(&spy->lock);
}
AST_LIST_TRAVERSE_SAFE_END
spy_cleanup(chan);
}
void ast_channel_spy_trigger_wait(struct ast_channel_spy *spy)
@ -1049,65 +1086,59 @@ void ast_channel_spy_trigger_wait(struct ast_channel_spy *spy)
void ast_channel_spy_remove(struct ast_channel *chan, struct ast_channel_spy *spy)
{
struct ast_frame *f;
if (!chan->spies)
return;
AST_LIST_REMOVE(&chan->spies->list, spy, list);
ast_mutex_lock(&spy->lock);
spy_detach(spy, chan);
spy_cleanup(chan);
}
spy->chan = NULL;
void ast_channel_spy_free(struct ast_channel_spy *spy)
{
struct ast_frame *f = NULL;
for (f = spy->read_queue.head; f; f = spy->read_queue.head) {
spy->read_queue.head = f->next;
ast_frfree(f);
}
if (spy->status == CHANSPY_DONE)
return;
/* Switch status to done in case we get called twice */
spy->status = CHANSPY_DONE;
/* Drop any frames in the queue */
for (f = spy->write_queue.head; f; f = spy->write_queue.head) {
spy->write_queue.head = f->next;
ast_frfree(f);
}
for (f = spy->read_queue.head; f; f= spy->read_queue.head) {
spy->read_queue.head = f->next;
ast_frfree(f);
}
/* Destroy the condition if in use */
if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE)
ast_cond_destroy(&spy->trigger);
ast_mutex_unlock(&spy->lock);
ast_log(LOG_DEBUG, "Spy %s removed from channel %s\n",
spy->type, chan->name);
/* Destroy our mutex since it is no longer in use */
ast_mutex_destroy(&spy->lock);
if (AST_LIST_EMPTY(&chan->spies->list)) {
if (chan->spies->read_translator.path)
ast_translator_free_path(chan->spies->read_translator.path);
if (chan->spies->write_translator.path)
ast_translator_free_path(chan->spies->write_translator.path);
free(chan->spies);
chan->spies = NULL;
}
return;
}
static void detach_spies(struct ast_channel *chan)
{
struct ast_channel_spy *spy;
struct ast_channel_spy *spy = NULL;
if (!chan->spies)
return;
/* Marking the spies as done is sufficient. Chanspy or spy users will get the picture. */
AST_LIST_TRAVERSE(&chan->spies->list, spy, list) {
ast_mutex_lock(&spy->lock);
spy->chan = NULL;
if (spy->status == CHANSPY_RUNNING)
spy->status = CHANSPY_DONE;
if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE)
ast_cond_signal(&spy->trigger);
ast_mutex_unlock(&spy->lock);
AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->spies->list, spy, list) {
AST_LIST_REMOVE_CURRENT(&chan->spies->list, list);
spy_detach(spy, chan);
}
AST_LIST_TRAVERSE_SAFE_END
AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->spies->list, spy, list)
ast_channel_spy_remove(chan, spy);
AST_LIST_TRAVERSE_SAFE_END;
spy_cleanup(chan);
}
/*--- ast_softhangup_nolock: Softly hangup a channel, don't lock */

@ -2447,7 +2447,7 @@ static int sip_hangup(struct ast_channel *ast)
{
struct sip_pvt *p = ast->tech_pvt;
int needcancel = 0;
struct ast_flags locflags = {0};
int needdestroy = 0;
if (!p) {
ast_log(LOG_DEBUG, "Asked to hangup channel not connected\n");
@ -2481,7 +2481,6 @@ static int sip_hangup(struct ast_channel *ast)
#endif
/* Disconnect */
p = ast->tech_pvt;
if (p->vad) {
ast_dsp_free(p->vad);
}
@ -2493,7 +2492,16 @@ static int sip_hangup(struct ast_channel *ast)
ast_mutex_unlock(&usecnt_lock);
ast_update_use_count();
ast_set_flag(&locflags, SIP_NEEDDESTROY);
/* Do not destroy this pvt until we have timeout or
get an answer to the BYE or INVITE/CANCEL
If we get no answer during retransmit period, drop the call anyway.
(Sorry, mother-in-law, you can't deny a hangup by sending
603 declined to BYE...)
*/
if (ast_test_flag(p, SIP_ALREADYGONE))
needdestroy = 1; /* Set destroy flag at end of this function */
else
sip_scheddestroy(p, 32000);
/* Start the process if it's not already started */
if (!ast_test_flag(p, SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) {
@ -2506,13 +2514,12 @@ static int sip_hangup(struct ast_channel *ast)
it pending */
if (!ast_test_flag(p, SIP_CAN_BYE)) {
ast_set_flag(p, SIP_PENDINGBYE);
/* Do we need a timer here if we don't hear from them at all? */
} else {
/* Send a new request: CANCEL */
transmit_request_with_auth(p, SIP_CANCEL, p->ocseq, 1, 0);
/* Actually don't destroy us yet, wait for the 487 on our original
INVITE, but do set an autodestruct just in case we never get it. */
ast_clear_flag(&locflags, SIP_NEEDDESTROY);
sip_scheddestroy(p, 32000);
}
if ( p->initid != -1 ) {
/* channel still up - reverse dec of inUse counter
@ -2538,7 +2545,8 @@ static int sip_hangup(struct ast_channel *ast)
}
}
}
ast_copy_flags(p, (&locflags), SIP_NEEDDESTROY);
if (needdestroy)
ast_set_flag(p, SIP_NEEDDESTROY);
ast_mutex_unlock(&p->lock);
return 0;
}
@ -10085,6 +10093,9 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_
handle_response_invite(p, resp, rest, req, ignore, seqno);
} else if (sipmethod == SIP_REGISTER) {
res = handle_response_register(p, resp, rest, req, ignore, seqno);
} else if (sipmethod == SIP_BYE) {
/* Ok, we're ready to go */
ast_set_flag(p, SIP_NEEDDESTROY);
}
break;
case 401: /* Not www-authorized on SIP method */
@ -10239,6 +10250,9 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_
} else if (sipmethod == SIP_MESSAGE)
/* We successfully transmitted a message */
ast_set_flag(p, SIP_NEEDDESTROY);
else if (sipmethod == SIP_BYE)
/* Ok, we're ready to go */
ast_set_flag(p, SIP_NEEDDESTROY);
break;
case 401: /* www-auth */
case 407:
@ -10924,10 +10938,15 @@ static int handle_request_bye(struct sip_pvt *p, struct sip_request *req, int de
if (p->owner)
ast_queue_hangup(p->owner);
}
} else if (p->owner)
} else if (p->owner) {
ast_queue_hangup(p->owner);
else
if (option_debug > 2)
ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n.");
} else {
ast_set_flag(p, SIP_NEEDDESTROY);
if (option_debug > 2)
ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n.");
}
transmit_response(p, "200 OK", req);
return 1;
@ -13057,24 +13076,26 @@ static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, struc
if (!p)
return -1;
ast_mutex_lock(&p->lock);
if (rtp) {
if (rtp) {
changed |= ast_rtp_get_peer(rtp, &p->redirip);
#ifdef SIP_MIDCOM
if (m_cb)
m_cb->ast_rtp_get_their_nat_audio_hook(rtp, p->r);
m_cb->ast_rtp_get_their_nat_audio_hook(rtp, p->r);
#endif
}
else
} else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) {
memset(&p->redirip, 0, sizeof(p->redirip));
if (vrtp) {
changed = 1;
}
if (vrtp) {
changed |= ast_rtp_get_peer(vrtp, &p->vredirip);
#ifdef SIP_MIDCOM
if (m_cb)
m_cb->ast_rtp_get_their_nat_video_hook(vrtp, p->r);
m_cb->ast_rtp_get_their_nat_video_hook(vrtp, p->r);
#endif
}
else
} else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) {
memset(&p->vredirip, 0, sizeof(p->vredirip));
changed = 1;
}
if (codecs && (p->redircodecs != codecs)) {
p->redircodecs = codecs;
changed = 1;

@ -16,7 +16,7 @@
; Trunk groups are used for NFAS or GR-303 connections.
;
; Group: Defines a trunk group.
; group => <trunkgroup>,<dchannel>[,<backup1>...]
; trunkgroup => <trunkgroup>,<dchannel>[,<backup1>...]
;
; trunkgroup is the numerical trunk group to create
; dchannel is the zap channel which will have the

@ -94,6 +94,15 @@ int ast_channel_spy_add(struct ast_channel *chan, struct ast_channel_spy *spy);
*/
void ast_channel_spy_remove(struct ast_channel *chan, struct ast_channel_spy *spy);
/*!
\brief Free a spy.
\param spy The spy to free
\return nothing
Note: This function MUST NOT be called with the spy locked.
*/
void ast_channel_spy_free(struct ast_channel_spy *spy);
/*!
\brief Find all spies of a particular type on a channel and stop them.
\param chan The channel to operate on

Loading…
Cancel
Save