From 45fd07dc33b5dd845e2b266adda5d24a4d500f96 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sat, 28 Aug 2010 18:22:14 +0800 Subject: nat: Attempt to assign the BSC Timeslot based on a free list Do attempt to not reassign an endpoint immediately but go to the next free one. --- openbsc/include/openbsc/bsc_nat.h | 6 ++++- openbsc/src/nat/bsc_mgcp_utils.c | 52 ++++++++++++++++++++++++++++++++++-- openbsc/src/nat/bsc_nat.c | 2 +- openbsc/tests/bsc-nat/bsc_nat_test.c | 13 ++++++--- 4 files changed, 65 insertions(+), 8 deletions(-) diff --git a/openbsc/include/openbsc/bsc_nat.h b/openbsc/include/openbsc/bsc_nat.h index 5f746f237..11c24dc60 100644 --- a/openbsc/include/openbsc/bsc_nat.h +++ b/openbsc/include/openbsc/bsc_nat.h @@ -75,6 +75,10 @@ struct bsc_connection { struct timer_list ping_timeout; struct timer_list pong_timeout; + /* mgcp related code */ + int endpoint_status[33]; + int last_endpoint; + /* a back pointer */ struct bsc_nat *nat; }; @@ -253,7 +257,7 @@ struct sccp_connections *patch_sccp_src_ref_to_msc(struct msgb *, struct bsc_nat * MGCP/Audio handling */ int bsc_write_mgcp(struct bsc_connection *bsc, const uint8_t *data, unsigned int length); -int bsc_mgcp_assign(struct sccp_connections *, struct msgb *msg); +int bsc_mgcp_assign_patch(struct sccp_connections *, struct msgb *msg); void bsc_mgcp_init(struct sccp_connections *); void bsc_mgcp_dlcx(struct sccp_connections *); void bsc_mgcp_free_endpoints(struct bsc_nat *nat); diff --git a/openbsc/src/nat/bsc_mgcp_utils.c b/openbsc/src/nat/bsc_mgcp_utils.c index 8ed930145..475e04cc2 100644 --- a/openbsc/src/nat/bsc_mgcp_utils.c +++ b/openbsc/src/nat/bsc_mgcp_utils.c @@ -38,7 +38,36 @@ #include #include -int bsc_mgcp_assign(struct sccp_connections *con, struct msgb *msg) +static int bsc_assign_endpoint(struct bsc_connection *bsc, struct sccp_connections *con) +{ + const int number_endpoints = ARRAY_SIZE(bsc->endpoint_status); + int 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; + con->bsc_endp = endpoint; + bsc->last_endpoint = endpoint; + return 0; + } + } + + return -1; +} + +static uint16_t create_cic(int endpoint) +{ + int timeslot, multiplex; + + mgcp_endpoint_to_timeslot(endpoint, &multiplex, ×lot); + return (multiplex << 5) | (timeslot & 0x1f); +} + +int bsc_mgcp_assign_patch(struct sccp_connections *con, struct msgb *msg) { struct sccp_connections *mcon; struct tlv_parsed tp; @@ -83,7 +112,17 @@ int bsc_mgcp_assign(struct sccp_connections *con, struct msgb *msg) } con->msc_endp = endp; - con->bsc_endp = endp; + if (bsc_assign_endpoint(con->bsc, con) != 0) + return -1; + + /* + * now patch the message for the new CIC... + * still assumed to be one multiplex only + */ + cic = htons(create_cic(con->bsc_endp)); + memcpy((uint8_t *) TLVP_VAL(&tp, GSM0808_IE_CIRCUIT_IDENTITY_CODE), + &cic, sizeof(cic)); + return 0; } @@ -94,6 +133,15 @@ static void bsc_mgcp_free_endpoint(struct bsc_nat *nat, int i) nat->bsc_endpoints[i].transaction_id = NULL; } + /* Free the endpoint status, so we can allocate it again */ + if (nat->bsc_endpoints[i].bsc) { + struct bsc_connection *bsc = nat->bsc_endpoints[i].bsc; + if (bsc->endpoint_status[i] != 1) + LOGP(DNAT, LOGL_ERROR, "Endpoint %d should be allocated\n", i); + + bsc->endpoint_status[i] = 0; + } + nat->bsc_endpoints[i].transaction_state = 0; nat->bsc_endpoints[i].bsc = NULL; } diff --git a/openbsc/src/nat/bsc_nat.c b/openbsc/src/nat/bsc_nat.c index 997a57f44..a380a61fb 100644 --- a/openbsc/src/nat/bsc_nat.c +++ b/openbsc/src/nat/bsc_nat.c @@ -422,7 +422,7 @@ static int forward_sccp_to_bts(struct bsc_msc_connection *msc_con, struct msgb * struct rate_ctr_group *ctrg; ctrg = con->bsc->cfg->stats.ctrg; rate_ctr_inc(&ctrg->ctr[BCFG_CTR_SCCP_CALLS]); - if (bsc_mgcp_assign(con, msg) != 0) + if (bsc_mgcp_assign_patch(con, msg) != 0) LOGP(DNAT, LOGL_ERROR, "Failed to assign...\n"); } else LOGP(DNAT, LOGL_ERROR, "Assignment command but no BSC.\n"); diff --git a/openbsc/tests/bsc-nat/bsc_nat_test.c b/openbsc/tests/bsc-nat/bsc_nat_test.c index b7a89c5b7..acc5de343 100644 --- a/openbsc/tests/bsc-nat/bsc_nat_test.c +++ b/openbsc/tests/bsc-nat/bsc_nat_test.c @@ -444,7 +444,7 @@ static void test_mgcp_ass_tracking(void) msg = msgb_alloc(4096, "foo"); copy_to_msg(msg, ass_cmd, sizeof(ass_cmd)); parsed = bsc_nat_parse(msg); - if (bsc_mgcp_assign(&con, msg) != 0) { + if (bsc_mgcp_assign_patch(&con, msg) != 0) { fprintf(stderr, "Failed to handle assignment.\n"); abort(); } @@ -454,14 +454,19 @@ static void test_mgcp_ass_tracking(void) abort(); } - if (con.bsc_endp != 21) { - fprintf(stderr, "Assigned timeslot should have been 21.\n"); + if (con.bsc_endp != 1) { + fprintf(stderr, "Assigned timeslot should have been 1.\n"); abort(); } + if (con.bsc->endpoint_status[1] != 1) { + fprintf(stderr, "The status on the BSC is wrong.\n"); + abort(); + } + talloc_free(parsed); bsc_mgcp_dlcx(&con); - if (con.bsc_endp != -1 || con.msc_endp != -1) { + if (con.bsc_endp != -1 || con.msc_endp != -1 || con.bsc->endpoint_status[1] != 0) { fprintf(stderr, "Clearing should remove the mapping.\n"); abort(); } -- cgit v1.2.3