tests/gb: Add test for GPRS NS protocol

This tests the connection establishment by directly calling
gprs_ns_rcvmsg() and printing the resulting messages and the
NS-VC list.
This commit is contained in:
Jacob Erlbeck 2013-10-08 12:04:43 +02:00 committed by Holger Hans Peter Freyther
parent 73ae7a9ca0
commit dcce196be9
4 changed files with 383 additions and 1 deletions

View File

@ -4,7 +4,8 @@ check_PROGRAMS = timer/timer_test sms/sms_test ussd/ussd_test \
smscb/smscb_test bits/bitrev_test a5/a5_test \
conv/conv_test auth/milenage_test lapd/lapd_test \
gsm0808/gsm0808_test gsm0408/gsm0408_test \
gb/bssgp_fc_test logging/logging_test fr/fr_test \
gb/bssgp_fc_test gb/gprs_ns_test \
logging/logging_test fr/fr_test \
loggingrb/loggingrb_test strrb/strrb_test \
vty/vty_test
@ -51,6 +52,9 @@ ussd_ussd_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gs
gb_bssgp_fc_test_SOURCES = gb/bssgp_fc_test.c
gb_bssgp_fc_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gb/libosmogb.la
gb_gprs_ns_test_SOURCES = gb/gprs_ns_test.c
gb_gprs_ns_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gb/libosmogb.la $(LIBRARY_DL)
logging_logging_test_SOURCES = logging/logging_test.c
logging_logging_test_LDADD = $(top_builddir)/src/libosmocore.la
@ -92,6 +96,7 @@ EXTRA_DIST = testsuite.at $(srcdir)/package.m4 $(TESTSUITE) \
lapd/lapd_test.ok gsm0408/gsm0408_test.ok \
gsm0808/gsm0808_test.ok gb/bssgp_fc_tests.err \
gb/bssgp_fc_tests.ok gb/bssgp_fc_tests.sh \
gb/gprs_ns_test.ok \
msgfile/msgfile_test.ok msgfile/msgconfig.cfg \
logging/logging_test.ok logging/logging_test.err \
fr/fr_test.ok loggingrb/logging_test.ok \

247
tests/gb/gprs_ns_test.c Normal file
View File

@ -0,0 +1,247 @@
/* test routines for NS connection handling
* (C) 2013 by sysmocom s.f.m.c. GmbH
* Author: Jacob Erlbeck <jerlbeck@sysmocom.de>
*/
#undef _GNU_SOURCE
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <getopt.h>
#include <dlfcn.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <osmocom/core/msgb.h>
#include <osmocom/core/application.h>
#include <osmocom/core/utils.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/talloc.h>
#include <osmocom/gprs/gprs_msgb.h>
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gprs/gprs_bssgp.h>
/* GPRS Network Service, PDU type: NS_RESET,
* Cause: O&M intervention, NS VCI: 0x1122, NSEI 0x1122
*/
static const unsigned char gprs_ns_reset[12] = {
0x02, 0x00, 0x81, 0x01, 0x01, 0x82, 0x11, 0x22,
0x04, 0x82, 0x11, 0x22
};
/* GPRS Network Service, PDU type: NS_RESET,
* Cause: O&M intervention, NS VCI: 0x3344, NSEI 0x1122
*/
static const unsigned char gprs_ns_reset_vci2[12] = {
0x02, 0x00, 0x81, 0x01, 0x01, 0x82, 0x33, 0x44,
0x04, 0x82, 0x11, 0x22
};
/* GPRS Network Service, PDU type: NS_RESET,
* Cause: O&M intervention, NS VCI: 0x1122, NSEI 0x3344
*/
static const unsigned char gprs_ns_reset_nsei2[12] = {
0x02, 0x00, 0x81, 0x01, 0x01, 0x82, 0x11, 0x22,
0x04, 0x82, 0x33, 0x44
};
/* GPRS Network Service, PDU type: NS_ALIVE */
static const unsigned char gprs_ns_alive[1] = {
0x0a
};
/* GPRS Network Service, PDU type: NS_STATUS,
* Cause: PDU not compatible with the protocol state
* PDU: NS_ALIVE
*/
static const unsigned char gprs_ns_status_invalid_alive[7] = {
0x08, 0x00, 0x81, 0x0a, 0x02, 0x81, 0x0a
};
/* GPRS Network Service, PDU type: NS_ALIVE_ACK */
static const unsigned char gprs_ns_alive_ack[1] = {
0x0b
};
/* GPRS Network Service, PDU type: NS_UNBLOCK */
static const unsigned char gprs_ns_unblock[1] = {
0x06
};
/* GPRS Network Service, PDU type: NS_STATUS,
* Cause: PDU not compatible with the protocol state
* PDU: NS_RESET_ACK, NS VCI: 0x1122, NSEI 0x1122
*/
static const unsigned char gprs_ns_status_invalid_reset_ack[15] = {
0x08, 0x00, 0x81, 0x0a, 0x02, 0x89, 0x03, 0x01,
0x82, 0x11, 0x22, 0x04, 0x82, 0x11, 0x22
};
/* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0 */
static const unsigned char gprs_bssgp_reset[22] = {
0x00, 0x00, 0x00, 0x00, 0x22, 0x04, 0x82, 0x4a,
0x2e, 0x07, 0x81, 0x08, 0x08, 0x88, 0x10, 0x20,
0x30, 0x40, 0x50, 0x60, 0x10, 0x00
};
int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg,
struct sockaddr_in *saddr, enum gprs_ns_ll ll);
/* override */
int gprs_ns_callback(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
struct msgb *msg, uint16_t bvci)
{
printf("CALLBACK, event %d, msg length %d, bvci 0x%04x\n%s\n\n",
event, msgb_bssgp_len(msg), bvci,
osmo_hexdump(msgb_bssgph(msg), msgb_bssgp_len(msg)));
return 0;
}
/* override */
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen)
{
typedef ssize_t (*sendto_t)(int, const void *, size_t, int,
const struct sockaddr *, socklen_t);
static sendto_t real_sendto = NULL;
if (!real_sendto)
real_sendto = dlsym(RTLD_NEXT, "sendto");
if (sockfd != 0xdead && ((struct sockaddr_in *)dest_addr)->sin_addr.s_addr != htonl(0x01020304))
return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
printf("RESPONSE, msg length %d\n%s\n\n", len, osmo_hexdump(buf, len));
return len;
}
static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text, struct sockaddr_in *peer, const unsigned char* data, size_t data_len)
{
struct msgb *msg;
int ret;
if (data_len > NS_ALLOC_SIZE - NS_ALLOC_HEADROOM) {
fprintf(stderr, "message too long: %d\n", data_len);
return -1;
}
msg = gprs_ns_msgb_alloc();
memmove(msg->data, data, data_len);
msg->l2h = msg->data;
msgb_put(msg, data_len);
printf("PROCESSING %s from 0x%08x:%d\n%s\n\n",
text, ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
osmo_hexdump(data, data_len));
ret = gprs_ns_rcvmsg(nsi, msg, peer, GPRS_NS_LL_UDP);
printf("result (%s) = %d\n\n", text, ret);
msgb_free(msg);
return ret;
}
static void gprs_dump_nsi(struct gprs_ns_inst *nsi)
{
struct gprs_nsvc *nsvc;
printf("Current NS-VCIs:\n");
llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
struct sockaddr_in *peer = &(nsvc->ip.bts_addr);
printf(" VCI 0x%04x, NSEI 0x%04x, peer 0x%08x:%d\n",
nsvc->nsvci, nsvc->nsei,
ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port)
);
}
printf("\n");
}
static void test_ns()
{
struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
struct sockaddr_in peer[4] = {{0},};
peer[0].sin_family = AF_INET;
peer[0].sin_port = htons(1111);
peer[0].sin_addr.s_addr = htonl(0x01020304);
peer[1].sin_family = AF_INET;
peer[1].sin_port = htons(2222);
peer[1].sin_addr.s_addr = htonl(0x01020304);
peer[2].sin_family = AF_INET;
peer[2].sin_port = htons(3333);
peer[2].sin_addr.s_addr = htonl(0x01020304);
peer[3].sin_family = AF_INET;
peer[3].sin_port = htons(4444);
peer[3].sin_addr.s_addr = htonl(0x01020304);
gprs_process_message(nsi, "RESET", &peer[0],
gprs_ns_reset, sizeof(gprs_ns_reset));
gprs_dump_nsi(nsi);
gprs_process_message(nsi, "ALIVE", &peer[0],
gprs_ns_alive, sizeof(gprs_ns_alive));
gprs_process_message(nsi, "UNBLOCK", &peer[0],
gprs_ns_unblock, sizeof(gprs_ns_unblock));
gprs_process_message(nsi, "BSSGP RESET", &peer[0],
gprs_bssgp_reset, sizeof(gprs_bssgp_reset));
printf("--- Peer port changes, RESET, message remains unchanged ---\n\n");
gprs_process_message(nsi, "RESET", &peer[1],
gprs_ns_reset, sizeof(gprs_ns_reset));
gprs_dump_nsi(nsi);
printf("--- Peer port changes, RESET, VCI changes ---\n\n");
gprs_process_message(nsi, "RESET", &peer[2],
gprs_ns_reset_vci2, sizeof(gprs_ns_reset_vci2));
gprs_dump_nsi(nsi);
printf("--- Peer port changes, RESET, NSEI changes ---\n\n");
gprs_process_message(nsi, "RESET", &peer[3],
gprs_ns_reset_nsei2, sizeof(gprs_ns_reset_nsei2));
gprs_dump_nsi(nsi);
printf("--- Peer port 3333, RESET, VCI is changed back ---\n\n");
gprs_process_message(nsi, "RESET", &peer[2],
gprs_ns_reset, sizeof(gprs_ns_reset));
gprs_dump_nsi(nsi);
printf("--- Peer port 4444, RESET, NSEI is changed back ---\n\n");
gprs_process_message(nsi, "RESET", &peer[3],
gprs_ns_reset, sizeof(gprs_ns_reset));
gprs_dump_nsi(nsi);
gprs_ns_destroy(nsi);
nsi = NULL;
}
int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
{
return -1;
}
static struct log_info info = {};
int main(int argc, char **argv)
{
osmo_init_logging(&info);
log_set_use_color(osmo_stderr_target, 0);
log_set_print_filename(osmo_stderr_target, 0);
printf("===== NS protocol test START\n");
test_ns();
printf("===== NS protocol test END\n\n");
exit(EXIT_SUCCESS);
}

124
tests/gb/gprs_ns_test.ok Normal file
View File

@ -0,0 +1,124 @@
===== NS protocol test START
PROCESSING RESET from 0x01020304:1111
02 00 81 01 01 82 11 22 04 82 11 22
RESPONSE, msg length 1
0a
RESPONSE, msg length 9
03 01 82 11 22 04 82 11 22
result (RESET) = 9
Current NS-VCIs:
VCI 0x1122, NSEI 0x1122, peer 0x01020304:1111
PROCESSING ALIVE from 0x01020304:1111
0a
RESPONSE, msg length 1
0b
result (ALIVE) = 1
PROCESSING UNBLOCK from 0x01020304:1111
06
RESPONSE, msg length 1
07
result (UNBLOCK) = 1
PROCESSING BSSGP RESET from 0x01020304:1111
00 00 00 00 22 04 82 4a 2e 07 81 08 08 88 10 20 30 40 50 60 10 00
CALLBACK, event 0, msg length 18, bvci 0x0000
22 04 82 4a 2e 07 81 08 08 88 10 20 30 40 50 60 10 00
result (BSSGP RESET) = 0
--- Peer port changes, RESET, message remains unchanged ---
PROCESSING RESET from 0x01020304:2222
02 00 81 01 01 82 11 22 04 82 11 22
RESPONSE, msg length 1
0a
RESPONSE, msg length 9
03 01 82 11 22 04 82 11 22
result (RESET) = 9
Current NS-VCIs:
VCI 0x1122, NSEI 0x1122, peer 0x01020304:2222
--- Peer port changes, RESET, VCI changes ---
PROCESSING RESET from 0x01020304:3333
02 00 81 01 01 82 33 44 04 82 11 22
RESPONSE, msg length 1
0a
RESPONSE, msg length 9
03 01 82 33 44 04 82 11 22
result (RESET) = 9
Current NS-VCIs:
VCI 0x3344, NSEI 0x1122, peer 0x01020304:3333
--- Peer port changes, RESET, NSEI changes ---
PROCESSING RESET from 0x01020304:4444
02 00 81 01 01 82 11 22 04 82 33 44
RESPONSE, msg length 1
0a
RESPONSE, msg length 9
03 01 82 11 22 04 82 33 44
result (RESET) = 9
Current NS-VCIs:
VCI 0x1122, NSEI 0x3344, peer 0x01020304:4444
VCI 0x3344, NSEI 0x1122, peer 0x01020304:3333
--- Peer port 3333, RESET, VCI is changed back ---
PROCESSING RESET from 0x01020304:3333
02 00 81 01 01 82 11 22 04 82 11 22
RESPONSE, msg length 1
0a
RESPONSE, msg length 9
03 01 82 11 22 04 82 11 22
result (RESET) = 9
Current NS-VCIs:
VCI 0x1122, NSEI 0x3344, peer 0x01020304:4444
VCI 0x1122, NSEI 0x1122, peer 0x01020304:3333
--- Peer port 4444, RESET, NSEI is changed back ---
PROCESSING RESET from 0x01020304:4444
02 00 81 01 01 82 11 22 04 82 11 22
RESPONSE, msg length 1
0a
RESPONSE, msg length 9
03 01 82 11 22 04 82 11 22
result (RESET) = 9
Current NS-VCIs:
VCI 0x1122, NSEI 0x1122, peer 0x01020304:4444
VCI 0x1122, NSEI 0x1122, peer 0x01020304:3333
===== NS protocol test END

View File

@ -106,6 +106,12 @@ cat $abs_srcdir/vty/vty_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/vty/vty_test], [0], [expout], [ignore])
AT_CLEANUP
AT_SETUP([gprs-ns])
AT_KEYWORDS([gprs-ns])
cat $abs_srcdir/gb/gprs_ns_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/gb/gprs_ns_test], [0], [expout], [ignore])
AT_CLEANUP
AT_SETUP([bssgp-fc])
AT_KEYWORDS([bssgp-fc])
cat $abs_srcdir/gb/bssgp_fc_tests.ok > expout