view libgsmhr1/rtp_in.c @ 586:b21ea4ab586d

libgsmhr1: update for TW-TS-002 version 1.2.0 The component of libgsmhr1 being changed is RTP input functions; the change is accepting FT=1 (invalid SID) frames both with and without payload data bits.
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 10 Mar 2025 02:03:31 +0000 (3 weeks ago)
parents cc3a831712a4
children
line wrap: on
line source
/*
 * The function implemented in this module takes whatever HRv1 payload format
 * came in from RTP (can be RFC 5993 with or without TW-TS-002 extensions,
 * can be bare TS 101 318, can be zero-length or missing payload) and turns it
 * into canonical TW-TS-002 format, be it for storage or for immediate
 * further processing.
 */

#include <stdint.h>
#include <string.h>
#include "tw_gsmhr.h"

int gsmhr_rtp_in_preen(const uint8_t *rtp_in, unsigned rtp_in_len,
			uint8_t *canon_pl)
{
	int ft;

	switch (rtp_in_len) {
	case 0:
		/* BFI-no-data, but not an invalid RTP input per se */
		canon_pl[0] = 0x70;
		return 0;
	case 1:
		/*
		 * This length is valid only if the payload is in
		 * RFC 5993 or TW-TS-002 format with FT=1 or FT=7.
		 */
		if (rtp_in[0] & 0x80)
			goto bad_rtp_input;
		ft = rtp_in[0] >> 4;
		switch (ft) {
		case 1:
			if (rtp_in[0] & 0x04)
				goto bad_rtp_input;
			/* FALL THRU */
		case 7:
			canon_pl[0] = rtp_in[0];
			return 0;
		default:
			goto bad_rtp_input;
		}
	case GSMHR_FRAME_LEN_RPF:
		/*
		 * The length is that of a TS 101 318 payload.
		 * No further checks can be done: every possible
		 * bit pattern is a valid payload in this format.
		 * But we do need to check for a perfect SID
		 * (the only kind of SID this format allows)
		 * and mark it accordingly in the output.
		 */
		canon_pl[0] = gsmhr_ts101318_is_perfect_sid(rtp_in) << 4;
		memcpy(canon_pl + 1, rtp_in, GSMHR_FRAME_LEN_RPF);
		return 0;
	case GSMHR_FRAME_LEN_5993:
		/*
		 * This length is valid only if the payload is in
		 * RFC 5993 or TW-TS-002 format with FT=0, FT=2 or FT=6.
		 */
		if (rtp_in[0] & 0x80)
			goto bad_rtp_input;
		ft = rtp_in[0] >> 4;
		switch (ft) {
		case 1:
			if (!(rtp_in[0] & 0x04))
				goto bad_rtp_input;
			/* FALL THRU */
		case 0:
		case 2:
		case 6:
			memcpy(canon_pl, rtp_in, GSMHR_FRAME_LEN_5993);
			return 0;
		default:
			goto bad_rtp_input;
		}
	default:
	bad_rtp_input:
		/*
		 * Treat it like BFI-no-data, and tell the caller
		 * that we received an invalid RTP payload.
		 */
		canon_pl[0] = 0x70;
		return -1;
	}
}