blob: 12c436bc1d7121d85068b5487a9cf0409a61184a [file] [log] [blame]
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +02001#include <stdio.h>
Pablo Neira Ayuso1fd93bb2012-08-23 23:26:19 +02002#include <signal.h>
Harald Welte71d87b22011-07-18 14:49:56 +02003#include <osmocom/core/talloc.h>
Pablo Neira Ayuso54b49792011-06-07 12:15:26 +02004#include <osmocom/abis/abis.h>
Pablo Neira Ayuso177094b2011-06-07 12:21:51 +02005#include <osmocom/abis/e1_input.h>
Pablo Neira Ayusoe19c70a2011-06-12 15:15:30 +02006#include <osmocom/core/application.h>
7#include <osmocom/core/logging.h>
Pablo Neira Ayuso904d8f22011-07-05 18:32:12 +02008#include <osmocom/gsm/protocol/gsm_12_21.h>
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +02009
Pablo Neira Ayuso54b49792011-06-07 12:15:26 +020010static void *tall_test;
Pablo Neira Ayusoc9c4fd32011-06-30 12:19:42 +020011static struct e1inp_sign_link *oml_sign_link, *rsl_sign_link;
Pablo Neira Ayuso54b49792011-06-07 12:15:26 +020012
Pablo Neira Ayusofe8ab0a2011-07-02 18:48:45 +020013#define DBSCTEST 0
Pablo Neira Ayusoe19c70a2011-06-12 15:15:30 +020014
15struct log_info_cat bsc_test_cat[] = {
16 [DBSCTEST] = {
17 .name = "DBSCTEST",
18 .description = "BSC-mode test",
19 .color = "\033[1;35m",
20 .enabled = 1, .loglevel = LOGL_NOTICE,
21 },
22};
23
Pablo Neira Ayuso2b352012011-07-02 17:45:42 +020024static struct e1inp_sign_link *
25sign_link_up(void *dev, struct e1inp_line *line, enum e1inp_sign_type type)
26{
27 struct e1inp_sign_link *sign_link = NULL;
Pablo Neira Ayuso1ca98b92011-07-08 15:05:42 +020028 struct e1inp_line *oml_line;
Pablo Neira Ayuso2b352012011-07-02 17:45:42 +020029
30 switch(type) {
31 case E1INP_SIGN_OML:
32 LOGP(DBSCTEST, LOGL_NOTICE, "OML link up request received.\n");
Pau Espin Pedrolb5cfc6b2018-10-02 21:22:18 +020033 e1inp_ts_config_sign(e1inp_line_ipa_oml_ts(line), line);
Pablo Neira Ayuso2b352012011-07-02 17:45:42 +020034 sign_link = oml_sign_link =
Pau Espin Pedrolb5cfc6b2018-10-02 21:22:18 +020035 e1inp_sign_link_create(e1inp_line_ipa_oml_ts(line),
Pablo Neira Ayuso2b352012011-07-02 17:45:42 +020036 E1INP_SIGN_OML, NULL, 255, 0);
37 break;
38 case E1INP_SIGN_RSL:
Pablo Neira Ayuso1ca98b92011-07-08 15:05:42 +020039 if (!oml_sign_link) {
40 LOGP(DBSCTEST, LOGL_ERROR, "OML link not yet set, "
41 "giving up\n");
42 return NULL;
43 }
Pablo Neira Ayuso2b352012011-07-02 17:45:42 +020044 LOGP(DBSCTEST, LOGL_NOTICE, "RSL link up request received.\n");
Pablo Neira Ayuso1ca98b92011-07-08 15:05:42 +020045
46 /* We have to use the same line that the OML link. */
47 oml_line = oml_sign_link->ts->line;
Pau Espin Pedrolb5cfc6b2018-10-02 21:22:18 +020048 e1inp_ts_config_sign(e1inp_line_ipa_rsl_ts(oml_line, 0),
Pablo Neira Ayuso1ca98b92011-07-08 15:05:42 +020049 oml_line);
Pablo Neira Ayuso2b352012011-07-02 17:45:42 +020050 sign_link = rsl_sign_link =
Pau Espin Pedrolb5cfc6b2018-10-02 21:22:18 +020051 e1inp_sign_link_create(e1inp_line_ipa_rsl_ts(oml_line, 0),
Pablo Neira Ayuso1ca98b92011-07-08 15:05:42 +020052 E1INP_SIGN_RSL, NULL, 0, 0);
Pablo Neira Ayuso2b352012011-07-02 17:45:42 +020053 break;
54 default:
55 break;
56 }
57 if (sign_link)
58 LOGP(DBSCTEST, LOGL_NOTICE, "signal link has been set up.\n");
59
60 return sign_link;
61}
62
63static void sign_link_down(struct e1inp_line *line)
64{
65 LOGP(DBSCTEST, LOGL_NOTICE, "signal link has been closed\n");
Pablo Neira Ayuso5a8cca32012-08-22 14:01:49 +020066 if (oml_sign_link) {
Pablo Neira Ayuso49bc8722011-07-08 15:23:36 +020067 e1inp_sign_link_destroy(oml_sign_link);
Pablo Neira Ayuso5a8cca32012-08-22 14:01:49 +020068 oml_sign_link = NULL;
69 }
70 if (rsl_sign_link) {
Pablo Neira Ayuso49bc8722011-07-08 15:23:36 +020071 e1inp_sign_link_destroy(rsl_sign_link);
Pablo Neira Ayuso5a8cca32012-08-22 14:01:49 +020072 rsl_sign_link = NULL;
73 }
Pablo Neira Ayuso2b352012011-07-02 17:45:42 +020074}
75
Pablo Neira Ayuso904d8f22011-07-05 18:32:12 +020076static void fill_om_hdr(struct abis_om_hdr *oh, uint8_t len)
77{
78 oh->mdisc = ABIS_OM_MDISC_FOM;
79 oh->placement = ABIS_OM_PLACEMENT_ONLY;
80 oh->sequence = 0;
81 oh->length = len;
82}
83
84static void fill_om_fom_hdr(struct abis_om_hdr *oh, uint8_t len,
85 uint8_t msg_type, uint8_t obj_class,
86 uint8_t bts_nr, uint8_t trx_nr, uint8_t ts_nr)
87{
88 struct abis_om_fom_hdr *foh =
89 (struct abis_om_fom_hdr *) oh->data;
90
91 fill_om_hdr(oh, len+sizeof(*foh));
92 foh->msg_type = msg_type;
93 foh->obj_class = obj_class;
94 foh->obj_inst.bts_nr = bts_nr;
95 foh->obj_inst.trx_nr = trx_nr;
96 foh->obj_inst.ts_nr = ts_nr;
97}
98
99#define OM_ALLOC_SIZE 1024
100#define OM_HEADROOM_SIZE 128
101
102static struct msgb *nm_msgb_alloc(void)
103{
104 return msgb_alloc_headroom(OM_ALLOC_SIZE, OM_HEADROOM_SIZE, "OML");
105}
106
107
108static int abis_nm_sw_act_req_ack(struct e1inp_sign_link *sign_link,
109 uint8_t obj_class,
110 uint8_t i1, uint8_t i2, uint8_t i3,
111 uint8_t *attr, int att_len)
112{
113 struct abis_om_hdr *oh;
114 struct msgb *msg = nm_msgb_alloc();
115 uint8_t msgtype = NM_MT_SW_ACT_REQ_ACK;
116
117 oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE);
118 fill_om_fom_hdr(oh, att_len, msgtype, obj_class, i1, i2, i3);
119
120 if (attr) {
121 uint8_t *ptr = msgb_put(msg, att_len);
122 memcpy(ptr, attr, att_len);
123 }
124 msg->dst = sign_link;
125 return abis_sendmsg(msg);
126}
127
128static int abis_nm_rx_sw_act_req(struct msgb *msg)
129{
130 struct abis_om_hdr *oh = msgb_l2(msg);
131 struct abis_om_fom_hdr *foh = msgb_l3(msg);
132 int ret;
133
134 ret = abis_nm_sw_act_req_ack(msg->dst,
135 foh->obj_class,
136 foh->obj_inst.bts_nr,
137 foh->obj_inst.trx_nr,
138 foh->obj_inst.ts_nr,
139 foh->data, oh->length-sizeof(*foh));
140
141 return ret;
142}
143
144static int abis_nm_rcvmsg_fom(struct msgb *msg)
145{
146 struct abis_om_fom_hdr *foh = msgb_l3(msg);
147 uint8_t mt = foh->msg_type;
148 int ret = 0;
149
150 switch (mt) {
151 case NM_MT_SW_ACT_REQ: /* Software activate request from BTS. */
152 ret = abis_nm_rx_sw_act_req(msg);
153 break;
154 default:
155 break;
156 }
157 return ret;
158}
159
160static int abis_nm_rcvmsg(struct msgb *msg)
161{
162 int ret = 0;
163 struct abis_om_hdr *oh = msgb_l2(msg);
164
165 msg->l3h = (unsigned char *)oh + sizeof(*oh);
166 switch (oh->mdisc) {
167 case ABIS_OM_MDISC_FOM:
168 ret = abis_nm_rcvmsg_fom(msg);
169 break;
170 default:
171 LOGP(DBSCTEST, LOGL_ERROR, "unknown OML message\n");
172 break;
173 }
174 return ret;
175}
176
Pablo Neira Ayusodbd82fb2011-07-05 15:29:23 +0200177static int sign_link(struct msgb *msg)
Pablo Neira Ayuso2b352012011-07-02 17:45:42 +0200178{
Pablo Neira Ayuso904d8f22011-07-05 18:32:12 +0200179 int ret = 0;
180 struct e1inp_sign_link *link = msg->dst;
181
182 switch(link->type) {
183 case E1INP_SIGN_RSL:
184 LOGP(DBSCTEST, LOGL_NOTICE, "RSL message received.\n");
185 break;
186 case E1INP_SIGN_OML:
187 LOGP(DBSCTEST, LOGL_NOTICE, "OML message received.\n");
188 ret = abis_nm_rcvmsg(msg);
189 break;
190 default:
191 LOGP(DBSCTEST, LOGL_ERROR, "Unknown signallin message.\n");
192 break;
193 }
Pablo Neira Ayuso72516042012-08-23 23:34:05 +0200194 msgb_free(msg);
Pablo Neira Ayuso904d8f22011-07-05 18:32:12 +0200195 return ret;
Pablo Neira Ayuso2b352012011-07-02 17:45:42 +0200196}
197
Pablo Neira Ayusoe19c70a2011-06-12 15:15:30 +0200198const struct log_info bsc_test_log_info = {
199 .filter_fn = NULL,
200 .cat = bsc_test_cat,
201 .num_cat = ARRAY_SIZE(bsc_test_cat),
202};
203
Pablo Neira Ayuso1fd93bb2012-08-23 23:26:19 +0200204static struct e1inp_line *line;
205
206static void sighandler(int foo)
207{
Pau Espin Pedrol3b9bebf2020-07-15 15:49:44 +0200208 e1inp_line_put2(line, "ctor");
Pablo Neira Ayuso1fd93bb2012-08-23 23:26:19 +0200209 exit(EXIT_SUCCESS);
210}
211
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200212int main(void)
213{
Pablo Neira Ayuso54b49792011-06-07 12:15:26 +0200214 tall_test = talloc_named_const(NULL, 1, "e1inp_test");
215 libosmo_abis_init(tall_test);
Pau Espin Pedrolc04d8d22018-04-17 14:42:44 +0200216 msgb_talloc_ctx_init(tall_test, 0);
217 osmo_init_logging2(tall_test, &bsc_test_log_info);
Pablo Neira Ayusoe19c70a2011-06-12 15:15:30 +0200218
Pablo Neira Ayuso5a4b7c52011-06-07 14:07:48 +0200219 struct e1inp_line_ops ops = {
Pablo Neira Ayuso4e862cb2011-08-19 18:43:38 +0200220 .cfg = {
221 .ipa = {
222 .addr = "0.0.0.0",
223 .role = E1INP_LINE_R_BSC,
224 },
225 },
Pablo Neira Ayuso5a4b7c52011-06-07 14:07:48 +0200226 .sign_link_up = sign_link_up,
Pablo Neira Ayusoc9c4fd32011-06-30 12:19:42 +0200227 .sign_link_down = sign_link_down,
Pablo Neira Ayuso5a4b7c52011-06-07 14:07:48 +0200228 .sign_link = sign_link,
Pablo Neira Ayuso5a4b7c52011-06-07 14:07:48 +0200229 };
230
Pablo Neira Ayuso1fd93bb2012-08-23 23:26:19 +0200231 if (signal(SIGINT, sighandler) == SIG_ERR ||
232 signal(SIGTERM, sighandler) == SIG_ERR) {
233 perror("Cannot set sighandler");
234 exit(EXIT_FAILURE);
235 }
236
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200237#define LINENR 0
238
Pablo Neira Ayusof163d232011-06-25 18:42:55 +0200239 line = e1inp_line_create(LINENR, "ipa");
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200240 if (line == NULL) {
Pablo Neira Ayusoe19c70a2011-06-12 15:15:30 +0200241 LOGP(DBSCTEST, LOGL_ERROR, "problem creating E1 line\n");
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200242 exit(EXIT_FAILURE);
243 }
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200244
Pablo Neira Ayusof163d232011-06-25 18:42:55 +0200245 e1inp_line_bind_ops(line, &ops);
246
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200247 /*
248 * Depending if this is a real or virtual E1 lines:
249 * - real (ISDN): create signal link for OML and RSL before line up.
Pablo Neira Ayuso5a4b7c52011-06-07 14:07:48 +0200250 * - vitual (INET): we create it in signal_link_up(...) callback.
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200251 *
252 * The signal link is created via e1inp_sign_link_create(...)
253 *
254 * See e1_reconfig_trx and e1_reconfig_bts in libbsc/e1_config.c,
255 * it explains how this is done with ISDN.
256 */
257
Pablo Neira Ayusof163d232011-06-25 18:42:55 +0200258 if (e1inp_line_update(line) < 0) {
Pablo Neira Ayusoe19c70a2011-06-12 15:15:30 +0200259 LOGP(DBSCTEST, LOGL_ERROR, "problem creating E1 line\n");
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200260 exit(EXIT_FAILURE);
261 }
262
Pablo Neira Ayusoe19c70a2011-06-12 15:15:30 +0200263 LOGP(DBSCTEST, LOGL_NOTICE, "entering main loop\n");
264
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200265 while (1) {
266 osmo_select_main(0);
267 }
268 return 0;
269}