aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/libbsc/system_information.c
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2014-12-28 15:00:45 +0100
committerHarald Welte <laforge@gnumonks.org>2014-12-30 00:35:28 +0100
commit30f1f376383df3ae8d85e96542bf14d174c25d89 (patch)
treed2c7cf085cce2a44ad055b741b25ef8794f105a2 /openbsc/src/libbsc/system_information.c
parent65be6de155407142ddab44faf8aee5f8d5ebf628 (diff)
Add basic support for CBCH / SMS-CB (Cell Brroadcast)
We can now configure the pyisical channel types for CBCH either in the CCCH+SDCCH4 or in the SDCCH8 chanel combination. Depending on whether a CBCH exists on the BTS, we also generate the SI4 with matching CBCH channel description to notify the phones of the existance of the CBCH. There is now a VTY command how a SMS-CB message can be sent to a given BTS. We do not yet have any logic at all for actual scheduling of multiple CBCH RSL messages towards one or multiple BTSs yet, though.
Diffstat (limited to 'openbsc/src/libbsc/system_information.c')
-rw-r--r--openbsc/src/libbsc/system_information.c37
1 files changed, 35 insertions, 2 deletions
diff --git a/openbsc/src/libbsc/system_information.c b/openbsc/src/libbsc/system_information.c
index 97827f2d9..29b9b191d 100644
--- a/openbsc/src/libbsc/system_information.c
+++ b/openbsc/src/libbsc/system_information.c
@@ -555,11 +555,34 @@ static int generate_si3(uint8_t *output, struct gsm_bts *bts)
return sizeof(*si3) + rc;
}
+/* return the gsm_lchan for the CBCH (if it exists at all) */
+static struct gsm_lchan *bts_get_cbch(struct gsm_bts *bts)
+{
+ struct gsm_lchan *lchan = NULL;
+ struct gsm_bts_trx *trx = bts->c0;
+
+ if (trx->ts[0].pchan == GSM_PCHAN_CCCH_SDCCH4_CBCH)
+ lchan = &trx->ts[0].lchan[2];
+ else {
+ int i;
+ for (i = 0; i < 8; i++) {
+ if (trx->ts[i].pchan == GSM_PCHAN_SDCCH8_SACCH8C_CBCH) {
+ lchan = &trx->ts[i].lchan[2];
+ break;
+ }
+ }
+ }
+
+ return lchan;
+}
+
static int generate_si4(uint8_t *output, struct gsm_bts *bts)
{
int rc;
struct gsm48_system_information_type_4 *si4 =
(struct gsm48_system_information_type_4 *) output;
+ struct gsm_lchan *cbch_lchan;
+ uint8_t *restoct = si4->data;
/* length of all IEs present except SI4 rest octets and l2_plen */
int l2_plen = sizeof(*si4) - 1;
@@ -577,15 +600,25 @@ static int generate_si4(uint8_t *output, struct gsm_bts *bts)
si4->rach_control = bts->si_common.rach_control;
/* Optional: CBCH Channel Description + CBCH Mobile Allocation */
+ cbch_lchan = bts_get_cbch(bts);
+ if (cbch_lchan) {
+ struct gsm48_chan_desc cd;
+ gsm48_lchan2chan_desc(&cd, cbch_lchan);
+ tv_fixed_put(si4->data, GSM48_IE_CBCH_CHAN_DESC, 4,
+ (uint8_t *) &cd);
+ l2_plen += 4 + 1;
+ restoct += 4 + 1;
+ /* we don't use hopping and thus don't need a CBCH MA */
+ }
si4->header.l2_plen = (l2_plen << 2) | 1;
/* SI4 Rest Octets (10.5.2.35), containing
Optional Power offset, GPRS Indicator,
Cell Identity, LSA ID, Selection Parameter */
- rc = rest_octets_si4(si4->data, &si_info);
+ rc = rest_octets_si4(restoct, &si_info);
- return sizeof(*si4) + rc;
+ return l2_plen + 1 + rc;
}
static int generate_si5(uint8_t *output, struct gsm_bts *bts)