fixeria has uploaded this change for review.

View Change

layer23/sysinfo: implement decoding of SI13 Rest Octets

Change-Id: Ia6ff7d4e37816c6321b54c1f7f8d7110e557f8c5
Related: SYS#5500
---
M src/host/layer23/include/osmocom/bb/common/sysinfo.h
M src/host/layer23/src/common/sysinfo.c
M src/host/layer23/src/mobile/gsm48_rr.c
3 files changed, 169 insertions(+), 12 deletions(-)

git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/12/30812/1
diff --git a/src/host/layer23/include/osmocom/bb/common/sysinfo.h b/src/host/layer23/include/osmocom/bb/common/sysinfo.h
index 6a915d0..429b90d 100644
--- a/src/host/layer23/include/osmocom/bb/common/sysinfo.h
+++ b/src/host/layer23/include/osmocom/bb/common/sysinfo.h
@@ -21,7 +21,8 @@
struct gsm48_sysinfo {
/* flags of available information */
uint8_t si1, si2, si2bis, si2ter, si3,
- si4, si5, si5bis, si5ter, si6;
+ si4, si5, si5bis, si5ter, si6,
+ si13;

/* memory maps to simply detect change in system info messages */
uint8_t si1_msg[23];
@@ -34,6 +35,7 @@
uint8_t si5b_msg[18];
uint8_t si5t_msg[18];
uint8_t si6_msg[18];
+ uint8_t si13_msg[23];

struct gsm_sysinfo_freq freq[1024]; /* all frequencies */
uint16_t hopping[64]; /* hopping arfcn */
@@ -66,9 +68,46 @@
uint8_t ecsm;
uint8_t sched;
uint8_t sched_where;
- uint8_t gprs;
- uint8_t gprs_ra_colour;
- uint8_t gprs_si13_pos;
+
+ struct {
+ /* si3/si4 rest */
+ uint8_t supported;
+ uint8_t ra_colour;
+ uint8_t si13_pos;
+
+ /* si13 rest */
+ uint8_t hopping;
+ uint8_t hsn;
+ uint8_t rfl_num_len;
+ uint8_t rfl_num[4];
+
+ uint8_t ma_bitlen;
+ uint8_t ma_bitmap[64 / 8];
+ uint8_t arfcn_idx_len;
+ uint8_t arfcn_idx[16];
+
+ /* PBCCH is not present */
+ uint8_t rac;
+ uint8_t prio_acc_thresh;
+ uint8_t nco;
+
+ /* GPRS Cell Options */
+ uint8_t nmo;
+ uint8_t T3168;
+ uint8_t T3192;
+ uint8_t ab_type;
+ uint8_t ctrl_ack_type;
+ uint8_t bs_cv_max;
+ uint8_t pan_params_present;
+ uint8_t pan_dec;
+ uint8_t pan_inc;
+ uint8_t pan_max;
+
+ /* EGPRS Cell Options */
+ uint8_t egprs_supported;
+ uint8_t egprs_pkt_chan_req;
+ uint8_t egprs_bep_period;
+ } gprs;

/* cell selection */
int8_t ms_txpwr_max_cch;
@@ -151,6 +190,8 @@
const struct gsm48_system_information_type_5ter *si, int len);
int gsm48_decode_sysinfo6(struct gsm48_sysinfo *s,
const struct gsm48_system_information_type_6 *si, int len);
+int gsm48_decode_sysinfo13(struct gsm48_sysinfo *s,
+ const struct gsm48_system_information_type_13 *si, int len);
int gsm48_decode_mobile_alloc(struct gsm_sysinfo_freq *freq,
const uint8_t *ma, uint8_t len,
uint16_t *hopping, uint8_t *hopp_len, int si4);
diff --git a/src/host/layer23/src/common/sysinfo.c b/src/host/layer23/src/common/sysinfo.c
index a912e9c..7f86b57 100644
--- a/src/host/layer23/src/common/sysinfo.c
+++ b/src/host/layer23/src/common/sysinfo.c
@@ -23,6 +23,8 @@
#include <osmocom/core/utils.h>
#include <osmocom/core/bitvec.h>

+#include <osmocom/gprs/rlcmac/gprs_rlcmac.h>
+
#include <osmocom/bb/common/osmocom_data.h>
#include <osmocom/bb/common/networks.h>
#include <osmocom/bb/common/logging.h>
@@ -536,11 +538,11 @@
s->sched = 0;
/* GPRS Indicator */
if (bitvec_get_bit_high(&bv) == H) {
- s->gprs = 1;
- s->gprs_ra_colour = bitvec_get_uint(&bv, 3);
- s->gprs_si13_pos = bitvec_get_uint(&bv, 1);
+ s->gprs.supported = 1;
+ s->gprs.ra_colour = bitvec_get_uint(&bv, 3);
+ s->gprs.si13_pos = bitvec_get_uint(&bv, 1);
} else
- s->gprs = 0;
+ s->gprs.supported = 0;

return 0;
}
@@ -571,11 +573,11 @@
s->po = 0;
/* GPRS Indicator */
if (bitvec_get_bit_high(&bv) == H) {
- s->gprs = 1;
- s->gprs_ra_colour = bitvec_get_uint(&bv, 3);
- s->gprs_si13_pos = bitvec_get_uint(&bv, 1);
+ s->gprs.supported = 1;
+ s->gprs.ra_colour = bitvec_get_uint(&bv, 3);
+ s->gprs.si13_pos = bitvec_get_uint(&bv, 1);
} else
- s->gprs = 0;
+ s->gprs.supported = 0;
// todo: more rest octet bits

return 0;
@@ -840,6 +842,86 @@
return 0;
}

+int gsm48_decode_sysinfo13(struct gsm48_sysinfo *s,
+ const struct gsm48_system_information_type_13 *si, int len)
+{
+ SI13_RestOctets_t si13ro;
+ int rc;
+
+ rc = osmo_gprs_rlcmac_decode_si13ro(&si13ro, si->rest_octets, sizeof(s->si13_msg));
+ if (rc != 0) {
+ LOGP(DRR, LOGL_ERROR, "Failed to parse SI13 Rest Octets\n");
+ return rc;
+ }
+
+ if (si13ro.UnionType != 0) {
+ LOGP(DRR, LOGL_NOTICE, "PBCCH is deprecated and not supported\n");
+ return -ENOTSUP;
+ }
+
+ s->gprs.hopping = si13ro.Exist_MA;
+ if (s->gprs.hopping) {
+ const GPRS_Mobile_Allocation_t *gma = &si13ro.GPRS_Mobile_Allocation;
+
+ s->gprs.hsn = gma->HSN;
+ s->gprs.rfl_num_len = gma->ElementsOf_RFL_NUMBER;
+ memcpy(&s->gprs.rfl_num[0], &gma->RFL_NUMBER[0], sizeof(gma->RFL_NUMBER));
+
+ if (gma->UnionType == 0) { /* MA Bitmap */
+ const MobileAllocation_t *ma = &gma->u.MA;
+ s->gprs.ma_bitlen = ma->MA_BitLength;
+ memcpy(&s->gprs.ma_bitmap[0], &ma->MA_BITMAP[0], sizeof(ma->MA_BITMAP));
+ } else { /* ARFCN Index List */
+ const ARFCN_index_list_t *ai = &gma->u.ARFCN_index_list;
+ s->gprs.arfcn_idx_len = ai->ElementsOf_ARFCN_INDEX;
+ memcpy(&s->gprs.arfcn_idx[0], &ai->ARFCN_INDEX[0], sizeof(ai->ARFCN_INDEX));
+ }
+ }
+
+ const PBCCH_Not_present_t *np = &si13ro.u.PBCCH_Not_present;
+
+ s->gprs.rac = np->RAC;
+ s->gprs.prio_acc_thresh = np->PRIORITY_ACCESS_THR;
+ s->gprs.nco = np->NETWORK_CONTROL_ORDER;
+
+ const GPRS_Cell_Options_t *gco = &np->GPRS_Cell_Options;
+
+ s->gprs.nmo = gco->NMO;
+ s->gprs.T3168 = gco->T3168;
+ s->gprs.T3192 = gco->T3192;
+ s->gprs.ab_type = gco->ACCESS_BURST_TYPE;
+ s->gprs.ctrl_ack_type = !gco->CONTROL_ACK_TYPE; /* inversed */
+ s->gprs.bs_cv_max = gco->BS_CV_MAX;
+
+ s->gprs.pan_params_present = gco->Exist_PAN;
+ if (s->gprs.pan_params_present) {
+ s->gprs.pan_dec = gco->PAN_DEC;
+ s->gprs.pan_dec = gco->PAN_INC;
+ s->gprs.pan_dec = gco->PAN_MAX;
+ }
+
+ s->gprs.egprs_supported = 0;
+ if (gco->Exist_Extension_Bits) {
+ /* CSN.1 codec is not powerful enough (yet?) to decode this part :( */
+ unsigned int ext_len = gco->Extension_Bits.extension_length;
+ const uint8_t *ext = &gco->Extension_Bits.Extension_Info[0];
+
+ s->gprs.egprs_supported = (ext[0] >> 7);
+ if (s->gprs.egprs_supported) {
+ if (ext_len < 6)
+ return -EINVAL;
+ s->gprs.egprs_pkt_chan_req = ~ext[0] & (1 << 6); /* inversed */
+ s->gprs.egprs_bep_period = (ext[0] >> 2) & 0x0f;
+ }
+ }
+
+ /* TODO: GPRS_Power_Control_Parameters */
+
+ s->si13 = 1;
+
+ return 0;
+}
+
int gsm48_encode_lai_hex(struct gsm48_loc_area_id *lai,
uint16_t mcc, uint16_t mnc, uint16_t lac)
{
diff --git a/src/host/layer23/src/mobile/gsm48_rr.c b/src/host/layer23/src/mobile/gsm48_rr.c
index 8a920ee..deb76c9 100644
--- a/src/host/layer23/src/mobile/gsm48_rr.c
+++ b/src/host/layer23/src/mobile/gsm48_rr.c
@@ -2086,6 +2086,38 @@
return gsm48_new_sysinfo(ms, si->system_information);
}

+/* receive "SYSTEM INFORMATION 13" message (9.1.43a) */
+static int gsm48_rr_rx_sysinfo13(struct osmocom_ms *ms, struct msgb *msg)
+{
+ const struct gsm48_system_information_type_13 *si = msgb_l3(msg);
+ int rest_octets_len = msgb_l3len(msg) - sizeof(si->header);
+ struct gsm48_sysinfo *s = ms->cellsel.si;
+
+ if (!s) {
+ LOGP(DRR, LOGL_INFO,
+ "No cell selected, SYSTEM INFORMATION 13 ignored\n");
+ return -EINVAL;
+ }
+
+ if (rest_octets_len < 0) {
+ LOGP(DRR, LOGL_NOTICE,
+ "Short read of SYSTEM INFORMATION 13 message.\n");
+ return -EINVAL;
+ }
+
+ if (!memcmp(si, s->si13_msg, MIN(msgb_l3len(msg), sizeof(s->si6_msg))))
+ return 0;
+
+ gsm48_decode_sysinfo13(s, si, msgb_l3len(msg));
+
+ LOGP(DRR, LOGL_INFO,
+ "New SYSTEM INFORMATION 13 (%s, RAC 0x%02x, NCO %u, MNO %u)\n",
+ s->gprs.egprs_supported ? "EGPRS" : "GPRS only",
+ s->gprs.rac, s->gprs.nco, s->gprs.nmo);
+
+ return gsm48_new_sysinfo(ms, si->header.system_information);
+}
+
/*
* paging
*/
@@ -4820,6 +4852,8 @@
return gsm48_rr_rx_sysinfo3(ms, msg);
case GSM48_MT_RR_SYSINFO_4:
return gsm48_rr_rx_sysinfo4(ms, msg);
+ case GSM48_MT_RR_SYSINFO_13:
+ return gsm48_rr_rx_sysinfo13(ms, msg);
default:
#if 0
LOGP(DRR, LOGL_NOTICE, "BCCH message type 0x%02x not sup.\n",

To view, visit change 30812. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: osmocom-bb
Gerrit-Branch: master
Gerrit-Change-Id: Ia6ff7d4e37816c6321b54c1f7f8d7110e557f8c5
Gerrit-Change-Number: 30812
Gerrit-PatchSet: 1
Gerrit-Owner: fixeria <vyanitskiy@sysmocom.de>
Gerrit-MessageType: newchange