aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src
diff options
context:
space:
mode:
authorHarald Welte <laforge@netfilter.org>2009-12-13 10:53:12 +0100
committerHarald Welte <laforge@netfilter.org>2009-12-13 10:53:12 +0100
commiteab84a112c3ef8c35835a2ba23fa978fff4d218b (patch)
tree99fa6ef4f469c55a9993bd1ef746e714af497b4d /openbsc/src
parent09b7e7fa43c74d35e8ea935f3096993e3360f33a (diff)
[RRLP] make RRLP mode configurable from config file
We now support different RRLP modes (including "none" to disable RRLP), you can configure it via "rrlp mode" in the "network" section of openbsc.cfg.
Diffstat (limited to 'openbsc/src')
-rw-r--r--openbsc/src/gsm_data.c23
-rw-r--r--openbsc/src/rrlp.c44
-rw-r--r--openbsc/src/vty_interface.c14
3 files changed, 74 insertions, 7 deletions
diff --git a/openbsc/src/gsm_data.c b/openbsc/src/gsm_data.c
index fef1127eb..cdaba9e52 100644
--- a/openbsc/src/gsm_data.c
+++ b/openbsc/src/gsm_data.c
@@ -367,3 +367,26 @@ const char *gsm_auth_policy_name(enum gsm_auth_policy policy)
return gsm_auth_policy_names[policy];
}
+static const char *rrlp_mode_names[] = {
+ [RRLP_MODE_NONE] = "none",
+ [RRLP_MODE_MS_BASED] = "ms-based",
+ [RRLP_MODE_MS_PREF] = "ms-preferred",
+ [RRLP_MODE_ASS_PREF] = "ass-preferred",
+};
+
+enum rrlp_mode rrlp_mode_parse(const char *arg)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(rrlp_mode_names); i++) {
+ if (!strcmp(arg, rrlp_mode_names[i]))
+ return i;
+ }
+ return RRLP_MODE_NONE;
+}
+
+const char *rrlp_mode_name(enum rrlp_mode mode)
+{
+ if (mode > ARRAY_SIZE(rrlp_mode_names))
+ return "none";
+ return rrlp_mode_names[mode];
+}
diff --git a/openbsc/src/rrlp.c b/openbsc/src/rrlp.c
index 523b53f0b..60ce750ad 100644
--- a/openbsc/src/rrlp.c
+++ b/openbsc/src/rrlp.c
@@ -1,4 +1,4 @@
-
+/* Radio Resource LCS (Location) Protocol, GMS TS 04.31 */
/* (C) 2009 by Harald Welte <laforge@gnumonks.org>
*
@@ -28,9 +28,42 @@
#include <openbsc/gsm_subscriber.h>
#include <openbsc/chan_alloc.h>
-/* RRLP MS based position request */
+/* RRLP msPositionReq, nsBased,
+ * Accuracy=60, Method=gps, ResponseTime=2, oneSet */
static const u_int8_t ms_based_pos_req[] = { 0x40, 0x01, 0x78, 0xa8 };
+/* RRLP msPositionReq, msBasedPref,
+ Accuracy=60, Method=gpsOrEOTD, ResponseTime=5, multipleSets */
+static const u_int8_t ms_pref_pos_req[] = { 0x40, 0x02, 0x79, 0x50 };
+
+/* RRLP msPositionReq, msAssistedPref,
+ Accuracy=60, Method=gpsOrEOTD, ResponseTime=5, multipleSets */
+static const u_int8_t ass_pref_pos_req[] = { 0x40, 0x03, 0x79, 0x50 };
+
+static int send_rrlp_req(struct gsm_lchan *lchan)
+{
+ struct gsm_network *net = lchan->ts->trx->bts->network;
+ const u_int8_t *req;
+
+ switch (net->rrlp.mode) {
+ case RRLP_MODE_MS_BASED:
+ req = ms_based_pos_req;
+ break;
+ case RRLP_MODE_MS_PREF:
+ req = ms_pref_pos_req;
+ break;
+ case RRLP_MODE_ASS_PREF:
+ req = ass_pref_pos_req;
+ break;
+ case RRLP_MODE_NONE:
+ default:
+ return 0;
+ }
+
+ return gsm48_send_rr_app_info(lchan, 0x00,
+ sizeof(ms_based_pos_req), req);
+}
+
static int subscr_sig_cb(unsigned int subsys, unsigned int signal,
void *handler_data, void *signal_data)
{
@@ -44,8 +77,7 @@ static int subscr_sig_cb(unsigned int subsys, unsigned int signal,
lchan = lchan_for_subscr(subscr);
if (!lchan)
break;
- gsm48_send_rr_app_info(lchan, 0x00, sizeof(ms_based_pos_req),
- ms_based_pos_req);
+ send_rrlp_req(lchan);
break;
}
return 0;
@@ -59,9 +91,7 @@ static int paging_sig_cb(unsigned int subsys, unsigned int signal,
switch (signal) {
case S_PAGING_COMPLETED:
/* A subscriber has attached. */
- gsm48_send_rr_app_info(psig_data->lchan, 0x00,
- sizeof(ms_based_pos_req),
- ms_based_pos_req);
+ send_rrlp_req(psig_data->lchan);
break;
}
return 0;
diff --git a/openbsc/src/vty_interface.c b/openbsc/src/vty_interface.c
index 529b0d481..adef1480a 100644
--- a/openbsc/src/vty_interface.c
+++ b/openbsc/src/vty_interface.c
@@ -91,6 +91,8 @@ static void net_dump_vty(struct vty *vty, struct gsm_network *net)
VTY_NEWLINE);
vty_out(vty, " NECI (TCH/H): %u%s", net->neci,
VTY_NEWLINE);
+ vty_out(vty, " RRLP Mode: %s%s", rrlp_mode_name(net->rrlp.mode),
+ VTY_NEWLINE);
}
DEFUN(show_net, show_net_cmd, "show network",
@@ -289,6 +291,8 @@ static int config_write_net(struct vty *vty)
gsmnet->reject_cause, VTY_NEWLINE);
vty_out(vty, " encryption a5 %u%s", gsmnet->a5_encryption, VTY_NEWLINE);
vty_out(vty, " neci %u%s", gsmnet->neci, VTY_NEWLINE);
+ vty_out(vty, " rrlp mode %s%s", rrlp_mode_name(gsmnet->rrlp.mode),
+ VTY_NEWLINE);
vty_out(vty, " timer t3101 %u%s", gsmnet->T3101, VTY_NEWLINE);
vty_out(vty, " timer t3103 %u%s", gsmnet->T3103, VTY_NEWLINE);
vty_out(vty, " timer t3105 %u%s", gsmnet->T3105, VTY_NEWLINE);
@@ -838,6 +842,15 @@ DEFUN(cfg_net_neci,
return CMD_SUCCESS;
}
+DEFUN(cfg_net_rrlp_mode, cfg_net_rrlp_mode_cmd,
+ "rrlp mode (none|ms-based|ms-preferred|ass-preferred)",
+ "Set the Radio Resource Location Protocol Mode")
+{
+ gsmnet->rrlp.mode = rrlp_mode_parse(argv[0]);
+
+ return CMD_SUCCESS;
+}
+
#define DECLARE_TIMER(number) \
DEFUN(cfg_net_T##number, \
cfg_net_T##number##_cmd, \
@@ -1344,6 +1357,7 @@ int bsc_vty_init(struct gsm_network *net)
install_element(GSMNET_NODE, &cfg_net_reject_cause_cmd);
install_element(GSMNET_NODE, &cfg_net_encryption_cmd);
install_element(GSMNET_NODE, &cfg_net_neci_cmd);
+ install_element(GSMNET_NODE, &cfg_net_rrlp_mode_cmd);
install_element(GSMNET_NODE, &cfg_net_T3101_cmd);
install_element(GSMNET_NODE, &cfg_net_T3103_cmd);
install_element(GSMNET_NODE, &cfg_net_T3105_cmd);