# HG changeset patch # User Mychaela Falconia # Date 1718434357 0 # Node ID cc3a831712a47f53a17b516058ec4037fe58442c # Parent 45bf34451dd7d6f4f577f68f26b64070043a8888 libgsmhr1: implement arbitrary RTP input diff -r 45bf34451dd7 -r cc3a831712a4 libgsmhr1/Makefile --- a/libgsmhr1/Makefile Sat Jun 15 06:22:21 2024 +0000 +++ b/libgsmhr1/Makefile Sat Jun 15 06:52:37 2024 +0000 @@ -1,4 +1,4 @@ -OBJS= pack_frame.o twts002_in.o unpack_frame.o +OBJS= pack_frame.o rtp_in.o twts002_in.o unpack_frame.o HDRS= tw_gsmhr.h LIB= libgsmhr1.a diff -r 45bf34451dd7 -r cc3a831712a4 libgsmhr1/rtp_in.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libgsmhr1/rtp_in.c Sat Jun 15 06:52:37 2024 +0000 @@ -0,0 +1,70 @@ +/* + * 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 +#include +#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; + if (ft == 1 || ft == 7) { + canon_pl[0] = rtp_in[0]; + return 0; + } else + 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; + if (ft == 0 || ft == 2 || ft == 6) { + memcpy(canon_pl, rtp_in, GSMHR_FRAME_LEN_5993); + return 0; + } else + 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; + } +} diff -r 45bf34451dd7 -r cc3a831712a4 libgsmhr1/tw_gsmhr.h --- a/libgsmhr1/tw_gsmhr.h Sat Jun 15 06:22:21 2024 +0000 +++ b/libgsmhr1/tw_gsmhr.h Sat Jun 15 06:52:37 2024 +0000 @@ -46,6 +46,9 @@ void gsmhr_encoder_twts002_out(const int16_t *param, uint8_t *payload); int gsmhr_decoder_twts002_in(const uint8_t *payload, int16_t *param); +int gsmhr_rtp_in_preen(const uint8_t *rtp_in, unsigned rtp_in_len, + uint8_t *canon_pl); + /* perfect SID detection and regeneration */ int gsmhr_ts101318_is_perfect_sid(const uint8_t *payload);