aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2013-06-12 08:42:19 +0200
committerAndreas Eversberg <jolly@eversberg.eu>2013-07-29 12:44:51 +0200
commitb007ff913814e4075d879417a164fadf5ce5b8fa (patch)
tree461de8241250d3842288b2d06c132c5311943994
parent9da656969950b93e530087796faaaea193ebb724 (diff)
HO: Improve silent call feature
Since we use late assignment now, we must assign requested channel after paging response.
-rw-r--r--openbsc/include/openbsc/gsm_data.h1
-rw-r--r--openbsc/include/openbsc/signal.h1
-rw-r--r--openbsc/include/openbsc/silent_call.h4
-rw-r--r--openbsc/src/libbsc/bsc_api.c9
-rw-r--r--openbsc/src/libmsc/silent_call.c23
-rw-r--r--openbsc/src/libmsc/vty_interface_layer3.c46
6 files changed, 65 insertions, 19 deletions
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 6f6b5b909..9c2737e56 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/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/openbsc/include/openbsc/signal.h b/openbsc/include/openbsc/signal.h
index 02f32459c..2b8607d1c 100644
--- a/openbsc/include/openbsc/signal.h
+++ b/openbsc/include/openbsc/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/openbsc/include/openbsc/silent_call.h b/openbsc/include/openbsc/silent_call.h
index 2492903c2..9e087c986 100644
--- a/openbsc/include/openbsc/silent_call.h
+++ b/openbsc/include/openbsc/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/openbsc/src/libbsc/bsc_api.c b/openbsc/src/libbsc/bsc_api.c
index 4964b5f6d..22e774c03 100644
--- a/openbsc/src/libbsc/bsc_api.c
+++ b/openbsc/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/openbsc/src/libmsc/silent_call.c b/openbsc/src/libmsc/silent_call.c
index cdc82b534..6bfd6b228 100644
--- a/openbsc/src/libmsc/silent_call.c
+++ b/openbsc/src/libmsc/silent_call.c
@@ -34,11 +34,14 @@
#include <openbsc/chan_alloc.h>
#include <openbsc/osmo_msc.h>
+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/openbsc/src/libmsc/vty_interface_layer3.c b/openbsc/src/libmsc/vty_interface_layer3.c
index e46886086..163e58e32 100644
--- a/openbsc/src/libmsc/vty_interface_layer3.c
+++ b/openbsc/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);