aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <holger@moiji-mobile.com>2014-08-08 21:06:30 +0200
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2014-08-08 21:17:36 +0200
commit93dfa24f429e0a1d59d60d8c8f5055e81a0b2e45 (patch)
tree2a4c2b73bf26d5261bb641bb7dbc0f59234696de /openbsc/src
parent350de9fe80239cf4b93cdba1c051a2078843d5e4 (diff)
bsc: Add a ctrl command to send a ussdNotify for a call
Send a non-call related SS message for an active call indentified by the CIC of that call. As an ugly hack the order of the SS release and the invocation are changed. That was necessary for the E71 on a TCH. The time between notify and release was just too short. The right would be to wait for the returnResultLast but this would involve keeping more local state. Let's see how far we get here. It might be necessary to change the order in the other call sites as well.
Diffstat (limited to 'openbsc/src')
-rw-r--r--openbsc/src/libbsc/bsc_api.c5
-rw-r--r--openbsc/src/osmo-bsc/osmo_bsc_bssap.c7
-rw-r--r--openbsc/src/osmo-bsc/osmo_bsc_ctrl.c76
3 files changed, 84 insertions, 4 deletions
diff --git a/openbsc/src/libbsc/bsc_api.c b/openbsc/src/libbsc/bsc_api.c
index 04a4619a7..5ce0bc41d 100644
--- a/openbsc/src/libbsc/bsc_api.c
+++ b/openbsc/src/libbsc/bsc_api.c
@@ -857,3 +857,8 @@ static __attribute__((constructor)) void on_dso_load_bsc(void)
{
osmo_signal_register_handler(SS_LCHAN, bsc_handle_lchan_signal, NULL);
}
+
+struct llist_head *bsc_api_sub_connections(struct gsm_network *net)
+{
+ return &sub_connections;
+}
diff --git a/openbsc/src/osmo-bsc/osmo_bsc_bssap.c b/openbsc/src/osmo-bsc/osmo_bsc_bssap.c
index f58d96f03..dda31578e 100644
--- a/openbsc/src/osmo-bsc/osmo_bsc_bssap.c
+++ b/openbsc/src/osmo-bsc/osmo_bsc_bssap.c
@@ -299,7 +299,6 @@ static int bssmap_handle_assignm_req(struct osmo_bsc_sccp_con *conn,
struct osmo_msc_data *msc;
struct tlv_parsed tp;
uint8_t *data;
- uint16_t cic;
uint8_t timeslot;
uint8_t multiplex;
enum gsm48_chan_mode chan_mode = GSM48_CMODE_SIGN;
@@ -322,9 +321,9 @@ static int bssmap_handle_assignm_req(struct osmo_bsc_sccp_con *conn,
goto reject;
}
- cic = ntohs(read_data16(TLVP_VAL(&tp, GSM0808_IE_CIRCUIT_IDENTITY_CODE)));
- timeslot = cic & 0x1f;
- multiplex = (cic & ~0x1f) >> 5;
+ conn->cic = ntohs(read_data16(TLVP_VAL(&tp, GSM0808_IE_CIRCUIT_IDENTITY_CODE)));
+ timeslot = conn->cic & 0x1f;
+ multiplex = (conn->cic & ~0x1f) >> 5;
/*
* Currently we only support a limited subset of all
diff --git a/openbsc/src/osmo-bsc/osmo_bsc_ctrl.c b/openbsc/src/osmo-bsc/osmo_bsc_ctrl.c
index 883205781..6b6b8a1f2 100644
--- a/openbsc/src/osmo-bsc/osmo_bsc_ctrl.c
+++ b/openbsc/src/osmo-bsc/osmo_bsc_ctrl.c
@@ -25,6 +25,7 @@
#include <openbsc/osmo_bsc_rf.h>
#include <openbsc/osmo_msc_data.h>
#include <openbsc/signal.h>
+#include <openbsc/gsm_04_80.h>
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/signal.h>
@@ -631,6 +632,78 @@ static int verify_net_inform_msc(struct ctrl_cmd *cmd, const char *value, void *
return 0;
}
+CTRL_CMD_DEFINE(net_ussd_notify, "ussd-notify-v1");
+static int get_net_ussd_notify(struct ctrl_cmd *cmd, void *data)
+{
+ cmd->reply = "There is nothing to read";
+ return CTRL_CMD_ERROR;
+}
+
+static int set_net_ussd_notify(struct ctrl_cmd *cmd, void *data)
+{
+ struct gsm_subscriber_connection *conn;
+ struct gsm_network *net;
+ char *saveptr = NULL;
+ char *cic_str, *alert_str, *text_str;
+ int cic, alert;
+
+ /* Verify has done the test for us */
+ cic_str = strtok_r(cmd->value, ",", &saveptr);
+ alert_str = strtok_r(NULL, ",", &saveptr);
+ text_str = strtok_r(NULL, ",", &saveptr);
+
+ if (!cic_str || !alert_str || !text_str) {
+ cmd->reply = "Programming issue. How did this pass verify?";
+ return CTRL_CMD_ERROR;
+ }
+
+ cmd->reply = "No connection found";
+
+ cic = atoi(cic_str);
+ alert = atoi(alert_str);
+
+ net = cmd->node;
+ llist_for_each_entry(conn, bsc_api_sub_connections(net), entry) {
+ if (!conn->sccp_con)
+ continue;
+
+ if (conn->sccp_con->cic != cic)
+ continue;
+
+ /*
+ * This is a hack. My E71 does not like to immediately
+ * receive a release complete on a TCH. So schedule a
+ * release complete to clear any previous attempt. The
+ * right thing would be to track invokeId and only send
+ * the release complete when we get a returnResultLast
+ * for this invoke id.
+ */
+ gsm0480_send_releaseComplete(conn);
+ gsm0480_send_ussdNotify(conn, alert, text_str);
+ cmd->reply = "Found a connection";
+ break;
+ }
+
+ return CTRL_CMD_REPLY;
+}
+
+static int verify_net_ussd_notify(struct ctrl_cmd *cmd, const char *value, void *data)
+{
+ char *saveptr = NULL;
+ char *inp, *cic, *alert, *text;
+
+ inp = talloc_strdup(cmd, value);
+
+ cic = strtok_r(inp, ",", &saveptr);
+ alert = strtok_r(NULL, ",", &saveptr);
+ text = strtok_r(NULL, ",", &saveptr);
+
+ talloc_free(inp);
+ if (!cic || !alert || !text)
+ return 1;
+ return 0;
+}
+
static int msc_signal_handler(unsigned int subsys, unsigned int signal,
void *handler_data, void *signal_data)
{
@@ -689,6 +762,9 @@ int bsc_ctrl_cmds_install(struct gsm_network *net)
rc = ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_net_inform_msc);
if (rc)
goto end;
+ rc = ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_net_ussd_notify);
+ if (rc)
+ goto end;
rc = osmo_signal_register_handler(SS_L_INPUT, &bts_connection_status_trap_cb, net);
end: