aboutsummaryrefslogtreecommitdiffstats
path: root/src/gsm/iuup_crc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gsm/iuup_crc.c')
-rw-r--r--src/gsm/iuup_crc.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/src/gsm/iuup_crc.c b/src/gsm/iuup_crc.c
new file mode 100644
index 00000000..1cefe5a3
--- /dev/null
+++ b/src/gsm/iuup_crc.c
@@ -0,0 +1,95 @@
+#include <stdint.h>
+#include <stdio.h>
+
+#include <osmocom/core/crc8gen.h>
+#include <osmocom/core/crc16gen.h>
+
+static const struct osmo_crc8gen_code iuup_hdr_crc_code = {
+ .bits = 6,
+ .poly = 47,
+ .init = 0,
+ .remainder = 0,
+};
+
+static const struct osmo_crc16gen_code iuup_data_crc_code = {
+ .bits = 10,
+ .poly = 563,
+ .init = 0,
+ .remainder = 0,
+};
+
+static int iuup_get_payload_offset(const uint8_t *iuup_pdu)
+{
+ uint8_t pdu_type = iuup_pdu[0] >> 4;
+ switch (pdu_type) {
+ case 0:
+ case 14:
+ return 4;
+ case 1:
+ return 3;
+ default:
+ return -1;
+ }
+}
+
+int osmo_iuup_compute_payload_crc(const uint8_t *iuup_pdu, unsigned int pdu_len)
+{
+ ubit_t buf[1024*8];
+ uint8_t pdu_type;
+ int offset, payload_len_bytes;
+
+ if (pdu_len < 1)
+ return -1;
+
+ pdu_type = iuup_pdu[0] >> 4;
+
+ /* Type 1 has no CRC */
+ if (pdu_type == 1)
+ return 0;
+
+ offset = iuup_get_payload_offset(iuup_pdu, pdu_len);
+ if (offset < 0)
+ return offset;
+
+ if (pdu_len < offset)
+ return -1;
+
+ payload_len_bytes = pdu_eln - offset;
+ osmo_pbit2ubit(buf, iuup_pdu+offset, payload_len_bytes*8);
+ return osmo_crc16gen_compute_bits(&iuup_data_crc_code, buf, payload_len_bytes*8);
+}
+
+int osmo_iuup_compute_header_crc(const uint8_t *iuup_pdu, unsigned int pdu_len)
+{
+ ubit_t buf[2*8];
+
+ if (pdu_len < 2)
+ return -1;
+
+ osmo_pbit2ubit(buf, iuup_pdu, 2*8);
+ return osmo_crc8gen_compute_bits(&iuup_hdr_crc_code, buf, 2*8);
+}
+
+#if 0
+/* Frame 29 of MobileOriginatingCall_AMR.cap */
+const uint8_t iuup_frame29[] = {
+ 0x02, 0x00, 0x7d, 0x27, 0x55, 0x00, 0x88, 0xb6, 0x66, 0x79, 0xe1, 0xe0,
+ 0x01, 0xe7, 0xcf, 0xf0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+
+int main(int argc, char **argv)
+{
+ ubit_t buf[1024*8];
+ int rc;
+
+ osmo_pbit2ubit(buf, iuup_frame29, 2*8);
+ rc = osmo_crc8gen_compute_bits(&iuup_hdr_crc_code, buf, 2*8);
+ printf("Header CRC = 0x%02x\n", rc);
+
+ osmo_pbit2ubit(buf, iuup_frame29+4, 31*8);
+ rc = osmo_crc16gen_compute_bits(&iuup_data_crc_code, buf, 31*8);
+ printf("Payload CRC = 0x%03x\n", rc);
+}
+#endif