blob: bcfd4606b6afc29bf5a72fcacc90a7cabfcb0e90 [file] [log] [blame]
Alexander Couzens1c8785d2020-12-17 06:58:53 +01001/* test routines for NS connection handling
2 * (C) 2020 sysmocom - s.f.m.c. GmbH
3 * Author: Alexander Couzens <lynxis@fe80.eu>
4 *
5 * SPDX-License-Identifier: GPL-2.0+
6 */
7
8#undef _GNU_SOURCE
9#define _GNU_SOURCE
10
11#include <stdio.h>
12#include <stdlib.h>
13#include <unistd.h>
14#include <stdint.h>
15#include <string.h>
16#include <getopt.h>
17#include <dlfcn.h>
18#include <sys/types.h>
19#include <sys/socket.h>
20
21#include <osmocom/core/fsm.h>
22#include <osmocom/core/msgb.h>
23#include <osmocom/core/application.h>
24#include <osmocom/core/utils.h>
25#include <osmocom/core/logging.h>
26#include <osmocom/core/socket.h>
27#include <osmocom/core/talloc.h>
28#include <osmocom/core/write_queue.h>
29#include <osmocom/gprs/gprs_msgb.h>
30#include <osmocom/gprs/gprs_ns2.h>
31#include <osmocom/gprs/gprs_bssgp.h>
32
33#include "../../src/gb/gprs_ns2_internal.h"
34
35int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
36{
37 return -1;
38}
39
40static struct log_info info = {};
41
42static int ns_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
43{
44 return 0;
45}
46
Alexander Couzensaf5bfeb2021-01-17 20:12:37 +010047static void clear_pdus(struct gprs_ns2_vc_bind *bind)
Alexander Couzens1c8785d2020-12-17 06:58:53 +010048{
Alexander Couzensaf5bfeb2021-01-17 20:12:37 +010049 struct osmo_wqueue *queue = bind->priv;
50 osmo_wqueue_clear(queue);
Alexander Couzens1c8785d2020-12-17 06:58:53 +010051}
52
53struct gprs_ns2_vc_driver vc_driver_dummy = {
54 .name = "GB UDP dummy",
Alexander Couzensaf5bfeb2021-01-17 20:12:37 +010055 .free_bind = clear_pdus,
Alexander Couzens1c8785d2020-12-17 06:58:53 +010056};
57
58static int vc_sendmsg(struct gprs_ns2_vc *nsvc, struct msgb *msg)
59{
60 struct gprs_ns2_vc_bind *bind = nsvc->bind;
61 struct osmo_wqueue *queue = bind->priv;
62
63 osmo_wqueue_enqueue(queue, msg);
64 return 0;
65}
66
67static struct gprs_ns2_vc_bind *dummy_bind(struct gprs_ns2_inst *nsi, const char *name)
68{
69 struct gprs_ns2_vc_bind *bind = talloc_zero(nsi, struct gprs_ns2_vc_bind);
70 OSMO_ASSERT(bind);
71
72 bind->name = talloc_strdup(bind, name);
73 bind->driver = &vc_driver_dummy;
74 bind->ll = GPRS_NS2_LL_UDP;
75 bind->transfer_capability = 42;
76 bind->nsi = nsi;
77 bind->send_vc = vc_sendmsg;
78 bind->priv = talloc_zero(bind, struct osmo_wqueue);
79 struct osmo_wqueue *queue = bind->priv;
80
81 INIT_LLIST_HEAD(&bind->nsvc);
82 llist_add(&bind->list, &nsi->binding);
83 osmo_wqueue_init(queue, 100);
84
85 return bind;
86}
87
88void test_nse_transfer_cap(void *ctx)
89{
90 struct gprs_ns2_inst *nsi;
91 struct gprs_ns2_vc_bind *bind[2];
92 struct gprs_ns2_nse *nse;
93 struct gprs_ns2_vc *nsvc[3];
94
95 /* create a UDP dummy bind[0] with transfer cap 42.
96 * create nse (nsei 1001)
97 * create 2x nsvc with the same bind.
98 * nsvc[0] or nsvc[1] is alive (or both) cap == 42
99 *
100 * create a second bind with transfer cap == 23
101 * create 3rd nsvc with bind[1]
102 * transfer cap should be 42 + 23
103 */
104
105 printf("--- Testing NSE transfer cap\n");
106
107 printf("---- Create NSE + Binds\n");
108 nsi = gprs_ns2_instantiate(ctx, ns_prim_cb, NULL);
109 bind[0] = dummy_bind(nsi, "transfercap1");
110 bind[1] = dummy_bind(nsi, "transfercap2");
111 bind[1]->transfer_capability = 23;
112 nse = gprs_ns2_create_nse(nsi, 1001, GPRS_NS2_LL_UDP, NS2_DIALECT_STATIC_ALIVE);
113 OSMO_ASSERT(nse);
114
115 printf("---- Test with NSVC[0]\n");
Harald Welte603f4042020-11-29 17:39:19 +0100116 nsvc[0] = ns2_vc_alloc(bind[0], nse, false, NS2_VC_MODE_ALIVE, NULL);
Alexander Couzens1c8785d2020-12-17 06:58:53 +0100117 OSMO_ASSERT(nsvc[0]);
118 OSMO_ASSERT(ns2_count_transfer_cap(nse, 0) == 0);
119 nsvc[0]->fi->state = 3; /* HACK: 3 = GPRS_NS2_ST_UNBLOCKED */
120 ns2_nse_notify_unblocked(nsvc[0], true);
121 OSMO_ASSERT(ns2_count_transfer_cap(nse, 0) == 42);
122
123 printf("---- Test with NSVC[1]\n");
Harald Welte603f4042020-11-29 17:39:19 +0100124 nsvc[1] = ns2_vc_alloc(bind[0], nse, false, NS2_VC_MODE_ALIVE, NULL);
Alexander Couzens1c8785d2020-12-17 06:58:53 +0100125 OSMO_ASSERT(nsvc[1]);
126 OSMO_ASSERT(ns2_count_transfer_cap(nse, 0) == 42);
127 nsvc[1]->fi->state = 3; /* HACK: 3 = GPRS_NS2_ST_UNBLOCKED */
128 ns2_nse_notify_unblocked(nsvc[1], true);
129 OSMO_ASSERT(ns2_count_transfer_cap(nse, 0) == 42);
130
131 printf("---- Test with NSVC[2]\n");
Harald Welte603f4042020-11-29 17:39:19 +0100132 nsvc[2] = ns2_vc_alloc(bind[1], nse, false, NS2_VC_MODE_ALIVE, NULL);
Alexander Couzens1c8785d2020-12-17 06:58:53 +0100133 OSMO_ASSERT(nsvc[2]);
134 OSMO_ASSERT(ns2_count_transfer_cap(nse, 0) == 42);
135 nsvc[2]->fi->state = 3; /* HACK: 3 = GPRS_NS2_ST_UNBLOCKED */
136 ns2_nse_notify_unblocked(nsvc[2], true);
137 OSMO_ASSERT(ns2_count_transfer_cap(nse, 0) == 42 + 23);
138
139 printf("---- Test with NSVC[1] removed\n");
140 /* reset nsvc[1] to be unconfigured - shouldn't change anything */
141 nsvc[1]->fi->state = 0; /* HACK: 0 = GPRS_NS2_ST_UNCONFIGURED */
142 ns2_nse_notify_unblocked(nsvc[1], false);
143 OSMO_ASSERT(ns2_count_transfer_cap(nse, 0) == 42 + 23);
144
Alexander Couzensaca31b82021-01-17 20:15:20 +0100145 gprs_ns2_free(nsi);
Alexander Couzens1c8785d2020-12-17 06:58:53 +0100146 printf("--- Finish NSE transfer cap\n");
147
148}
149
150int main(int argc, char **argv)
151{
152 void *ctx = talloc_named_const(NULL, 0, "gprs_ns2_test");
153 osmo_init_logging2(ctx, &info);
154 log_set_use_color(osmo_stderr_target, 0);
155 log_set_print_filename(osmo_stderr_target, 0);
156 log_set_print_filename(osmo_stderr_target, 0);
157 log_set_log_level(osmo_stderr_target, LOGL_INFO);
158 setlinebuf(stdout);
159
160 printf("===== NS2 protocol test START\n");
161 test_nse_transfer_cap(ctx);
162 printf("===== NS2 protocol test END\n\n");
163
Alexander Couzense19b7962021-01-17 20:07:54 +0100164 talloc_free(ctx);
Alexander Couzens1c8785d2020-12-17 06:58:53 +0100165 exit(EXIT_SUCCESS);
166}