From 123bc3283460ef24f054abef756ba6fcbd4188cc Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sat, 16 Apr 2011 14:06:18 +0200 Subject: [PATCH] ussd: Keep track of used TIs for USSD and forward messages Keep track of the used transaction identifier and always forward messages to the USSD provider. E.g. this can be used to have a dialogue going. Right now it is still possible that the MSC will close down the connection. --- openbsc/include/openbsc/bsc_nat_sccp.h | 3 + openbsc/src/osmo-bsc_nat/bsc_nat.c | 2 + openbsc/src/osmo-bsc_nat/bsc_ussd.c | 80 +++++++++++++++++++------- 3 files changed, 65 insertions(+), 20 deletions(-) diff --git a/openbsc/include/openbsc/bsc_nat_sccp.h b/openbsc/include/openbsc/bsc_nat_sccp.h index a66732dfa..20db2c12f 100644 --- a/openbsc/include/openbsc/bsc_nat_sccp.h +++ b/openbsc/include/openbsc/bsc_nat_sccp.h @@ -80,6 +80,9 @@ struct sccp_connections { int imsi_checked; char *imsi; + /* remember which Transactions we run over the bypass */ + char ussd_ti[8]; + /* * audio handling. Remember if we have ever send a CRCX, * remember the endpoint used by the MSC and BSC. diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat.c b/openbsc/src/osmo-bsc_nat/bsc_nat.c index c9c9b7bfe..4a6e36d91 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_nat.c +++ b/openbsc/src/osmo-bsc_nat/bsc_nat.c @@ -981,6 +981,8 @@ static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg) msg = bsc_nat_rewrite_setup(bsc->nat, msg, parsed, con->imsi); talloc_free(parsed); parsed = NULL; + } else if (con->con_local == NAT_CON_END_USSD) { + bsc_check_ussd(con, parsed, msg); } con_bsc = con->bsc; diff --git a/openbsc/src/osmo-bsc_nat/bsc_ussd.c b/openbsc/src/osmo-bsc_nat/bsc_ussd.c index 8c8963e47..0392e9b10 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_ussd.c +++ b/openbsc/src/osmo-bsc_nat/bsc_ussd.c @@ -252,6 +252,30 @@ int bsc_ussd_init(struct bsc_nat *nat) ntohl(addr.s_addr), 5001, 0, ussd_listen_cb, nat); } +static int forward_ussd_simple(struct sccp_connections *con, struct msgb *input) +{ + struct msgb *copy; + struct bsc_nat_ussd_con *ussd; + + if (!con->bsc->nat->ussd_con) + return -1; + + copy = msgb_alloc_headroom(4096, 128, "forward bts"); + if (!copy) { + LOGP(DNAT, LOGL_ERROR, "Allocation failed, not forwarding.\n"); + return -1; + } + + /* copy the data into the copy */ + copy->l2h = msgb_put(copy, msgb_l2len(input)); + memcpy(copy->l2h, input->l2h, msgb_l2len(input)); + + /* send it out */ + ussd = con->bsc->nat->ussd_con; + bsc_do_write(&ussd->queue, copy, IPAC_PROTO_SCCP); + return 0; +} + static int forward_ussd(struct sccp_connections *con, const struct ussd_request *req, struct msgb *input) { @@ -302,6 +326,7 @@ int bsc_check_ussd(struct sccp_connections *con, struct bsc_nat_parsed *parsed, uint32_t len; uint8_t msg_type; uint8_t proto; + uint8_t ti; struct gsm48_hdr *hdr48; struct bsc_nat_acc_lst *lst; struct ussd_request req; @@ -338,30 +363,45 @@ int bsc_check_ussd(struct sccp_connections *con, struct bsc_nat_parsed *parsed, proto = hdr48->proto_discr & 0x0f; msg_type = hdr48->msg_type & 0xbf; - if (proto != GSM48_PDISC_NC_SS || msg_type != GSM0480_MTYPE_REGISTER) + ti = (hdr48->proto_discr & 0x70) >> 4; + if (proto != GSM48_PDISC_NC_SS) return 0; - /* now check if it is a IMSI we care about */ - lst = bsc_nat_acc_lst_find(con->bsc->nat, con->bsc->nat->ussd_lst_name); - if (!lst) - return 0; + if (msg_type == GSM0480_MTYPE_REGISTER) { - if (bsc_nat_lst_check_allow(lst, con->imsi) != 0) - return 0; + /* now check if it is a IMSI we care about */ + lst = bsc_nat_acc_lst_find(con->bsc->nat, + con->bsc->nat->ussd_lst_name); + if (!lst) + return 0; - /* now decode the message and see if we really want to handle it */ - memset(&req, 0, sizeof(req)); - if (gsm0480_decode_ussd_request(hdr48, len, &req) != 1) - return 0; - if (req.text[0] == 0xff) - return 0; + if (bsc_nat_lst_check_allow(lst, con->imsi) != 0) + return 0; - if (regexec(&con->bsc->nat->ussd_query_re, req.text, 0, NULL, 0) == REG_NOMATCH) - return 0; + /* now decode the message and see if we really want to handle it */ + memset(&req, 0, sizeof(req)); + if (gsm0480_decode_ussd_request(hdr48, len, &req) != 1) + return 0; + if (req.text[0] == 0xff) + return 0; - /* 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; + if (regexec(&con->bsc->nat->ussd_query_re, + req.text, 0, NULL, 0) == REG_NOMATCH) + return 0; + + /* found a USSD query for our subscriber */ + LOGP(DNAT, LOGL_NOTICE, "Found USSD query for %s\n", con->imsi); + con->ussd_ti[ti] = 1; + if (forward_ussd(con, &req, msg) != 0) + return 0; + return 1; + } else if (msg_type == GSM0480_MTYPE_FACILITY && con->ussd_ti[ti]) { + LOGP(DNAT, LOGL_NOTICE, "Forwarding message part of TI: %d %s\n", + ti, con->imsi); + if (forward_ussd_simple(con, msg) != 0) + return 0; + return 1; + } + + return 0; }