blob: 84164a0a49fb3c6a7394f0d3e49d51738e6730e5 [file] [log] [blame]
Jacob Erlbeck626369c2015-06-15 11:04:25 +02001/*
2 * LlcTest.cpp
3 *
4 * Copyright (C) 2015 by Sysmocom s.f.m.c. GmbH
5 *
6 * All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Affero General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU Affero General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23extern "C" {
24 #include <osmocom/core/linuxlist.h>
25}
26
27#include "llc.h"
28#include "gprs_debug.h"
29
30extern "C" {
31#include "pcu_vty.h"
32
33#include <osmocom/core/application.h>
34#include <osmocom/core/msgb.h>
35#include <osmocom/core/talloc.h>
36#include <osmocom/core/utils.h>
Pau Espin Pedrol5fc6e012020-02-26 20:05:33 +010037#include <osmocom/core/timer.h>
Jacob Erlbeck626369c2015-06-15 11:04:25 +020038#include <osmocom/vty/vty.h>
39}
40
41
42void *tall_pcu_ctx;
43int16_t spoof_mnc = 0, spoof_mcc = 0;
Neels Hofmeyrbdc55fa2018-02-21 00:39:07 +010044bool spoof_mnc_3_digits = false;
Jacob Erlbeck626369c2015-06-15 11:04:25 +020045
Jacob Erlbeckb671dbf2015-06-15 14:32:33 +020046static void enqueue_data(gprs_llc_queue *queue, const uint8_t *data, size_t len,
Pau Espin Pedrol5fc6e012020-02-26 20:05:33 +010047 const struct timeval *expire_time)
Jacob Erlbeck626369c2015-06-15 11:04:25 +020048{
49 struct timeval *tv;
50 uint8_t *msg_data;
51 struct msgb *llc_msg = msgb_alloc(len + sizeof(*tv) * 2,
52 "llc_pdu_queue");
53
Jacob Erlbeck626369c2015-06-15 11:04:25 +020054 msg_data = (uint8_t *)msgb_put(llc_msg, len);
55
56 memcpy(msg_data, data, len);
57
Pau Espin Pedrol5fc6e012020-02-26 20:05:33 +010058 queue->enqueue(llc_msg, expire_time);
Jacob Erlbeck626369c2015-06-15 11:04:25 +020059}
60
Jacob Erlbeckb671dbf2015-06-15 14:32:33 +020061static void dequeue_and_check(gprs_llc_queue *queue, const uint8_t *exp_data,
Pau Espin Pedrol5fc6e012020-02-26 20:05:33 +010062 size_t len, const gprs_llc_queue::MetaInfo *exp_info)
Jacob Erlbeck626369c2015-06-15 11:04:25 +020063{
64 struct msgb *llc_msg;
Jacob Erlbeckb671dbf2015-06-15 14:32:33 +020065 const gprs_llc_queue::MetaInfo *info_res;
Jacob Erlbeck626369c2015-06-15 11:04:25 +020066
Jacob Erlbeckb671dbf2015-06-15 14:32:33 +020067 llc_msg = queue->dequeue(&info_res);
Jacob Erlbeck626369c2015-06-15 11:04:25 +020068 OSMO_ASSERT(llc_msg != NULL);
69
Neels Hofmeyrd34646a2017-02-08 17:07:40 +010070 fprintf(stderr, "dequeued msg, length %u (expected %zu), data %s\n",
Jacob Erlbeckb671dbf2015-06-15 14:32:33 +020071 msgb_length(llc_msg), len, msgb_hexdump(llc_msg));
Jacob Erlbeck626369c2015-06-15 11:04:25 +020072
Maxd3a0d912019-03-05 16:15:01 +010073 if (!msgb_eq_data_print(llc_msg, exp_data, len))
74 fprintf(stderr, "check failed!\n");
Jacob Erlbeckb671dbf2015-06-15 14:32:33 +020075
Pau Espin Pedrol5fc6e012020-02-26 20:05:33 +010076 if (exp_info) {
77 OSMO_ASSERT(memcmp(&exp_info->recv_time, &info_res->recv_time, sizeof(info_res->recv_time)) == 0);
78 OSMO_ASSERT(memcmp(&exp_info->expire_time, &info_res->expire_time, sizeof(info_res->expire_time)) == 0);
79 }
Jacob Erlbeck626369c2015-06-15 11:04:25 +020080 msgb_free(llc_msg);
81}
82
Jacob Erlbeckb671dbf2015-06-15 14:32:33 +020083static void enqueue_data(gprs_llc_queue *queue, const char *message,
Pau Espin Pedrol5fc6e012020-02-26 20:05:33 +010084 const struct timeval *expire_time)
Jacob Erlbeck626369c2015-06-15 11:04:25 +020085{
Pau Espin Pedrol5fc6e012020-02-26 20:05:33 +010086 enqueue_data(queue, (uint8_t *)(message), strlen(message), expire_time);
Jacob Erlbeck626369c2015-06-15 11:04:25 +020087}
88
Jacob Erlbeckb671dbf2015-06-15 14:32:33 +020089static void dequeue_and_check(gprs_llc_queue *queue, const char *exp_message,
90 const gprs_llc_queue::MetaInfo *exp_info = 0)
Jacob Erlbeck626369c2015-06-15 11:04:25 +020091{
Jacob Erlbeckb671dbf2015-06-15 14:32:33 +020092 dequeue_and_check(queue,
93 (uint8_t *)(exp_message), strlen(exp_message), exp_info);
Jacob Erlbeck626369c2015-06-15 11:04:25 +020094}
95
96static void test_llc_queue()
97{
98 gprs_llc_queue queue;
Pau Espin Pedrol5fc6e012020-02-26 20:05:33 +010099 struct timeval expire_time = {0};
Jacob Erlbeck626369c2015-06-15 11:04:25 +0200100
101 printf("=== start %s ===\n", __func__);
102
103 queue.init();
104 OSMO_ASSERT(queue.size() == 0);
Jacob Erlbeck07eb6552015-06-15 11:05:44 +0200105 OSMO_ASSERT(queue.octets() == 0);
Jacob Erlbeck626369c2015-06-15 11:04:25 +0200106
Pau Espin Pedrol5fc6e012020-02-26 20:05:33 +0100107 enqueue_data(&queue, "LLC message", &expire_time);
Jacob Erlbeck626369c2015-06-15 11:04:25 +0200108 OSMO_ASSERT(queue.size() == 1);
Jacob Erlbeck07eb6552015-06-15 11:05:44 +0200109 OSMO_ASSERT(queue.octets() == 11);
Jacob Erlbeck626369c2015-06-15 11:04:25 +0200110
Pau Espin Pedrol5fc6e012020-02-26 20:05:33 +0100111 enqueue_data(&queue, "other LLC message", &expire_time);
Jacob Erlbeck626369c2015-06-15 11:04:25 +0200112 OSMO_ASSERT(queue.size() == 2);
Jacob Erlbeck07eb6552015-06-15 11:05:44 +0200113 OSMO_ASSERT(queue.octets() == 28);
Jacob Erlbeck626369c2015-06-15 11:04:25 +0200114
115 dequeue_and_check(&queue, "LLC message");
116 OSMO_ASSERT(queue.size() == 1);
Jacob Erlbeck07eb6552015-06-15 11:05:44 +0200117 OSMO_ASSERT(queue.octets() == 17);
Jacob Erlbeck626369c2015-06-15 11:04:25 +0200118
119 dequeue_and_check(&queue, "other LLC message");
120 OSMO_ASSERT(queue.size() == 0);
Jacob Erlbeck07eb6552015-06-15 11:05:44 +0200121 OSMO_ASSERT(queue.octets() == 0);
Jacob Erlbeck626369c2015-06-15 11:04:25 +0200122
Pau Espin Pedrol5fc6e012020-02-26 20:05:33 +0100123 enqueue_data(&queue, "LLC", &expire_time);
Jacob Erlbeck626369c2015-06-15 11:04:25 +0200124 OSMO_ASSERT(queue.size() == 1);
Jacob Erlbeck07eb6552015-06-15 11:05:44 +0200125 OSMO_ASSERT(queue.octets() == 3);
Jacob Erlbeck626369c2015-06-15 11:04:25 +0200126
127 queue.clear(NULL);
128 OSMO_ASSERT(queue.size() == 0);
Jacob Erlbeck07eb6552015-06-15 11:05:44 +0200129 OSMO_ASSERT(queue.octets() == 0);
Jacob Erlbeck626369c2015-06-15 11:04:25 +0200130
131 printf("=== end %s ===\n", __func__);
132}
133
Jacob Erlbeckb671dbf2015-06-15 14:32:33 +0200134static void test_llc_meta()
135{
136 gprs_llc_queue queue;
Pau Espin Pedrol5fc6e012020-02-26 20:05:33 +0100137 gprs_llc_queue::MetaInfo info1 = {0};
138 gprs_llc_queue::MetaInfo info2 = {0};
Jacob Erlbeckb671dbf2015-06-15 14:32:33 +0200139
140 printf("=== start %s ===\n", __func__);
141
142 queue.init();
143 OSMO_ASSERT(queue.size() == 0);
144 OSMO_ASSERT(queue.octets() == 0);
145
Pau Espin Pedrol5fc6e012020-02-26 20:05:33 +0100146 info1.recv_time.tv_sec = 123456777;
147 info1.recv_time.tv_usec = 123456;
148 info1.expire_time.tv_sec = 123456789;
149 info1.expire_time.tv_usec = 987654;
150 osmo_gettimeofday_override_time = info1.recv_time;
151 enqueue_data(&queue, "LLC message 1", &info1.expire_time);
152
Pau Espin Pedrol40d4e352020-03-11 13:06:13 +0100153 info2.recv_time.tv_sec = 123458000;
Pau Espin Pedrol5fc6e012020-02-26 20:05:33 +0100154 info2.recv_time.tv_usec = 547352;
Pau Espin Pedrol40d4e352020-03-11 13:06:13 +0100155 info2.expire_time.tv_sec = 123458006;
Pau Espin Pedrol5fc6e012020-02-26 20:05:33 +0100156 info2.expire_time.tv_usec = 867252;
157 osmo_gettimeofday_override_time = info2.recv_time;
158 enqueue_data(&queue, "LLC message 2", &info2.expire_time);
Jacob Erlbeckb671dbf2015-06-15 14:32:33 +0200159
160 dequeue_and_check(&queue, "LLC message 1", &info1);
161 dequeue_and_check(&queue, "LLC message 2", &info2);
162
163 queue.clear(NULL);
164 OSMO_ASSERT(queue.size() == 0);
165 OSMO_ASSERT(queue.octets() == 0);
166
167 printf("=== end %s ===\n", __func__);
168}
169
Jacob Erlbeck257b6302015-08-21 18:07:47 +0200170static void test_llc_merge()
171{
172 gprs_llc_queue queue1;
173 gprs_llc_queue queue2;
Pau Espin Pedrol5fc6e012020-02-26 20:05:33 +0100174 struct timeval expire_time = {0};
Jacob Erlbeck257b6302015-08-21 18:07:47 +0200175
176 printf("=== start %s ===\n", __func__);
177
178 queue1.init();
179 queue2.init();
180
Pau Espin Pedrol5fc6e012020-02-26 20:05:33 +0100181 osmo_gettimeofday_override_time.tv_sec += 1;
182 enqueue_data(&queue1, "*A*", &expire_time);
Jacob Erlbeck257b6302015-08-21 18:07:47 +0200183
Pau Espin Pedrol5fc6e012020-02-26 20:05:33 +0100184 osmo_gettimeofday_override_time.tv_sec += 1;
185 enqueue_data(&queue1, "*B*", &expire_time);
Jacob Erlbeck257b6302015-08-21 18:07:47 +0200186
Pau Espin Pedrol5fc6e012020-02-26 20:05:33 +0100187 osmo_gettimeofday_override_time.tv_sec += 1;
188 enqueue_data(&queue2, "*C*", &expire_time);
Jacob Erlbeck257b6302015-08-21 18:07:47 +0200189
Pau Espin Pedrol5fc6e012020-02-26 20:05:33 +0100190 osmo_gettimeofday_override_time.tv_sec += 1;
191 enqueue_data(&queue1, "*D*", &expire_time);
Jacob Erlbeck257b6302015-08-21 18:07:47 +0200192
Pau Espin Pedrol5fc6e012020-02-26 20:05:33 +0100193 osmo_gettimeofday_override_time.tv_sec += 1;
194 enqueue_data(&queue2, "*E*", &expire_time);
Jacob Erlbeck257b6302015-08-21 18:07:47 +0200195
196 OSMO_ASSERT(queue1.size() == 3);
197 OSMO_ASSERT(queue1.octets() == 9);
198 OSMO_ASSERT(queue2.size() == 2);
199 OSMO_ASSERT(queue2.octets() == 6);
200
201 queue2.move_and_merge(&queue1);
202
203 OSMO_ASSERT(queue1.size() == 0);
204 OSMO_ASSERT(queue1.octets() == 0);
205 OSMO_ASSERT(queue2.size() == 5);
206 OSMO_ASSERT(queue2.octets() == 15);
207
208 dequeue_and_check(&queue2, "*A*");
209 dequeue_and_check(&queue2, "*B*");
210 dequeue_and_check(&queue2, "*C*");
211 dequeue_and_check(&queue2, "*D*");
212 dequeue_and_check(&queue2, "*E*");
213
214 OSMO_ASSERT(queue2.size() == 0);
215 OSMO_ASSERT(queue2.octets() == 0);
216
217 printf("=== end %s ===\n", __func__);
218}
219
Jacob Erlbeck626369c2015-06-15 11:04:25 +0200220int main(int argc, char **argv)
221{
222 struct vty_app_info pcu_vty_info = {0};
223
224 tall_pcu_ctx = talloc_named_const(NULL, 1, "LlcTest context");
225 if (!tall_pcu_ctx)
226 abort();
227
Neels Hofmeyrd34646a2017-02-08 17:07:40 +0100228 msgb_talloc_ctx_init(tall_pcu_ctx, 0);
Neels Hofmeyr42f2d612018-04-01 16:54:40 +0200229 osmo_init_logging2(tall_pcu_ctx, &gprs_log_info);
Jacob Erlbeck626369c2015-06-15 11:04:25 +0200230 log_set_use_color(osmo_stderr_target, 0);
231 log_set_print_filename(osmo_stderr_target, 0);
232 log_set_log_level(osmo_stderr_target, LOGL_INFO);
Maxd3a0d912019-03-05 16:15:01 +0100233 log_parse_category_mask(osmo_stderr_target, "DPCU,3:DLGLOBAL,1:");
Jacob Erlbeck626369c2015-06-15 11:04:25 +0200234
235 vty_init(&pcu_vty_info);
Pau Espin Pedrolcd2ac562019-08-05 14:30:44 +0200236 pcu_vty_init();
Jacob Erlbeck626369c2015-06-15 11:04:25 +0200237
Pau Espin Pedrol5fc6e012020-02-26 20:05:33 +0100238 osmo_gettimeofday_override = true;
239 osmo_gettimeofday_override_time.tv_sec = 123456777;
240 osmo_gettimeofday_override_time.tv_usec = 123456;
241
Jacob Erlbeck626369c2015-06-15 11:04:25 +0200242 test_llc_queue();
Jacob Erlbeckb671dbf2015-06-15 14:32:33 +0200243 test_llc_meta();
Jacob Erlbeck257b6302015-08-21 18:07:47 +0200244 test_llc_merge();
Jacob Erlbeck626369c2015-06-15 11:04:25 +0200245
246 if (getenv("TALLOC_REPORT_FULL"))
247 talloc_report_full(tall_pcu_ctx, stderr);
248
249 return EXIT_SUCCESS;
250}
251
252extern "C" {
253void l1if_pdch_req() { abort(); }
254void l1if_connect_pdch() { abort(); }
255void l1if_close_pdch() { abort(); }
256void l1if_open_pdch() { abort(); }
257}