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

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/main/features.c: Loading...
trunk/apps/app_directed_pickup.c
Diff Revision 5 Diff Revision 6
[20] 164 lines
[+20] [+] static int pickup_by_channel(struct ast_channel *chan, char *pickup)
165
	}
165
	}
166

    
   
166

   
167
	/* 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 */
168
	if (chan != target) {
168
	if (chan != target) {
169
		res = ast_do_pickup(chan, target);
169
		res = ast_do_pickup(chan, target);
170
	}
170
	} else {
171

    
   

   
172
	ast_channel_unlock(target);
171
		ast_channel_unlock(target);
173
	target = ast_channel_unref(target);
172
		target = ast_channel_unref(target);

    
   
173
	}
174

    
   
174

   
175
	return res;
175
	return res;
176
}
176
}
177

    
   
177

   
178
/* Attempt to pick up specified extension with context */
178
/* Attempt to pick up specified extension with context */
[+20] [20] 18 lines
[+20] [+] static int pickup_by_exten(struct ast_channel *chan, const char *exten, const char *context)
197

    
   
197

   
198
	ast_channel_iterator_destroy(iter);
198
	ast_channel_iterator_destroy(iter);
199

    
   
199

   
200
	if (target) {
200
	if (target) {
201
		res = ast_do_pickup(chan, target);
201
		res = ast_do_pickup(chan, target);
202
		ast_channel_unlock(target);

   
203
		target = ast_channel_unref(target);

   
204
	}
202
	}
205

    
   
203

   
206
	return res;
204
	return res;
207
}
205
}
208

    
   
206

   
[+20] [20] 21 lines
[+20] [+] static int pickup_by_mark(struct ast_channel *chan, const char *mark)
230
	struct ast_channel *target;
228
	struct ast_channel *target;
231
	int res = -1;
229
	int res = -1;
232

    
   
230

   
233
	if ((target = ast_channel_callback(find_by_mark, NULL, (char *) mark, 0))) {
231
	if ((target = ast_channel_callback(find_by_mark, NULL, (char *) mark, 0))) {
234
		ast_channel_lock(target);
232
		ast_channel_lock(target);

    
   
233
		if (!target->masq && can_pickup(target)) {
235
		res = ast_do_pickup(chan, target);
234
			res = ast_do_pickup(chan, target);

    
   
235
		} else {

    
   
236
			ast_log(LOG_WARNING, "target has gone, or not ringing anymore for %s\n", chan->name);
236
		ast_channel_unlock(target);
237
			ast_channel_unlock(target);
237
		target = ast_channel_unref(target);
238
			target = ast_channel_unref(target);
238
	}
239
		}

    
   
240
	}
239

    
   
241

   
240
	return res;
242
	return res;
241
}
243
}
242

    
   
244

   
243
static int find_channel_by_group(void *obj, void *arg, void *data, int flags)
245
static int find_channel_by_group(void *obj, void *arg, void *data, int flags)
[+20] [20] 13 lines
[+20] static int pickup_by_mark(struct ast_channel *chan, const char *mark)
257
static int pickup_by_group(struct ast_channel *chan)
259
static int pickup_by_group(struct ast_channel *chan)
258
{
260
{
259
	struct ast_channel *target;
261
	struct ast_channel *target;
260
	int res = -1;
262
	int res = -1;
261
	if ((target = ast_channel_callback(find_channel_by_group, NULL, chan, 0))) {
263
	if ((target = ast_channel_callback(find_channel_by_group, NULL, chan, 0))) {

    
   
264
		ast_log(LOG_NOTICE, "%s, pickup attempt by %s\n", target->name, chan->name);
262
		ast_channel_lock(target);
265
		ast_channel_lock(target);

    
   
266
		if (!target->masq && can_pickup(target)) {
263
		res = ast_do_pickup(chan, target);
267
			res = ast_do_pickup(chan, target);

    
   
268
		} else {

    
   
269
			ast_log(LOG_WARNING, "target has gone, or not ringing anymore for %s\n", chan->name);
264
		ast_channel_unlock(target);
270
			ast_channel_unlock(target);
265
		target = ast_channel_unref(target);
271
			target = ast_channel_unref(target);
266
	}
272
		}

    
   
273
	}
267
	return res;
274
	return res;
268
}
275
}
269

    
   
276

   
270
/* application entry point for Pickup() */
277
/* application entry point for Pickup() */
271
static int pickup_exec(struct ast_channel *chan, const char *data)
278
static int pickup_exec(struct ast_channel *chan, const char *data)
[+20] [20] 47 lines
[+20] [+] static int pickup_by_part(struct ast_channel *chan, const char *part)
319
	struct ast_channel *target;
326
	struct ast_channel *target;
320
	int res = -1;
327
	int res = -1;
321

    
   
328

   
322
	if ((target = ast_channel_callback(find_by_part, NULL, (char *) part, 0))) {
329
	if ((target = ast_channel_callback(find_by_part, NULL, (char *) part, 0))) {
323
		ast_channel_lock(target);
330
		ast_channel_lock(target);

    
   
331
		if (!target->masq && can_pickup(target)) {
324
		res = ast_do_pickup(chan, target);
332
			res = ast_do_pickup(chan, target);

    
   
333
		} else {

    
   
334
			ast_log(LOG_WARNING, "target has gone, or not ringing anymore for %s\n", chan->name);
325
		ast_channel_unlock(target);
335
			ast_channel_unlock(target);
326
		target = ast_channel_unref(target);
336
			target = ast_channel_unref(target);
327
	}
337
		}

    
   
338
	}
328

    
   
339

   
329
	return res;
340
	return res;
330
}
341
}
331

    
   
342

   
332
/* application entry point for PickupChan() */
343
/* application entry point for PickupChan() */
[+20] [20] 61 lines
trunk/main/features.c
Diff Revision 5 Diff Revision 6
 
  1. trunk/apps/app_directed_pickup.c: Loading...
  2. trunk/main/features.c: 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.