aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvan Kluchnikov <kluchnikovi@gmail.com>2017-07-04 15:21:38 +0300
committerIvan Kluchnikov <kluchnikovi@gmail.com>2017-07-04 15:46:07 +0300
commit07e11826d423572fea17d702d4020df6a7e86509 (patch)
tree090b3b2ec0982fcafb449137fe9e77fdae8884c9
parentcf5c67033fc4c8820613f4abae6a2e0c777306a2 (diff)
Implement handover support for mncc bridge mode
* Introduced mncc message with type MNCC_RTP_MODIFY for forwarding modified rtp info to external application. * Added handler for HANDOVER_DETECT signal, which forwards rtp info (modified during handover process) to external application via mncc.
-rw-r--r--openbsc/include/openbsc/mncc.h1
-rw-r--r--openbsc/src/libmsc/gsm_04_08.c75
-rw-r--r--openbsc/src/libmsc/mncc.c1
3 files changed, 77 insertions, 0 deletions
diff --git a/openbsc/include/openbsc/mncc.h b/openbsc/include/openbsc/mncc.h
index 49f0c8b..e75ce67 100644
--- a/openbsc/include/openbsc/mncc.h
+++ b/openbsc/include/openbsc/mncc.h
@@ -95,6 +95,7 @@ struct gsm_call {
#define MNCC_RTP_CREATE 0x0204
#define MNCC_RTP_CONNECT 0x0205
#define MNCC_RTP_FREE 0x0206
+#define MNCC_RTP_MODIFY 0x0207
#define GSM_TCHF_FRAME 0x0300
#define GSM_TCHF_FRAME_EFR 0x0301
diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c
index 38a050d..4a0e394 100644
--- a/openbsc/src/libmsc/gsm_04_08.c
+++ b/openbsc/src/libmsc/gsm_04_08.c
@@ -3503,6 +3503,80 @@ static int tch_rtp_signal(struct gsm_lchan *lchan, int signal)
return 0;
}
+static int ho_detect(struct gsm_lchan *lchan)
+{
+ struct gsm_network *net;
+ struct gsm_trans *tmp, *trans = NULL;
+
+ net = lchan->ts->trx->bts->network;
+ llist_for_each_entry(tmp, &net->trans_list, entry) {
+ if (!tmp->conn)
+ continue;
+ if (tmp->conn->lchan != lchan && tmp->conn->ho_lchan != lchan)
+ continue;
+ trans = tmp;
+ break;
+ }
+
+ if (!trans) {
+ LOGP(DMNCC, LOGL_ERROR, "%s lchan signal but no transaction.\n",
+ gsm_lchan_name(lchan));
+ return 0;
+ }
+
+ LOGP(DMNCC, LOGL_NOTICE, "%s sending pending RTP modify ind.\n",
+ gsm_lchan_name(lchan));
+
+ int msg_type;
+ switch (lchan->abis_ip.rtp_payload) {
+ case RTP_PT_GSM_FULL:
+ msg_type = GSM_TCHF_FRAME;
+ break;
+ case RTP_PT_GSM_EFR:
+ msg_type = GSM_TCHF_FRAME_EFR;
+ break;
+ case RTP_PT_GSM_HALF:
+ msg_type = GSM_TCHH_FRAME;
+ break;
+ case RTP_PT_AMR:
+ msg_type = GSM_TCH_FRAME_AMR;
+ break;
+ default:
+ LOGP(DMNCC, LOGL_ERROR, "%s unknown payload type %d\n",
+ gsm_lchan_name(lchan), lchan->abis_ip.rtp_payload);
+ msg_type = 0;
+ break;
+ }
+
+ mncc_recv_rtp(net, trans->callref, MNCC_RTP_MODIFY,
+ lchan->abis_ip.bound_ip,
+ lchan->abis_ip.bound_port,
+ lchan->abis_ip.rtp_payload,
+ msg_type);
+ return 0;
+}
+
+/* some other part of the code sends us a signal */
+static int handle_lchan_signal(unsigned int subsys, unsigned int signal,
+ void *handler_data, void *signal_data)
+{
+ struct lchan_signal_data *lchan_data;
+ struct gsm_lchan *lchan;
+
+ lchan_data = signal_data;
+ switch (subsys) {
+ case SS_LCHAN:
+ lchan = lchan_data->lchan;
+ switch (signal) {
+ case S_LCHAN_HANDOVER_DETECT:
+ if (lchan->conn && lchan->conn->mncc_rtp_bridge)
+ return ho_detect(lchan);
+ }
+ break;
+ }
+
+ return 0;
+}
static struct downstate {
uint32_t states;
@@ -4035,4 +4109,5 @@ int gsm0408_dispatch(struct gsm_subscriber_connection *conn, struct msgb *msg)
static __attribute__((constructor)) void on_dso_load_0408(void)
{
osmo_signal_register_handler(SS_ABISIP, handle_abisip_signal, NULL);
+ osmo_signal_register_handler(SS_LCHAN, handle_lchan_signal, NULL);
}
diff --git a/openbsc/src/libmsc/mncc.c b/openbsc/src/libmsc/mncc.c
index 8110ead..52b71de 100644
--- a/openbsc/src/libmsc/mncc.c
+++ b/openbsc/src/libmsc/mncc.c
@@ -85,6 +85,7 @@ static const struct value_string mncc_names[] = {
{ MNCC_RTP_CREATE, "MNCC_RTP_CREATE" },
{ MNCC_RTP_CONNECT, "MNCC_RTP_CONNECT" },
{ MNCC_RTP_FREE, "MNCC_RTP_FREE" },
+ { MNCC_RTP_MODIFY, "MNCC_RTP_MODIFY" },
{ GSM_TCHF_FRAME, "GSM_TCHF_FRAME" },
{ GSM_TCHF_FRAME_EFR, "GSM_TCHF_FRAME_EFR" },
{ GSM_TCHH_FRAME, "GSM_TCHH_FRAME" },