[PATCH] layer23 cell_log: log CBCH cell info
Alex Badea
vamposdecampos at gmail.com
Sat Jan 5 20:29:58 CET 2013
If System Information contained CBCH channel description,
tune to it and log SMSCB messages with a Geographical Scope
of Cell Wide (Immediate) -- these are typically used for
"Cell Info Display".
The CBCH timeout is set to a generous 8 seconds; this is because
we need 4 frames for reassembly, we usually miss the first, and we
might hit a burst of Null SMSCB messages.
By default this feature is disabled; it can be enabled via a new '-B'
or '--cbch' commandline argument.
Signed-off-by: Alex Badea <vamposdecampos at gmail.com>
---
This patch requires the CBCH DM flag patch[1], and the libosmocore patch
series[2] for SMSCB reassembly.
[1] http://lists.osmocom.org/pipermail/baseband-devel/2013-January/003612.html
[2] http://lists.osmocom.org/pipermail/baseband-devel/2013-January/003642.html
src/host/layer23/src/misc/app_cell_log.c | 11 +++-
src/host/layer23/src/misc/cell_log.c | 114 +++++++++++++++++++++++++++++-
2 files changed, 121 insertions(+), 4 deletions(-)
diff --git a/src/host/layer23/src/misc/app_cell_log.c b/src/host/layer23/src/misc/app_cell_log.c
index a7f42c3..5ed1d6b 100644
--- a/src/host/layer23/src/misc/app_cell_log.c
+++ b/src/host/layer23/src/misc/app_cell_log.c
@@ -45,6 +45,7 @@ extern uint16_t (*band_range)[][2];
char *logname = "/var/log/osmocom.log";
int RACH_MAX = 2;
+int do_cbch = 0;
int _scan_work(struct osmocom_ms *ms)
{
@@ -103,7 +104,8 @@ static int l23_getopt_options(struct option **options)
#endif
{"gps", 1, 0, 'g'},
{"baud", 1, 0, 'b'},
- {"arfcns", 1, 0, 'A'}
+ {"arfcns", 1, 0, 'A'},
+ {"cbch", 1, 0, 'B'},
};
*options = opts;
@@ -162,6 +164,8 @@ static int l23_cfg_print_help()
printf(" -f --gps DEVICE /dev/ttyACM0. GPS serial device.\n");
printf(" -b --baud BAUDRAT The baud rate of the GPS device\n");
printf(" -A --arfcns ARFCNS The list of arfcns to be monitored\n");
+ printf(" -B --cbch Scan and log info from the CBCH\n");
+
return 0;
}
@@ -224,6 +228,9 @@ static int l23_cfg_handle(int c, const char *optarg)
parse_band_range((char*)optarg);
printf("New frequencies range: %s\n", print_band_range(*band_range, buf, sizeof(buf)));
break;
+ case 'B':
+ do_cbch = 1;
+ break;
}
return 0;
@@ -234,7 +241,7 @@ cmd_line_error:
static struct l23_app_info info = {
.copyright = "Copyright (C) 2010 Andreas Eversberg\n",
- .getopt_string = "g:p:l:r:nf:b:A:",
+ .getopt_string = "g:p:l:r:nf:b:A:B",
.cfg_supported = l23_cfg_supported,
.cfg_getopt_opt = l23_getopt_options,
.cfg_handle_opt = l23_cfg_handle,
diff --git a/src/host/layer23/src/misc/cell_log.c b/src/host/layer23/src/misc/cell_log.c
index 7340dcb..41a34fd 100644
--- a/src/host/layer23/src/misc/cell_log.c
+++ b/src/host/layer23/src/misc/cell_log.c
@@ -26,6 +26,8 @@
#include <stdlib.h>
#include <time.h>
#include <errno.h>
+#include <ctype.h>
+#include <arpa/inet.h>
#include <l1ctl_proto.h>
@@ -35,6 +37,7 @@
#include <osmocom/core/msgb.h>
#include <osmocom/gsm/gsm_utils.h>
#include <osmocom/gsm/protocol/gsm_04_08.h>
+#include <osmocom/gsm/protocol/gsm_03_41.h>
#include <osmocom/gsm/rsl.h>
#include <osmocom/bb/common/l1ctl.h>
@@ -47,6 +50,7 @@
#define READ_WAIT 2, 0
#define RACH_WAIT 0, 900000
+#define CBCH_WAIT 8, 0
#define MIN_RXLEV_DBM -106
#define MAX_DIST 2000
@@ -55,6 +59,7 @@ enum {
SCAN_STATE_SYNC,
SCAN_STATE_READ,
SCAN_STATE_RACH,
+ SCAN_STATE_CBCH,
};
/* ranges of bands */
@@ -89,6 +94,7 @@ static int rach_count;
static FILE *logfp = NULL;
extern char *logname;
extern int RACH_MAX;
+extern int do_cbch;
static struct gsm48_sysinfo sysinfo;
@@ -115,6 +121,7 @@ struct rach_ref {
static void start_sync(void);
static void start_rach(void);
+static void start_cbch(void);
static void start_pm(void);
static void log_gps(void)
@@ -228,6 +235,11 @@ static void timeout_cb(void *arg)
rach_count++;
start_rach();
break;
+ case SCAN_STATE_CBCH:
+ LOGP(DRR, LOGL_INFO, "Timeout on CBCH\n");
+ l1ctl_tx_dm_rel_req(ms);
+ start_sync();
+ break;
}
}
@@ -245,6 +257,35 @@ static void start_timer(int sec, int micro)
osmo_timer_schedule(&timer, sec, micro);
}
+static void start_cbch(void)
+{
+ struct gsm48_sysinfo *s = &sysinfo;
+ int res;
+
+ if (!do_cbch) {
+ res = -1;
+ } else if (!s->chan_nr) {
+ LOGP(DRR, LOGL_DEBUG, "No CBCH description in sysinfo\n");
+ res = -1;
+ } else if (s->h) {
+ res = l1ctl_tx_dm_est_req_h1(ms,
+ s->maio, s->hsn, s->hopping, s->hopp_len,
+ s->chan_nr, s->tsc,
+ GSM48_CMODE_SIGN, 0, L1CTL_DM_F_CBCH);
+ } else {
+ res = l1ctl_tx_dm_est_req_h0(ms, s->arfcn, s->chan_nr, s->tsc,
+ GSM48_CMODE_SIGN, 0, L1CTL_DM_F_CBCH);
+ }
+
+ if (res < 0) {
+ start_sync();
+ return;
+ }
+
+ state = SCAN_STATE_CBCH;
+ start_timer(CBCH_WAIT);
+}
+
static void start_rach(void)
{
struct gsm48_sysinfo *s = &sysinfo;
@@ -254,7 +295,7 @@ static void start_rach(void)
if (rach_count == RACH_MAX) {
log_sysinfo();
- start_sync();
+ start_cbch();
return;
}
@@ -433,7 +474,7 @@ static int ta_result(uint8_t ta)
}
log_sysinfo();
- start_sync();
+ start_cbch();
return 0;
}
@@ -737,6 +778,70 @@ int chan_conf(struct osmocom_ms *ms, struct msgb *msg)
return 0;
}
+static int sms_bc_cmd(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct abis_rsl_cchan_hdr *ch = msgb_l2(msg);
+ struct tlv_parsed tv;
+ struct rsl_ie_cb_cmd_type *cmd_type;
+ struct gsm341_ms_message *cbmsg;
+ unsigned int cbmsglen;
+ char buf[256], *p;
+
+ DEBUGP(DRSL, "RSLms SMS BC CMD chan_nr=0x%02x\n",
+ ch->chan_nr);
+
+ rsl_tlv_parse(&tv, ch->data, msgb_l2len(msg) - sizeof(*ch));
+ if (!TLVP_PRESENT(&tv, RSL_IE_SMSCB_MSG) ||
+ !TLVP_PRESENT(&tv, RSL_IE_CB_CMD_TYPE)) {
+ LOGP(DRR, LOGL_ERROR, "SMS_BC_CMD missing mandatory IEs\n");
+ return -EINVAL;
+ }
+
+ cmd_type = (struct rsl_ie_cb_cmd_type *) TLVP_VAL(&tv, RSL_IE_CB_CMD_TYPE);
+ cbmsg = (struct gsm341_ms_message *) TLVP_VAL(&tv, RSL_IE_SMSCB_MSG);
+ cbmsglen = TLVP_LEN(&tv, RSL_IE_SMSCB_MSG);
+ if (cbmsglen < sizeof(*cbmsg)) {
+ LOGP(DRR, LOGL_ERROR, "RSL_IE_SMSCB_MSG too short\n");
+ return -EINVAL;
+ }
+
+ if (cmd_type->command != RSL_CB_CMD_TYPE_NORMAL)
+ return 0;
+
+ gsm_7bit_decode(buf, cbmsg->data, cbmsglen - sizeof(*cbmsg));
+ for (p = buf; *p; p++)
+ if (!isprint(*p))
+ *p = '_';
+
+ LOGP(DSUM, LOGL_INFO, "Cell info: gs=%d code=%d update=%d id=%d text=\"%s\"\n",
+ cbmsg->serial.gs,
+ GSM341_MSG_CODE(cbmsg),
+ cbmsg->serial.update,
+ ntohs(cbmsg->msg_id),
+ buf);
+
+ if (cbmsg->serial.gs != GSM341_GS_CELL_WIDE_IMMED)
+ return 0;
+
+ LOGFILE("[cbch]\n");
+ LOGFILE("arfcn %d\n", sysinfo.arfcn);
+ LOGFILE("gs %d code %d update %d msg_id %d page %d numpages %d\n",
+ cbmsg->serial.gs,
+ GSM341_MSG_CODE(cbmsg),
+ cbmsg->serial.update,
+ ntohs(cbmsg->msg_id),
+ cbmsg->page.current, cbmsg->page.total);
+ LOGFILE("text \"%s\"\n", buf);
+ LOGFILE("\n");
+ LOGFLUSH();
+
+ l1ctl_tx_dm_rel_req(ms);
+ stop_timer();
+
+ start_sync();
+ return 0;
+}
+
static int rcv_cch(struct osmocom_ms *ms, struct msgb *msg)
{
struct abis_rsl_cchan_hdr *ch = msgb_l2(msg);
@@ -751,6 +856,11 @@ static int rcv_cch(struct osmocom_ms *ms, struct msgb *msg)
msgb_free(msg);
return rc;
}
+ if (state == SCAN_STATE_CBCH && msg_type == RSL_MT_SMS_BC_CMD) {
+ rc = sms_bc_cmd(ms, msg);
+ msgb_free(msg);
+ return rc;
+ }
LOGP(DRSL, LOGL_NOTICE, "RSLms message unhandled\n");
msgb_free(msg);
--
1.7.0.4
More information about the baseband-devel
mailing list