}
static struct ast_frame *ast_rtp_interpret(struct ast_rtp_instance *instance, struct ast_srtp *srtp,
- const struct ast_sockaddr *remote_address, unsigned char *read_area, int length, int prev_seqno)
+ const struct ast_sockaddr *remote_address, unsigned char *read_area, int length, int prev_seqno,
+ unsigned int bundled)
{
unsigned int *rtpheader = (unsigned int*)(read_area);
struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
struct ast_rtp_instance *instance1;
- int res = length, hdrlen = 12, seqno, payloadtype, padding, mark, ext, cc;
+ int res = length, hdrlen = 12, ssrc, seqno, payloadtype, padding, mark, ext, cc;
unsigned int timestamp;
RAII_VAR(struct ast_rtp_payload_type *, payload, NULL, ao2_cleanup);
struct frame_list frames;
}
/* Pull out the various other fields we will need */
+ ssrc = ntohl(rtpheader[2]);
seqno = ntohl(rtpheader[0]);
payloadtype = (seqno & 0x7f0000) >> 16;
padding = seqno & (1 << 29);
return AST_LIST_FIRST(&frames) ? AST_LIST_FIRST(&frames) : &ast_null_frame;
}
+ /* Only non-bundled instances can change/learn the remote's SSRC implicitly. */
+ if (!bundled) {
+ /* Force a marker bit and change SSRC if the SSRC changes */
+ if (rtp->themssrc_valid && rtp->themssrc != ssrc) {
+ struct ast_frame *f, srcupdate = {
+ AST_FRAME_CONTROL,
+ .subclass.integer = AST_CONTROL_SRCCHANGE,
+ };
+
+ if (!mark) {
+ if (ast_debug_rtp_packet_is_allowed) {
+ ast_debug(0, "(%p) RTP forcing Marker bit, because SSRC has changed\n", instance);
+ }
+ mark = 1;
+ }
+
+ f = ast_frisolate(&srcupdate);
+ AST_LIST_INSERT_TAIL(&frames, f, frame_list);
+
+ rtp->seedrxseqno = 0;
+ rtp->rxcount = 0;
+ rtp->rxoctetcount = 0;
+ rtp->cycles = 0;
+ prev_seqno = 0;
+ rtp->last_seqno = 0;
+ rtp->last_end_timestamp = 0;
+ if (rtp->rtcp) {
+ rtp->rtcp->expected_prior = 0;
+ rtp->rtcp->received_prior = 0;
+ }
+ }
+
+ rtp->themssrc = ssrc; /* Record their SSRC to put in future RR */
+ rtp->themssrc_valid = 1;
+ }
+
rtp->rxcount++;
rtp->rxoctetcount += (res - hdrlen);
if (rtp->rxcount == 1) {
struct ast_srtp *srtp;
RAII_VAR(struct ast_rtp_instance *, child, NULL, rtp_instance_unlock);
struct ast_sockaddr addr;
- int res, hdrlen = 12, version, payloadtype, mark;
+ int res, hdrlen = 12, version, payloadtype;
unsigned char *read_area = rtp->rawdata + AST_FRIENDLY_OFFSET;
size_t read_area_size = sizeof(rtp->rawdata) - AST_FRIENDLY_OFFSET;
unsigned int *rtpheader = (unsigned int*)(read_area), seqno, ssrc, timestamp, prev_seqno;
struct ast_sockaddr remote_address = { {0,} };
struct frame_list frames;
struct ast_frame *frame;
+ unsigned int bundled;
/* If this is actually RTCP let's hop on over and handle it */
if (rtcp) {
/* Pull out the various other fields we will need */
payloadtype = (seqno & 0x7f0000) >> 16;
- mark = seqno & (1 << 23);
seqno &= 0xffff;
timestamp = ntohl(rtpheader[1]);
AST_LIST_HEAD_INIT_NOLOCK(&frames);
- /* Only non-bundled instances can change/learn the remote's SSRC implicitly. */
- if (!child && !AST_VECTOR_SIZE(&rtp->ssrc_mapping)) {
- /* Force a marker bit and change SSRC if the SSRC changes */
- if (rtp->themssrc_valid && rtp->themssrc != ssrc) {
- struct ast_frame *f, srcupdate = {
- AST_FRAME_CONTROL,
- .subclass.integer = AST_CONTROL_SRCCHANGE,
- };
-
- if (!mark) {
- if (ast_debug_rtp_packet_is_allowed) {
- ast_debug(0, "(%p) RTP forcing Marker bit, because SSRC has changed\n", instance);
- }
- mark = 1;
- }
-
- f = ast_frisolate(&srcupdate);
- AST_LIST_INSERT_TAIL(&frames, f, frame_list);
-
- rtp->seedrxseqno = 0;
- rtp->rxcount = 0;
- rtp->rxoctetcount = 0;
- rtp->cycles = 0;
- rtp->lastrxseqno = 0;
- rtp->last_seqno = 0;
- rtp->last_end_timestamp = 0;
- if (rtp->rtcp) {
- rtp->rtcp->expected_prior = 0;
- rtp->rtcp->received_prior = 0;
- }
- }
-
- rtp->themssrc = ssrc; /* Record their SSRC to put in future RR */
- rtp->themssrc_valid = 1;
- }
+ bundled = (child || AST_VECTOR_SIZE(&rtp->ssrc_mapping)) ? 1 : 0;
prev_seqno = rtp->lastrxseqno;
rtp->lastrxseqno = seqno;
if (!rtp->recv_buffer) {
/* If there is no receive buffer then we can pass back the frame directly */
- frame = ast_rtp_interpret(instance, srtp, &addr, read_area, res, prev_seqno);
+ frame = ast_rtp_interpret(instance, srtp, &addr, read_area, res, prev_seqno, bundled);
AST_LIST_INSERT_TAIL(&frames, frame, frame_list);
return AST_LIST_FIRST(&frames);
} else if (rtp->expectedrxseqno == -1 || seqno == rtp->expectedrxseqno) {
* return it directly without duplicating it.
*/
if (!ast_data_buffer_count(rtp->recv_buffer)) {
- frame = ast_rtp_interpret(instance, srtp, &addr, read_area, res, prev_seqno);
+ frame = ast_rtp_interpret(instance, srtp, &addr, read_area, res, prev_seqno, bundled);
AST_LIST_INSERT_TAIL(&frames, frame, frame_list);
return AST_LIST_FIRST(&frames);
}
* chance it will be overwritten.
*/
if (!ast_data_buffer_get(rtp->recv_buffer, rtp->expectedrxseqno)) {
- frame = ast_rtp_interpret(instance, srtp, &addr, read_area, res, prev_seqno);
+ frame = ast_rtp_interpret(instance, srtp, &addr, read_area, res, prev_seqno, bundled);
AST_LIST_INSERT_TAIL(&frames, frame, frame_list);
return AST_LIST_FIRST(&frames);
}
* to the head of the frames list and avoid having to duplicate it but this would result in out
* of order packet processing by libsrtp which we are trying to avoid.
*/
- frame = ast_frdup(ast_rtp_interpret(instance, srtp, &addr, read_area, res, prev_seqno));
+ frame = ast_frdup(ast_rtp_interpret(instance, srtp, &addr, read_area, res, prev_seqno, bundled));
if (frame) {
AST_LIST_INSERT_TAIL(&frames, frame, frame_list);
prev_seqno = seqno;
break;
}
- frame = ast_frdup(ast_rtp_interpret(instance, srtp, &addr, payload->buf, payload->size, prev_seqno));
+ frame = ast_frdup(ast_rtp_interpret(instance, srtp, &addr, payload->buf, payload->size, prev_seqno, bundled));
ast_free(payload);
if (!frame) {
/* If the packet we received is the one we are expecting at this point then add it in */
if (rtp->expectedrxseqno == seqno) {
- frame = ast_frdup(ast_rtp_interpret(instance, srtp, &addr, read_area, res, prev_seqno));
+ frame = ast_frdup(ast_rtp_interpret(instance, srtp, &addr, read_area, res, prev_seqno, bundled));
if (frame) {
AST_LIST_INSERT_TAIL(&frames, frame, frame_list);
prev_seqno = seqno;
payload = (struct ast_rtp_rtcp_nack_payload *)ast_data_buffer_remove(rtp->recv_buffer, rtp->expectedrxseqno);
if (payload) {
- frame = ast_frdup(ast_rtp_interpret(instance, srtp, &addr, payload->buf, payload->size, prev_seqno));
+ frame = ast_frdup(ast_rtp_interpret(instance, srtp, &addr, payload->buf, payload->size, prev_seqno, bundled));
if (frame) {
AST_LIST_INSERT_TAIL(&frames, frame, frame_list);
prev_seqno = rtp->expectedrxseqno;
* to be the last packet processed right now and it is also guaranteed that it will always return
* non-NULL.
*/
- frame = ast_rtp_interpret(instance, srtp, &addr, read_area, res, prev_seqno);
+ frame = ast_rtp_interpret(instance, srtp, &addr, read_area, res, prev_seqno, bundled);
AST_LIST_INSERT_TAIL(&frames, frame, frame_list);
rtp->expectedrxseqno = seqno + 1;
if (rtp->expectedrxseqno == SEQNO_CYCLE_OVER) {