ip.access: Support multi-TRX / RSL stream ID

In order to support multi-TRX configurations, we need to be able
to cope with multiple RSL streams (each with their own stream identifier)
inside one ip.access TCP connection.

Since this is very similar to using the TEI on a E1 line, we simply
recycle the logic and data fields that are used for the TEI.
This commit is contained in:
Harald Welte 2009-10-20 00:22:00 +02:00
parent 31a74906a3
commit 8175e95222
2 changed files with 55 additions and 24 deletions

View File

@ -222,20 +222,20 @@ static int ipaccess_rcvmsg(struct e1inp_line *line, struct msgb *msg,
if (bfd->priv_nr == 1) {
bts->oml_link = e1inp_sign_link_create(&line->ts[1-1],
E1INP_SIGN_OML, bts->c0,
0, 0xff);
bts->oml_tei, 0);
} else if (bfd->priv_nr == 2) {
struct e1inp_ts *e1i_ts;
struct bsc_fd *newbfd;
struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, trx_id);
/* FIXME: implement this for non-0 TRX */
bfd->data = line = bts->oml_link->ts->line;
e1i_ts = &line->ts[2-1];
e1i_ts = &line->ts[2+trx_id - 1];
newbfd = &e1i_ts->driver.ipaccess.fd;
e1inp_ts_config(e1i_ts, line, E1INP_TS_TYPE_SIGN);
bts->c0->rsl_link =
e1inp_sign_link_create(e1i_ts,
E1INP_SIGN_RSL, bts->c0,
0, 0);
trx->rsl_link = e1inp_sign_link_create(e1i_ts,
E1INP_SIGN_RSL, trx,
trx->rsl_tei, 0);
/* get rid of our old temporary bfd */
memcpy(newbfd, bfd, sizeof(*newbfd));
bsc_unregister_fd(bfd);
@ -337,7 +337,7 @@ static int handle_ts1_read(struct bsc_fd *bfd)
/* BIG FAT WARNING: bfd might no longer exist here, since ipaccess_rcvmsg()
* might have free'd it !!! */
link = e1inp_lookup_sign_link(e1i_ts, 0, hh->proto);
link = e1inp_lookup_sign_link(e1i_ts, hh->proto, 0);
if (!link) {
printf("no matching signalling link for hh->proto=0x%02x\n", hh->proto);
msgb_free(msg);
@ -345,17 +345,17 @@ static int handle_ts1_read(struct bsc_fd *bfd)
}
msg->trx = link->trx;
switch (hh->proto) {
case IPAC_PROTO_RSL:
switch (link->type) {
case E1INP_SIGN_RSL:
if (!rsl_up) {
e1inp_event(e1i_ts, EVT_E1_TEI_UP, 0, IPAC_PROTO_RSL);
e1inp_event(e1i_ts, EVT_E1_TEI_UP, link->tei, link->sapi);
rsl_up = 1;
}
ret = abis_rsl_rcvmsg(msg);
break;
case IPAC_PROTO_OML:
case E1INP_SIGN_OML:
if (!oml_up) {
e1inp_event(e1i_ts, EVT_E1_TEI_UP, 0, IPAC_PROTO_OML);
e1inp_event(e1i_ts, EVT_E1_TEI_UP, link->tei, link->sapi);
oml_up = 1;
}
ret = abis_nm_rcvmsg(msg);
@ -426,9 +426,8 @@ static int handle_ts1_write(struct bsc_fd *bfd)
return -EINVAL;
}
msg->l2h = msg->data;
ipaccess_prepend_header(msg, proto);
ipaccess_prepend_header(msg, sign_link->tei);
DEBUGP(DMI, "TX %u: %s\n", ts_nr, hexdump(msg->l2h, msgb_l2len(msg)));
@ -505,7 +504,6 @@ static int listen_fd_cb(struct bsc_fd *listen_bfd, unsigned int what)
//line->driver_data = e1h;
/* create virrtual E1 timeslots for signalling */
e1inp_ts_config(&line->ts[1-1], line, E1INP_TS_TYPE_SIGN);
e1inp_ts_config(&line->ts[2-1], line, E1INP_TS_TYPE_SIGN);
e1i_ts = &line->ts[idx];

View File

@ -127,17 +127,19 @@ static void bts_dump_vty(struct vty *vty, struct gsm_bts *bts)
if (bts->cell_barred)
vty_out(vty, " CELL IS BARRED%s", VTY_NEWLINE);
if (is_ipaccess_bts(bts))
vty_out(vty, " Unit ID: %u/%u/0%s",
vty_out(vty, " Unit ID: %u/%u/0, OML Stream ID 0x%02x%s",
bts->ip_access.site_id, bts->ip_access.bts_id,
VTY_NEWLINE);
bts->oml_tei, VTY_NEWLINE);
vty_out(vty, " NM State: ");
net_dump_nmstate(vty, &bts->nm_state);
vty_out(vty, " Site Mgr NM State: ");
net_dump_nmstate(vty, &bts->site_mgr.nm_state);
vty_out(vty, " Paging: FIXME pending requests, %u free slots%s",
bts->paging.available_slots, VTY_NEWLINE);
vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
e1isl_dump_vty(vty, bts->oml_link);
if (!is_ipaccess_bts(bts)) {
vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
e1isl_dump_vty(vty, bts->oml_link);
}
/* FIXME: oml_link, chan_desc */
}
@ -238,10 +240,11 @@ static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
VTY_NEWLINE);
if (bts->cell_barred)
vty_out(vty, " cell barred 1%s", VTY_NEWLINE);
if (is_ipaccess_bts(bts))
if (is_ipaccess_bts(bts)) {
vty_out(vty, " ip.access unit_id %u %u%s",
bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE);
else {
vty_out(vty, " oml ip.access stream_id %u%s", bts->oml_tei, VTY_NEWLINE);
} else {
config_write_e1_link(vty, &bts->oml_e1_link, " oml ");
vty_out(vty, " oml e1 tei %u%s", bts->oml_tei, VTY_NEWLINE);
}
@ -285,8 +288,13 @@ static void trx_dump_vty(struct vty *vty, struct gsm_bts_trx *trx)
net_dump_nmstate(vty, &trx->nm_state);
vty_out(vty, " Baseband Transceiver NM State: ");
net_dump_nmstate(vty, &trx->bb_transc.nm_state);
vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
e1isl_dump_vty(vty, trx->rsl_link);
if (is_ipaccess_bts(trx->bts)) {
vty_out(vty, " ip.access stream ID: 0x%02x%s",
trx->rsl_tei, VTY_NEWLINE);
} else {
vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE);
e1isl_dump_vty(vty, trx->rsl_link);
}
}
DEFUN(show_trx,
@ -819,6 +827,11 @@ DEFUN(cfg_bts_type,
bts->type = parse_btstype(argv[0]);
if (is_ipaccess_bts(bts)) {
/* Set the default OML Stream ID to 0xff */
bts->oml_tei = 0xff;
}
return CMD_SUCCESS;
}
@ -941,6 +954,25 @@ DEFUN(cfg_bts_unit_id,
return CMD_SUCCESS;
}
DEFUN(cfg_bts_stream_id,
cfg_bts_stream_id_cmd,
"oml ip.access stream_id <0-255>",
"Set the ip.access Stream ID of the OML link of this BTS\n")
{
struct gsm_bts *bts = vty->index;
int stream_id = atoi(argv[0]);
if (!is_ipaccess_bts(bts)) {
vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
return CMD_WARNING;
}
bts->oml_tei = stream_id;
return CMD_SUCCESS;
}
DEFUN(cfg_bts_oml_e1,
cfg_bts_oml_e1_cmd,
"oml e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full)",
@ -1207,6 +1239,7 @@ int bsc_vty_init(struct gsm_network *net)
install_element(BTS_NODE, &cfg_bts_tsc_cmd);
install_element(BTS_NODE, &cfg_bts_bsic_cmd);
install_element(BTS_NODE, &cfg_bts_unit_id_cmd);
install_element(BTS_NODE, &cfg_bts_stream_id_cmd);
install_element(BTS_NODE, &cfg_bts_oml_e1_cmd);
install_element(BTS_NODE, &cfg_bts_oml_e1_tei_cmd);
install_element(BTS_NODE, &cfg_bts_challoc_cmd);