Review Board 1.7.16


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

Changes between revision 7 and 11

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

  1. trunk/apps/app_directed_pickup.c: Loading...
  2. trunk/channels/chan_sip.c: Loading...
  3. trunk/include/asterisk/features.h: Loading...
  4. trunk/main/features.c: Loading...
  5. trunk/res/res_features.exports.in: Loading...
trunk/apps/app_directed_pickup.c
Diff Revision 7 Diff Revision 11
[20] 239 lines
[+20] [+] static int pickup_by_mark(struct ast_channel *chan, const char *mark)
240
	} else {
240
	} else {
241
		ast_log(LOG_WARNING, "target has gone, or not ringing anymore for %s\n", chan->name);
241
		ast_log(LOG_WARNING, "target has gone, or not ringing anymore for %s\n", chan->name);
242
	}
242
	}
243
	ast_channel_unlock(target);
243
	ast_channel_unlock(target);
244
	target = ast_channel_unref(target);
244
	target = ast_channel_unref(target);
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)
249
static int find_channel_by_group(void *obj, void *arg, void *data, int flags)
250
{
250
{
251
	struct ast_channel *chan = obj;
251
	struct ast_channel *chan = obj;
252
	struct ast_channel *c = data;
252
	struct ast_channel *c = data;

    
   
253
	int i;
253

    
   
254

   
254
	ast_channel_lock(chan);
255
	ast_channel_lock(chan);
255
	int i = (c != chan) &&
256
	i = (c != chan) && (chan->pickupgroup & c->callgroup) &&
256
		(chan->pickupgroup & c->callgroup) &&

   
257
		can_pickup(chan);
257
		can_pickup(chan);
258

    
   
258

   
259
	ast_channel_unlock(chan);
259
	ast_channel_unlock(chan);
260
	return i ? CMP_MATCH | CMP_STOP : 0;
260
	return i ? CMP_MATCH | CMP_STOP : 0;
261
}
261
}
[+20] [20] 4 lines
[+20] [+] static int pickup_by_group(struct ast_channel *chan)
266
	int res = -1;
266
	int res = -1;
267

    
   
267

   
268
	if (!(target = ast_channel_callback(find_channel_by_group, NULL, chan, 0))) {
268
	if (!(target = ast_channel_callback(find_channel_by_group, NULL, chan, 0))) {
269
		return res;
269
		return res;
270
	}
270
	}
271
	
271

   
272
	ast_log(LOG_NOTICE, "%s, pickup attempt by %s\n", target->name, chan->name);
272
	ast_log(LOG_NOTICE, "%s, pickup attempt by %s\n", target->name, chan->name);
273
	ast_channel_lock(target);
273
	ast_channel_lock(target);
274
	if (can_pickup(target)) {
274
	if (can_pickup(target)) {
275
		res = ast_do_pickup(chan, target);
275
		res = ast_do_pickup(chan, target);
276
	} else {
276
	} else {
277
		ast_log(LOG_WARNING, "target has gone, or not ringing anymore for %s\n", chan->name);
277
		ast_log(LOG_WARNING, "target has gone, or not ringing anymore for %s\n", chan->name);
278
	}
278
	}
279
	ast_channel_unlock(target);
279
	ast_channel_unlock(target);
280
	target = ast_channel_unref(target);
280
	target = ast_channel_unref(target);
281
	
281

   
282
	return res;
282
	return res;
283
}
283
}
284

    
   
284

   
285
/* application entry point for Pickup() */
285
/* application entry point for Pickup() */
286
static int pickup_exec(struct ast_channel *chan, const char *data)
286
static int pickup_exec(struct ast_channel *chan, const char *data)
[+20] [20] 4 lines
[+20] static int pickup_by_group(struct ast_channel *chan)
291

    
   
291

   
292
	if (ast_strlen_zero(data)) {
292
	if (ast_strlen_zero(data)) {
293
		res = pickup_by_group(chan);
293
		res = pickup_by_group(chan);
294
		return res;
294
		return res;
295
	}
295
	}
296
	
296

   
297
	/* Parse extension (and context if there) */
297
	/* Parse extension (and context if there) */
298
	while (!ast_strlen_zero(tmp) && (exten = strsep(&tmp, "&"))) {
298
	while (!ast_strlen_zero(tmp) && (exten = strsep(&tmp, "&"))) {
299
		if ((context = strchr(exten, '@')))
299
		if ((context = strchr(exten, '@')))
300
			*context++ = '\0';
300
			*context++ = '\0';
301
		if (!ast_strlen_zero(context) && !strcasecmp(context, PICKUPMARK)) {
301
		if (!ast_strlen_zero(context) && !strcasecmp(context, PICKUPMARK)) {
[+20] [20] 111 lines
trunk/channels/chan_sip.c
Diff Revision 7 Diff Revision 11
 
trunk/include/asterisk/features.h
Diff Revision 7 Diff Revision 11
 
trunk/main/features.c
Diff Revision 7 Diff Revision 11
 
trunk/res/res_features.exports.in
Diff Revision 7 Diff Revision 11
 
  1. trunk/apps/app_directed_pickup.c: Loading...
  2. trunk/channels/chan_sip.c: Loading...
  3. trunk/include/asterisk/features.h: Loading...
  4. trunk/main/features.c: Loading...
  5. trunk/res/res_features.exports.in: Loading...

https://reviewboard.asterisk.org/ runs on a server provided by Digium, Inc. and uses bandwidth donated to the open source Asterisk community by API Digital Communications in Huntsville, AL USA.
Please report problems with this site to asteriskteam@digium.com.