diff options
-rw-r--r-- | include/osmocom/bsc/gsm_04_08_rr.h | 3 | ||||
-rw-r--r-- | include/osmocom/bsc/gsm_data.h | 7 | ||||
-rw-r--r-- | src/osmo-bsc/abis_rsl.c | 41 | ||||
-rw-r--r-- | src/osmo-bsc/gsm_04_08_rr.c | 106 | ||||
-rw-r--r-- | src/osmo-bsc/lchan_fsm.c | 47 | ||||
-rw-r--r-- | tests/gsm0408/gsm0408_test.c | 36 |
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[] = { |