Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sundry fixes #10

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion src/mast.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ typedef struct
double packet_duration; // a=ptime

char ptp_gmid[24]; // a=ts-refclk
unsigned int ptp_domain; // a=ts-refclk
uint64_t clock_offset; // a=mediaclk
} mast_sdp_t;

Expand All @@ -158,6 +159,7 @@ void mast_sdp_set_encoding_name(mast_sdp_t *sdp, const char* encoding_name);

#define RTP_MAX_PAYLOAD (1440)
#define RTP_HEADER_LENGTH (12)
#define RTP_VERSION (2)

typedef struct
{
Expand Down Expand Up @@ -186,7 +188,27 @@ int mast_rtp_recv( mast_socket_t* socket, mast_rtp_packet_t* packet );
// Return the duration of a packet in microseconds
int mast_rtp_packet_duration(mast_rtp_packet_t* packet, mast_sdp_t* sdp);


#define RTP_SEQ_MOD (1<<16)
#define RTP_MIN_SEQUENTIAL 2

typedef struct {
uint16_t max_seq;
uint32_t cycles;
uint32_t base_seq;
uint32_t bad_seq;
uint32_t probation;
uint32_t received;
uint32_t expected_prior;
uint32_t received_prior;
uint32_t transit;
uint32_t jitter;
} mast_rtp_sequence_state_t;

void
mast_rtp_init_sequence(mast_rtp_sequence_state_t *s, uint16_t seq);

int
mast_rtp_update_sequence(mast_rtp_sequence_state_t *s, uint16_t seq);

// ------- Audio File Writing ---------

Expand Down
31 changes: 28 additions & 3 deletions src/rtp.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

int mast_rtp_parse( mast_rtp_packet_t* packet )
{
int header_len = RTP_HEADER_LENGTH;
size_t header_len = RTP_HEADER_LENGTH;

// Byte 1
packet->version = bitMask(packet->buffer[0], 0x02, 6);
Expand All @@ -39,12 +39,37 @@ int mast_rtp_parse( mast_rtp_packet_t* packet )
packet->ssrc = bytesToUInt32(&packet->buffer[8]);

// Calculate the size of the payload
// FIXME: skip over header extension
header_len += (packet->csrc_count * 4);

if (packet->extension) {
uint16_t ext_header_len;

if (packet->length < header_len + 4)
return -1;

/* ignore extension header ID at buffer + header_len */
ext_header_len = bytesToUInt16(&packet->buffer[header_len + 2]);
header_len += 4 + (ext_header_len * 4);
}

if (packet->length < header_len)
return -1;

packet->payload_length = packet->length - header_len;
packet->payload = packet->buffer + header_len;

// FIXME: Remove padding from payload_length
if (packet->padding) {
uint8_t padding_len;

if (packet->payload_length < 1)
return -1;

padding_len = packet->payload[packet->payload_length - 1];
if (padding_len < 1 || padding_len > packet->payload_length)
return -1;

packet->payload_length -= padding_len;
}

// Success
return 0;
Expand Down
9 changes: 6 additions & 3 deletions src/sdp.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ static void sdp_media_parse(mast_sdp_t *sdp, char* line, int line_num)
char *port = strsep(&line, " ");
char *proto = strsep(&line, " ");
char *fmt = strsep(&line, " ");
char *pEnd = NULL;

if (media == NULL || strcmp(media, "audio") != 0) {
mast_error("SDP media type is not audio: %s", media);
Expand All @@ -92,7 +93,7 @@ static void sdp_media_parse(mast_sdp_t *sdp, char* line, int line_num)
mast_error("SDP transport protocol is not RTP/AVP: %s", proto);
}

if (fmt == NULL || strlen(fmt) > 2) {
if (fmt == NULL || strtoul(fmt, &pEnd, 10) > 127 || *pEnd) {
mast_error("SDP media format is not valid: %s", fmt);
} else {
mast_sdp_set_payload_type(sdp, atoi(fmt));
Expand Down Expand Up @@ -133,8 +134,10 @@ static void sdp_attribute_parse(mast_sdp_t *sdp, char* line, int line_num)
strncpy(sdp->ptp_gmid, ptp_gmid, sizeof(sdp->ptp_gmid)-1);
}

if (ptp_domain && strcmp(ptp_domain, "0") != 0) {
mast_warn("PTP domain is not 0: %s", ptp_version);
if (ptp_domain) {
sdp->ptp_domain = atoi(ptp_domain);
if (sdp->ptp_domain)
mast_warn("PTP domain is not 0: %s", ptp_version);
}
} else {
mast_warn("SDP Clock Source is not PTP");
Expand Down
97 changes: 97 additions & 0 deletions src/sequence.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
Copyright (C) The Internet Society (2003). All Rights Reserved.

This document and translations of it may be copied and furnished to
others, and derivative works that comment on or otherwise explain it
or assist in its implementation may be prepared, copied, published
and distributed, in whole or in part, without restriction of any
kind, provided that the above copyright notice and this paragraph are
included on all such copies and derivative works. However, this
document itself may not be modified in any way, such as by removing
the copyright notice or references to the Internet Society or other
Internet organizations, except as needed for the purpose of
developing Internet standards in which case the procedures for
copyrights defined in the Internet Standards process must be
followed, or as required to translate it into languages other than
English.

The limited permissions granted above are perpetual and will not be
revoked by the Internet Society or its successors or assigns.

This document and the information contained herein is provided on an
"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*/

#include "mast.h"

void
mast_rtp_init_sequence(mast_rtp_sequence_state_t *s, uint16_t seq)
{
s->base_seq = seq;
s->max_seq = seq;
s->bad_seq = RTP_SEQ_MOD + 1;
s->cycles = 0;
s->received = 0;
s->received_prior = 0;
s->expected_prior = 0;
}

int
mast_rtp_update_sequence(mast_rtp_sequence_state_t *s, uint16_t seq)
{
uint16_t udelta = seq - s->max_seq;
#define MAX_DROPOUT 3000
#define MAX_MISORDER 100

/*
* Source is not valid until RTP_MIN_SEQUENTIAL packets with
* sequential sequence numbers have been received.
*/
if (s->probation) {
/* packet is in sequence */
if (seq == s->max_seq + 1) {
s->probation--;
s->max_seq = seq;
if (s->probation == 0) {
mast_rtp_init_sequence(s, seq);
s->received++;
return TRUE;
}
} else {
s->probation = RTP_MIN_SEQUENTIAL - 1;
s->max_seq = seq;
}
return FALSE;
} else if (udelta < MAX_DROPOUT) {
/* in order, with permissible gap */
if (seq < s->max_seq) {
/*
* Sequence number wrapped - count another 64K cycle.
*/
s->cycles += RTP_SEQ_MOD;
}
s->max_seq = seq;
} else if (udelta <= RTP_SEQ_MOD - MAX_MISORDER) {
/* the sequence number made a very large jump */
if (seq == s->bad_seq) {
/*
* Two sequential packets -- assume that the other side
* restarted without telling us so just re-sync
* (i.e., pretend this was the first packet).
*/
mast_rtp_init_sequence(s, seq);
} else {
s->bad_seq = (seq + 1) & (RTP_SEQ_MOD-1);
return FALSE;
}
} else {
/* duplicate or reordered packet */
}

s->received++;
return TRUE;
}