From fb758f026078a7e44d426ad726c018fe09b73a09 Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Wed, 12 Jun 2013 08:42:19 +0200 Subject: HO: Improve silent call feature Since we use late assignment now, we must assign requested channel after paging response. --- include/osmocom/bsc/gsm_data.h | 1 + include/osmocom/bsc/signal.h | 1 + include/osmocom/bsc/silent_call.h | 4 ++-- src/libbsc/bsc_api.c | 9 ++++++++ src/libmsc/silent_call.c | 23 ++++++++++++++++---- src/libmsc/vty_interface_layer3.c | 46 ++++++++++++++++++++++++++++----------- 6 files changed, 65 insertions(+), 19 deletions(-) diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h index 6f6b5b909..9c2737e56 100644 --- a/include/osmocom/bsc/gsm_data.h +++ b/include/osmocom/bsc/gsm_data.h @@ -123,6 +123,7 @@ struct gsm_subscriber_connection { /* Are we part of a special "silent" call */ int silent_call; + void *silent_call_vty; int put_channel; /* bsc structures */ diff --git a/include/osmocom/bsc/signal.h b/include/osmocom/bsc/signal.h index 02f32459c..2b8607d1c 100644 --- a/include/osmocom/bsc/signal.h +++ b/include/osmocom/bsc/signal.h @@ -155,6 +155,7 @@ struct scall_signal_data { struct gsm_subscriber *subscr; struct gsm_subscriber_connection *conn; void *data; + uint8_t type; }; struct ipacc_ack_signal_data { diff --git a/include/osmocom/bsc/silent_call.h b/include/osmocom/bsc/silent_call.h index 2492903c2..9e087c986 100644 --- a/include/osmocom/bsc/silent_call.h +++ b/include/osmocom/bsc/silent_call.h @@ -3,8 +3,8 @@ struct gsm_subscriber_connection; -extern int gsm_silent_call_start(struct gsm_subscriber *subscr, - void *data, int type); +extern int gsm_silent_call_start(struct gsm_subscriber *subscr, void *data, + uint8_t rqd_type, uint8_t lchan_type); extern int gsm_silent_call_stop(struct gsm_subscriber *subscr); extern int silent_call_rx(struct gsm_subscriber_connection *conn, struct msgb *msg); extern int silent_call_reroute(struct gsm_subscriber_connection *conn, struct msgb *msg); diff --git a/src/libbsc/bsc_api.c b/src/libbsc/bsc_api.c index 4964b5f6d..22e774c03 100644 --- a/src/libbsc/bsc_api.c +++ b/src/libbsc/bsc_api.c @@ -484,6 +484,15 @@ static void handle_ass_compl(struct gsm_subscriber_connection *conn, lchan_to_chosen_channel(conn->lchan), conn->lchan->encr.alg_id, chan_mode_to_speech(conn->lchan)); + + if (conn->silent_call) { + struct scall_signal_data sigdata; + sigdata.conn = conn; + sigdata.data = conn->silent_call_vty; + sigdata.type = conn->lchan->type; + + osmo_signal_dispatch(SS_SCALL, S_SCALL_SUCCESS, &sigdata); + } } static void handle_ass_fail(struct gsm_subscriber_connection *conn, diff --git a/src/libmsc/silent_call.c b/src/libmsc/silent_call.c index cdc82b534..6bfd6b228 100644 --- a/src/libmsc/silent_call.c +++ b/src/libmsc/silent_call.c @@ -34,11 +34,14 @@ #include #include +static uint8_t silent_call_type; + /* paging of the requested subscriber has completed */ static int paging_cb_silent(unsigned int hooknum, unsigned int event, struct msgb *msg, void *_conn, void *_data) { struct gsm_subscriber_connection *conn = _conn; + struct gsm_lchan *lchan; struct scall_signal_data sigdata; int rc = 0; @@ -52,11 +55,20 @@ static int paging_cb_silent(unsigned int hooknum, unsigned int event, switch (event) { case GSM_PAGING_SUCCEEDED: + lchan = conn->lchan; + sigdata.type = lchan->type; DEBUGPC(DLSMS, "success, using Timeslot %u on ARFCN %u\n", - conn->lchan->ts->nr, conn->lchan->ts->trx->arfcn); + lchan->ts->nr, lchan->ts->trx->arfcn); conn->silent_call = 1; - /* increment lchan reference count */ + conn->silent_call_vty = _data; osmo_signal_dispatch(SS_SCALL, S_SCALL_SUCCESS, &sigdata); + /* assign to given channel type, if not already */ + if (silent_call_type == lchan->type) + break; + if (silent_call_type == GSM_LCHAN_SDCCH) + break; + gsm0808_assign_req(conn, GSM48_CMODE_SIGN, + silent_call_type == GSM_LCHAN_TCH_F); break; case GSM_PAGING_EXPIRED: case GSM_PAGING_BUSY: @@ -114,11 +126,14 @@ int silent_call_reroute(struct gsm_subscriber_connection *conn, struct msgb *msg /* initiate a silent call with a given subscriber */ -int gsm_silent_call_start(struct gsm_subscriber *subscr, void *data, int type) +int gsm_silent_call_start(struct gsm_subscriber *subscr, void *data, + uint8_t rqd_type, uint8_t lchan_type) { int rc; - rc = paging_request(subscr->net, subscr, type, + silent_call_type = lchan_type; + + rc = paging_request(subscr->net, subscr, rqd_type, paging_cb_silent, data); return rc; } diff --git a/src/libmsc/vty_interface_layer3.c b/src/libmsc/vty_interface_layer3.c index e46886086..163e58e32 100644 --- a/src/libmsc/vty_interface_layer3.c +++ b/src/libmsc/vty_interface_layer3.c @@ -337,7 +337,8 @@ DEFUN(subscriber_silent_call_start, { struct gsm_network *gsmnet = gsmnet_from_vty(vty); struct gsm_subscriber *subscr = get_subscr_by_argv(gsmnet, argv[0], argv[1]); - int rc, type; + int rc; + uint8_t rqd_type, lchan_type; if (!subscr) { vty_out(vty, "%% No subscriber found for %s %s%s", @@ -345,16 +346,21 @@ DEFUN(subscriber_silent_call_start, return CMD_WARNING; } - if (!strcmp(argv[2], "tch/f")) - type = RSL_CHANNEED_TCH_F; - else if (!strcmp(argv[2], "tch/any")) - type = RSL_CHANNEED_TCH_ForH; - else if (!strcmp(argv[2], "sdcch")) - type = RSL_CHANNEED_SDCCH; - else - type = RSL_CHANNEED_ANY; /* Defaults to ANY */ + if (!strcmp(argv[2], "tch/f")) { + rqd_type = RSL_CHANNEED_TCH_F; + lchan_type = GSM_LCHAN_TCH_F; + } else if (!strcmp(argv[2], "tch/any")) { + rqd_type = RSL_CHANNEED_TCH_ForH; + lchan_type = GSM_LCHAN_TCH_H; + } else if (!strcmp(argv[2], "sdcch")) { + rqd_type = RSL_CHANNEED_SDCCH; + lchan_type = GSM_LCHAN_SDCCH; + } else { + rqd_type = RSL_CHANNEED_ANY; /* Defaults to ANY */ + lchan_type = GSM_LCHAN_SDCCH; + } - rc = gsm_silent_call_start(subscr, vty, type); + rc = gsm_silent_call_start(subscr, vty, rqd_type, lchan_type); if (rc <= 0) { vty_out(vty, "%% Subscriber not attached%s", VTY_NEWLINE); @@ -754,12 +760,26 @@ static int scall_cbfn(unsigned int subsys, unsigned int signal, { struct scall_signal_data *sigdata = signal_data; struct vty *vty = sigdata->data; + char *type; switch (signal) { case S_SCALL_SUCCESS: - vty_out(vty, "%% silent call on ARFCN %u timeslot %u%s", - sigdata->conn->lchan->ts->trx->arfcn, sigdata->conn->lchan->ts->nr, - VTY_NEWLINE); + switch (sigdata->type) { + case GSM_LCHAN_TCH_F: + type = "(TCH/F)"; + break; + case GSM_LCHAN_TCH_H: + type = "(TCH/H)"; + break; + case GSM_LCHAN_SDCCH: + type = "(SDCCH)"; + break; + default: + type = "(unknown type)"; + } + vty_out(vty, "%% silent call on ARFCN %u timeslot %u %s%s", + sigdata->conn->lchan->ts->trx->arfcn, + sigdata->conn->lchan->ts->nr, type, VTY_NEWLINE); break; case S_SCALL_EXPIRED: vty_out(vty, "%% silent call expired paging%s", VTY_NEWLINE); -- cgit v1.2.3