[PATCH] layer23 cell_log: log CBCH cell info

Alex Badea vamposdecampos at gmail.com
Sat Jan 5 19:29:58 UTC 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