From 591003328dac804592c8a5dc749d93d5e0be4347 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sat, 28 Aug 2010 14:56:00 +0800 Subject: nat: Use the bsc_timeslot when talking to the BSC downstream --- openbsc/src/nat/bsc_mgcp_utils.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'openbsc/src') diff --git a/openbsc/src/nat/bsc_mgcp_utils.c b/openbsc/src/nat/bsc_mgcp_utils.c index 067df0eda..e3258f02f 100644 --- a/openbsc/src/nat/bsc_mgcp_utils.c +++ b/openbsc/src/nat/bsc_mgcp_utils.c @@ -156,9 +156,10 @@ void bsc_mgcp_dlcx(struct sccp_connections *con) { /* send a DLCX down the stream */ if (con->bsc_timeslot != -1 && con->crcx) { - int endp = mgcp_timeslot_to_endpoint(0, con->msc_timeslot); - bsc_mgcp_send_dlcx(con->bsc, endp); - bsc_mgcp_free_endpoint(con->bsc->nat, endp); + int bsc_endp = mgcp_timeslot_to_endpoint(0, con->bsc_timeslot); + int msc_endp = mgcp_timeslot_to_endpoint(0, con->msc_timeslot); + bsc_mgcp_send_dlcx(con->bsc, bsc_endp); + bsc_mgcp_free_endpoint(con->bsc->nat, msc_endp); } bsc_mgcp_init(con); -- cgit v1.2.3 From f4b343920668280b39ddb95209f6ab0ceccab630 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sat, 28 Aug 2010 16:08:39 +0800 Subject: nat: Make the code work in terms of endpoints instead of timeslot/multiplex We are going to have more than one trunk, so all code hardcoding the multiplex to zero must go. Avoid this kind of problem by saving the MGCP endpoint number and comparing that. --- openbsc/src/nat/bsc_mgcp_utils.c | 30 ++++++++++++++---------------- openbsc/src/nat/bsc_nat_vty.c | 2 +- 2 files changed, 15 insertions(+), 17 deletions(-) (limited to 'openbsc/src') diff --git a/openbsc/src/nat/bsc_mgcp_utils.c b/openbsc/src/nat/bsc_mgcp_utils.c index e3258f02f..4983c352c 100644 --- a/openbsc/src/nat/bsc_mgcp_utils.c +++ b/openbsc/src/nat/bsc_mgcp_utils.c @@ -45,7 +45,7 @@ int bsc_mgcp_assign(struct sccp_connections *con, struct msgb *msg) uint16_t cic; uint8_t timeslot; uint8_t multiplex; - int combined; + int endp; if (!msg->l3h) { LOGP(DNAT, LOGL_ERROR, "Assignment message should have l3h pointer.\n"); @@ -68,22 +68,22 @@ int bsc_mgcp_assign(struct sccp_connections *con, struct msgb *msg) multiplex = (cic & ~0x1f) >> 5; - combined = (32 * multiplex) + timeslot; + endp = mgcp_timeslot_to_endpoint(multiplex, timeslot); /* find stale connections using that endpoint */ llist_for_each_entry(mcon, &con->bsc->nat->sccp_connections, list_entry) { - if (mcon->msc_timeslot == combined) { + if (mcon->msc_endp == endp) { LOGP(DNAT, LOGL_ERROR, - "Timeslot %d was assigned to 0x%x and now 0x%x\n", - combined, + "Endpoint %d was assigned to 0x%x and now 0x%x\n", + endp, sccp_src_ref_to_int(&mcon->patched_ref), sccp_src_ref_to_int(&con->patched_ref)); bsc_mgcp_dlcx(mcon); } } - con->msc_timeslot = combined; - con->bsc_timeslot = con->msc_timeslot; + con->msc_endp = endp; + con->bsc_endp = endp; return 0; } @@ -147,19 +147,17 @@ static void bsc_mgcp_send_dlcx(struct bsc_connection *bsc, int endpoint) void bsc_mgcp_init(struct sccp_connections *con) { - con->msc_timeslot = -1; - con->bsc_timeslot = -1; + con->msc_endp = -1; + con->bsc_endp = -1; con->crcx = 0; } void bsc_mgcp_dlcx(struct sccp_connections *con) { /* send a DLCX down the stream */ - if (con->bsc_timeslot != -1 && con->crcx) { - int bsc_endp = mgcp_timeslot_to_endpoint(0, con->bsc_timeslot); - int msc_endp = mgcp_timeslot_to_endpoint(0, con->msc_timeslot); - bsc_mgcp_send_dlcx(con->bsc, bsc_endp); - bsc_mgcp_free_endpoint(con->bsc->nat, msc_endp); + if (con->bsc_endp != -1 && con->crcx) { + bsc_mgcp_send_dlcx(con->bsc, con->bsc_endp); + bsc_mgcp_free_endpoint(con->bsc->nat, con->msc_endp); } bsc_mgcp_init(con); @@ -172,9 +170,9 @@ struct sccp_connections *bsc_mgcp_find_con(struct bsc_nat *nat, int endpoint) struct sccp_connections *sccp; llist_for_each_entry(sccp, &nat->sccp_connections, list_entry) { - if (sccp->msc_timeslot == -1) + if (sccp->msc_endp == -1) continue; - if (mgcp_timeslot_to_endpoint(0, sccp->msc_timeslot) != endpoint) + if (sccp->msc_endp != endpoint) continue; con = sccp; diff --git a/openbsc/src/nat/bsc_nat_vty.c b/openbsc/src/nat/bsc_nat_vty.c index d8af1c23f..b72eb4e26 100644 --- a/openbsc/src/nat/bsc_nat_vty.c +++ b/openbsc/src/nat/bsc_nat_vty.c @@ -121,7 +121,7 @@ DEFUN(show_sccp, show_sccp_cmd, "show sccp connections", sccp_src_ref_to_int(&con->patched_ref), con->has_remote_ref, sccp_src_ref_to_int(&con->remote_ref), - con->msc_timeslot, con->bsc_timeslot, + con->msc_endp, con->bsc_endp, bsc_con_type_to_string(con->con_type), VTY_NEWLINE); } -- cgit v1.2.3 From c021fbe603c69c2ca79f6c91b1af109fd7e1613f Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sat, 28 Aug 2010 16:46:27 +0800 Subject: nat: Reindent the code, no functional change --- openbsc/src/nat/bsc_mgcp_utils.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'openbsc/src') diff --git a/openbsc/src/nat/bsc_mgcp_utils.c b/openbsc/src/nat/bsc_mgcp_utils.c index 4983c352c..567c325b1 100644 --- a/openbsc/src/nat/bsc_mgcp_utils.c +++ b/openbsc/src/nat/bsc_mgcp_utils.c @@ -274,30 +274,30 @@ int bsc_mgcp_policy_cb(struct mgcp_config *cfg, int endpoint, int state, const c static void free_chan_downstream(struct mgcp_endpoint *endp, struct bsc_endpoint *bsc_endp, struct bsc_connection *bsc) { - LOGP(DMGCP, LOGL_ERROR, "No CI, freeing endpoint 0x%x in state %d\n", - ENDPOINT_NUMBER(endp), bsc_endp->transaction_state); - - /* if a CRCX failed... send a DLCX down the stream */ - if (bsc_endp->transaction_state == MGCP_ENDP_CRCX) { - struct sccp_connections *con; - con = bsc_mgcp_find_con(bsc->nat, ENDPOINT_NUMBER(endp)); - if (!con) { - LOGP(DMGCP, LOGL_ERROR, - "No SCCP connection for endp 0x%x\n", - ENDPOINT_NUMBER(endp)); + LOGP(DMGCP, LOGL_ERROR, "No CI, freeing endpoint 0x%x in state %d\n", + ENDPOINT_NUMBER(endp), bsc_endp->transaction_state); + + /* if a CRCX failed... send a DLCX down the stream */ + if (bsc_endp->transaction_state == MGCP_ENDP_CRCX) { + struct sccp_connections *con; + con = bsc_mgcp_find_con(bsc->nat, ENDPOINT_NUMBER(endp)); + if (!con) { + LOGP(DMGCP, LOGL_ERROR, + "No SCCP connection for endp 0x%x\n", + ENDPOINT_NUMBER(endp)); + } else { + if (con->bsc == bsc) { + bsc_mgcp_send_dlcx(bsc, ENDPOINT_NUMBER(endp)); + con->crcx = 0; } else { - if (con->bsc == bsc) { - bsc_mgcp_send_dlcx(bsc, ENDPOINT_NUMBER(endp)); - con->crcx = 0; - } else { - LOGP(DMGCP, LOGL_ERROR, - "Endpoint belongs to a different BSC\n"); - } + LOGP(DMGCP, LOGL_ERROR, + "Endpoint belongs to a different BSC\n"); } } + } - bsc_mgcp_free_endpoint(bsc->nat, ENDPOINT_NUMBER(endp)); - mgcp_free_endp(endp); + bsc_mgcp_free_endpoint(bsc->nat, ENDPOINT_NUMBER(endp)); + mgcp_free_endp(endp); } /* -- cgit v1.2.3 From 39cd32e650d490ba2d5e74f2df90a3f12514d618 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sat, 28 Aug 2010 18:11:07 +0800 Subject: nat: Remove the CRCX value from the nat Assume that if the MSC has assigned a timeslot/multiplex it will also be used for the MGCP. So we just assume that it was allocated on the BSC as well... in the worse case we will send a DLCX downstream but it should be fine. --- openbsc/src/nat/bsc_mgcp_utils.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'openbsc/src') diff --git a/openbsc/src/nat/bsc_mgcp_utils.c b/openbsc/src/nat/bsc_mgcp_utils.c index 567c325b1..8ed930145 100644 --- a/openbsc/src/nat/bsc_mgcp_utils.c +++ b/openbsc/src/nat/bsc_mgcp_utils.c @@ -149,13 +149,12 @@ void bsc_mgcp_init(struct sccp_connections *con) { con->msc_endp = -1; con->bsc_endp = -1; - con->crcx = 0; } void bsc_mgcp_dlcx(struct sccp_connections *con) { /* send a DLCX down the stream */ - if (con->bsc_endp != -1 && con->crcx) { + if (con->bsc_endp != -1) { bsc_mgcp_send_dlcx(con->bsc, con->bsc_endp); bsc_mgcp_free_endpoint(con->bsc->nat, con->msc_endp); } @@ -253,7 +252,6 @@ int bsc_mgcp_policy_cb(struct mgcp_config *cfg, int endpoint, int state, const c } /* send the message and a fake MDCX to force sending of a dummy packet */ - sccp->crcx = 1; bsc_write(sccp->bsc, bsc_msg, NAT_IPAC_PROTO_MGCP); bsc_mgcp_send_mdcx(sccp->bsc, mgcp_endp); return MGCP_POLICY_DEFER; @@ -288,7 +286,6 @@ static void free_chan_downstream(struct mgcp_endpoint *endp, struct bsc_endpoint } else { if (con->bsc == bsc) { bsc_mgcp_send_dlcx(bsc, ENDPOINT_NUMBER(endp)); - con->crcx = 0; } else { LOGP(DMGCP, LOGL_ERROR, "Endpoint belongs to a different BSC\n"); -- cgit v1.2.3 From 45fd07dc33b5dd845e2b266adda5d24a4d500f96 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sat, 28 Aug 2010 18:22:14 +0800 Subject: 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. --- openbsc/src/nat/bsc_mgcp_utils.c | 52 ++++++++++++++++++++++++++++++++++++++-- openbsc/src/nat/bsc_nat.c | 2 +- 2 files changed, 51 insertions(+), 3 deletions(-) (limited to 'openbsc/src') 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 #include -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"); -- cgit v1.2.3 From 0d8330c8cc066ce6609286fe58de3f7962ef7736 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sat, 28 Aug 2010 18:33:34 +0800 Subject: nat: Add vty command to show the endpoint allocation status --- openbsc/src/nat/bsc_nat_vty.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'openbsc/src') diff --git a/openbsc/src/nat/bsc_nat_vty.c b/openbsc/src/nat/bsc_nat_vty.c index b72eb4e26..0bbd313a9 100644 --- a/openbsc/src/nat/bsc_nat_vty.c +++ b/openbsc/src/nat/bsc_nat_vty.c @@ -29,6 +29,7 @@ #include #include +#include #include @@ -148,6 +149,30 @@ DEFUN(show_bsc, show_bsc_cmd, "show bsc connections", return CMD_SUCCESS; } +DEFUN(show_bsc_mgcp, show_bsc_mgcp_cmd, "show bsc mgcp NR", + SHOW_STR "Display the MGCP status for a given BSC") +{ + struct bsc_connection *con; + int nr = atoi(argv[0]); + int i; + + llist_for_each_entry(con, &_nat->bsc_connections, list_entry) { + if (!con->cfg) + continue; + if (con->cfg->nr != nr) + continue; + + vty_out(vty, "MGCP Status for %d%s", con->cfg->nr, VTY_NEWLINE); + for (i = 1; i < ARRAY_SIZE(con->endpoint_status); ++i) + vty_out(vty, " Endpoint 0x%x %s%s", i, + con->endpoint_status[i] == 0 ? "free" : "allocated", + VTY_NEWLINE); + break; + } + + return CMD_SUCCESS; +} + DEFUN(show_bsc_cfg, show_bsc_cfg_cmd, "show bsc config", SHOW_STR "Display information about known BSC configs") { @@ -564,6 +589,7 @@ int bsc_nat_vty_init(struct bsc_nat *nat) install_element_ve(&close_bsc_cmd); install_element_ve(&show_msc_cmd); install_element_ve(&test_regex_cmd); + install_element_ve(&show_bsc_mgcp_cmd); /* nat group */ install_element(CONFIG_NODE, &cfg_nat_cmd); -- cgit v1.2.3 From 8574dcf9da046daaff5703342e376f9f82cc8734 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sun, 29 Aug 2010 22:39:07 +0800 Subject: nat: Close the right endpoint down the stream. --- openbsc/src/nat/bsc_mgcp_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'openbsc/src') diff --git a/openbsc/src/nat/bsc_mgcp_utils.c b/openbsc/src/nat/bsc_mgcp_utils.c index 475e04cc2..2dcd25022 100644 --- a/openbsc/src/nat/bsc_mgcp_utils.c +++ b/openbsc/src/nat/bsc_mgcp_utils.c @@ -333,7 +333,7 @@ static void free_chan_downstream(struct mgcp_endpoint *endp, struct bsc_endpoint ENDPOINT_NUMBER(endp)); } else { if (con->bsc == bsc) { - bsc_mgcp_send_dlcx(bsc, ENDPOINT_NUMBER(endp)); + bsc_mgcp_send_dlcx(bsc, con->bsc_endp); } else { LOGP(DMGCP, LOGL_ERROR, "Endpoint belongs to a different BSC\n"); -- cgit v1.2.3 From 7d5bb26fdcb402e46fc301468ed903e4c4023bf0 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sun, 29 Aug 2010 22:44:10 +0800 Subject: nat: Remove the code that is wrongly placed.. i refers to the MSC side of endpoints and not the BSC.. --- openbsc/src/nat/bsc_mgcp_utils.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'openbsc/src') diff --git a/openbsc/src/nat/bsc_mgcp_utils.c b/openbsc/src/nat/bsc_mgcp_utils.c index 2dcd25022..12124aff2 100644 --- a/openbsc/src/nat/bsc_mgcp_utils.c +++ b/openbsc/src/nat/bsc_mgcp_utils.c @@ -133,15 +133,6 @@ 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; } -- cgit v1.2.3 From 601180f2d93e56757a02a2b2161a73ce6a99e8b8 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sun, 29 Aug 2010 23:40:33 +0800 Subject: nat: Send the right MDCX down the stream --- openbsc/src/nat/bsc_mgcp_utils.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'openbsc/src') diff --git a/openbsc/src/nat/bsc_mgcp_utils.c b/openbsc/src/nat/bsc_mgcp_utils.c index 12124aff2..b71ec9482 100644 --- a/openbsc/src/nat/bsc_mgcp_utils.c +++ b/openbsc/src/nat/bsc_mgcp_utils.c @@ -148,7 +148,7 @@ void bsc_mgcp_free_endpoints(struct bsc_nat *nat) } /* send a MDCX where we do not want a response */ -static void bsc_mgcp_send_mdcx(struct bsc_connection *bsc, struct mgcp_endpoint *endp) +static void bsc_mgcp_send_mdcx(struct bsc_connection *bsc, int port, struct mgcp_endpoint *endp) { char buf[2096]; int len; @@ -159,7 +159,7 @@ static void bsc_mgcp_send_mdcx(struct bsc_connection *bsc, struct mgcp_endpoint "\r\n" "c=IN IP4 %s\r\n" "m=audio %d RTP/AVP 255\r\n", - ENDPOINT_NUMBER(endp), + port, bsc->nat->mgcp_cfg->source_addr, endp->bts_end.local_port); if (len < 0) { @@ -292,7 +292,7 @@ int bsc_mgcp_policy_cb(struct mgcp_config *cfg, int endpoint, int state, const c /* send the message and a fake MDCX to force sending of a dummy packet */ bsc_write(sccp->bsc, bsc_msg, NAT_IPAC_PROTO_MGCP); - bsc_mgcp_send_mdcx(sccp->bsc, mgcp_endp); + bsc_mgcp_send_mdcx(sccp->bsc, sccp->bsc_endp, mgcp_endp); return MGCP_POLICY_DEFER; } else if (state == MGCP_ENDP_DLCX) { /* we will free the endpoint now and send a DLCX to the BSC */ -- cgit v1.2.3 From d38aa450d758cebbbb78194bdc35df6462ffe501 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Mon, 30 Aug 2010 11:58:49 +0800 Subject: nat: Document that the MDCX message is not implemented --- openbsc/src/nat/bsc_mgcp_utils.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'openbsc/src') diff --git a/openbsc/src/nat/bsc_mgcp_utils.c b/openbsc/src/nat/bsc_mgcp_utils.c index b71ec9482..e68b6479b 100644 --- a/openbsc/src/nat/bsc_mgcp_utils.c +++ b/openbsc/src/nat/bsc_mgcp_utils.c @@ -166,6 +166,8 @@ static void bsc_mgcp_send_mdcx(struct bsc_connection *bsc, int port, struct mgcp LOGP(DMGCP, LOGL_ERROR, "snprintf for DLCX failed.\n"); return; } + + #warning "The MDCX is not send to the BSC. It should" } static void bsc_mgcp_send_dlcx(struct bsc_connection *bsc, int endpoint) -- cgit v1.2.3 From bf812fa83cfff25540e29166246ca71d8ddf0de9 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Mon, 30 Aug 2010 12:01:36 +0800 Subject: nat: Use different static transaction numbers for the DLCX/MDCX message --- openbsc/src/nat/bsc_mgcp_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'openbsc/src') diff --git a/openbsc/src/nat/bsc_mgcp_utils.c b/openbsc/src/nat/bsc_mgcp_utils.c index e68b6479b..d8ec29869 100644 --- a/openbsc/src/nat/bsc_mgcp_utils.c +++ b/openbsc/src/nat/bsc_mgcp_utils.c @@ -176,7 +176,7 @@ static void bsc_mgcp_send_dlcx(struct bsc_connection *bsc, int endpoint) int len; len = snprintf(buf, sizeof(buf), - "DLCX 23 %x@mgw MGCP 1.0\r\n" + "DLCX 26 %x@mgw MGCP 1.0\r\n" "Z: noanswer\r\n", endpoint); if (len < 0) { LOGP(DMGCP, LOGL_ERROR, "snprintf for DLCX failed.\n"); -- cgit v1.2.3 From f7c86c5b4d8f7d909595c0f01fcfaf5da4c4e7c4 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Mon, 30 Aug 2010 13:44:32 +0800 Subject: nat: Replace the MGCP Endpoint if that is required Add code to replace the Endpoint number for the mgcp. --- openbsc/src/nat/bsc_mgcp_utils.c | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) (limited to 'openbsc/src') diff --git a/openbsc/src/nat/bsc_mgcp_utils.c b/openbsc/src/nat/bsc_mgcp_utils.c index d8ec29869..1728a41e7 100644 --- a/openbsc/src/nat/bsc_mgcp_utils.c +++ b/openbsc/src/nat/bsc_mgcp_utils.c @@ -196,6 +196,9 @@ void bsc_mgcp_dlcx(struct sccp_connections *con) { /* send a DLCX down the stream */ if (con->bsc_endp != -1) { + if (con->bsc->endpoint_status[con->bsc_endp] != 1) + LOGP(DNAT, LOGL_ERROR, "Endpoint 0x%x was not in use\n", con->bsc_endp); + con->bsc->endpoint_status[con->bsc_endp] = 0; bsc_mgcp_send_dlcx(con->bsc, con->bsc_endp); bsc_mgcp_free_endpoint(con->bsc->nat, con->msc_endp); } @@ -269,7 +272,7 @@ int bsc_mgcp_policy_cb(struct mgcp_config *cfg, int endpoint, int state, const c } /* we need to generate a new and patched message */ - bsc_msg = bsc_mgcp_rewrite((char *) nat->mgcp_msg, nat->mgcp_length, + bsc_msg = bsc_mgcp_rewrite((char *) nat->mgcp_msg, nat->mgcp_length, sccp->bsc_endp, nat->mgcp_cfg->source_addr, mgcp_endp->bts_end.local_port); if (!bsc_msg) { LOGP(DMGCP, LOGL_ERROR, "Failed to patch the msg.\n"); @@ -401,7 +404,7 @@ void bsc_mgcp_forward(struct bsc_connection *bsc, struct msgb *msg) * there should be nothing for us to rewrite so putting endp->rtp_port * with the value of 0 should be no problem. */ - output = bsc_mgcp_rewrite((char * ) msg->l2h, msgb_l2len(msg), + output = bsc_mgcp_rewrite((char * ) msg->l2h, msgb_l2len(msg), -1, bsc->nat->mgcp_cfg->source_addr, endp->net_end.local_port); if (!output) { @@ -438,9 +441,28 @@ uint32_t bsc_mgcp_extract_ci(const char *str) return ci; } +static void patch_mgcp(struct msgb *output, const char *op, const char *tok, + int endp, int len, int cr) +{ + int slen; + int ret; + char buf[40]; + + buf[0] = buf[39] = '\0'; + ret = sscanf(tok, "%*s %s", buf); + + slen = sprintf((char *) output->l3h, "%s %s %x@mgw MGCP 1.0%s", + op, buf, endp, cr ? "\r\n" : "\n"); + output->l3h = msgb_put(output, slen); +} + /* we need to replace some strings... */ -struct msgb *bsc_mgcp_rewrite(char *input, int length, const char *ip, int port) +struct msgb *bsc_mgcp_rewrite(char *input, int length, int endpoint, const char *ip, int port) { + static const char *crcx_str = "CRCX "; + static const char *dlcx_str = "DLCX "; + static const char *mdcx_str = "MDCX "; + static const char *ip_str = "c=IN IP4 "; static const char *aud_str = "m=audio "; @@ -461,11 +483,18 @@ struct msgb *bsc_mgcp_rewrite(char *input, int length, const char *ip, int port) running = input; output->l2h = output->data; + output->l3h = output->l2h; for (token = strsep(&running, "\n"); running; token = strsep(&running, "\n")) { int len = strlen(token); int cr = len > 0 && token[len - 1] == '\r'; - if (strncmp(ip_str, token, (sizeof ip_str) - 1) == 0) { + if (strncmp(crcx_str, token, (sizeof crcx_str) - 1) == 0) { + patch_mgcp(output, "CRCX", token, endpoint, len, cr); + } else if (strncmp(dlcx_str, token, (sizeof dlcx_str) - 1) == 0) { + patch_mgcp(output, "DLCX", token, endpoint, len, cr); + } else if (strncmp(mdcx_str, token, (sizeof mdcx_str) - 1) == 0) { + patch_mgcp(output, "MDCX", token, endpoint, len, cr); + } else if (strncmp(ip_str, token, (sizeof ip_str) - 1) == 0) { output->l3h = msgb_put(output, strlen(ip_str)); memcpy(output->l3h, ip_str, strlen(ip_str)); output->l3h = msgb_put(output, strlen(ip)); -- cgit v1.2.3