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 2 and 5

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 2 Diff Revision 5
[20] 94 lines
[+20] [+] ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
95

    
   
95

   
96
static const char app[] = "Pickup";
96
static const char app[] = "Pickup";
97
static const char app2[] = "PickupChan";
97
static const char app2[] = "PickupChan";
98
/*! \todo This application should return a result code, like PICKUPRESULT */
98
/*! \todo This application should return a result code, like PICKUPRESULT */
99

    
   
99

   
100
/* Perform actual pickup between two channels */

   
101
static int pickup_do(struct ast_channel *chan, struct ast_channel *target)

   
102
{

   
103
	return ast_do_pickup(chan, target);

   
104
}

   
105

    
   

   
106
/* Helper function that determines whether a channel is capable of being picked up */
100
/* Helper function that determines whether a channel is capable of being picked up */
107
static int can_pickup(struct ast_channel *chan)
101
static int can_pickup(struct ast_channel *chan)
108
{
102
{
109
	if (!chan->pbx && (chan->_state == AST_STATE_RINGING || chan->_state == AST_STATE_RING || chan->_state == AST_STATE_DOWN))
103
	if (!chan->pbx && (chan->_state == AST_STATE_RINGING || chan->_state == AST_STATE_RING || chan->_state == AST_STATE_DOWN))
110
		return 1;
104
		return 1;
[+20] [20] 59 lines
[+20] [+] static int pickup_by_channel(struct ast_channel *chan, char *pickup)
170
		return -1;
164
		return -1;
171
	}
165
	}
172

    
   
166

   
173
	/* Just check that we are not picking up the SAME as target */
167
	/* Just check that we are not picking up the SAME as target */
174
	if (chan != target) {
168
	if (chan != target) {
175
		res = pickup_do(chan, target);
169
		res = ast_do_pickup(chan, target);
176
	}
170
	}
177

    
   
171

   
178
	ast_channel_unlock(target);
172
	ast_channel_unlock(target);
179
	target = ast_channel_unref(target);
173
	target = ast_channel_unref(target);
180

    
   
174

   
[+20] [20] 21 lines
[+20] [+] static int pickup_by_exten(struct ast_channel *chan, const char *exten, const char *context)
202
	}
196
	}
203

    
   
197

   
204
	ast_channel_iterator_destroy(iter);
198
	ast_channel_iterator_destroy(iter);
205

    
   
199

   
206
	if (target) {
200
	if (target) {
207
		res = pickup_do(chan, target);
201
		res = ast_do_pickup(chan, target);
208
		ast_channel_unlock(target);
202
		ast_channel_unlock(target);
209
		target = ast_channel_unref(target);
203
		target = ast_channel_unref(target);
210
	}
204
	}
211

    
   
205

   
212
	return res;
206
	return res;
[+20] [20] 23 lines
[+20] [+] static int pickup_by_mark(struct ast_channel *chan, const char *mark)
236
	struct ast_channel *target;
230
	struct ast_channel *target;
237
	int res = -1;
231
	int res = -1;
238

    
   
232

   
239
	if ((target = ast_channel_callback(find_by_mark, NULL, (char *) mark, 0))) {
233
	if ((target = ast_channel_callback(find_by_mark, NULL, (char *) mark, 0))) {
240
		ast_channel_lock(target);
234
		ast_channel_lock(target);
241
		res = pickup_do(chan, target);
235
		res = ast_do_pickup(chan, target);
242
		ast_channel_unlock(target);
236
		ast_channel_unlock(target);
243
		target = ast_channel_unref(target);
237
		target = ast_channel_unref(target);
244
	}
238
	}
245

    
   
239

   
246
	return res;
240
	return res;
247
}
241
}
248

    
   
242

   

    
   
243
static int find_channel_by_group(void *obj, void *arg, void *data, int flags)

    
   
244
{

    
   
245
	struct ast_channel *chan = obj;

    
   
246
	struct ast_channel *c = data;

    
   
247

   

    
   
248
	ast_channel_lock(chan);

    
   
249
	int i = (c != chan) &&

    
   
250
		(chan->pickupgroup & c->callgroup) &&

    
   
251
		!c->masq && can_pickup(chan);

    
   
252

   

    
   
253
	ast_channel_unlock(chan);

    
   
254
	return i ? CMP_MATCH | CMP_STOP : 0;

    
   
255
}

    
   
256

   

    
   
257
static int pickup_by_group(struct ast_channel *chan)

    
   
258
{

    
   
259
	struct ast_channel *target;

    
   
260
	int res = -1;

    
   
261
	if ((target = ast_channel_callback(find_channel_by_group, NULL, chan, 0))) {

    
   
262
		ast_channel_lock(target);

    
   
263
		res = ast_do_pickup(chan, target);

    
   
264
		ast_channel_unlock(target);

    
   
265
		target = ast_channel_unref(target);

    
   
266
	}

    
   
267
	return res;

    
   
268
}

    
   
269

   
249
/* application entry point for Pickup() */
270
/* application entry point for Pickup() */
250
static int pickup_exec(struct ast_channel *chan, const char *data)
271
static int pickup_exec(struct ast_channel *chan, const char *data)
251
{
272
{
252
	int res = 0;
273
	int res = 0;
253
	char *tmp = ast_strdupa(data);
274
	char *tmp = ast_strdupa(data);
254
	char *exten = NULL, *context = NULL;
275
	char *exten = NULL, *context = NULL;
255

    
   
276

   
256
	if (ast_strlen_zero(data)) {
277
	if (ast_strlen_zero(data)) {
257
		res = ast_pickup_call(chan);
278
		res = pickup_by_group(chan);
258
		return res;
279
		return res;
259
	}
280
	}
260
	
281
	
261
	/* Parse extension (and context if there) */
282
	/* Parse extension (and context if there) */
262
	while (!ast_strlen_zero(tmp) && (exten = strsep(&tmp, "&"))) {
283
	while (!ast_strlen_zero(tmp) && (exten = strsep(&tmp, "&"))) {
[+20] [20] 35 lines
[+20] [+] static int pickup_by_part(struct ast_channel *chan, const char *part)
298
	struct ast_channel *target;
319
	struct ast_channel *target;
299
	int res = -1;
320
	int res = -1;
300

    
   
321

   
301
	if ((target = ast_channel_callback(find_by_part, NULL, (char *) part, 0))) {
322
	if ((target = ast_channel_callback(find_by_part, NULL, (char *) part, 0))) {
302
		ast_channel_lock(target);
323
		ast_channel_lock(target);
303
		res = pickup_do(chan, target);
324
		res = ast_do_pickup(chan, target);
304
		ast_channel_unlock(target);
325
		ast_channel_unlock(target);
305
		target = ast_channel_unref(target);
326
		target = ast_channel_unref(target);
306
	}
327
	}
307

    
   
328

   
308
	return res;
329
	return res;
[+20] [20] 64 lines
trunk/channels/chan_sip.c
Diff Revision 2 Diff Revision 5
 
trunk/include/asterisk/features.h
Diff Revision 2 Diff Revision 5
 
trunk/main/features.c
Diff Revision 2 Diff Revision 5
 
trunk/res/res_features.exports.in
Diff Revision 2 Diff Revision 5
 
  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.