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 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);
|
||||||
|
|
|
@ -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, ×lot);
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue