rest_octets: Implement actual SI6 rest octets encoding

There's very little sense behind introducing a function into
libosmogsm which doesn't implement 90% of the spec.  Let's allow
the caller to provide the various optional bits of information to
the encoder, rather than generating mostly static SI6 rest octets.

Change-Id: Id75005a0c4a02ce7f809692d58b3bd226bc582b2
This commit is contained in:
Harald Welte 2019-05-28 19:49:47 +02:00
parent f85b33f68f
commit 86156de20e
2 changed files with 75 additions and 14 deletions

View File

@ -20,7 +20,44 @@ int osmo_gsm48_rest_octets_si2quater_encode(uint8_t *data, uint8_t si2q_index, u
size_t *e_offset);
int osmo_gsm48_rest_octets_si2ter_encode(uint8_t *data);
int osmo_gsm48_rest_octets_si2bis_encode(uint8_t *data);
int osmo_gsm48_rest_octets_si6_encode(uint8_t *data, bool is1800_net);
struct osmo_gsm48_si_pch_nch_info {
bool present;
bool paging_channel_restructuring;
uint8_t nln_sacch;
bool call_priority_present;
uint8_t call_priority;
bool nln_status_sacch;
};
struct osmo_gsm48_si_vbs_vgcs_options {
bool present;
bool inband_notifications;
bool inband_pagings;
};
struct osmo_gsm48_si_dtm_support {
bool present;
uint8_t rac;
uint8_t max_lapdm;
};
struct osmo_gsm48_si_gprs_ms_txpwr_max_ccch {
bool present;
uint8_t max_txpwr;
};
struct osmo_gsm48_si6_ro_info {
struct osmo_gsm48_si_pch_nch_info pch_nch_info;
struct osmo_gsm48_si_vbs_vgcs_options vbs_vgcs_options;
struct osmo_gsm48_si_dtm_support dtm_support;
bool band_indicator_1900;
struct osmo_gsm48_si_gprs_ms_txpwr_max_ccch gprs_ms_txpwr_max_ccch;
/* MBMS: not supported in Osmocom */
/* AMR config (group channel): not supported in Osmocom */
};
int osmo_gsm48_rest_octets_si6_encode(uint8_t *data, const struct osmo_gsm48_si6_ro_info *in);
struct osmo_gsm48_si_selection_params {
uint16_t penalty_time:5,

View File

@ -687,7 +687,7 @@ int osmo_gsm48_rest_octets_si4_encode(uint8_t *data, const struct osmo_gsm48_si_
{ L | H < GPRS_MS_TXPWR_MAX_CCH : bit (5) > }
<implicit spare >;
*/
int osmo_gsm48_rest_octets_si6_encode(uint8_t *data, bool is1800_net)
int osmo_gsm48_rest_octets_si6_encode(uint8_t *data, const struct osmo_gsm48_si6_ro_info *in)
{
struct bitvec bv;
@ -695,19 +695,43 @@ int osmo_gsm48_rest_octets_si6_encode(uint8_t *data, bool is1800_net)
bv.data = data;
bv.data_len = 1;
/* no PCH/NCH info */
bitvec_set_bit(&bv, L);
/* no VBS/VGCS options */
bitvec_set_bit(&bv, L);
/* no DTM_support */
bitvec_set_bit(&bv, L);
/* band indicator */
if (is1800_net)
bitvec_set_bit(&bv, L);
else
if (in->pch_nch_info.present) {
bitvec_set_bit(&bv, H);
/* no GPRS_MS_TXPWR_MAX_CCH */
bitvec_set_bit(&bv, L);
bitvec_set_bit(&bv, !!in->pch_nch_info.paging_channel_restructuring);
bitvec_set_uint(&bv, in->pch_nch_info.nln_sacch, 2);
if (in->pch_nch_info.call_priority_present) {
bitvec_set_bit(&bv, 1);
bitvec_set_uint(&bv, in->pch_nch_info.call_priority, 3);
} else
bitvec_set_bit(&bv, 0);
bitvec_set_bit(&bv, !!in->pch_nch_info.nln_status_sacch);
} else
bitvec_set_bit(&bv, L);
if (in->vbs_vgcs_options.present) {
bitvec_set_bit(&bv, H);
bitvec_set_bit(&bv, !!in->vbs_vgcs_options.inband_notifications);
bitvec_set_bit(&bv, !!in->vbs_vgcs_options.inband_pagings);
} else
bitvec_set_bit(&bv, L);
if (in->dtm_support.present) {
bitvec_set_bit(&bv, H);
bitvec_set_uint(&bv, in->dtm_support.rac, 8);
bitvec_set_uint(&bv, in->dtm_support.max_lapdm, 3);
} else
bitvec_set_bit(&bv, L);
if (in->band_indicator_1900)
bitvec_set_bit(&bv, H);
else
bitvec_set_bit(&bv, L);
if (in->gprs_ms_txpwr_max_ccch.present) {
bitvec_set_bit(&bv, H);
bitvec_set_uint(&bv, in->gprs_ms_txpwr_max_ccch.max_txpwr, 5);
} else
bitvec_set_bit(&bv, L);
bitvec_spare_padding(&bv, (bv.data_len * 8) - 1);
return bv.data_len;