blob: a2473268faadcd0ddb3c68ebd1808b448703a14b [file] [log] [blame]
Jacob Erlbeckcdebf742014-10-14 14:49:37 +02001/* Test routines for the BSSGP implementation in libosmogb
2 *
3 * (C) 2014 by sysmocom s.f.m.c. GmbH
4 * Author: Jacob Erlbeck <jerlbeck@sysmocom.de>
5 *
6 * Skeleton based on bssgp_fc_test.c
7 * (C) 2012 by Harald Welte <laforge@gnumonks.org>
8 */
9
10#undef _GNU_SOURCE
11#define _GNU_SOURCE
12
13#include <osmocom/core/application.h>
14#include <osmocom/core/utils.h>
15#include <osmocom/core/logging.h>
16#include <osmocom/core/talloc.h>
17#include <osmocom/core/prim.h>
18#include <osmocom/gprs/gprs_bssgp.h>
19#include <osmocom/gprs/gprs_ns.h>
20
21#include <stdio.h>
22#include <stdlib.h>
23#include <stdint.h>
24#include <string.h>
25#include <getopt.h>
26#include <unistd.h>
27#include <netinet/ip.h>
Holger Hans Peter Freythere0a1a802014-10-25 12:19:56 +020028#include <sys/socket.h>
Jacob Erlbeckcdebf742014-10-14 14:49:37 +020029#include <dlfcn.h>
30
31#define BSS_NSEI 0x0b55
32
33static struct osmo_prim_hdr last_oph = {0};
34
35/* override */
36ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
37 const struct sockaddr *dest_addr, socklen_t addrlen)
38{
39 typedef ssize_t (*sendto_t)(int, const void *, size_t, int,
40 const struct sockaddr *, socklen_t);
41 static sendto_t real_sendto = NULL;
42 uint32_t dest_host = htonl(((struct sockaddr_in *)dest_addr)->sin_addr.s_addr);
43
44 if (!real_sendto)
45 real_sendto = dlsym(RTLD_NEXT, "sendto");
46
47 fprintf(stderr, "MESSAGE to 0x%08x, msg length %d\n%s\n",
48 dest_host, len, osmo_hexdump(buf, len));
49
50 return len;
51}
52
53/* override */
54int gprs_ns_callback(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
55 struct msgb *msg, uint16_t bvci)
56{
57 fprintf(stderr, "CALLBACK, event %d, msg length %d, bvci 0x%04x\n%s\n\n",
58 event, msgb_bssgp_len(msg), bvci,
59 osmo_hexdump(msgb_bssgph(msg), msgb_bssgp_len(msg)));
60 return 0;
61}
62
63int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
64{
65 printf("BSSGP primitive, SAP %d, prim = %d, op = %d, msg = %s\n",
66 oph->sap, oph->primitive, oph->operation, msgb_hexdump(oph->msg));
67
68 last_oph.sap = oph->sap;
69 last_oph.primitive = oph->primitive;
70 last_oph.operation = oph->operation;
71 last_oph.msg = NULL;
72 return -1;
73}
74
75static void msgb_bssgp_send_and_free(struct msgb *msg)
76{
77 msgb_nsei(msg) = BSS_NSEI;
78
79 bssgp_rcvmsg(msg);
80
81 msgb_free(msg);
82}
83
84static void send_bssgp_supend(enum bssgp_pdu_type pdu_type, uint32_t tlli)
85{
86 struct msgb *msg = bssgp_msgb_alloc();
87 uint32_t tlli_be = htonl(tlli);
88 uint8_t rai[] = {0x0f, 0xf1, 0x80, 0x20, 0x37, 0x00};
89
90 msgb_v_put(msg, pdu_type);
91 msgb_tvlv_put(msg, BSSGP_IE_TLLI, sizeof(tlli_be), (uint8_t *)&tlli_be);
92 msgb_tvlv_put(msg, BSSGP_IE_ROUTEING_AREA, sizeof(rai), &rai[0]);
93
94 msgb_bssgp_send_and_free(msg);
95}
96
97static void send_bssgp_resume(enum bssgp_pdu_type pdu_type, uint32_t tlli)
98{
99 struct msgb *msg = bssgp_msgb_alloc();
100 uint32_t tlli_be = htonl(tlli);
101 uint8_t rai[] = {0x0f, 0xf1, 0x80, 0x20, 0x37, 0x00};
102 uint8_t suspend_ref = 1;
103
104 msgb_v_put(msg, pdu_type);
105 msgb_tvlv_put(msg, BSSGP_IE_TLLI, sizeof(tlli_be), (uint8_t *)&tlli_be);
106 msgb_tvlv_put(msg, BSSGP_IE_ROUTEING_AREA, sizeof(rai), &rai[0]);
107 msgb_tvlv_put(msg, BSSGP_IE_SUSPEND_REF_NR, 1, &suspend_ref);
108
109 msgb_bssgp_send_and_free(msg);
110}
111
112static void test_bssgp_suspend_resume(void)
113{
114 const uint32_t tlli = 0xf0123456;
115
116 printf("----- %s START\n", __func__);
117 memset(&last_oph, 0, sizeof(last_oph));
118
119 send_bssgp_supend(BSSGP_PDUT_SUSPEND, tlli);
Jacob Erlbeckb43baf22014-09-10 12:43:28 +0200120 OSMO_ASSERT(last_oph.primitive == PRIM_BSSGP_GMM_SUSPEND);
Jacob Erlbeckcdebf742014-10-14 14:49:37 +0200121
122 send_bssgp_resume(BSSGP_PDUT_RESUME, tlli);
Jacob Erlbeckb43baf22014-09-10 12:43:28 +0200123 OSMO_ASSERT(last_oph.primitive == PRIM_BSSGP_GMM_RESUME);
Jacob Erlbeckcdebf742014-10-14 14:49:37 +0200124
125 printf("----- %s END\n", __func__);
126}
127
128static struct log_info info = {};
129
130int main(int argc, char **argv)
131{
132 struct sockaddr_in bss_peer= {0};
133
134 osmo_init_logging(&info);
135 log_set_use_color(osmo_stderr_target, 0);
136 log_set_print_filename(osmo_stderr_target, 0);
137
138 bssgp_nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
139
140 bss_peer.sin_family = AF_INET;
141 bss_peer.sin_port = htons(32000);
142 bss_peer.sin_addr.s_addr = htonl(0x7f0000ff);
143
144 gprs_ns_nsip_connect(bssgp_nsi, &bss_peer, BSS_NSEI, BSS_NSEI+1);
145
146
147 printf("===== BSSGP test START\n");
148 test_bssgp_suspend_resume();
149 printf("===== BSSGP test END\n\n");
150
151 exit(EXIT_SUCCESS);
152}