Fix directed group pickup feature code *8 with pickupsounds enabled , deadlock and segfault, affects 1.8.0 and trunk
Review Request #1185 - Created April 17, 2011 and submitted
Alec Davis | |
trunk | |
18654 | |
Reviewers | |
---|---|
asterisk-dev | |
rmudgett | |
Asterisk |
Since 1.8, the new pickupsound and pickupfailsound in features.conf cause many issues. 1). chan_sip:handle_request_invite() shouldn't be playing out the fail/success audio, as it has 'netlock' locked. 2). dialplan applications for directed_pickups shouldn't beep. 3). feature code for directed pickup should beep on success/failure if configured. Moved app_directed:pickup_do() to features:ast_do_pickup(). Functions below, all now use the new ast_do_pickup() app_directed_pickup.c: pickup_by_channel() pickup_by_exten() pickup_by_mark() pickup_by_part() features.c: ast_pickup_call() Created a sip_pickup() thread to handle the pickup and playout the audio, spawned from handle_request_invite.
pickup using *8 feature code, with pickup sounds enabled/disabled exten => 71,1,Pickup() ; any ringing extension in same pickupgroup exten => 72,1,Pickup(85@phones) ; dahdi extension exten => 73,1,Pickup(823@phones) ; sip extension
trunk/apps/app_directed_pickup.c | |||
---|---|---|---|
Diff Revision 2 | Diff Revision 4 | ||
![]() |
|||
![]() |
![]() static int pickup_by_mark(struct ast_channel *chan, const char *mark)
|
||
244 |
} |
244 |
} |
245 | 245 | ||
246 |
return res; |
246 |
return res; |
247 |
}
|
247 |
}
|
248 | 248 | ||
249 |
static int find_channel_by_group(void *obj, void *arg, void *data, int flags) |
||
250 |
{
|
||
251 |
struct ast_channel *c = data; |
||
252 |
struct ast_channel *chan = obj; |
||
253 | |||
254 |
ast_channel_lock(chan); |
||
255 |
int i = !chan->pbx && |
||
256 |
(c != chan) && |
||
257 |
(chan->pickupgroup & c->callgroup) && |
||
258 |
((chan->_state == AST_STATE_RINGING) || (chan->_state == AST_STATE_RING)) && |
||
259 |
!c->masq; |
||
260 | |||
261 |
ast_channel_unlock(chan); |
||
262 |
return i ? CMP_MATCH | CMP_STOP : 0; |
||
263 |
}
|
||
264 | |||
265 |
static int pickup_by_group(struct ast_channel *chan) |
||
266 |
{
|
||
267 |
struct ast_channel *target; |
||
268 |
int res = -1; |
||
269 |
if ((target = ast_channel_callback(find_channel_by_group, NULL, chan, 0))) { |
||
270 |
ast_channel_lock(target); |
||
271 |
res = ast_do_pickup(chan, target); |
||
272 |
ast_channel_unlock(target); |
||
273 |
target = ast_channel_unref(target); |
||
274 |
} |
||
275 |
return res; |
||
276 |
}
|
||
277 | |||
249 |
/* application entry point for Pickup() */
|
278 |
/* application entry point for Pickup() */
|
250 |
static int pickup_exec(struct ast_channel *chan, const char *data) |
279 |
static int pickup_exec(struct ast_channel *chan, const char *data) |
251 |
{
|
280 |
{
|
252 |
int res = 0; |
281 |
int res = 0; |
253 |
char *tmp = ast_strdupa(data); |
282 |
char *tmp = ast_strdupa(data); |
254 |
char *exten = NULL, *context = NULL; |
283 |
char *exten = NULL, *context = NULL; |
255 | 284 | ||
256 |
if (ast_strlen_zero(data)) { |
285 |
if (ast_strlen_zero(data)) { |
257 |
res = ast_pickup_call(chan); |
286 |
res = pickup_by_group(chan); |
258 |
return res; |
287 |
return res; |
259 |
} |
288 |
} |
260 |
|
289 |
|
261 |
/* Parse extension (and context if there) */ |
290 |
/* Parse extension (and context if there) */ |
262 |
while (!ast_strlen_zero(tmp) && (exten = strsep(&tmp, "&"))) { |
291 |
while (!ast_strlen_zero(tmp) && (exten = strsep(&tmp, "&"))) { |
![]() |
![]() |
trunk/channels/chan_sip.c | |
---|---|
Diff Revision 2 | Diff Revision 4 |
trunk/include/asterisk/features.h | |
---|---|
Diff Revision 2 | Diff Revision 4 |
trunk/main/features.c | |
---|---|
Diff Revision 2 | Diff Revision 4 |
trunk/res/res_features.exports.in | |
---|---|
Diff Revision 2 | Diff Revision 4 |
Other reviews