blob: f4aec1f8c60504a38040e6a1dfab8df0fec02194 [file] [log] [blame]
Neels Hofmeyr306dc092018-09-30 05:01:20 +02001/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
2/* IuUP protocol handling, minimal implementation */
3
4#pragma once
5
6#include <osmocom/core/endian.h>
7#include <osmocom/core/msgb.h>
8
9#define OSMO_IUUP_HEADROOM 32
10
11enum osmo_iuup_pdu_type {
12 OSMO_IUUP_PDU_DATA_WITH_CRC = 0,
13 OSMO_IUUP_PDU_CONTROL_PROCEDURE = 14,
14};
15
16enum osmo_iuup_acknack {
17 OSMO_IUUP_ACKNACK_PROCEDURE = 0,
18 OSMO_IUUP_ACKNACK_ACK = 1,
19 OSMO_IUUP_ACKNACK_NACK = 2,
20};
21
22enum osmo_iuup_procedure {
23 OSMO_IUUP_PROC_INITIALIZATION = 0,
24 OSMO_IUUP_PROC_RATE_CONTROL = 1,
25 OSMO_IUUP_PROC_TIME_ALIGNMENT = 2,
26 OSMO_IUUP_PROC_ERROR_EVENT = 3,
27};
28
29enum osmo_iuup_frame_good {
30 OSMO_IUUP_FRAME_GOOD = 0,
31 OSMO_IUUP_FRAME_BAD = 1,
32 OSMO_IUUP_FRAME_BAD_DUE_TO_RADIO = 2,
33};
34
35struct osmo_iuup_hdr_ctrl {
36#if OSMO_IS_BIG_ENDIAN
37 uint8_t pdu_type:4,
38 ack_nack:2,
39 frame_nr:2;
40 uint8_t mode_version:4,
41 procedure:4;
42 uint8_t header_crc:6,
43 payload_crc_hi:2;
44 uint8_t payload_crc_lo;
45 uint8_t payload[0];
46#elif OSMO_IS_LITTLE_ENDIAN
47 uint8_t frame_nr:2,
48 ack_nack:2,
49 pdu_type:4;
50 uint8_t procedure:4,
51 mode_version:4;
52 uint8_t payload_crc_hi:2,
53 header_crc:6;
54 uint8_t payload_crc_lo;
55 uint8_t payload[0];
56#endif
57} __attribute__((packed));
58
59union osmo_iuup_hdr_ctrl_payload {
60 struct {
61#if OSMO_IS_BIG_ENDIAN
62 uint8_t spare:3,
63 iptis_present:1,
64 subflows:3,
65 chain:1;
66#elif OSMO_IS_LITTLE_ENDIAN
67 uint8_t spare:3,
68 iptis_present:1,
69 subflows:3,
70 chain:1;
71#endif
72 } initialization;
73
74 struct {
75#if OSMO_IS_BIG_ENDIAN
76 uint8_t error_distance:2,
77 error_cause:6;
78#elif OSMO_IS_LITTLE_ENDIAN
79 uint8_t error_cause:6,
80 error_distance:2;
81#endif
82 } error_event;
83};
84
85extern const struct value_string osmo_iuup_error_cause_names[];
86static inline const char *osmo_iuup_error_cause_name(uint8_t val)
87{ return get_value_string(osmo_iuup_error_cause_names, val); }
88
89struct osmo_iuup_hdr_data {
90#if OSMO_IS_BIG_ENDIAN
91 uint8_t pdu_type:4,
92 frame_nr:4;
93 uint8_t frame_good:2,
94 rfci:6;
95 uint8_t header_crc:6,
96 payload_crc_hi:2;
97 uint8_t payload_crc_lo;
98#elif OSMO_IS_LITTLE_ENDIAN
99 uint8_t frame_nr:4,
100 pdu_type:4;
101 uint8_t rfci:6,
102 frame_good:2;
103 uint8_t payload_crc_hi:2,
104 header_crc:6;
105 uint8_t payload_crc_lo;
106#endif
107 uint8_t payload[0];
108} __attribute__((packed));
109
110int osmo_iuup_classify(bool log_errors,
111 const char *log_label,
112 struct msgb *pdu,
113 struct osmo_iuup_hdr_ctrl **is_ctrl,
114 struct osmo_iuup_hdr_data **is_data);
115bool osmo_iuup_is_init(struct msgb *pdu);
116void osmo_iuup_make_init_ack(struct msgb *ack);
117void osmo_iuup_set_checksums(uint8_t *iuup_header_and_payload, unsigned int header_and_payload_len);