aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2010-08-28 18:22:14 +0800
committerHolger Hans Peter Freyther <zecke@selfish.org>2010-08-29 16:35:26 +0800
commit45fd07dc33b5dd845e2b266adda5d24a4d500f96 (patch)
tree76a24118f01c2b15fa694820922775dda606f85a /openbsc/src
parent39cd32e650d490ba2d5e74f2df90a3f12514d618 (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.c52
-rw-r--r--openbsc/src/nat/bsc_nat.c2
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, &timeslot);
+ 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");