diff --git a/openbsc/include/openbsc/bsc_nat.h b/openbsc/include/openbsc/bsc_nat.h index 62db17af8..13d1b09f2 100644 --- a/openbsc/include/openbsc/bsc_nat.h +++ b/openbsc/include/openbsc/bsc_nat.h @@ -78,7 +78,7 @@ struct bsc_connection { struct timer_list pong_timeout; /* mgcp related code */ - int endpoint_status[32]; + char *_endpoint_status; int last_endpoint; /* a back pointer */ @@ -124,6 +124,9 @@ struct bsc_config { int forbid_paging; + /* audio handling */ + int number_multiplexes; + /* backpointer */ struct bsc_nat *nat; diff --git a/openbsc/src/nat/bsc_mgcp_utils.c b/openbsc/src/nat/bsc_mgcp_utils.c index aacfce6eb..d814f0dc3 100644 --- a/openbsc/src/nat/bsc_mgcp_utils.c +++ b/openbsc/src/nat/bsc_mgcp_utils.c @@ -38,18 +38,33 @@ #include #include +static int bsc_init_endps_if_needed(struct bsc_connection *con) +{ + /* we have done that */ + if (con->_endpoint_status) + return 0; + + /* we have no config... */ + if (!con->cfg) + return -1; + + con->_endpoint_status = talloc_zero_array(con, char, + (32 * con->cfg->number_multiplexes) + 1); + return con->_endpoint_status == NULL; +} + static int bsc_assign_endpoint(struct bsc_connection *bsc, struct sccp_connections *con) { - const int number_endpoints = ARRAY_SIZE(bsc->endpoint_status); + const int number_endpoints = 31 * bsc->cfg->number_multiplexes; int i; - for (i = 1; i < number_endpoints; ++i) { + for (i = 1; i <= number_endpoints; ++i) { int endpoint = (bsc->last_endpoint + i) % number_endpoints; if (endpoint == 0) endpoint = 1; - if (bsc->endpoint_status[endpoint] == 0) { - bsc->endpoint_status[endpoint] = 1; + if (bsc->_endpoint_status[endpoint] == 0) { + bsc->_endpoint_status[endpoint] = 1; con->bsc_endp = endpoint; bsc->last_endpoint = endpoint; return 0; @@ -119,6 +134,8 @@ int bsc_mgcp_assign_patch(struct sccp_connections *con, struct msgb *msg) } con->msc_endp = endp; + if (bsc_init_endps_if_needed(con->bsc) != 0) + return -1; if (bsc_assign_endpoint(con->bsc, con) != 0) return -1; @@ -202,10 +219,10 @@ void bsc_mgcp_init(struct sccp_connections *con) void bsc_mgcp_dlcx(struct sccp_connections *con) { /* send a DLCX down the stream */ - if (con->bsc_endp != -1) { - if (con->bsc->endpoint_status[con->bsc_endp] != 1) + if (con->bsc_endp != -1 && con->bsc->_endpoint_status) { + if (con->bsc->_endpoint_status[con->bsc_endp] != 1) LOGP(DNAT, LOGL_ERROR, "Endpoint 0x%x was not in use\n", con->bsc_endp); - con->bsc->endpoint_status[con->bsc_endp] = 0; + con->bsc->_endpoint_status[con->bsc_endp] = 0; bsc_mgcp_send_dlcx(con->bsc, con->bsc_endp); bsc_mgcp_free_endpoint(con->bsc->nat, con->msc_endp); } diff --git a/openbsc/src/nat/bsc_nat_utils.c b/openbsc/src/nat/bsc_nat_utils.c index 7b75fa56d..047038785 100644 --- a/openbsc/src/nat/bsc_nat_utils.c +++ b/openbsc/src/nat/bsc_nat_utils.c @@ -126,6 +126,7 @@ struct bsc_config *bsc_config_alloc(struct bsc_nat *nat, const char *token) conf->token = talloc_strdup(conf, token); conf->nr = nat->num_bsc; conf->nat = nat; + conf->number_multiplexes = 1; INIT_LLIST_HEAD(&conf->lac_list); diff --git a/openbsc/src/nat/bsc_nat_vty.c b/openbsc/src/nat/bsc_nat_vty.c index 532e7905c..01bee7489 100644 --- a/openbsc/src/nat/bsc_nat_vty.c +++ b/openbsc/src/nat/bsc_nat_vty.c @@ -172,15 +172,21 @@ DEFUN(show_bsc_mgcp, show_bsc_mgcp_cmd, "show bsc mgcp NR", int i; llist_for_each_entry(con, &_nat->bsc_connections, list_entry) { + int endpoints; if (!con->cfg) continue; if (con->cfg->nr != nr) continue; + /* this bsc has no audio endpoints yet */ + if (!con->_endpoint_status) + continue; + vty_out(vty, "MGCP Status for %d%s", con->cfg->nr, VTY_NEWLINE); - for (i = 1; i < ARRAY_SIZE(con->endpoint_status); ++i) + endpoints = 31 * con->cfg->number_multiplexes; + for (i = 1; i <= endpoints; ++i) vty_out(vty, " Endpoint 0x%x %s%s", i, - con->endpoint_status[i] == 0 ? "free" : "allocated", + con->_endpoint_status[i] == 0 ? "free" : "allocated", VTY_NEWLINE); break; } diff --git a/openbsc/tests/bsc-nat/bsc_nat_test.c b/openbsc/tests/bsc-nat/bsc_nat_test.c index c5edbfe1a..d5b1ab193 100644 --- a/openbsc/tests/bsc-nat/bsc_nat_test.c +++ b/openbsc/tests/bsc-nat/bsc_nat_test.c @@ -479,7 +479,7 @@ static void test_mgcp_ass_tracking(void) fprintf(stderr, "Assigned timeslot should have been 1.\n"); abort(); } - if (con.bsc->endpoint_status[0x1b] != 1) { + if (con.bsc->_endpoint_status[0x1b] != 1) { fprintf(stderr, "The status on the BSC is wrong.\n"); abort(); } @@ -498,7 +498,7 @@ static void test_mgcp_ass_tracking(void) bsc_mgcp_dlcx(&con); if (con.bsc_endp != -1 || con.msc_endp != -1 || - con.bsc->endpoint_status[1] != 0 || con.bsc->last_endpoint != 0x1b) { + con.bsc->_endpoint_status[1] != 0 || con.bsc->last_endpoint != 0x1b) { fprintf(stderr, "Clearing should remove the mapping.\n"); abort(); }