blob: 49262280ccf0dfb14d57a4202278209b03355881 [file] [log] [blame]
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +02001#include <stdio.h>
Pablo Neira Ayuso54b49792011-06-07 12:15:26 +02002#include <talloc.h>
3#include <osmocom/abis/abis.h>
Pablo Neira Ayuso177094b2011-06-07 12:21:51 +02004#include <osmocom/abis/e1_input.h>
Pablo Neira Ayusoe19c70a2011-06-12 15:15:30 +02005#include <osmocom/core/application.h>
6#include <osmocom/core/logging.h>
Pablo Neira Ayuso904d8f22011-07-05 18:32:12 +02007#include <osmocom/gsm/protocol/gsm_12_21.h>
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +02008
Pablo Neira Ayuso54b49792011-06-07 12:15:26 +02009static void *tall_test;
Pablo Neira Ayusoc9c4fd32011-06-30 12:19:42 +020010static struct e1inp_sign_link *oml_sign_link, *rsl_sign_link;
Pablo Neira Ayuso54b49792011-06-07 12:15:26 +020011
Pablo Neira Ayusofe8ab0a2011-07-02 18:48:45 +020012#define DBSCTEST 0
Pablo Neira Ayusoe19c70a2011-06-12 15:15:30 +020013
14struct log_info_cat bsc_test_cat[] = {
15 [DBSCTEST] = {
16 .name = "DBSCTEST",
17 .description = "BSC-mode test",
18 .color = "\033[1;35m",
19 .enabled = 1, .loglevel = LOGL_NOTICE,
20 },
21};
22
Pablo Neira Ayuso2b352012011-07-02 17:45:42 +020023static struct e1inp_sign_link *
24sign_link_up(void *dev, struct e1inp_line *line, enum e1inp_sign_type type)
25{
26 struct e1inp_sign_link *sign_link = NULL;
Pablo Neira Ayuso1ca98b92011-07-08 15:05:42 +020027 struct e1inp_line *oml_line;
Pablo Neira Ayuso2b352012011-07-02 17:45:42 +020028
29 switch(type) {
30 case E1INP_SIGN_OML:
31 LOGP(DBSCTEST, LOGL_NOTICE, "OML link up request received.\n");
32 e1inp_ts_config_sign(&line->ts[E1INP_SIGN_OML - 1], line);
33 sign_link = oml_sign_link =
34 e1inp_sign_link_create(&line->ts[E1INP_SIGN_OML - 1],
35 E1INP_SIGN_OML, NULL, 255, 0);
36 break;
37 case E1INP_SIGN_RSL:
Pablo Neira Ayuso1ca98b92011-07-08 15:05:42 +020038 if (!oml_sign_link) {
39 LOGP(DBSCTEST, LOGL_ERROR, "OML link not yet set, "
40 "giving up\n");
41 return NULL;
42 }
Pablo Neira Ayuso2b352012011-07-02 17:45:42 +020043 LOGP(DBSCTEST, LOGL_NOTICE, "RSL link up request received.\n");
Pablo Neira Ayuso1ca98b92011-07-08 15:05:42 +020044
45 /* We have to use the same line that the OML link. */
46 oml_line = oml_sign_link->ts->line;
47 e1inp_ts_config_sign(&oml_line->ts[E1INP_SIGN_RSL - 1],
48 oml_line);
Pablo Neira Ayuso2b352012011-07-02 17:45:42 +020049 sign_link = rsl_sign_link =
Pablo Neira Ayuso1ca98b92011-07-08 15:05:42 +020050 e1inp_sign_link_create(&oml_line->ts[E1INP_SIGN_RSL - 1],
51 E1INP_SIGN_RSL, NULL, 0, 0);
Pablo Neira Ayuso2b352012011-07-02 17:45:42 +020052 break;
53 default:
54 break;
55 }
56 if (sign_link)
57 LOGP(DBSCTEST, LOGL_NOTICE, "signal link has been set up.\n");
58
59 return sign_link;
60}
61
62static void sign_link_down(struct e1inp_line *line)
63{
64 LOGP(DBSCTEST, LOGL_NOTICE, "signal link has been closed\n");
Pablo Neira Ayuso49bc8722011-07-08 15:23:36 +020065 if (oml_sign_link)
66 e1inp_sign_link_destroy(oml_sign_link);
67 if (rsl_sign_link)
68 e1inp_sign_link_destroy(rsl_sign_link);
Pablo Neira Ayuso2b352012011-07-02 17:45:42 +020069}
70
Pablo Neira Ayuso904d8f22011-07-05 18:32:12 +020071static void fill_om_hdr(struct abis_om_hdr *oh, uint8_t len)
72{
73 oh->mdisc = ABIS_OM_MDISC_FOM;
74 oh->placement = ABIS_OM_PLACEMENT_ONLY;
75 oh->sequence = 0;
76 oh->length = len;
77}
78
79static void fill_om_fom_hdr(struct abis_om_hdr *oh, uint8_t len,
80 uint8_t msg_type, uint8_t obj_class,
81 uint8_t bts_nr, uint8_t trx_nr, uint8_t ts_nr)
82{
83 struct abis_om_fom_hdr *foh =
84 (struct abis_om_fom_hdr *) oh->data;
85
86 fill_om_hdr(oh, len+sizeof(*foh));
87 foh->msg_type = msg_type;
88 foh->obj_class = obj_class;
89 foh->obj_inst.bts_nr = bts_nr;
90 foh->obj_inst.trx_nr = trx_nr;
91 foh->obj_inst.ts_nr = ts_nr;
92}
93
94#define OM_ALLOC_SIZE 1024
95#define OM_HEADROOM_SIZE 128
96
97static struct msgb *nm_msgb_alloc(void)
98{
99 return msgb_alloc_headroom(OM_ALLOC_SIZE, OM_HEADROOM_SIZE, "OML");
100}
101
102
103static int abis_nm_sw_act_req_ack(struct e1inp_sign_link *sign_link,
104 uint8_t obj_class,
105 uint8_t i1, uint8_t i2, uint8_t i3,
106 uint8_t *attr, int att_len)
107{
108 struct abis_om_hdr *oh;
109 struct msgb *msg = nm_msgb_alloc();
110 uint8_t msgtype = NM_MT_SW_ACT_REQ_ACK;
111
112 oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE);
113 fill_om_fom_hdr(oh, att_len, msgtype, obj_class, i1, i2, i3);
114
115 if (attr) {
116 uint8_t *ptr = msgb_put(msg, att_len);
117 memcpy(ptr, attr, att_len);
118 }
119 msg->dst = sign_link;
120 return abis_sendmsg(msg);
121}
122
123static int abis_nm_rx_sw_act_req(struct msgb *msg)
124{
125 struct abis_om_hdr *oh = msgb_l2(msg);
126 struct abis_om_fom_hdr *foh = msgb_l3(msg);
127 int ret;
128
129 ret = abis_nm_sw_act_req_ack(msg->dst,
130 foh->obj_class,
131 foh->obj_inst.bts_nr,
132 foh->obj_inst.trx_nr,
133 foh->obj_inst.ts_nr,
134 foh->data, oh->length-sizeof(*foh));
135
136 return ret;
137}
138
139static int abis_nm_rcvmsg_fom(struct msgb *msg)
140{
141 struct abis_om_fom_hdr *foh = msgb_l3(msg);
142 uint8_t mt = foh->msg_type;
143 int ret = 0;
144
145 switch (mt) {
146 case NM_MT_SW_ACT_REQ: /* Software activate request from BTS. */
147 ret = abis_nm_rx_sw_act_req(msg);
148 break;
149 default:
150 break;
151 }
152 return ret;
153}
154
155static int abis_nm_rcvmsg(struct msgb *msg)
156{
157 int ret = 0;
158 struct abis_om_hdr *oh = msgb_l2(msg);
159
160 msg->l3h = (unsigned char *)oh + sizeof(*oh);
161 switch (oh->mdisc) {
162 case ABIS_OM_MDISC_FOM:
163 ret = abis_nm_rcvmsg_fom(msg);
164 break;
165 default:
166 LOGP(DBSCTEST, LOGL_ERROR, "unknown OML message\n");
167 break;
168 }
169 return ret;
170}
171
Pablo Neira Ayusodbd82fb2011-07-05 15:29:23 +0200172static int sign_link(struct msgb *msg)
Pablo Neira Ayuso2b352012011-07-02 17:45:42 +0200173{
Pablo Neira Ayuso904d8f22011-07-05 18:32:12 +0200174 int ret = 0;
175 struct e1inp_sign_link *link = msg->dst;
176
177 switch(link->type) {
178 case E1INP_SIGN_RSL:
179 LOGP(DBSCTEST, LOGL_NOTICE, "RSL message received.\n");
180 break;
181 case E1INP_SIGN_OML:
182 LOGP(DBSCTEST, LOGL_NOTICE, "OML message received.\n");
183 ret = abis_nm_rcvmsg(msg);
184 break;
185 default:
186 LOGP(DBSCTEST, LOGL_ERROR, "Unknown signallin message.\n");
187 break;
188 }
189 return ret;
Pablo Neira Ayuso2b352012011-07-02 17:45:42 +0200190}
191
Pablo Neira Ayusoe19c70a2011-06-12 15:15:30 +0200192const struct log_info bsc_test_log_info = {
193 .filter_fn = NULL,
194 .cat = bsc_test_cat,
195 .num_cat = ARRAY_SIZE(bsc_test_cat),
196};
197
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200198int main(void)
199{
200 struct e1inp_line *line;
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200201
Pablo Neira Ayuso54b49792011-06-07 12:15:26 +0200202 tall_test = talloc_named_const(NULL, 1, "e1inp_test");
203 libosmo_abis_init(tall_test);
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200204
Pablo Neira Ayusoe19c70a2011-06-12 15:15:30 +0200205 osmo_init_logging(&bsc_test_log_info);
206
Pablo Neira Ayuso5a4b7c52011-06-07 14:07:48 +0200207 struct e1inp_line_ops ops = {
Pablo Neira Ayusof163d232011-06-25 18:42:55 +0200208 .addr = "0.0.0.0",
209 .role = E1INP_LINE_R_BSC,
Pablo Neira Ayuso5a4b7c52011-06-07 14:07:48 +0200210 .sign_link_up = sign_link_up,
Pablo Neira Ayusoc9c4fd32011-06-30 12:19:42 +0200211 .sign_link_down = sign_link_down,
Pablo Neira Ayuso5a4b7c52011-06-07 14:07:48 +0200212 .sign_link = sign_link,
Pablo Neira Ayuso5a4b7c52011-06-07 14:07:48 +0200213 };
214
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200215#define LINENR 0
216
Pablo Neira Ayusof163d232011-06-25 18:42:55 +0200217 line = e1inp_line_create(LINENR, "ipa");
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200218 if (line == NULL) {
Pablo Neira Ayusoe19c70a2011-06-12 15:15:30 +0200219 LOGP(DBSCTEST, LOGL_ERROR, "problem creating E1 line\n");
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200220 exit(EXIT_FAILURE);
221 }
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200222
Pablo Neira Ayusof163d232011-06-25 18:42:55 +0200223 e1inp_line_bind_ops(line, &ops);
224
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200225 /*
226 * Depending if this is a real or virtual E1 lines:
227 * - real (ISDN): create signal link for OML and RSL before line up.
Pablo Neira Ayuso5a4b7c52011-06-07 14:07:48 +0200228 * - vitual (INET): we create it in signal_link_up(...) callback.
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200229 *
230 * The signal link is created via e1inp_sign_link_create(...)
231 *
232 * See e1_reconfig_trx and e1_reconfig_bts in libbsc/e1_config.c,
233 * it explains how this is done with ISDN.
234 */
235
Pablo Neira Ayusof163d232011-06-25 18:42:55 +0200236 if (e1inp_line_update(line) < 0) {
Pablo Neira Ayusoe19c70a2011-06-12 15:15:30 +0200237 LOGP(DBSCTEST, LOGL_ERROR, "problem creating E1 line\n");
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200238 exit(EXIT_FAILURE);
239 }
240
Pablo Neira Ayusoe19c70a2011-06-12 15:15:30 +0200241 LOGP(DBSCTEST, LOGL_NOTICE, "entering main loop\n");
242
Pablo Neira Ayuso0ba77d52011-06-05 18:32:44 +0200243 while (1) {
244 osmo_select_main(0);
245 }
246 return 0;
247}