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.
This commit is contained in:
Holger Hans Peter Freyther 2010-08-28 18:22:14 +08:00
parent 39cd32e650
commit 45fd07dc33
4 changed files with 65 additions and 8 deletions

View File

@ -75,6 +75,10 @@ struct bsc_connection {
struct timer_list ping_timeout; struct timer_list ping_timeout;
struct timer_list pong_timeout; struct timer_list pong_timeout;
/* mgcp related code */
int endpoint_status[33];
int last_endpoint;
/* a back pointer */ /* a back pointer */
struct bsc_nat *nat; 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 * MGCP/Audio handling
*/ */
int bsc_write_mgcp(struct bsc_connection *bsc, const uint8_t *data, unsigned int length); 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_init(struct sccp_connections *);
void bsc_mgcp_dlcx(struct sccp_connections *); void bsc_mgcp_dlcx(struct sccp_connections *);
void bsc_mgcp_free_endpoints(struct bsc_nat *nat); void bsc_mgcp_free_endpoints(struct bsc_nat *nat);

View File

@ -38,7 +38,36 @@
#include <errno.h> #include <errno.h>
#include <unistd.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 sccp_connections *mcon;
struct tlv_parsed tp; struct tlv_parsed tp;
@ -83,7 +112,17 @@ int bsc_mgcp_assign(struct sccp_connections *con, struct msgb *msg)
} }
con->msc_endp = endp; 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; 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; 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].transaction_state = 0;
nat->bsc_endpoints[i].bsc = NULL; nat->bsc_endpoints[i].bsc = NULL;
} }

View File

@ -422,7 +422,7 @@ static int forward_sccp_to_bts(struct bsc_msc_connection *msc_con, struct msgb *
struct rate_ctr_group *ctrg; struct rate_ctr_group *ctrg;
ctrg = con->bsc->cfg->stats.ctrg; ctrg = con->bsc->cfg->stats.ctrg;
rate_ctr_inc(&ctrg->ctr[BCFG_CTR_SCCP_CALLS]); 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"); LOGP(DNAT, LOGL_ERROR, "Failed to assign...\n");
} else } else
LOGP(DNAT, LOGL_ERROR, "Assignment command but no BSC.\n"); LOGP(DNAT, LOGL_ERROR, "Assignment command but no BSC.\n");

View File

@ -444,7 +444,7 @@ static void test_mgcp_ass_tracking(void)
msg = msgb_alloc(4096, "foo"); msg = msgb_alloc(4096, "foo");
copy_to_msg(msg, ass_cmd, sizeof(ass_cmd)); copy_to_msg(msg, ass_cmd, sizeof(ass_cmd));
parsed = bsc_nat_parse(msg); 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"); fprintf(stderr, "Failed to handle assignment.\n");
abort(); abort();
} }
@ -454,14 +454,19 @@ static void test_mgcp_ass_tracking(void)
abort(); abort();
} }
if (con.bsc_endp != 21) { if (con.bsc_endp != 1) {
fprintf(stderr, "Assigned timeslot should have been 21.\n"); fprintf(stderr, "Assigned timeslot should have been 1.\n");
abort(); abort();
} }
if (con.bsc->endpoint_status[1] != 1) {
fprintf(stderr, "The status on the BSC is wrong.\n");
abort();
}
talloc_free(parsed); talloc_free(parsed);
bsc_mgcp_dlcx(&con); 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"); fprintf(stderr, "Clearing should remove the mapping.\n");
abort(); abort();
} }