dexter has uploaded this change for review.

View Change

pcu_sock: handle multiple BTSs with one BSC co-located PCU (in theory)

The current PCU implementation has never been tested with multiple BTS
attached to it. This is due to the fact that it has been used
exclusively in an BTS co-located setup where naturally only one BTS is
present. The PCU sock protocol supports multiple BTSs in theory and we
should handle this correctly. We also should add a check and print an
error message in case two or more BTSs with BSC co-located PCU (Ericsson
RBS) are configured.

Related: OS#5198
Change-Id: I0b42c2c130106f6ffca2dd08d079e1a7bda41f0b
---
M src/osmo-bsc/pcu_sock.c
1 file changed, 114 insertions(+), 58 deletions(-)

git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/18/31618/1
diff --git a/src/osmo-bsc/pcu_sock.c b/src/osmo-bsc/pcu_sock.c
index f136e21..933ff5f 100644
--- a/src/osmo-bsc/pcu_sock.c
+++ b/src/osmo-bsc/pcu_sock.c
@@ -361,11 +361,11 @@
if (pcu_connected(bts)) {
/* In cases where the CCU is connected via an E1 line, we transmit the connection parameters for the
* PDCH before we announce the other BTS related parameters. At the moment Ericsson RBS is the only
- * E1 BTS we support. */
- if (is_ericsson_bts(bts))
+ * E1 BTS we support and also the only BTS we support with a BSC co-located-pcu */
+ if (is_ericsson_bts(bts)) {
pcu_tx_e1_ccu_ind(bts);
-
- pcu_tx_info_ind(bts);
+ pcu_tx_info_ind(bts);
+ }
}
}

@@ -713,8 +713,9 @@
int rc = 0;
struct gsm_bts *bts;

- /* FIXME: allow multiple BTS */
- bts = llist_entry(net->bts_list.next, struct gsm_bts, list);
+ bts = gsm_bts_num(net, pcu_prim->bts_nr);
+ if (!bts)
+ return -EINVAL;

switch (msg_type) {
case PCU_IF_MSG_DATA_REQ:
@@ -766,25 +767,11 @@
return 0;
}

-static void pcu_sock_close(struct pcu_sock_state *state)
+static void pdch_deact_bts(struct gsm_bts *bts)
{
- struct osmo_fd *bfd = &state->conn_bfd;
- struct gsm_bts *bts;
struct gsm_bts_trx *trx;
int j;

- /* FIXME: allow multiple BTS */
- bts = llist_entry(state->net->bts_list.next, struct gsm_bts, list);
-
- LOGP(DPCU, LOGL_NOTICE, "PCU socket has LOST connection\n");
-
- close(bfd->fd);
- bfd->fd = -1;
- osmo_fd_unregister(bfd);
-
- /* re-enable the generation of ACCEPT for new connections */
- osmo_fd_read_enable(&state->listen_bfd);
-
#if 0
/* remove si13, ... */
bts->si_valid &= ~(1 << SYSINFO_TYPE_13);
@@ -806,6 +793,27 @@
}
}
}
+}
+
+static void pcu_sock_close(struct pcu_sock_state *state)
+{
+ struct osmo_fd *bfd = &state->conn_bfd;
+ struct gsm_bts *bts;
+
+ LOGP(DPCU, LOGL_NOTICE, "PCU socket has LOST connection\n");
+
+ close(bfd->fd);
+ bfd->fd = -1;
+ osmo_fd_unregister(bfd);
+
+ /* re-enable the generation of ACCEPT for new connections */
+ osmo_fd_read_enable(&state->listen_bfd);
+
+ /* Disable all PDCHs on all BTSs that are served by the PCU */
+ llist_for_each_entry(bts, &state->net->bts_list, list) {
+ if (is_ericsson_bts(bts))
+ pdch_deact_bts(bts);
+ }

/* flush the queue */
while (!llist_empty(&state->upqueue)) {
@@ -923,46 +931,10 @@
return rc;
}

-/* accept connection coming from PCU */
-static int pcu_sock_accept(struct osmo_fd *bfd, unsigned int flags)
+static void pdch_act_bts(struct gsm_bts *bts)
{
- struct pcu_sock_state *state = (struct pcu_sock_state *)bfd->data;
- struct osmo_fd *conn_bfd = &state->conn_bfd;
- struct sockaddr_un un_addr;
- struct gsm_bts *bts;
struct gsm_bts_trx *trx;
int j;
- socklen_t len;
- int rc;
-
- /* FIXME: allow multiple BTS */
- bts = llist_entry(state->net->bts_list.next, struct gsm_bts, list);
-
- len = sizeof(un_addr);
- rc = accept(bfd->fd, (struct sockaddr *) &un_addr, &len);
- if (rc < 0) {
- LOG_BTS(bts, DPCU, LOGL_ERROR, "Failed to accept a new connection\n");
- return -1;
- }
-
- if (conn_bfd->fd >= 0) {
- LOG_BTS(bts, DPCU, LOGL_NOTICE, "PCU connects but we already have another active connection ?!?\n");
- /* We already have one PCU connected, this is all we support */
- osmo_fd_read_disable(&state->listen_bfd);
- close(rc);
- return 0;
- }
-
- osmo_fd_setup(conn_bfd, rc, OSMO_FD_READ, pcu_sock_cb, state, 0);
-
- if (osmo_fd_register(conn_bfd) != 0) {
- LOG_BTS(bts, DPCU, LOGL_ERROR, "Failed to register new connection fd\n");
- close(conn_bfd->fd);
- conn_bfd->fd = -1;
- return -1;
- }
-
- LOG_BTS(bts, DPCU, LOGL_NOTICE, "PCU socket connected to external PCU\n");

/* activate PDCH */
llist_for_each_entry(trx, &bts->trx_list, list) {
@@ -975,6 +947,72 @@
}
}
}
+}
+
+/* Check if there are multiple BTSs configured that would require a BSC co-located PCU */
+static bool check_for_multiple_bts(struct llist_head *bts_list)
+{
+ unsigned int bts_count = 0;
+ struct gsm_bts *bts;
+
+ llist_for_each_entry(bts, bts_list, list) {
+ if (is_ericsson_bts(bts))
+ bts_count++;
+ }
+
+ if (bts_count > 1)
+ return true;
+ return false;
+}
+
+
+/* accept connection coming from PCU */
+static int pcu_sock_accept(struct osmo_fd *bfd, unsigned int flags)
+{
+ struct pcu_sock_state *state = (struct pcu_sock_state *)bfd->data;
+ struct osmo_fd *conn_bfd = &state->conn_bfd;
+ struct sockaddr_un un_addr;
+ struct gsm_bts *bts;
+ socklen_t len;
+ int rc;
+
+ /* FIXME: allow multiple BTS in OsmoPCU */
+ if (check_for_multiple_bts(&state->net->bts_list)) {
+ LOGP(DPCU, LOGL_ERROR, "This version of OsmoBSC can only handle one (Ericsson RBS) BTS with BSC co-located PCU\n");
+ LOGP(DPCU, LOGL_ERROR, "Failed to accept a new connection\n");
+ }
+
+ len = sizeof(un_addr);
+ rc = accept(bfd->fd, (struct sockaddr *) &un_addr, &len);
+ if (rc < 0) {
+ LOGP(DPCU, LOGL_ERROR, "Failed to accept a new connection\n");
+ return -1;
+ }
+
+ if (conn_bfd->fd >= 0) {
+ LOGP(DPCU, LOGL_NOTICE, "PCU connects but we already have another active connection ?!?\n");
+ /* We already have one PCU connected, this is all we support */
+ osmo_fd_read_disable(&state->listen_bfd);
+ close(rc);
+ return 0;
+ }
+
+ osmo_fd_setup(conn_bfd, rc, OSMO_FD_READ, pcu_sock_cb, state, 0);
+
+ if (osmo_fd_register(conn_bfd) != 0) {
+ LOGP(DPCU, LOGL_ERROR, "Failed to register new connection fd\n");
+ close(conn_bfd->fd);
+ conn_bfd->fd = -1;
+ return -1;
+ }
+
+ LOGP(DPCU, LOGL_NOTICE, "PCU socket connected to external PCU\n");
+
+ /* Activate all PDCHs on all BTSs that are served by the PCU */
+ llist_for_each_entry(bts, &state->net->bts_list, list) {
+ if (is_ericsson_bts(bts))
+ pdch_act_bts(bts);
+ }

return 0;
}

To view, visit change 31618. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Change-Id: I0b42c2c130106f6ffca2dd08d079e1a7bda41f0b
Gerrit-Change-Number: 31618
Gerrit-PatchSet: 1
Gerrit-Owner: dexter <pmaier@sysmocom.de>
Gerrit-MessageType: newchange