From 8f215c9fc948fe93c2e743df2d5d36df9dda01ce Mon Sep 17 00:00:00 2001 From: Alexander Couzens Date: Mon, 25 Jan 2021 15:27:56 +0100 Subject: tests: gprs_ns2: add unitdata unit test test sending unitdata over a alive and blocked NSVC. Change-Id: I2c44b711d004d2ca08e05d4f54519ad8dbd77c27 --- tests/gb/gprs_ns2_test.c | 139 ++++++++++++++++++++++++++++++++++++++++++++++ tests/gb/gprs_ns2_test.ok | 9 +++ 2 files changed, 148 insertions(+) diff --git a/tests/gb/gprs_ns2_test.c b/tests/gb/gprs_ns2_test.c index 44c9ce41..10f430df 100644 --- a/tests/gb/gprs_ns2_test.c +++ b/tests/gb/gprs_ns2_test.c @@ -39,9 +39,18 @@ int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx) } static struct log_info info = {}; +static struct osmo_wqueue *unitdata = NULL; static int ns_prim_cb(struct osmo_prim_hdr *oph, void *ctx) { + OSMO_ASSERT(oph->sap == SAP_NS); + if (oph->msg) { + if (oph->primitive == PRIM_NS_UNIT_DATA) { + osmo_wqueue_enqueue(unitdata, oph->msg); + } else { + msgb_free(oph->msg); + } + } return 0; } @@ -114,6 +123,46 @@ static struct gprs_ns2_vc_bind *dummy_bind(struct gprs_ns2_inst *nsi, const char return bind; } +static void free_loopback(struct gprs_ns2_vc_bind *bind) {} + +struct gprs_ns2_vc_driver vc_driver_loopback = { + .name = "loopback dummy", + .free_bind = free_loopback, +}; + +/* loopback the msg */ +static int loopback_sendmsg(struct gprs_ns2_vc *nsvc, struct msgb *msg) +{ + struct gprs_ns2_vc *target = nsvc->priv; + return ns2_recv_vc(target, msg); +} + +/* create a loopback nsvc object which can be used with ns2_tx_* functions. it's not fully registered etc. */ +static struct gprs_ns2_vc *loopback_nsvc(struct gprs_ns2_vc_bind *bind, struct gprs_ns2_vc *target) +{ + struct gprs_ns2_vc *nsvc = talloc_zero(bind, struct gprs_ns2_vc); + memcpy(nsvc, target, sizeof(struct gprs_ns2_vc)); + nsvc->bind = bind; + nsvc->priv = target; + return nsvc; +} + +/* a loop back bind to use the tx_ functions from gprs_ns2_message.c */ +static struct gprs_ns2_vc_bind *loopback_bind(struct gprs_ns2_inst *nsi, const char *name) +{ + struct gprs_ns2_vc_bind *bind = talloc_zero(nsi, struct gprs_ns2_vc_bind); + OSMO_ASSERT(bind); + bind->name = talloc_strdup(bind, name); + bind->driver = &vc_driver_loopback; + bind->ll = GPRS_NS2_LL_UDP; + bind->transfer_capability = 99; + bind->nsi = nsi; + bind->send_vc = loopback_sendmsg; + INIT_LLIST_HEAD(&bind->nsvc); + llist_add(&bind->list, &nsi->binding); + return bind; +} + void test_nse_transfer_cap(void *ctx) { struct gprs_ns2_inst *nsi; @@ -233,6 +282,93 @@ void test_block_unblock_nsvc(void *ctx) printf("--- Finish NSE block unblock nsvc\n"); } +static struct msgb *generate_unitdata(const char *msgname) +{ + struct gprs_ns_hdr *nsh; + struct msgb *msg = msgb_alloc_headroom(NS_ALLOC_SIZE, NS_ALLOC_HEADROOM, msgname); + OSMO_ASSERT(msg); + + msg->l2h = msgb_put(msg, sizeof(*nsh) + 6); + nsh = (struct gprs_ns_hdr *) msg->l2h; + nsh->pdu_type = NS_PDUT_UNITDATA; + nsh->data[0] = 0; /* sdu control */ + nsh->data[1] = 0; /* msb bvci */ + nsh->data[2] = 12; /* lsb bvci */ + nsh->data[3] = 0xab; /* first data byte */ + nsh->data[4] = 0xcd; + nsh->data[5] = 0xef; + + return msg; +} + +void test_unitdata(void *ctx) +{ + struct gprs_ns2_inst *nsi; + struct gprs_ns2_vc_bind *bind[2]; + struct gprs_ns2_vc_bind *loopbind; + struct gprs_ns2_nse *nse; + struct gprs_ns2_vc *nsvc[2]; + struct gprs_ns2_vc *loop[2]; + + struct msgb *msg, *other; + char idbuf[32]; + int i; + + printf("--- Testing unitdata test\n"); + osmo_wqueue_clear(unitdata); + printf("---- Create NSE + Binds\n"); + nsi = gprs_ns2_instantiate(ctx, ns_prim_cb, NULL); + bind[0] = dummy_bind(nsi, "bblock1"); + bind[1] = dummy_bind(nsi, "bblock2"); + loopbind = loopback_bind(nsi, "loopback"); + nse = gprs_ns2_create_nse(nsi, 1004, GPRS_NS2_LL_UDP, NS2_DIALECT_STATIC_RESETBLOCK); + OSMO_ASSERT(nse); + + for (i=0; i<2; i++) { + printf("---- Create NSVC[%d]\n", i); + snprintf(idbuf, sizeof(idbuf), "NSE%05u-dummy-%i", nse->nsei, i); + nsvc[i] = ns2_vc_alloc(bind[i], nse, false, NS2_VC_MODE_BLOCKRESET, idbuf); + loop[i] = loopback_nsvc(loopbind, nsvc[i]); + OSMO_ASSERT(nsvc[i]); + gprs_ns2_vc_fsm_start(nsvc[i]); + OSMO_ASSERT(!gprs_ns2_vc_is_unblocked(nsvc[i])); + ns2_tx_reset(loop[i], NS_CAUSE_OM_INTERVENTION); + ns2_tx_unblock(loop[i]); + OSMO_ASSERT(gprs_ns2_vc_is_unblocked(nsvc[i])); + } + + /* both nsvcs are unblocked and alive */ + printf("---- Send UNITDATA to NSVC[0]\n"); + msg = generate_unitdata("test_unitdata"); + ns2_recv_vc(nsvc[0], msg); + other = msgb_dequeue(&unitdata->msg_queue); + OSMO_ASSERT(msg == other); + other = msgb_dequeue(&unitdata->msg_queue); + OSMO_ASSERT(NULL == other); + + printf("---- Send Block NSVC[0]\n"); + ns2_vc_block(nsvc[0]); + ns2_tx_block_ack(loop[0]); + + /* try to receive a unitdata - this should be dropped & freed by NS */ + printf("---- Try to receive over blocked NSVC[0]\n"); + ns2_recv_vc(nsvc[0], msg); + other = msgb_dequeue(&unitdata->msg_queue); + OSMO_ASSERT(NULL == other); + + /* nsvc[1] should be still good */ + printf("---- Receive over NSVC[1]\n"); + msg = generate_unitdata("test_unitdata2"); + ns2_recv_vc(nsvc[1], msg); + other = msgb_dequeue(&unitdata->msg_queue); + OSMO_ASSERT(msg == other); + msgb_free(msg); + + gprs_ns2_free(nsi); + printf("--- Finish unitdata test\n"); +} + + int main(int argc, char **argv) { void *ctx = talloc_named_const(NULL, 0, "gprs_ns2_test"); @@ -241,11 +377,14 @@ int main(int argc, char **argv) log_set_print_filename(osmo_stderr_target, 0); log_set_print_filename(osmo_stderr_target, 0); log_set_log_level(osmo_stderr_target, LOGL_INFO); + unitdata = talloc_zero(ctx, struct osmo_wqueue); + osmo_wqueue_init(unitdata, 100); setlinebuf(stdout); printf("===== NS2 protocol test START\n"); test_nse_transfer_cap(ctx); test_block_unblock_nsvc(ctx); + test_unitdata(ctx); printf("===== NS2 protocol test END\n\n"); talloc_free(ctx); diff --git a/tests/gb/gprs_ns2_test.ok b/tests/gb/gprs_ns2_test.ok index 27c72fac..7d123255 100644 --- a/tests/gb/gprs_ns2_test.ok +++ b/tests/gb/gprs_ns2_test.ok @@ -11,5 +11,14 @@ ---- Create NSVC[i] ---- Create NSVC[i] --- Finish NSE block unblock nsvc +--- Testing unitdata test +---- Create NSE + Binds +---- Create NSVC[0] +---- Create NSVC[1] +---- Send UNITDATA to NSVC[0] +---- Send Block NSVC[0] +---- Try to receive over blocked NSVC[0] +---- Receive over NSVC[1] +--- Finish unitdata test ===== NS2 protocol test END -- cgit v1.2.3