aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmocom/bsc/gsm_04_08_rr.h3
-rw-r--r--include/osmocom/bsc/gsm_data.h7
-rw-r--r--src/osmo-bsc/abis_rsl.c41
-rw-r--r--src/osmo-bsc/gsm_04_08_rr.c106
-rw-r--r--src/osmo-bsc/lchan_fsm.c47
-rw-r--r--tests/gsm0408/gsm0408_test.c36
6 files changed, 140 insertions, 100 deletions
diff --git a/include/osmocom/bsc/gsm_04_08_rr.h b/include/osmocom/bsc/gsm_04_08_rr.h
index 91dcbe35a..5ddee7fc3 100644
--- a/include/osmocom/bsc/gsm_04_08_rr.h
+++ b/include/osmocom/bsc/gsm_04_08_rr.h
@@ -21,7 +21,8 @@ int send_siemens_mrpci(struct gsm_lchan *lchan,
uint8_t *classmark2_lv);
int gsm48_send_rr_classmark_enquiry(struct gsm_lchan *lchan);
int gsm48_send_rr_ciph_mode(struct gsm_lchan *lchan, int want_imeisv);
-int gsm48_multirate_config(uint8_t *lv, const struct gsm48_multi_rate_conf *mr_conf,
+int gsm48_multirate_config(struct msgb *msg,
+ const struct gsm48_multi_rate_conf *mr_conf,
const struct amr_mode *modes, unsigned int num_modes);
struct msgb *gsm48_make_ho_cmd(struct gsm_lchan *new_lchan, uint8_t power_command, uint8_t ho_ref);
int gsm48_send_ho_cmd(struct gsm_lchan *old_lchan, struct gsm_lchan *new_lchan,
diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h
index 04d5e52b2..3ed624f26 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -634,6 +634,7 @@ struct gsm_lchan {
struct {
struct lchan_activate_info info;
+ struct gsm48_multi_rate_conf mr_conf_filtered;
bool activ_ack; /*< true as soon as RSL Chan Activ Ack is received */
bool immediate_assignment_sent;
/*! This flag ensures that when an lchan activation has succeeded, and we have already
@@ -645,6 +646,7 @@ struct gsm_lchan {
struct {
struct lchan_modify_info info;
+ struct gsm48_multi_rate_conf mr_conf_filtered;
bool concluded;
} modify;
@@ -675,10 +677,6 @@ struct gsm_lchan {
/* Encryption information */
struct gsm_encr encr;
- /* AMR bits */
- uint8_t mr_ms_lv[7];
- uint8_t mr_bts_lv[7];
-
/* Established data link layer services */
uint8_t sapis[8];
@@ -722,6 +720,7 @@ struct gsm_lchan {
/* After the Channel Activation ACK or RSL Mode Modify ACK is received, this reflects the actually used
* channel_mode_and_rate. */
struct channel_mode_and_rate current_ch_mode_rate;
+ struct gsm48_multi_rate_conf current_mr_conf;
};
/* One Timeslot in a TRX */
diff --git a/src/osmo-bsc/abis_rsl.c b/src/osmo-bsc/abis_rsl.c
index ecc7329f8..4c108d090 100644
--- a/src/osmo-bsc/abis_rsl.c
+++ b/src/osmo-bsc/abis_rsl.c
@@ -463,21 +463,11 @@ static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
return 0;
}
-static void mr_config_for_bts(struct gsm_lchan *lchan, struct msgb *msg,
- const struct channel_mode_and_rate *ch_mode_rate)
+static int put_mr_config_for_bts(struct msgb *msg, const struct gsm48_multi_rate_conf *mr_conf_filtered,
+ const struct amr_multirate_conf *mr_modes)
{
- uint8_t len;
-
- if (ch_mode_rate->chan_mode != GSM48_CMODE_SPEECH_AMR)
- return;
-
- len = lchan->mr_bts_lv[0];
- if (!len) {
- LOG_LCHAN(lchan, LOGL_ERROR, "Missing Multirate Config (len is zero)\n");
- return;
- }
- msgb_tlv_put(msg, RSL_IE_MR_CONFIG, lchan->mr_bts_lv[0],
- lchan->mr_bts_lv + 1);
+ msgb_put_u8(msg, RSL_IE_MR_CONFIG);
+ return gsm48_multirate_config(msg, mr_conf_filtered, mr_modes->bts_mode, mr_modes->num_modes);
}
/* indicate FACCH/SACCH Repetition to be performed by BTS,
@@ -603,7 +593,16 @@ int rsl_tx_chan_activ(struct gsm_lchan *lchan, uint8_t act_type, uint8_t ho_ref)
add_power_control_params(msg, RSL_IE_BS_POWER_PARAM, lchan);
add_power_control_params(msg, RSL_IE_MS_POWER_PARAM, lchan);
- mr_config_for_bts(lchan, msg, &lchan->activate.info.ch_mode_rate);
+ if (lchan->activate.info.ch_mode_rate.chan_mode == GSM48_CMODE_SPEECH_AMR) {
+ rc = put_mr_config_for_bts(msg, &lchan->activate.mr_conf_filtered,
+ (lchan->type == GSM_LCHAN_TCH_F) ? &bts->mr_full : &bts->mr_half);
+ if (rc) {
+ LOG_LCHAN(lchan, LOGL_ERROR, "Cannot encode MultiRate Configuration IE\n");
+ msgb_free(msg);
+ return rc;
+ }
+ }
+
rep_acch_cap_for_bts(lchan, msg);
msg->dst = trx->rsl_link;
@@ -633,6 +632,7 @@ int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
struct rsl_ie_chan_mode cm;
+ struct gsm_bts *bts = lchan->ts->trx->bts;
rc = channel_mode_from_lchan(&cm, lchan, &lchan->modify.info.ch_mode_rate);
if (rc < 0)
@@ -653,7 +653,16 @@ int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info);
}
- mr_config_for_bts(lchan, msg, &lchan->modify.info.ch_mode_rate);
+ if (lchan->modify.info.ch_mode_rate.chan_mode == GSM48_CMODE_SPEECH_AMR) {
+ rc = put_mr_config_for_bts(msg, &lchan->modify.mr_conf_filtered,
+ (lchan->type == GSM_LCHAN_TCH_F) ? &bts->mr_full : &bts->mr_half);
+ if (rc) {
+ LOG_LCHAN(lchan, LOGL_ERROR, "Cannot encode MultiRate Configuration IE\n");
+ msgb_free(msg);
+ return rc;
+ }
+ }
+
rep_acch_cap_for_bts(lchan, msg);
msg->dst = lchan->ts->trx->rsl_link;
diff --git a/src/osmo-bsc/gsm_04_08_rr.c b/src/osmo-bsc/gsm_04_08_rr.c
index bcc61a5ef..d392c0587 100644
--- a/src/osmo-bsc/gsm_04_08_rr.c
+++ b/src/osmo-bsc/gsm_04_08_rr.c
@@ -232,11 +232,11 @@ int get_reason_by_chreq(uint8_t ra, int neci)
return GSM_CHREQ_REASON_OTHER;
}
-static void mr_config_for_ms(struct gsm_lchan *lchan, struct msgb *msg)
+static int put_mr_config_for_ms(struct msgb *msg, const struct gsm48_multi_rate_conf *mr_conf_filtered,
+ const struct amr_multirate_conf *mr_modes)
{
- if (lchan->current_ch_mode_rate.chan_mode == GSM48_CMODE_SPEECH_AMR)
- msgb_tlv_put(msg, GSM48_IE_MUL_RATE_CFG, lchan->mr_ms_lv[0],
- lchan->mr_ms_lv + 1);
+ msgb_put_u8(msg, GSM48_IE_MUL_RATE_CFG);
+ return gsm48_multirate_config(msg, mr_conf_filtered, mr_modes->ms_mode, mr_modes->num_modes);
}
#define CELL_SEL_IND_AFTER_REL_EARCFN_ENTRY (1+16+4+1+1)
@@ -397,12 +397,12 @@ static void gsm48_cell_desc(struct gsm48_cell_desc *cd,
}
/*! \brief Encode a TS 04.08 multirate config LV according to 10.5.2.21aa.
- * \param[out] lv caller-allocated buffer of 7 bytes. First octet is is length.
+ * \param[out] msg msgb to append to.
* \param[in] mr_conf multi-rate configuration to encode (selected modes).
* \param[in] modes array describing the AMR modes.
* \param[in] num_modes length of the modes array.
* \returns 0 on success, -EINVAL on failure. */
-int gsm48_multirate_config(uint8_t *lv,
+int gsm48_multirate_config(struct msgb *msg,
const struct gsm48_multi_rate_conf *mr_conf,
const struct amr_mode *modes, unsigned int num_modes)
{
@@ -413,6 +413,8 @@ int gsm48_multirate_config(uint8_t *lv,
bool mode_valid;
uint8_t *gsm48_ie = (uint8_t *) mr_conf;
const struct amr_mode *modes_selected[4];
+ uint8_t *len;
+ uint8_t *data;
/* Check if modes for consistency (order and duplicates) */
for (i = 0; i < num_modes; i++) {
@@ -482,28 +484,49 @@ int gsm48_multirate_config(uint8_t *lv,
/* When the caller is not interested in any result, skip the actual
* composition of the IE (dry run) */
- if (!lv)
+ if (!msg)
return 0;
/* Compose output buffer */
- lv[0] = (num == 1) ? 2 : (num + 2);
- memcpy(lv + 1, gsm48_ie, 2);
+ /* length */
+ len = msgb_put(msg, 1);
+
+ /* Write octet 3 (Multirate speech version, NSCB, ICMI, spare, Start mode)
+ * and octet 4 (Set of AMR codec modes) */
+ data = msgb_put(msg, 2);
+ memcpy(data, gsm48_ie, 2);
if (num == 1)
- return 0;
+ goto return_msg;
- lv[3] = modes_selected[0]->threshold & 0x3f;
- lv[4] = modes_selected[0]->hysteresis << 4;
+ /* more than 1 mode: write octet 5 and 6: threshold 1 and hysteresis 1 */
+ data = msgb_put(msg, 2);
+ data[0] = modes_selected[0]->threshold & 0x3f;
+ data[1] = modes_selected[0]->hysteresis << 4;
if (num == 2)
- return 0;
- lv[4] |= (modes_selected[1]->threshold & 0x3f) >> 2;
- lv[5] = modes_selected[1]->threshold << 6;
- lv[5] |= (modes_selected[1]->hysteresis & 0x0f) << 2;
+ goto return_msg;
+
+ /* more than 2 modes: complete octet 6 and add octet 7: threshold 2 and hysteresis 2.
+ * Threshold 2 starts in octet 6. */
+ data[1] |= (modes_selected[1]->threshold & 0x3f) >> 2;
+ /* octet 7 */
+ data = msgb_put(msg, 1);
+ data[0] = modes_selected[1]->threshold << 6;
+ data[0] |= (modes_selected[1]->hysteresis & 0x0f) << 2;
if (num == 3)
- return 0;
- lv[5] |= (modes_selected[2]->threshold & 0x3f) >> 4;
- lv[6] = modes_selected[2]->threshold << 4;
- lv[6] |= modes_selected[2]->hysteresis & 0x0f;
-
+ goto return_msg;
+
+ /* four modes: complete octet 7 and add octet 8: threshold 3 and hysteresis 3.
+ * Threshold 3 starts in octet 7. */
+ data[0] |= (modes_selected[2]->threshold & 0x3f) >> 4;
+ /* octet 8 */
+ data = msgb_put(msg, 1);
+ data[0] = modes_selected[2]->threshold << 4;
+ data[0] |= modes_selected[2]->hysteresis & 0x0f;
+
+return_msg:
+ /* Place written len in the IE length field. msg->tail points one byte after the last data octet, len points at
+ * the L octet of the TLV. */
+ *len = (msg->tail - 1) - len;
return 0;
}
@@ -516,6 +539,7 @@ struct msgb *gsm48_make_ho_cmd(struct gsm_lchan *new_lchan, uint8_t power_comman
struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
struct gsm48_ho_cmd *ho =
(struct gsm48_ho_cmd *) msgb_put(msg, sizeof(*ho));
+ struct gsm_bts *bts = new_lchan->ts->trx->bts;
gh->proto_discr = GSM48_PDISC_RR;
gh->msg_type = GSM48_MT_RR_HANDO_CMD;
@@ -548,9 +572,14 @@ struct msgb *gsm48_make_ho_cmd(struct gsm_lchan *new_lchan, uint8_t power_comman
}
/* in case of multi rate we need to attach a config */
- if (new_lchan->current_ch_mode_rate.chan_mode == GSM48_CMODE_SPEECH_AMR)
- msgb_tlv_put(msg, GSM48_IE_MUL_RATE_CFG, new_lchan->mr_ms_lv[0],
- new_lchan->mr_ms_lv + 1);
+ if (new_lchan->current_ch_mode_rate.chan_mode == GSM48_CMODE_SPEECH_AMR) {
+ if (put_mr_config_for_ms(msg, &new_lchan->current_mr_conf,
+ (new_lchan->type == GSM_LCHAN_TCH_F) ? &bts->mr_full : &bts->mr_half)) {
+ LOG_LCHAN(new_lchan, LOGL_ERROR, "Cannot encode MultiRate Configuration IE\n");
+ msgb_free(msg);
+ return NULL;
+ }
+ }
return msg;
}
@@ -572,9 +601,10 @@ int gsm48_send_rr_ass_cmd(struct gsm_lchan *current_lchan, struct gsm_lchan *new
struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
struct gsm48_ass_cmd *ass =
(struct gsm48_ass_cmd *) msgb_put(msg, sizeof(*ass));
+ struct gsm_bts *bts = new_lchan->ts->trx->bts;
DEBUGP(DRR, "-> ASSIGNMENT COMMAND tch_mode=0x%02x\n",
- current_lchan->conn->assignment.selected_ch_mode_rate.chan_mode);
+ new_lchan->current_ch_mode_rate.chan_mode);
msg->lchan = current_lchan;
gh->proto_discr = GSM48_PDISC_RR;
@@ -593,14 +623,13 @@ int gsm48_send_rr_ass_cmd(struct gsm_lchan *current_lchan, struct gsm_lchan *new
/* Cell Channel Description (freq. hopping), TV (see 3GPP TS 44.018, 10.5.2.1b) */
if (new_lchan->ts->hopping.enabled) {
- const struct gsm48_system_information_type_1 *si1 = \
- GSM_BTS_SI(new_lchan->ts->trx->bts, 1);
+ const struct gsm48_system_information_type_1 *si1 = GSM_BTS_SI(bts, 1);
msgb_tv_fixed_put(msg, GSM48_IE_CELL_CH_DESC,
sizeof(si1->cell_channel_description),
si1->cell_channel_description);
}
- msgb_tv_put(msg, GSM48_IE_CHANMODE_1, current_lchan->conn->assignment.selected_ch_mode_rate.chan_mode);
+ msgb_tv_put(msg, GSM48_IE_CHANMODE_1, new_lchan->current_ch_mode_rate.chan_mode);
/* Mobile Allocation (freq. hopping), TLV (see 3GPP TS 44.018, 10.5.2.21) */
if (new_lchan->ts->hopping.enabled) {
@@ -609,7 +638,15 @@ int gsm48_send_rr_ass_cmd(struct gsm_lchan *current_lchan, struct gsm_lchan *new
}
/* in case of multi rate we need to attach a config */
- mr_config_for_ms(new_lchan, msg);
+ if (new_lchan->current_ch_mode_rate.chan_mode == GSM48_CMODE_SPEECH_AMR) {
+ int rc = put_mr_config_for_ms(msg, &new_lchan->current_mr_conf,
+ (new_lchan->type == GSM_LCHAN_TCH_F) ? &bts->mr_full : &bts->mr_half);
+ if (rc) {
+ LOG_LCHAN(current_lchan, LOGL_ERROR, "Cannot encode MultiRate Configuration IE\n");
+ msgb_free(msg);
+ return rc;
+ }
+ }
return gsm48_sendmsg(msg);
}
@@ -643,6 +680,7 @@ int gsm48_lchan_modify(struct gsm_lchan *lchan, uint8_t mode)
struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
struct gsm48_chan_mode_modify *cmm =
(struct gsm48_chan_mode_modify *) msgb_put(msg, sizeof(*cmm));
+ struct gsm_bts *bts = lchan->ts->trx->bts;
DEBUGP(DRR, "-> CHANNEL MODE MODIFY mode=0x%02x\n", mode);
@@ -656,7 +694,15 @@ int gsm48_lchan_modify(struct gsm_lchan *lchan, uint8_t mode)
cmm->mode = mode;
/* in case of multi rate we need to attach a config */
- mr_config_for_ms(lchan, msg);
+ if (lchan->modify.info.ch_mode_rate.chan_mode == GSM48_CMODE_SPEECH_AMR) {
+ int rc = put_mr_config_for_ms(msg, &lchan->modify.mr_conf_filtered,
+ (lchan->type == GSM_LCHAN_TCH_F) ? &bts->mr_full : &bts->mr_half);
+ if (rc) {
+ LOG_LCHAN(lchan, LOGL_ERROR, "Cannot encode MultiRate Configuration IE\n");
+ msgb_free(msg);
+ return rc;
+ }
+ }
return gsm48_sendmsg(msg);
}
diff --git a/src/osmo-bsc/lchan_fsm.c b/src/osmo-bsc/lchan_fsm.c
index 2e810bccd..a3438f758 100644
--- a/src/osmo-bsc/lchan_fsm.c
+++ b/src/osmo-bsc/lchan_fsm.c
@@ -546,51 +546,23 @@ static int mr_config_filter(struct gsm48_multi_rate_conf *mr_conf_result,
return 0;
}
-static int mr_config_render_lv(uint8_t *mr_ms_lv, uint8_t *mr_bts_lv,
- const struct gsm48_multi_rate_conf *mr_conf,
- const struct amr_multirate_conf *amr_mrc,
- const struct gsm_lchan *logging)
-{
- if (gsm48_multirate_config(mr_ms_lv, mr_conf, amr_mrc->ms_mode, amr_mrc->num_modes)) {
- LOG_LCHAN(logging, LOGL_ERROR, "can not encode multirate configuration (MS)\n");
- return -EINVAL;
- }
- if (gsm48_multirate_config(mr_bts_lv, mr_conf, amr_mrc->bts_mode, amr_mrc->num_modes)) {
- LOG_LCHAN(logging, LOGL_ERROR, "can not encode multirate configuration (BTS)\n");
- return -EINVAL;
- }
- return 0;
-}
-
/* Configure the multirate setting on this channel. */
-static int lchan_mr_config(struct gsm_lchan *lchan, uint16_t s15_s0)
+static int lchan_mr_config(struct gsm48_multi_rate_conf *mr_conf, const struct gsm_lchan *lchan, uint16_t s15_s0)
{
struct gsm_bts *bts = lchan->ts->trx->bts;
bool full_rate = lchan->type == GSM_LCHAN_TCH_F;
struct amr_multirate_conf *amr_mrc = full_rate ? &bts->mr_full : &bts->mr_half;
struct gsm48_multi_rate_conf *mr_filter_msc = NULL;
- struct gsm48_multi_rate_conf mr_conf;
- int rc;
/* If activated for VTY, there may not be a conn indicating an MSC AMR configuration. */
if (lchan->conn && lchan->conn->sccp.msc)
mr_filter_msc = &lchan->conn->sccp.msc->amr_conf;
- rc = mr_config_filter(&mr_conf,
- full_rate,
- amr_mrc, mr_filter_msc,
- s15_s0,
- lchan);
- if (rc)
- return rc;
-
- /* FIXME: this actually modifies the lchan->mr_ms_lv and ->mr_bts_lv before an ACK for these AMR bits has been
- * received. Until an ACK is received, all state should live in lchan->activate.* or lchan->modify.* ONLY. */
- rc = mr_config_render_lv(lchan->mr_ms_lv, lchan->mr_bts_lv, &mr_conf, amr_mrc, lchan);
- if (rc)
- return rc;
-
- return 0;
+ return mr_config_filter(mr_conf,
+ full_rate,
+ amr_mrc, mr_filter_msc,
+ s15_s0,
+ lchan);
}
static void lchan_fsm_unused(struct osmo_fsm_inst *fi, uint32_t event, void *data)
@@ -655,7 +627,7 @@ static void lchan_fsm_wait_ts_ready_onenter(struct osmo_fsm_inst *fi, uint32_t p
}
if (info->ch_mode_rate.chan_mode == GSM48_CMODE_SPEECH_AMR) {
- if (lchan_mr_config(lchan, info->ch_mode_rate.s15_s0) < 0) {
+ if (lchan_mr_config(&lchan->activate.mr_conf_filtered, lchan, info->ch_mode_rate.s15_s0) < 0) {
lchan_fail("Can not generate multirate configuration IE\n");
return;
}
@@ -813,6 +785,7 @@ static void lchan_fsm_post_activ_ack(struct osmo_fsm_inst *fi)
struct gsm_lchan *lchan = lchan_fi_lchan(fi);
lchan->current_ch_mode_rate = lchan->activate.info.ch_mode_rate;
+ lchan->current_mr_conf = lchan->activate.mr_conf_filtered;
LOG_LCHAN(lchan, LOGL_INFO, "Rx Activ ACK %s\n",
gsm48_chan_mode_name(lchan->current_ch_mode_rate.chan_mode));
@@ -984,6 +957,7 @@ static void lchan_fsm_wait_rsl_chan_mode_modify_ack(struct osmo_fsm_inst *fi, ui
case LCHAN_EV_RSL_CHAN_MODE_MODIFY_ACK:
/* The Channel Mode Modify was ACKed, now the requested values become the accepted and used values. */
lchan->current_ch_mode_rate = lchan->modify.info.ch_mode_rate;
+ lchan->current_mr_conf = lchan->modify.mr_conf_filtered;
if (lchan->modify.info.requires_voice_stream
&& !lchan->fi_rtp) {
@@ -1136,7 +1110,8 @@ static void lchan_fsm_established(struct osmo_fsm_inst *fi, uint32_t event, void
use_mgwep_ci = lchan_use_mgw_endpoint_ci_bts(lchan);
if (modif_info->ch_mode_rate.chan_mode == GSM48_CMODE_SPEECH_AMR) {
- if (lchan_mr_config(lchan, modif_info->ch_mode_rate.s15_s0) < 0) {
+ if (lchan_mr_config(&lchan->modify.mr_conf_filtered, lchan, modif_info->ch_mode_rate.s15_s0)
+ < 0) {
lchan_fail("Can not generate multirate configuration IE\n");
return;
}
diff --git a/tests/gsm0408/gsm0408_test.c b/tests/gsm0408/gsm0408_test.c
index 8220c4fc5..a1aa5f494 100644
--- a/tests/gsm0408/gsm0408_test.c
+++ b/tests/gsm0408/gsm0408_test.c
@@ -780,10 +780,10 @@ static void test_gsm48_ra_id_by_bts()
static void test_gsm48_multirate_config()
{
- uint8_t lv[7];
struct gsm48_multi_rate_conf *gsm48_ie;
struct amr_multirate_conf mr;
int rc;
+ struct msgb *msg = msgb_alloc(32, "test_gsm48_multirate_config");
memset(&mr, 0, sizeof(mr));
@@ -807,17 +807,19 @@ static void test_gsm48_multirate_config()
mr.ms_mode[1].mode = 4;
mr.ms_mode[2].mode = 5;
mr.ms_mode[3].mode = 7;
- rc = gsm48_multirate_config(lv, gsm48_ie, mr.ms_mode, 4);
+ msgb_trim(msg, 0);
+ rc = gsm48_multirate_config(msg, gsm48_ie, mr.ms_mode, 4);
OSMO_ASSERT(rc == 0);
printf("gsm48_multirate_config(): rc=%i, lv=%s\n", rc,
- osmo_hexdump_nospc(lv, 1 + lv[0]));
+ osmo_hexdump_nospc(msg->data, msg->len));
/* Test #2: 4 active set members, but wrong mode order: */
mr.ms_mode[3].mode = 2;
mr.ms_mode[2].mode = 4;
mr.ms_mode[1].mode = 5;
mr.ms_mode[0].mode = 7;
- rc = gsm48_multirate_config(lv, gsm48_ie, mr.ms_mode, 4);
+ msgb_trim(msg, 0);
+ rc = gsm48_multirate_config(msg, gsm48_ie, mr.ms_mode, 4);
OSMO_ASSERT(rc == -EINVAL);
/* Test #3: Normal configuration with 3 active set members */
@@ -829,16 +831,18 @@ static void test_gsm48_multirate_config()
mr.ms_mode[2].threshold = 0;
mr.ms_mode[2].hysteresis = 0;
- rc = gsm48_multirate_config(lv, gsm48_ie, mr.ms_mode, 4);
+ msgb_trim(msg, 0);
+ rc = gsm48_multirate_config(msg, gsm48_ie, mr.ms_mode, 3);
OSMO_ASSERT(rc == 0);
printf("gsm48_multirate_config(): rc=%i, lv=%s\n", rc,
- osmo_hexdump_nospc(lv, 1 + lv[0]));
+ osmo_hexdump_nospc(msg->data, msg->len));
/* Test #4: 3 active set members, but wrong mode order: */
mr.ms_mode[0].mode = 2;
mr.ms_mode[2].mode = 4;
mr.ms_mode[1].mode = 5;
- rc = gsm48_multirate_config(lv, gsm48_ie, mr.ms_mode, 4);
+ msgb_trim(msg, 0);
+ rc = gsm48_multirate_config(msg, gsm48_ie, mr.ms_mode, 3);
OSMO_ASSERT(rc == -EINVAL);
/* Test #5: Normal configuration with 2 active set members */
@@ -850,15 +854,17 @@ static void test_gsm48_multirate_config()
mr.ms_mode[1].threshold = 0;
mr.ms_mode[1].hysteresis = 0;
- rc = gsm48_multirate_config(lv, gsm48_ie, mr.ms_mode, 4);
+ msgb_trim(msg, 0);
+ rc = gsm48_multirate_config(msg, gsm48_ie, mr.ms_mode, 2);
OSMO_ASSERT(rc == 0);
printf("gsm48_multirate_config(): rc=%i, lv=%s\n", rc,
- osmo_hexdump_nospc(lv, 1 + lv[0]));
+ osmo_hexdump_nospc(msg->data, msg->len));
/* Test #6: 2 active set members, but wrong mode order: */
mr.ms_mode[1].mode = 2;
mr.ms_mode[0].mode = 4;
- rc = gsm48_multirate_config(lv, gsm48_ie, mr.ms_mode, 4);
+ msgb_trim(msg, 0);
+ rc = gsm48_multirate_config(msg, gsm48_ie, mr.ms_mode, 2);
OSMO_ASSERT(rc == -EINVAL);
/* Test #7: Normal configuration with 1 active set member */
@@ -870,15 +876,19 @@ static void test_gsm48_multirate_config()
mr.ms_mode[0].threshold = 0;
mr.ms_mode[0].hysteresis = 0;
- rc = gsm48_multirate_config(lv, gsm48_ie, mr.ms_mode, 4);
+ msgb_trim(msg, 0);
+ rc = gsm48_multirate_config(msg, gsm48_ie, mr.ms_mode, 1);
OSMO_ASSERT(rc == 0);
printf("gsm48_multirate_config(): rc=%i, lv=%s\n", rc,
- osmo_hexdump_nospc(lv, 1 + lv[0]));
+ osmo_hexdump_nospc(msg->data, msg->len));
/* Test #8: 0 active set members: */
mr.ms_mode[0].mode = 0;
- rc = gsm48_multirate_config(lv, gsm48_ie, mr.ms_mode, 4);
+ msgb_trim(msg, 0);
+ rc = gsm48_multirate_config(msg, gsm48_ie, mr.ms_mode, 1);
OSMO_ASSERT(rc == -EINVAL);
+
+ msgb_free(msg);
}
static const struct log_info_cat log_categories[] = {