blob: be26c99dc44d6298eb902bb3d16f38565820554d [file] [log] [blame]
Harald Weltebe3c38c2023-11-23 22:08:51 +01001#include <osmocom/core/utils.h>
2#include <osmocom/gsm/rlp.h>
3
4struct rlp_testcase {
5 const char *name;
6 const char *encoded_hex;
7 struct osmo_rlp_frame_decoded decoded;
8};
9
10
11const struct rlp_testcase testcases[] = {
12 {
13 .name = "XID1",
14 .encoded_hex = "f95f1100213d313d414e6108510600000000000000000000000000c13c6b",
15 .decoded = {
16 .version = 0,
17 .ftype = OSMO_RLP_FT_U,
18 .u_ftype = OSMO_RLP_U_FT_XID,
19 .s_ftype = 0,
20 .c_r = 1,
21 .p_f = 1,
22 .s_bits = 0,
23 .n_s = 0,
24 .n_r = 0,
25 .fcs = 0x6b3cc1,
26 .info = { 0x11, 0x00, 0x21, 0x3d, 0x31, 0x3d, 0x41, 0x4e, 0x61, 0x08,
27 0x51, 0x06, },
28 .info_len = 25,
29 },
30 }, {
31 .name = "XID2",
32 .encoded_hex = "f95f1101213d313d41305106610774000008060000000000000000ba14a0",
33 .decoded = {
34 .version = 0,
35 .ftype = OSMO_RLP_FT_U,
36 .u_ftype = OSMO_RLP_U_FT_XID,
37 .s_ftype = 0,
38 .c_r = 1,
39 .p_f = 1,
40 .s_bits = 0,
41 .n_s = 0,
42 .n_r = 0,
43 .fcs = 0xa014ba,
44 .info = { 0x11, 0x01, 0x21, 0x3d, 0x31, 0x3d, 0x41, 0x30, 0x51, 0x06,
45 0x61, 0x07, 0x74, 0x00, 0x00, 0x08, 0x06, },
46 .info_len = 25,
47 },
48 }, {
49 .name = "SABM",
50 .encoded_hex = "f91f0000000000000000000000000000000000000000000000000063b2f3",
51 .decoded = {
52 .version = 0,
53 .ftype = OSMO_RLP_FT_U,
54 .u_ftype = OSMO_RLP_U_FT_SABM,
55 .s_ftype = 0,
56 .c_r = 1,
57 .p_f = 1,
58 .s_bits = 0,
59 .n_s = 0,
60 .n_r = 0,
61 .fcs = 0xf3b263,
62 .info = {},
63 .info_len = 0,
64 },
65 }, {
66 .name = "UA",
67 .encoded_hex = "f8330000000000000000000000000000000000000000000000000029d801",
68 .decoded = {
69 .version = 0,
70 .ftype = OSMO_RLP_FT_U,
71 .u_ftype = OSMO_RLP_U_FT_UA,
72 .s_ftype = 0,
73 .c_r = 0,
74 .p_f = 1,
75 .s_bits = 0,
76 .n_s = 0,
77 .n_r = 0,
78 .fcs = 0x01d829,
79 .info = {},
80 .info_len = 0,
81 },
82 }, {
83 .name = "IS1",
84 .encoded_hex = "01001f000000000000000000000000000000000000000000000000f174ad",
85 .decoded = {
86 .version = 0,
87 .ftype = OSMO_RLP_FT_IS,
88 .u_ftype = 0,
89 .s_ftype = 0,
90 .c_r = 1,
91 .p_f = 0,
92 .s_bits = 0,
93 .n_s = 0,
94 .n_r = 0,
95 .fcs = 0xad74f1,
96 .info = { 0x1f, },
97 .info_len = 25,
98 },
99 }, {
100 .name = "IS2",
101 .encoded_hex = "010401661fffffffffffffffffffffffffffffffffffffffffffff388cd3",
102 .decoded = {
103 .version = 0,
104 .ftype = OSMO_RLP_FT_IS,
105 .u_ftype = 0,
106 .s_ftype = 0,
107 .c_r = 1,
108 .p_f = 0,
109 .s_bits = 0,
110 .n_s = 0,
111 .n_r = 1,
112 .fcs = 0xd38c38,
113 .info = { 0x01, 0x66, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
114 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
115 0xff, 0xff, 0xff, 0xff, 0xff },
116 .info_len = 25,
117 },
118 }, {
119 .name = "DISC",
120 .encoded_hex = "f923000000000000000000000000000000000000000000000000007986f2",
121 .decoded = {
122 .version = 0,
123 .ftype = OSMO_RLP_FT_U,
124 .u_ftype = OSMO_RLP_U_FT_DISC,
125 .s_ftype = 0,
126 .c_r = 1,
127 .p_f = 1,
128 .s_bits = 0,
129 .n_s = 0,
130 .n_r = 0,
131 .fcs = 0xf28679,
132 .info = { },
133 .info_len = 0,
134 },
135 }
136};
137
138static void rlp_frame_print_u(const struct osmo_rlp_frame_decoded *rf)
139{
140 OSMO_ASSERT(rf->ftype == OSMO_RLP_FT_U);
141 printf("C/R=%u P/F=%u U %s (FCS=0x%06x) %s\n", rf->c_r, rf->p_f,
142 get_value_string(osmo_rlp_ftype_u_vals, rf->u_ftype),
143 rf->fcs,
144 rf->u_ftype == OSMO_RLP_U_FT_XID ? osmo_hexdump_nospc(rf->info, rf->info_len) : "");
145}
146
147static void rlp_frame_print_s(const struct osmo_rlp_frame_decoded *rf)
148{
149 OSMO_ASSERT(rf->ftype == OSMO_RLP_FT_S);
150 printf("C/R=%u P/F=%u S N(R)=%u %s (FCS=0x%06x)\n", rf->c_r, rf->p_f,
151 rf->n_r, get_value_string(osmo_rlp_ftype_s_vals, rf->s_ftype),
152 rf->fcs);
153}
154
155static void rlp_frame_print_is(const struct osmo_rlp_frame_decoded *rf)
156{
157 OSMO_ASSERT(rf->ftype == OSMO_RLP_FT_IS);
158 printf("C/R=%u P/F=%u IS N(R)=%u N(S)=%u %s (FCS=0x%06x) %s\n", rf->c_r, rf->p_f,
159 rf->n_r, rf->n_s, get_value_string(osmo_rlp_ftype_s_vals, rf->s_ftype),
160 rf->fcs, osmo_hexdump_nospc(rf->info, rf->info_len));
161}
162
163static void rlp_frame_print(const struct osmo_rlp_frame_decoded *rf)
164{
165 switch (rf->ftype) {
166 case OSMO_RLP_FT_U:
167 rlp_frame_print_u(rf);
168 break;
169 case OSMO_RLP_FT_S:
170 rlp_frame_print_s(rf);
171 break;
172 case OSMO_RLP_FT_IS:
173 rlp_frame_print_is(rf);
174 break;
175 default:
176 OSMO_ASSERT(0);
177 }
178}
179
180static void execute_rlp_test(const struct rlp_testcase *tc)
181{
182 struct osmo_rlp_frame_decoded decoded;
183 uint8_t inbuf[240/8];
184 int rc;
185
186 printf("=== STARTING TESTCASE '%s'\n", tc->name);
187
188 rc = osmo_hexparse(tc->encoded_hex, inbuf, sizeof(inbuf));
189 OSMO_ASSERT(rc == 240/8);
190
191 printf("Decoding %s:\n", tc->encoded_hex);
192 rc = osmo_rlp_decode(&decoded, 0, inbuf, rc);
193 OSMO_ASSERT(rc == 0);
194
195 printf("Comparing...\n");
196 rlp_frame_print(&decoded);
197 if (memcmp(&decoded, &tc->decoded, sizeof(decoded))) {
198 printf("DOESN'T MATCH EXPECTED DECODE:\n");
199 rlp_frame_print(&tc->decoded);
200 }
201
202 printf("Reencoding...\n");
203 uint8_t reencoded[240/8];
204 rc = osmo_rlp_encode(reencoded, sizeof(reencoded), &tc->decoded);
205 OSMO_ASSERT(rc == 240/8);
206 if (memcmp(inbuf, reencoded, sizeof(inbuf)))
207 printf("DOESN'T MATCH EXPECTED ENCODE FROM ABOVE\n");
208}
209
210int main(int argc, char **argv)
211{
212 for (unsigned int i = 0; i < ARRAY_SIZE(testcases); i++) {
213 const struct rlp_testcase *tc = &testcases[i];
214 execute_rlp_test(tc);
215 }
216
217}