diff options
author | Holger Hans Peter Freyther <zecke@selfish.org> | 2010-08-28 18:22:14 +0800 |
---|---|---|
committer | Holger Hans Peter Freyther <zecke@selfish.org> | 2010-08-29 16:35:26 +0800 |
commit | 45fd07dc33b5dd845e2b266adda5d24a4d500f96 (patch) | |
tree | 76a24118f01c2b15fa694820922775dda606f85a /openbsc/src | |
parent | 39cd32e650d490ba2d5e74f2df90a3f12514d618 (diff) |
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.
Diffstat (limited to 'openbsc/src')
-rw-r--r-- | openbsc/src/nat/bsc_mgcp_utils.c | 52 | ||||
-rw-r--r-- | openbsc/src/nat/bsc_nat.c | 2 |
2 files changed, 51 insertions, 3 deletions
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 <errno.h> #include <unistd.h> -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"); |