aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--openbsc/include/openbsc/bsc_api.h2
-rw-r--r--openbsc/include/openbsc/osmo_bsc.h3
-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
5 files changed, 89 insertions, 4 deletions
diff --git a/openbsc/include/openbsc/bsc_api.h b/openbsc/include/openbsc/bsc_api.h
index f52984f39..a21fb74d8 100644
--- a/openbsc/include/openbsc/bsc_api.h
+++ b/openbsc/include/openbsc/bsc_api.h
@@ -52,4 +52,6 @@ int gsm0808_page(struct gsm_bts *bts, unsigned int page_group,
unsigned int mi_len, uint8_t *mi, int chan_type);
int gsm0808_clear(struct gsm_subscriber_connection *conn);
+struct llist_head *bsc_api_sub_connections(struct gsm_network *net);
+
#endif
diff --git a/openbsc/include/openbsc/osmo_bsc.h b/openbsc/include/openbsc/osmo_bsc.h
index 7e931c8d9..cd4e4deb9 100644
--- a/openbsc/include/openbsc/osmo_bsc.h
+++ b/openbsc/include/openbsc/osmo_bsc.h
@@ -22,6 +22,9 @@ struct osmo_bsc_sccp_con {
struct llist_head entry;
int ciphering_handled;
+
+ /* for audio handling */
+ uint16_t cic;
int rtp_port;
/* SCCP connection realted */
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: