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:
parent
39cd32e650
commit
45fd07dc33
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue