@@ -1,6 +1,7 @@
#pragma once
#include <stdint.h>
+#include <stdbool.h>
#include <osmocom/core/utils.h>
@@ -41,6 +42,8 @@
AMR_GOOD = 1
};
+bool osmo_fr_check_sid(uint8_t *rtp_payload, size_t payload_len);
+bool osmo_hr_check_sid(uint8_t *rtp_payload, size_t payload_len);
int osmo_amr_rtp_enc(uint8_t *payload, uint8_t cmr, enum osmo_amr_type ft,
enum osmo_amr_quality bfi);
int osmo_amr_rtp_dec(const uint8_t *payload, int payload_len, uint8_t *cmr,
@@ -22,6 +22,10 @@
*/
#include <stdint.h>
+#include <stdbool.h>
+
+#include <osmocom/core/bitvec.h>
+#include <osmocom/core/utils.h>
/* GSM FR - subjective importance bit ordering */
/* This array encodes GSM 05.03 Table 2.
@@ -292,3 +296,38 @@
11, /* LARc1:0 */
29, /* LARc5:0 */
};
+
+/*! \brief Check whether RTP frame contains FR SID code word according to
+ * TS 101 318 §5.1.2
+ * \param[in] rtp_payload Buffer with RTP payload
+ * \param[in] payload_len Length of payload
+ * \returns true if code word is found, false otherwise
+ */
+bool osmo_fr_check_sid(uint8_t *rtp_payload, size_t payload_len)
+{
+ struct bitvec bv;
+ uint16_t i, z_bits[] = { 59, 60, 62, 63, 65, 66, 68, 69, 71, 72, 74, 75,
+ 77, 78, 80, 81, 83, 84, 86, 87, 89, 90, 92, 93,
+ 95, 96, 115, 116, 118, 119, 121, 122, 124, 125,
+ 127, 128, 130, 131, 133, 134, 136, 137, 139,
+ 140, 142, 143, 145, 146, 148, 149, 151, 152,
+ 171, 172, 174, 175, 177, 178, 180, 181, 183,
+ 184, 186, 187, 189, 190, 192, 193, 195, 196,
+ 198, 199, 201, 202, 204, 205, 207, 208, 227,
+ 228, 230, 231, 233, 234, 236, 237, 239, 242,
+ 245, 248, 251, 254, 257, 260, 263 };
+
+ /* signature does not match Full Rate SID */
+ if ((rtp_payload[0] >> 4) != 0xD)
+ return false;
+
+ bv.data = rtp_payload;
+ bv.data_len = payload_len;
+
+ /* code word is all 0 at given bits, numbered from 1 */
+ for (i = 0; i < ARRAY_SIZE(z_bits); i++)
+ if (bitvec_get_bit_pos(&bv, z_bits[i]) != ZERO)
+ return false;
+
+ return true;
+}
@@ -22,6 +22,10 @@
*/
#include <stdint.h>
+#include <stdbool.h>
+
+#include <osmocom/core/bitvec.h>
+#include <osmocom/core/utils.h>
/* GSM HR unvoiced (mode=0) frames - subjective importance bit ordering */
/* This array encode mapping between GSM 05.03 Table 3a (bits
@@ -260,3 +264,31 @@
82, /* Code 3:6 */
81, /* Code 3:7 */
};
+
+static inline uint16_t mask(const uint8_t msb)
+{
+ const uint16_t m = (uint16_t)1 << (msb - 1);
+ return (m - 1) ^ m;
+}
+
+/*! \brief Check whether RTP frame contains HR SID code word according to
+ * TS 101 318 §5.2.2
+ * \param[in] rtp_payload Buffer with RTP payload
+ * \param[in] payload_len Length of payload
+ * \returns true if code word is found, false otherwise
+ */
+bool osmo_hr_check_sid(uint8_t *rtp_payload, size_t payload_len)
+{
+ uint8_t i, bits[] = { 1, 2, 8, 9, 5, 4, 9, 5, 4, 9, 5, 4, 9, 5 };
+ struct bitvec bv;
+ bv.data = rtp_payload;
+ bv.data_len = payload_len;
+ bv.cur_bit = 33;
+
+ /* code word is all 1 at given bits, numbered from 1, MODE is always 3 */
+ for (i = 0; i < ARRAY_SIZE(bits); i++)
+ if (bitvec_get_uint(&bv, bits[i]) != mask(bits[i]))
+ return false;
+
+ return true;
+}
@@ -20,6 +20,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <stdbool.h>
#include <osmocom/core/utils.h>
#include <osmocom/codec/codec.h>
@@ -68,6 +69,26 @@
cmpr(_cmr, cmr), cmpr(_ft, ft), cmpr(_bfi, bfi), cmi, sti);
}
+uint8_t fr[] = {0xd8, 0xa9, 0xb5, 0x1d, 0xda, 0xa8, 0x82, 0xcc, 0xec, 0x52,
+ 0x29, 0x05, 0xa8, 0xc3, 0xe3, 0x0e, 0xb0, 0x89, 0x7a, 0xee,
+ 0x42, 0xca, 0xc4, 0x97, 0x22, 0xe6, 0x9e, 0xa8, 0xb8, 0xec,
+ 0x52, 0x26, 0xbd};
+uint8_t sid_fr[] = {0xd7, 0x27, 0x93, 0xe5, 0xe3, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+uint8_t hr[] = {0x06, 0x46, 0x76, 0xb1, 0x8e, 0x48, 0x9a, 0x2f, 0x5e, 0x4c,
+ 0x22, 0x2b, 0x62, 0x25};
+uint8_t sid_hr[] = {0x03, 0x8e, 0xb6, 0xcb, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff};
+
+static void test_sid_xr(uint8_t *t, size_t len, bool hr)
+{
+ printf("%s SID ? %s:: %d\n", hr ? "HR" : "FR", osmo_hexdump(t, len),
+ hr ? osmo_hr_check_sid(t, len) : osmo_fr_check_sid(t, len));
+}
+
int main(int argc, char **argv)
{
printf("AMR RTP payload decoder test:\n");
@@ -79,6 +100,13 @@
test_amr_rt(AMR_12_2, AMR_12_2, AMR_GOOD);
test_amr_rt(AMR_7_40, AMR_7_40, AMR_BAD);
test_amr_rt(AMR_7_40, AMR_7_40, AMR_GOOD);
+ printf("FR RTP payload SID test:\n");
+ test_sid_xr(sid_fr, 33, false);
+ test_sid_xr(fr, 33, false);
+
+ printf("HR RTP payload SID test:\n");
+ test_sid_xr(sid_hr, 14, true);
+ test_sid_xr(hr, 14, true);
return 0;
}
@@ -7,3 +7,9 @@
[33/33] AMR 12,2 kbit/s (GSM-EFR), CMR: OK, FT: OK, BFI: OK, CMI: -1, STI: -1
[21/21] AMR 7,40 kbit/s (TDMA-EFR), CMR: OK, FT: OK, BFI: OK, CMI: -1, STI: -1
[21/21] AMR 7,40 kbit/s (TDMA-EFR), CMR: OK, FT: OK, BFI: OK, CMI: -1, STI: -1
+FR RTP payload SID test:
+FR SID ? d7 27 93 e5 e3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 :: 1
+FR SID ? d8 a9 b5 1d da a8 82 cc ec 52 29 05 a8 c3 e3 0e b0 89 7a ee 42 ca c4 97 22 e6 9e a8 b8 ec 52 26 bd :: 0
+HR RTP payload SID test:
+HR SID ? 03 8e b6 cb ff ff ff ff ff ff ff ff ff ff :: 1
+HR SID ? 06 46 76 b1 8e 48 9a 2f 5e 4c 22 2b 62 25 :: 0