aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2010-10-15 10:09:31 +0200
committerHolger Hans Peter Freyther <zecke@selfish.org>2010-10-25 21:06:03 +0200
commit4c401e7a1a35d67256baaaa28f5f2965884f96c8 (patch)
treecd865574fc449d3171baeaf4bc4aedcb657773c1 /openbsc
parentec8a4e23d31ec84a041cbdbebea476258db87b0d (diff)
nat: Forward extra state and the message to the USSD provider
Forward the SCCP state and the data to the USSD provider, also mark the connection as local.
Diffstat (limited to 'openbsc')
-rw-r--r--openbsc/src/nat/bsc_nat.c6
-rw-r--r--openbsc/src/nat/bsc_ussd.c37
2 files changed, 39 insertions, 4 deletions
diff --git a/openbsc/src/nat/bsc_nat.c b/openbsc/src/nat/bsc_nat.c
index fb4c1507c..daabf0976 100644
--- a/openbsc/src/nat/bsc_nat.c
+++ b/openbsc/src/nat/bsc_nat.c
@@ -856,10 +856,8 @@ static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg)
}
/* hand data to a side channel */
- if (bsc_check_ussd(con, parsed, msg) == 1) {
- /* we are going to take over the connection */
- /* TODO: */
- }
+ if (bsc_check_ussd(con, parsed, msg) == 1)
+ con->con_local = 2;
}
con_bsc = con->bsc;
diff --git a/openbsc/src/nat/bsc_ussd.c b/openbsc/src/nat/bsc_ussd.c
index 6640635e8..cd40566eb 100644
--- a/openbsc/src/nat/bsc_ussd.c
+++ b/openbsc/src/nat/bsc_ussd.c
@@ -31,6 +31,8 @@
#include <osmocore/talloc.h>
#include <osmocore/tlv.h>
+#include <osmocom/sccp/sccp.h>
+
#include <sys/socket.h>
#include <string.h>
#include <unistd.h>
@@ -220,6 +222,39 @@ int bsc_ussd_init(struct bsc_nat *nat)
ntohl(addr.s_addr), 5001, ussd_listen_cb);
}
+static int forward_ussd(struct sccp_connections *con, const struct ussd_request *req,
+ struct msgb *input)
+{
+ struct msgb *msg;
+ struct ipac_msgt_sccp_state *state;
+ struct bsc_nat_ussd_con *ussd;
+
+ if (!con->bsc->nat->ussd_con)
+ return -1;
+
+ msg = msgb_alloc_headroom(4096, 128, "forward ussd");
+ if (!msg) {
+ LOGP(DNAT, LOGL_ERROR, "Allocation failed, not forwarding.\n");
+ return -1;
+ }
+
+ msg->l2h = msgb_put(msg, 1);
+ msg->l2h[0] = IPAC_MSGT_SCCP_STATE;
+
+ /* fill out the data */
+ state = (struct ipac_msgt_sccp_state *) msgb_put(msg, sizeof(*state));
+ state->trans_id = req->transaction_id;
+ state->invoke_id = req->invoke_id;
+ memcpy(&state->src_ref, &con->remote_ref, sizeof(con->remote_ref));
+ memcpy(&state->dst_ref, &con->real_ref, sizeof(con->real_ref));
+ memcpy(state->imsi, con->imsi, strlen(con->imsi));
+
+ ussd = con->bsc->nat->ussd_con;
+ bsc_do_write(&ussd->queue, msg, IPAC_PROTO_IPACCESS);
+
+ return 0;
+}
+
int bsc_check_ussd(struct sccp_connections *con, struct bsc_nat_parsed *parsed,
struct msgb *msg)
{
@@ -279,5 +314,7 @@ int bsc_check_ussd(struct sccp_connections *con, struct bsc_nat_parsed *parsed,
/* found a USSD query for our subscriber */
LOGP(DNAT, LOGL_NOTICE, "Found USSD query for %s\n", con->imsi);
+ if (forward_ussd(con, &req, msg) != 0)
+ return 0;
return 1;
}