aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--openbsc/include/openbsc/gsm_data.h15
-rw-r--r--openbsc/src/gsm_data.c23
-rw-r--r--openbsc/src/rrlp.c44
-rw-r--r--openbsc/src/vty_interface.c14
4 files changed, 89 insertions, 7 deletions
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 7184a85a5..57665386d 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -38,6 +38,13 @@ enum gsm_chan_t {
GSM_LCHAN_UNKNOWN,
};
+/* RRLP mode of operation */
+enum rrlp_mode {
+ RRLP_MODE_NONE,
+ RRLP_MODE_MS_BASED,
+ RRLP_MODE_MS_PREF,
+ RRLP_MODE_ASS_PREF,
+};
/* Channel Request reason */
enum gsm_chreq_reason_t {
@@ -449,6 +456,11 @@ struct gsm_network {
int T3117;
int T3119;
int T3141;
+
+ /* Radio Resource Location Protocol (TS 04.31) */
+ struct {
+ enum rrlp_mode mode;
+ } rrlp;
};
#define SMS_HDR_SIZE 128
@@ -533,6 +545,9 @@ static inline int is_siemens_bts(struct gsm_bts *bts)
enum gsm_auth_policy gsm_auth_policy_parse(const char *arg);
const char *gsm_auth_policy_name(enum gsm_auth_policy policy);
+enum rrlp_mode rrlp_mode_parse(const char *arg);
+const char *rrlp_mode_name(enum rrlp_mode mode);
+
void gsm_trx_lock_rf(struct gsm_bts_trx *trx, int locked);
#endif
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);