blob: ff7740494816ee90a93783b127557092d7cf3d76 [file] [log] [blame]
Holger Hans Peter Freytherfaf1f642011-06-23 17:53:27 -04001#include <stdio.h>
2#include <stdlib.h>
3#include <inttypes.h>
4
5#include <openbsc/gprs_llc.h>
Holger Hans Peter Freytherce1b22e2014-08-04 14:22:13 +02006#include <openbsc/gprs_utils.h>
Holger Hans Peter Freytherfaf1f642011-06-23 17:53:27 -04007
Jacob Erlbeck0572ee02015-01-12 11:14:18 +01008#include <openbsc/debug.h>
9
10#include <osmocom/core/application.h>
Harald Welte23d77d52016-04-25 19:07:34 +020011#include <osmocom/gsm/gsup.h>
Jacob Erlbeck0572ee02015-01-12 11:14:18 +010012
Holger Hans Peter Freytherfaf1f642011-06-23 17:53:27 -040013#define ASSERT_FALSE(x) if (x) { printf("Should have returned false.\n"); abort(); }
14#define ASSERT_TRUE(x) if (!x) { printf("Should have returned true.\n"); abort(); }
15
16/**
17 * GSM 04.64 8.4.2 Receipt of unacknowledged information
18 */
19static int nu_is_retransmission(uint16_t nu, uint16_t vur)
20{
21 int ret = gprs_llc_is_retransmit(nu, vur);
22 printf("N(U) = %d, V(UR) = %d => %s\n", nu, vur,
23 ret == 1 ? "retransmit" : "new");
24 return ret;
25}
26
27static void test_8_4_2()
28{
29 printf("Testing gprs_llc_is_retransmit.\n");
30
31 ASSERT_FALSE(nu_is_retransmission(0, 0));
32 ASSERT_TRUE (nu_is_retransmission(0, 1));
33
34 /* expect 1... check for retransmissions */
35 ASSERT_TRUE (nu_is_retransmission(0, 1));
36 ASSERT_TRUE (nu_is_retransmission(511, 1));
37 ASSERT_TRUE (nu_is_retransmission(483, 1));
38 ASSERT_TRUE (nu_is_retransmission(482, 1));
39 ASSERT_FALSE(nu_is_retransmission(481, 1));
40
41 /* expect 511... check for retransmissions */
42 ASSERT_FALSE(nu_is_retransmission(0, 240)); // ahead
43 ASSERT_FALSE(nu_is_retransmission(0, 511)); // ahead
44 ASSERT_FALSE(nu_is_retransmission(1, 511)); // ahead
45 ASSERT_FALSE(nu_is_retransmission(511, 511)); // same
46 ASSERT_TRUE (nu_is_retransmission(510, 511)); // behind
47 ASSERT_TRUE (nu_is_retransmission(481, 511)); // behind
48 ASSERT_FALSE(nu_is_retransmission(479, 511)); // wrapped
49}
50
Holger Hans Peter Freytherce1b22e2014-08-04 14:22:13 +020051static void apn_round_trip(const uint8_t *input, size_t len, const char *wanted_output)
52{
53 char output[len ? len : 1];
54 uint8_t encoded[len + 50];
55 char *out_str;
56 int enc_len;
57
58 /* decode and verify we have what we want */
59 out_str = gprs_apn_to_str(output, input, len);
60 OSMO_ASSERT(out_str);
61 OSMO_ASSERT(out_str == &output[0]);
62 OSMO_ASSERT(strlen(out_str) == strlen(wanted_output));
63 OSMO_ASSERT(strcmp(out_str, wanted_output) == 0);
64
65 /* encode and verify it */
66 if (len != 0) {
67 enc_len = gprs_str_to_apn(encoded, ARRAY_SIZE(encoded), wanted_output);
68 OSMO_ASSERT(enc_len == len);
69 OSMO_ASSERT(memcmp(encoded, input, enc_len) == 0);
70 } else {
71 enc_len = gprs_str_to_apn(encoded, 0, wanted_output);
72 OSMO_ASSERT(enc_len == -1);
73 }
74}
75
76static void test_gsm_03_03_apn(void)
77{
78
79 {
80 /* test invalid writes */
81 const uint8_t ref[10] = { 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF };
82 uint8_t output[10];
83 int enc_len;
84
85 memcpy(output, ref, ARRAY_SIZE(output));
86 enc_len = gprs_str_to_apn(output, 0, "");
87 OSMO_ASSERT(enc_len == -1);
88 OSMO_ASSERT(memcmp(ref, output, ARRAY_SIZE(ref)) == 0);
89
90 memcpy(output, ref, ARRAY_SIZE(output));
91 enc_len = gprs_str_to_apn(output, 0, "foo");
92 OSMO_ASSERT(enc_len == -1);
93 OSMO_ASSERT(memcmp(ref, output, ARRAY_SIZE(ref)) == 0);
94
95 memcpy(output, ref, ARRAY_SIZE(output));
96 enc_len = gprs_str_to_apn(output, 1, "foo");
97 OSMO_ASSERT(enc_len == -1);
98 OSMO_ASSERT(memcmp(ref + 1, output + 1, ARRAY_SIZE(ref) - 1) == 0);
99
100 memcpy(output, ref, ARRAY_SIZE(output));
101 enc_len = gprs_str_to_apn(output, 2, "foo");
102 OSMO_ASSERT(enc_len == -1);
103 OSMO_ASSERT(memcmp(ref + 2, output + 2, ARRAY_SIZE(ref) - 2) == 0);
104
105 memcpy(output, ref, ARRAY_SIZE(output));
106 enc_len = gprs_str_to_apn(output, 3, "foo");
107 OSMO_ASSERT(enc_len == -1);
108 OSMO_ASSERT(memcmp(ref + 3, output + 3, ARRAY_SIZE(ref) - 3) == 0);
109 }
110
111 {
112 /* single empty label */
113 uint8_t input[] = { 0x0 };
114 const char *output = "";
115 apn_round_trip(input, ARRAY_SIZE(input), output);
116 }
117
118 {
119 /* no label */
120 uint8_t input[] = { };
121 const char *output = "";
122 apn_round_trip(input, ARRAY_SIZE(input), output);
123 }
124
125 {
126 /* single label with A */
127 uint8_t input[] = { 0x1, 65 };
128 const char *output = "A";
129 apn_round_trip(input, ARRAY_SIZE(input), output);
130 OSMO_ASSERT(gprs_apn_to_str(NULL, input, ARRAY_SIZE(input) - 1) == NULL);
131 }
132
133 {
134 uint8_t input[] = { 0x3, 65, 66, 67, 0x2, 90, 122 };
135 const char *output = "ABC.Zz";
136 char tmp[strlen(output) + 1];
137 apn_round_trip(input, ARRAY_SIZE(input), output);
138 OSMO_ASSERT(gprs_apn_to_str(tmp, input, ARRAY_SIZE(input) - 1) == NULL);
139 OSMO_ASSERT(gprs_apn_to_str(tmp, input, ARRAY_SIZE(input) - 2) == NULL);
140 OSMO_ASSERT(gprs_apn_to_str(tmp, input, ARRAY_SIZE(input) - 4) == NULL);
141 OSMO_ASSERT(gprs_apn_to_str(tmp, input, ARRAY_SIZE(input) - 5) == NULL);
142 OSMO_ASSERT(gprs_apn_to_str(tmp, input, ARRAY_SIZE(input) - 6) == NULL);
143 }
144}
145
Jacob Erlbeck79af67d2015-01-19 08:27:34 +0100146static void test_gprs_timer_enc_dec(void)
147{
148 int i, u, secs, tmr;
149 const int upper_secs_test_limit = 12000;
150 int dec_secs, last_dec_secs = -1;
151
152 printf("Test GPRS timer decoding/encoding\n");
153
154 /* Check gprs_tmr_to_secs with all 256 encoded values */
155 for (u = 0; u <= GPRS_TMR_DEACTIVATED; u += 32) {
156 fprintf(stderr, "Testing decoding with timer value unit %u\n",
157 u / 32);
158 for (i = 0; i < 32; i++) {
159 switch (u) {
160 case GPRS_TMR_2SECONDS:
161 OSMO_ASSERT(gprs_tmr_to_secs(u + i) == 2 * i);
162 break;
163
164 default:
165 case GPRS_TMR_MINUTE:
166 OSMO_ASSERT(gprs_tmr_to_secs(u + i) == 60 * i);
167 break;
168
169 case GPRS_TMR_6MINUTE:
170 OSMO_ASSERT(gprs_tmr_to_secs(u + i) == 360 * i);
171 break;
172
173 case GPRS_TMR_DEACTIVATED:
174 OSMO_ASSERT(gprs_tmr_to_secs(u + i) == -1);
175 break;
176 }
177
178 OSMO_ASSERT(gprs_tmr_to_secs(u + i) < upper_secs_test_limit);
179 }
180 }
181
182 /* Check gprs_secs_to_tmr_floor for secs that can exactly be
183 * represented as GPRS timer values */
184 for (i = 0; i < GPRS_TMR_DEACTIVATED; i++) {
185 int j;
186 secs = gprs_tmr_to_secs(i);
187 tmr = gprs_secs_to_tmr_floor(secs);
188 OSMO_ASSERT(secs == gprs_tmr_to_secs(tmr));
189
190 /* Check that the highest resolution is used */
191 for (j = 0; j < tmr; j++)
192 OSMO_ASSERT(secs != gprs_tmr_to_secs(j));
193 }
194 OSMO_ASSERT(GPRS_TMR_DEACTIVATED == gprs_secs_to_tmr_floor(-1));
195
196 /* Check properties of gprs_secs_to_tmr_floor */
197 for (secs = 0; secs <= upper_secs_test_limit; secs++) {
198 int tmr = gprs_secs_to_tmr_floor(secs);
199 int delta_secs = gprs_tmr_to_secs((tmr & ~0x1f) | 1);
200 dec_secs = gprs_tmr_to_secs(tmr);
201
202 /* Check floor */
203 OSMO_ASSERT(dec_secs <= secs);
204 /* Check monotonicity */
205 OSMO_ASSERT(dec_secs >= last_dec_secs);
206 /* Check max distance (<= resolution) */
207 OSMO_ASSERT(dec_secs - last_dec_secs <= delta_secs);
208
209 last_dec_secs = dec_secs;
210 }
211}
212
Jacob Erlbeck0572ee02015-01-12 11:14:18 +0100213const struct log_info_cat default_categories[] = {
214 [DGPRS] = {
215 .name = "DGPRS",
216 .description = "GPRS Packet Service",
217 .enabled = 0, .loglevel = LOGL_DEBUG,
218 },
219};
220
221static struct log_info info = {
222 .cat = default_categories,
223 .num_cat = ARRAY_SIZE(default_categories),
224};
225
Holger Hans Peter Freytherfaf1f642011-06-23 17:53:27 -0400226int main(int argc, char **argv)
227{
Jacob Erlbeck0572ee02015-01-12 11:14:18 +0100228 osmo_init_logging(&info);
229
Holger Hans Peter Freytherfaf1f642011-06-23 17:53:27 -0400230 test_8_4_2();
Holger Hans Peter Freytherce1b22e2014-08-04 14:22:13 +0200231 test_gsm_03_03_apn();
Jacob Erlbeck79af67d2015-01-19 08:27:34 +0100232 test_gprs_timer_enc_dec();
Holger Hans Peter Freytherfaf1f642011-06-23 17:53:27 -0400233
234 printf("Done.\n");
235 return EXIT_SUCCESS;
236}