blob: e972cf4e8f7bb0159aa368e129f7e132f72e97ce [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>
37#include <osmocom/vty/vty.h>
38}
39
40
41void *tall_pcu_ctx;
42int16_t spoof_mnc = 0, spoof_mcc = 0;
43
Jacob Erlbeckb671dbf2015-06-15 14:32:33 +020044static void enqueue_data(gprs_llc_queue *queue, const uint8_t *data, size_t len,
45 gprs_llc_queue::MetaInfo *info = 0)
Jacob Erlbeck626369c2015-06-15 11:04:25 +020046{
47 struct timeval *tv;
48 uint8_t *msg_data;
49 struct msgb *llc_msg = msgb_alloc(len + sizeof(*tv) * 2,
50 "llc_pdu_queue");
51
Jacob Erlbeck626369c2015-06-15 11:04:25 +020052 msg_data = (uint8_t *)msgb_put(llc_msg, len);
53
54 memcpy(msg_data, data, len);
55
Jacob Erlbeckb671dbf2015-06-15 14:32:33 +020056 queue->enqueue(llc_msg, info);
Jacob Erlbeck626369c2015-06-15 11:04:25 +020057}
58
Jacob Erlbeckb671dbf2015-06-15 14:32:33 +020059static void dequeue_and_check(gprs_llc_queue *queue, const uint8_t *exp_data,
60 size_t len, const gprs_llc_queue::MetaInfo *exp_info = 0)
Jacob Erlbeck626369c2015-06-15 11:04:25 +020061{
62 struct msgb *llc_msg;
63 uint8_t *msg_data;
Jacob Erlbeckb671dbf2015-06-15 14:32:33 +020064 const gprs_llc_queue::MetaInfo *info_res;
Jacob Erlbeck626369c2015-06-15 11:04:25 +020065
Jacob Erlbeckb671dbf2015-06-15 14:32:33 +020066 llc_msg = queue->dequeue(&info_res);
Jacob Erlbeck626369c2015-06-15 11:04:25 +020067 OSMO_ASSERT(llc_msg != NULL);
68
Jacob Erlbeckb671dbf2015-06-15 14:32:33 +020069 fprintf(stderr, "dequeued msg, length %d (expected %d), data %s\n",
70 msgb_length(llc_msg), len, msgb_hexdump(llc_msg));
Jacob Erlbeck626369c2015-06-15 11:04:25 +020071
72 OSMO_ASSERT(msgb_length(llc_msg) == len);
73 msg_data = msgb_data(llc_msg);
74
75 OSMO_ASSERT(memcmp(msg_data, exp_data, len) == 0);
Jacob Erlbeckb671dbf2015-06-15 14:32:33 +020076
77 if (exp_info)
78 OSMO_ASSERT(memcmp(exp_info, info_res, sizeof(*exp_info)) == 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,
84 gprs_llc_queue::MetaInfo *info = 0)
Jacob Erlbeck626369c2015-06-15 11:04:25 +020085{
Jacob Erlbeckb671dbf2015-06-15 14:32:33 +020086 enqueue_data(queue, (uint8_t *)(message), strlen(message), info);
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;
99
100 printf("=== start %s ===\n", __func__);
101
102 queue.init();
103 OSMO_ASSERT(queue.size() == 0);
Jacob Erlbeck07eb6552015-06-15 11:05:44 +0200104 OSMO_ASSERT(queue.octets() == 0);
Jacob Erlbeck626369c2015-06-15 11:04:25 +0200105
106 enqueue_data(&queue, "LLC message");
107 OSMO_ASSERT(queue.size() == 1);
Jacob Erlbeck07eb6552015-06-15 11:05:44 +0200108 OSMO_ASSERT(queue.octets() == 11);
Jacob Erlbeck626369c2015-06-15 11:04:25 +0200109
110 enqueue_data(&queue, "other LLC message");
111 OSMO_ASSERT(queue.size() == 2);
Jacob Erlbeck07eb6552015-06-15 11:05:44 +0200112 OSMO_ASSERT(queue.octets() == 28);
Jacob Erlbeck626369c2015-06-15 11:04:25 +0200113
114 dequeue_and_check(&queue, "LLC message");
115 OSMO_ASSERT(queue.size() == 1);
Jacob Erlbeck07eb6552015-06-15 11:05:44 +0200116 OSMO_ASSERT(queue.octets() == 17);
Jacob Erlbeck626369c2015-06-15 11:04:25 +0200117
118 dequeue_and_check(&queue, "other LLC message");
119 OSMO_ASSERT(queue.size() == 0);
Jacob Erlbeck07eb6552015-06-15 11:05:44 +0200120 OSMO_ASSERT(queue.octets() == 0);
Jacob Erlbeck626369c2015-06-15 11:04:25 +0200121
122 enqueue_data(&queue, "LLC");
123 OSMO_ASSERT(queue.size() == 1);
Jacob Erlbeck07eb6552015-06-15 11:05:44 +0200124 OSMO_ASSERT(queue.octets() == 3);
Jacob Erlbeck626369c2015-06-15 11:04:25 +0200125
126 queue.clear(NULL);
127 OSMO_ASSERT(queue.size() == 0);
Jacob Erlbeck07eb6552015-06-15 11:05:44 +0200128 OSMO_ASSERT(queue.octets() == 0);
Jacob Erlbeck626369c2015-06-15 11:04:25 +0200129
130 printf("=== end %s ===\n", __func__);
131}
132
Jacob Erlbeckb671dbf2015-06-15 14:32:33 +0200133static void test_llc_meta()
134{
135 gprs_llc_queue queue;
Jacob Erlbeck34cf1562015-06-29 10:21:52 +0200136 gprs_llc_queue::MetaInfo info1;
137 gprs_llc_queue::MetaInfo info2;
138
139 info1.recv_time.tv_sec = 123456777;
140 info1.recv_time.tv_usec = 123456;
141 info1.expire_time.tv_sec = 123456789;
142 info1.expire_time.tv_usec = 987654;
143
144 info2.recv_time.tv_sec = 987654321;
145 info2.recv_time.tv_usec = 547352;
146 info2.expire_time.tv_sec = 987654327;
147 info2.expire_time.tv_usec = 867252;
Jacob Erlbeckb671dbf2015-06-15 14:32:33 +0200148
149 printf("=== start %s ===\n", __func__);
150
151 queue.init();
152 OSMO_ASSERT(queue.size() == 0);
153 OSMO_ASSERT(queue.octets() == 0);
154
155 enqueue_data(&queue, "LLC message 1", &info1);
156 enqueue_data(&queue, "LLC message 2", &info2);
157
158 dequeue_and_check(&queue, "LLC message 1", &info1);
159 dequeue_and_check(&queue, "LLC message 2", &info2);
160
161 queue.clear(NULL);
162 OSMO_ASSERT(queue.size() == 0);
163 OSMO_ASSERT(queue.octets() == 0);
164
165 printf("=== end %s ===\n", __func__);
166}
167
Jacob Erlbeck257b6302015-08-21 18:07:47 +0200168static void test_llc_merge()
169{
170 gprs_llc_queue queue1;
171 gprs_llc_queue queue2;
172 gprs_llc_queue::MetaInfo info = {0};
173
174 printf("=== start %s ===\n", __func__);
175
176 queue1.init();
177 queue2.init();
178
179 info.recv_time.tv_sec += 1;
180 enqueue_data(&queue1, "*A*", &info);
181
182 info.recv_time.tv_sec += 1;
183 enqueue_data(&queue1, "*B*", &info);
184
185 info.recv_time.tv_sec += 1;
186 enqueue_data(&queue2, "*C*", &info);
187
188 info.recv_time.tv_sec += 1;
189 enqueue_data(&queue1, "*D*", &info);
190
191 info.recv_time.tv_sec += 1;
192 enqueue_data(&queue2, "*E*", &info);
193
194 OSMO_ASSERT(queue1.size() == 3);
195 OSMO_ASSERT(queue1.octets() == 9);
196 OSMO_ASSERT(queue2.size() == 2);
197 OSMO_ASSERT(queue2.octets() == 6);
198
199 queue2.move_and_merge(&queue1);
200
201 OSMO_ASSERT(queue1.size() == 0);
202 OSMO_ASSERT(queue1.octets() == 0);
203 OSMO_ASSERT(queue2.size() == 5);
204 OSMO_ASSERT(queue2.octets() == 15);
205
206 dequeue_and_check(&queue2, "*A*");
207 dequeue_and_check(&queue2, "*B*");
208 dequeue_and_check(&queue2, "*C*");
209 dequeue_and_check(&queue2, "*D*");
210 dequeue_and_check(&queue2, "*E*");
211
212 OSMO_ASSERT(queue2.size() == 0);
213 OSMO_ASSERT(queue2.octets() == 0);
214
215 printf("=== end %s ===\n", __func__);
216}
217
Jacob Erlbeck626369c2015-06-15 11:04:25 +0200218static const struct log_info_cat default_categories[] = {
219 {"DPCU", "", "GPRS Packet Control Unit (PCU)", LOGL_INFO, 1},
220};
221
222static int filter_fn(const struct log_context *ctx,
223 struct log_target *tar)
224{
225 return 1;
226}
227
228const struct log_info debug_log_info = {
229 filter_fn,
230 (struct log_info_cat*)default_categories,
231 ARRAY_SIZE(default_categories),
232};
233
234int main(int argc, char **argv)
235{
236 struct vty_app_info pcu_vty_info = {0};
237
238 tall_pcu_ctx = talloc_named_const(NULL, 1, "LlcTest context");
239 if (!tall_pcu_ctx)
240 abort();
241
242 msgb_set_talloc_ctx(tall_pcu_ctx);
243 osmo_init_logging(&debug_log_info);
244 log_set_use_color(osmo_stderr_target, 0);
245 log_set_print_filename(osmo_stderr_target, 0);
246 log_set_log_level(osmo_stderr_target, LOGL_INFO);
247
248 vty_init(&pcu_vty_info);
249 pcu_vty_init(&debug_log_info);
250
251 test_llc_queue();
Jacob Erlbeckb671dbf2015-06-15 14:32:33 +0200252 test_llc_meta();
Jacob Erlbeck257b6302015-08-21 18:07:47 +0200253 test_llc_merge();
Jacob Erlbeck626369c2015-06-15 11:04:25 +0200254
255 if (getenv("TALLOC_REPORT_FULL"))
256 talloc_report_full(tall_pcu_ctx, stderr);
257
258 return EXIT_SUCCESS;
259}
260
261extern "C" {
262void l1if_pdch_req() { abort(); }
263void l1if_connect_pdch() { abort(); }
264void l1if_close_pdch() { abort(); }
265void l1if_open_pdch() { abort(); }
266}