aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@gnumonks.org>2011-07-08 14:17:15 +0200
committerPablo Neira Ayuso <pablo@gnumonks.org>2011-07-08 15:10:33 +0200
commit009573aa5b699f9758ed096ab03c5a509355d074 (patch)
tree214dbd4500699581466f07c280c7b3c3fb15c634 /tests
parent1ca98b9e9d9861928a735cdbcfdde5916befccd1 (diff)
tests: example BTS now sends an OML SW ACT REQ
This allows to test that the write path works and it allows you to get an idea on how to implement the BTS side by means of libosmo-abis.
Diffstat (limited to 'tests')
-rw-r--r--tests/e1inp_ipa_bts_test.c132
1 files changed, 130 insertions, 2 deletions
diff --git a/tests/e1inp_ipa_bts_test.c b/tests/e1inp_ipa_bts_test.c
index 7b7ee86..2bacb5e 100644
--- a/tests/e1inp_ipa_bts_test.c
+++ b/tests/e1inp_ipa_bts_test.c
@@ -6,6 +6,7 @@
#include <osmocom/core/logging.h>
#include <osmocom/core/application.h>
#include <osmocom/abis/ipaccess.h>
+#include <osmocom/gsm/protocol/gsm_12_21.h>
static void *tall_test;
static struct e1inp_sign_link *oml_sign_link, *rsl_sign_link;
@@ -27,6 +28,14 @@ const struct log_info bts_test_log_info = {
.num_cat = ARRAY_SIZE(bts_test_cat),
};
+enum bts_state_machine {
+ BTS_TEST_OML_SIGN_LINK_DOWN = 0,
+ BTS_TEST_OML_SIGN_LINK_UP,
+ BTS_TEST_OML_WAIT_SW_ACT_ACK,
+};
+
+static enum bts_state_machine bts_state = BTS_TEST_OML_SIGN_LINK_DOWN;
+
static struct e1inp_sign_link *
sign_link_up(void *unit, struct e1inp_line *line, enum e1inp_sign_type type)
{
@@ -46,6 +55,8 @@ sign_link_up(void *unit, struct e1inp_line *line, enum e1inp_sign_type type)
"cannot create OML sign link\n");
}
dst = oml_sign_link;
+ /* Now we can send OML messages to the BSC. */
+ bts_state = BTS_TEST_OML_SIGN_LINK_UP;
break;
case E1INP_SIGN_RSL:
LOGP(DBTSTEST, LOGL_NOTICE, "RSL link up request received.\n");
@@ -77,10 +88,108 @@ static void sign_link_down(struct e1inp_line *line)
e1inp_sign_link_destroy(rsl_sign_link);
}
+static int abis_nm_rcvmsg_fom(struct msgb *msg)
+{
+ struct abis_om_fom_hdr *foh = msgb_l3(msg);
+ uint8_t mt = foh->msg_type;
+ int ret = 0;
+
+ switch (mt) {
+ case NM_MT_SW_ACT_REQ_ACK: /* SW activate request ACK from BSC. */
+ LOGP(DBTSTEST, LOGL_NOTICE, "Receive SW Act Req ACK\n");
+ break;
+ default:
+ LOGP(DBTSTEST, LOGL_ERROR, "unknown OML message\n");
+ break;
+ }
+ return ret;
+}
+
+static int abis_nm_rcvmsg(struct msgb *msg)
+{
+ int ret = 0;
+ struct abis_om_hdr *oh = msgb_l2(msg);
+
+ msg->l3h = (unsigned char *)oh + sizeof(*oh);
+ switch (oh->mdisc) {
+ case ABIS_OM_MDISC_FOM:
+ ret = abis_nm_rcvmsg_fom(msg);
+ break;
+ default:
+ LOGP(DBTSTEST, LOGL_ERROR, "unknown OML message\n");
+ break;
+ }
+ return ret;
+}
+
static int sign_link(struct msgb *msg)
{
- LOGP(DBTSTEST, LOGL_NOTICE, "OML/RSL message received.\n");
- return 0;
+ int ret = 0;
+ struct e1inp_sign_link *link = msg->dst;
+
+ switch(link->type) {
+ case E1INP_SIGN_OML:
+ LOGP(DBTSTEST, LOGL_NOTICE, "OML message received.\n");
+ ret = abis_nm_rcvmsg(msg);
+ break;
+ case E1INP_SIGN_RSL:
+ LOGP(DBTSTEST, LOGL_NOTICE, "RSL message received.\n");
+ break;
+ default:
+ LOGP(DBTSTEST, LOGL_ERROR, "Unknown signalling message.\n");
+ break;
+ }
+ return ret;
+}
+
+static void fill_om_hdr(struct abis_om_hdr *oh, uint8_t len)
+{
+ oh->mdisc = ABIS_OM_MDISC_FOM;
+ oh->placement = ABIS_OM_PLACEMENT_ONLY;
+ oh->sequence = 0;
+ oh->length = len;
+}
+
+static void fill_om_fom_hdr(struct abis_om_hdr *oh, uint8_t len,
+ uint8_t msg_type, uint8_t obj_class,
+ uint8_t bts_nr, uint8_t trx_nr, uint8_t ts_nr)
+{
+ struct abis_om_fom_hdr *foh = (struct abis_om_fom_hdr *) oh->data;
+
+ fill_om_hdr(oh, len+sizeof(*foh));
+ foh->msg_type = msg_type;
+ foh->obj_class = obj_class;
+ foh->obj_inst.bts_nr = bts_nr;
+ foh->obj_inst.trx_nr = trx_nr;
+ foh->obj_inst.ts_nr = ts_nr;
+}
+
+#define OM_ALLOC_SIZE 1024
+#define OM_HEADROOM_SIZE 128
+
+static struct msgb *nm_msgb_alloc(void)
+{
+ return msgb_alloc_headroom(OM_ALLOC_SIZE, OM_HEADROOM_SIZE, "BTS/test");
+}
+
+static int abis_nm_sw_act_req(struct e1inp_sign_link *sign_link,
+ uint8_t obj_class,
+ uint8_t i1, uint8_t i2, uint8_t i3,
+ uint8_t *attr, int att_len)
+{
+ struct abis_om_hdr *oh;
+ struct msgb *msg = nm_msgb_alloc();
+ uint8_t msgtype = NM_MT_SW_ACT_REQ;
+
+ oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE);
+ fill_om_fom_hdr(oh, att_len, msgtype, obj_class, i1, i2, i3);
+
+ if (attr) {
+ uint8_t *ptr = msgb_put(msg, att_len);
+ memcpy(ptr, attr, att_len);
+ }
+ msg->dst = sign_link;
+ return abis_sendmsg(msg);
}
int main(void)
@@ -130,7 +239,26 @@ int main(void)
LOGP(DBTSTEST, LOGL_NOTICE, "entering main loop\n");
while (1) {
+ int ret;
+
osmo_select_main(0);
+
+ switch(bts_state) {
+ case BTS_TEST_OML_SIGN_LINK_DOWN:
+ /* Do nothing until OML link becomes ready. */
+ break;
+ case BTS_TEST_OML_SIGN_LINK_UP:
+ /* OML link is up, send SW ACT REQ. */
+ ret = abis_nm_sw_act_req(oml_sign_link, 0,
+ bts_dev_info.bts_id,
+ bts_dev_info.trx_id,
+ 0, NULL, 0);
+ bts_state = BTS_TEST_OML_WAIT_SW_ACT_ACK;
+ break;
+ case BTS_TEST_OML_WAIT_SW_ACT_ACK:
+ /* ... things should continue after this. */
+ break;
+ }
}
return 0;
}