Review Board 1.7.16


Pimp My SIP Media Improvements

Review Request #2318 - Created Feb. 6, 2013 and submitted

Joshua Colp
/team/file/pimp_sip_media
Reviewers
asterisk-dev
Asterisk
These changes clean up media handling, move some more stuff into res_sip_sdp_audio, fixes a few bugs, and adds some additional features.

The act of negotiating an SDP media stream and actually applying the media stream are now separate operations.
Hold/unhold works.
RTP over IPv6 works.
Use of the 'ptime' attribute works.
Local Packet2Packet bridging works.
Symmetric RTP can now be enabled per-endpoint.
Reduced memory pool usage.
Fixed bug where the RTP instance was never destroyed.
1. Sent and received calls from a few different devices
2. Held/unheld a call
3. Attempted to set up incompatible calls (only configured for gsm, but offering ulaw only)
/team/group/pimp_my_sip/channels/chan_gulp.c
Revision 381276 New Change
[20] 104 lines
[+20] [+] static struct ast_sip_session_supplement gulp_supplement = {
105
	.session_end = gulp_session_end,
105
	.session_end = gulp_session_end,
106
	.incoming_request = gulp_incoming_request,
106
	.incoming_request = gulp_incoming_request,
107
	.incoming_response = gulp_incoming_response,
107
	.incoming_response = gulp_incoming_response,
108
};
108
};
109

    
   
109

   
110
/*! \brief Function called by RTP engine to get local RTP peer */
110
/*! \brief Function called by RTP engine to get local audio RTP peer */
111
static enum ast_rtp_glue_result gulp_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance)
111
static enum ast_rtp_glue_result gulp_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance)
112
{
112
{

    
   
113
	struct ast_sip_session *session = ast_channel_tech_pvt(chan);

    
   
114

   

    
   
115
	if (!session || !session->media[AST_SIP_MEDIA_AUDIO].rtp) {
113
	return AST_RTP_GLUE_RESULT_FORBID;
116
		return AST_RTP_GLUE_RESULT_FORBID;
114
}
117
	}
115

    
   
118

   

    
   
119
	ao2_ref(session->media[AST_SIP_MEDIA_AUDIO].rtp, +1);

    
   
120
	*instance = session->media[AST_SIP_MEDIA_AUDIO].rtp;

    
   
121

   

    
   
122
	return AST_RTP_GLUE_RESULT_LOCAL;

    
   
123
}

    
   
124

   
116
/*! \brief Function called by RTP engine to get peer capabilities */
125
/*! \brief Function called by RTP engine to get peer capabilities */
117
static void gulp_get_codec(struct ast_channel *chan, struct ast_format_cap *result)
126
static void gulp_get_codec(struct ast_channel *chan, struct ast_format_cap *result)
118
{
127
{
119
}
128
}
120

    
   
129

   
[+20] [20] 45 lines
[+20] [+] static struct ast_channel *gulp_new(struct ast_sip_session *session, int state, const char *exten, const char *title, const char *linkedid, const char *cid_name)
166
	ast_format_copy(ast_channel_writeformat(chan), &fmt);
175
	ast_format_copy(ast_channel_writeformat(chan), &fmt);
167
	ast_format_copy(ast_channel_rawwriteformat(chan), &fmt);
176
	ast_format_copy(ast_channel_rawwriteformat(chan), &fmt);
168
	ast_format_copy(ast_channel_readformat(chan), &fmt);
177
	ast_format_copy(ast_channel_readformat(chan), &fmt);
169
	ast_format_copy(ast_channel_rawreadformat(chan), &fmt);
178
	ast_format_copy(ast_channel_rawreadformat(chan), &fmt);
170

    
   
179

   
171
	if (session->media.audio) {

   
172
		ast_channel_set_fd(chan, 0, ast_rtp_instance_fd(session->media.audio, 0));

   
173
		ast_channel_set_fd(chan, 1, ast_rtp_instance_fd(session->media.audio, 1));

   
174
	}

   
175

    
   

   
176
	if (state == AST_STATE_RING) {
180
	if (state == AST_STATE_RING) {
177
		ast_channel_rings_set(chan, 1);
181
		ast_channel_rings_set(chan, 1);
178
	}
182
	}
179

    
   
183

   
180
	ast_channel_adsicpe_set(chan, AST_ADSI_UNAVAILABLE);
184
	ast_channel_adsicpe_set(chan, AST_ADSI_UNAVAILABLE);
[+20] [20] 33 lines
[+20] [+] static struct ast_frame *gulp_read(struct ast_channel *ast)
214
	struct ast_sip_session *session = ast_channel_tech_pvt(ast);
218
	struct ast_sip_session *session = ast_channel_tech_pvt(ast);
215
	struct ast_frame *f;
219
	struct ast_frame *f;
216

    
   
220

   
217
	switch (ast_channel_fdno(ast)) {
221
	switch (ast_channel_fdno(ast)) {
218
	case 0:
222
	case 0:
219
		f = ast_rtp_instance_read(session->media.audio, 0);
223
		f = ast_rtp_instance_read(session->media[AST_SIP_MEDIA_AUDIO].rtp, 0);
220
		break;
224
		break;
221
	case 1:
225
	case 1:
222
		f = ast_rtp_instance_read(session->media.audio, 1);
226
		f = ast_rtp_instance_read(session->media[AST_SIP_MEDIA_AUDIO].rtp, 1);
223
		break;
227
		break;
224
	default:
228
	default:
225
		f = &ast_null_frame;
229
		f = &ast_null_frame;
226
	}
230
	}
227

    
   
231

   
228
	if (f->frametype == AST_FRAME_VOICE) {
232
	if (f && f->frametype == AST_FRAME_VOICE) {
229
		if (!(ast_format_cap_iscompatible(ast_channel_nativeformats(ast), &f->subclass.format))) {
233
		if (!(ast_format_cap_iscompatible(ast_channel_nativeformats(ast), &f->subclass.format))) {
230
			ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(&f->subclass.format));
234
			ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(&f->subclass.format));
231
			ast_format_cap_set(ast_channel_nativeformats(ast), &f->subclass.format);
235
			ast_format_cap_set(ast_channel_nativeformats(ast), &f->subclass.format);
232
			ast_set_read_format(ast, ast_channel_readformat(ast));
236
			ast_set_read_format(ast, ast_channel_readformat(ast));
233
			ast_set_write_format(ast, ast_channel_writeformat(ast));
237
			ast_set_write_format(ast, ast_channel_writeformat(ast));
[+20] [20] 20 lines
[+20] [+] static int gulp_write(struct ast_channel *ast, struct ast_frame *frame)
254
				ast_getformatname_multiple(buf, sizeof(buf), ast_channel_nativeformats(ast)),
258
				ast_getformatname_multiple(buf, sizeof(buf), ast_channel_nativeformats(ast)),
255
				ast_getformatname(ast_channel_readformat(ast)),
259
				ast_getformatname(ast_channel_readformat(ast)),
256
				ast_getformatname(ast_channel_writeformat(ast)));
260
				ast_getformatname(ast_channel_writeformat(ast)));
257
			return 0;
261
			return 0;
258
		}
262
		}
259
		if (session->media.audio) {
263
		if (session->media[AST_SIP_MEDIA_AUDIO].rtp) {
260
			res = ast_rtp_instance_write(session->media.audio, frame);
264
			res = ast_rtp_instance_write(session->media[AST_SIP_MEDIA_AUDIO].rtp, frame);
261
		}
265
		}
262
		break;
266
		break;
263
	default:
267
	default:
264
		ast_log(LOG_WARNING, "Can't send %d type frames with Gulp\n", frame->frametype);
268
		ast_log(LOG_WARNING, "Can't send %d type frames with Gulp\n", frame->frametype);
265
		break;
269
		break;
[+20] [20] 105 lines
[+20] [+] static int gulp_digit_begin(struct ast_channel *chan, char digit)
371
	struct ast_sip_session *session = ast_channel_tech_pvt(chan);
375
	struct ast_sip_session *session = ast_channel_tech_pvt(chan);
372
	int res = 0;
376
	int res = 0;
373

    
   
377

   
374
	switch (session->endpoint->dtmf) {
378
	switch (session->endpoint->dtmf) {
375
	case AST_SIP_DTMF_RFC_4733:
379
	case AST_SIP_DTMF_RFC_4733:
376
		ast_rtp_instance_dtmf_begin(session->media.audio, digit);
380
		if (session->media[AST_SIP_MEDIA_AUDIO].rtp) {

    
   
381
			ast_rtp_instance_dtmf_begin(session->media[AST_SIP_MEDIA_AUDIO].rtp, digit);

    
   
382
		}
377
	case AST_SIP_DTMF_NONE:
383
	case AST_SIP_DTMF_NONE:
378
		break;
384
		break;
379
	case AST_SIP_DTMF_INBAND:
385
	case AST_SIP_DTMF_INBAND:
380
		res = -1;
386
		res = -1;
381
		break;
387
		break;
[+20] [20] 13 lines
[+20] [+] static int gulp_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
395
	switch (session->endpoint->dtmf) {
401
	switch (session->endpoint->dtmf) {
396
	case AST_SIP_DTMF_INFO:
402
	case AST_SIP_DTMF_INFO:
397
		/* TODO: Send INFO dtmf here */
403
		/* TODO: Send INFO dtmf here */
398
		break;
404
		break;
399
	case AST_SIP_DTMF_RFC_4733:
405
	case AST_SIP_DTMF_RFC_4733:
400
		ast_rtp_instance_dtmf_end_with_duration(session->media.audio, digit, duration);
406
		if (session->media[AST_SIP_MEDIA_AUDIO].rtp) {

    
   
407
			ast_rtp_instance_dtmf_end_with_duration(session->media[AST_SIP_MEDIA_AUDIO].rtp, digit, duration);

    
   
408
		}
401
	case AST_SIP_DTMF_NONE:
409
	case AST_SIP_DTMF_NONE:
402
		break;
410
		break;
403
	case AST_SIP_DTMF_INBAND:
411
	case AST_SIP_DTMF_INBAND:
404
		res = -1;
412
		res = -1;
405
		break;
413
		break;
[+20] [20] 291 lines
[+20] [+] static void gulp_incoming_response(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
697
		if (ast_channel_state(session->channel) != AST_STATE_UP) {
705
		if (ast_channel_state(session->channel) != AST_STATE_UP) {
698
			ast_setstate(session->channel, AST_STATE_RINGING);
706
			ast_setstate(session->channel, AST_STATE_RINGING);
699
		}
707
		}
700
		break;
708
		break;
701
	case 183:
709
	case 183:
702
		ast_rtp_instance_activate(session->media.audio);

   
703
		ast_queue_control(session->channel, AST_CONTROL_PROGRESS);
710
		ast_queue_control(session->channel, AST_CONTROL_PROGRESS);
704
		break;
711
		break;
705
	case 200:
712
	case 200:
706
		ast_rtp_instance_activate(session->media.audio);

   
707
		ast_queue_control(session->channel, AST_CONTROL_ANSWER);
713
		ast_queue_control(session->channel, AST_CONTROL_ANSWER);
708
		break;
714
		break;
709
	default:
715
	default:
710
		break;
716
		break;
711
	}
717
	}
[+20] [20] 62 lines
/team/group/pimp_my_sip/configs/res_sip.conf.sample
Revision 381276 New Change
 
/team/group/pimp_my_sip/include/asterisk/res_sip.h
Revision 381276 New Change
 
/team/group/pimp_my_sip/include/asterisk/res_sip_session.h
Revision 381276 New Change
 
/team/group/pimp_my_sip/res/res_sip_sdp_audio.c
Revision 381276 New Change
 
/team/group/pimp_my_sip/res/res_sip_session.c
Revision 381276 New Change
 
/team/group/pimp_my_sip/res/res_sip/sip_configuration.c
Revision 381276 New Change
 
  1. /team/group/pimp_my_sip/channels/chan_gulp.c: Loading...
  2. /team/group/pimp_my_sip/configs/res_sip.conf.sample: Loading...
  3. /team/group/pimp_my_sip/include/asterisk/res_sip.h: Loading...
  4. /team/group/pimp_my_sip/include/asterisk/res_sip_session.h: Loading...
  5. /team/group/pimp_my_sip/res/res_sip_sdp_audio.c: Loading...
  6. /team/group/pimp_my_sip/res/res_sip_session.c: Loading...
  7. /team/group/pimp_my_sip/res/res_sip/sip_configuration.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.