diff options
-rw-r--r-- | openbsc/include/openbsc/bsc_api.h | 2 | ||||
-rw-r--r-- | openbsc/include/openbsc/gsm_04_08.h | 3 | ||||
-rw-r--r-- | openbsc/include/openbsc/gsm_data_shared.h | 10 | ||||
-rw-r--r-- | openbsc/src/libbsc/abis_rsl.c | 18 | ||||
-rw-r--r-- | openbsc/src/libbsc/bsc_api.c | 6 | ||||
-rw-r--r-- | openbsc/src/libbsc/bsc_vty.c | 59 | ||||
-rw-r--r-- | openbsc/src/libbsc/gsm_04_08_utils.c | 57 | ||||
-rw-r--r-- | openbsc/src/osmo-bsc/osmo_bsc_api.c | 36 |
8 files changed, 93 insertions, 98 deletions
diff --git a/openbsc/include/openbsc/bsc_api.h b/openbsc/include/openbsc/bsc_api.h index a70d765c1..a3d12f23b 100644 --- a/openbsc/include/openbsc/bsc_api.h +++ b/openbsc/include/openbsc/bsc_api.h @@ -40,7 +40,7 @@ struct bsc_api { * not implemented AMR5.9 will be used. */ void (*mr_config)(struct gsm_subscriber_connection *conn, - uint8_t *mr_ms_lv, uint8_t *mr_bts_lv); + struct gsm_lchan *lchan, int full_rate); }; int bsc_api_init(struct gsm_network *network, struct bsc_api *api); diff --git a/openbsc/include/openbsc/gsm_04_08.h b/openbsc/include/openbsc/gsm_04_08.h index 02b2e3b8a..02d67f762 100644 --- a/openbsc/include/openbsc/gsm_04_08.h +++ b/openbsc/include/openbsc/gsm_04_08.h @@ -14,6 +14,7 @@ struct gsm_network; struct gsm_trans; struct gsm_subscriber_connection; struct amr_multirate_conf; +struct amr_mode; #define GSM48_ALLOC_SIZE 2048 #define GSM48_ALLOC_HEADROOM 256 @@ -90,6 +91,6 @@ void gsm48_lchan2chan_desc(struct gsm48_chan_desc *cd, void release_security_operation(struct gsm_subscriber_connection *conn); void allocate_security_operation(struct gsm_subscriber_connection *conn); -int gsm48_multirate_config(uint8_t *lv, struct amr_multirate_conf *mr, int ms); +int gsm48_multirate_config(uint8_t *lv, struct amr_multirate_conf *mr, struct amr_mode *modes); #endif diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h index 5ff6c20eb..be3333ca1 100644 --- a/openbsc/include/openbsc/gsm_data_shared.h +++ b/openbsc/include/openbsc/gsm_data_shared.h @@ -150,14 +150,14 @@ struct bts_codec_conf { struct amr_mode { uint8_t mode; - uint8_t threshold_ms; - uint8_t hysteresis_ms; - uint8_t threshold_bts; - uint8_t hysteresis_bts; + uint8_t threshold; + uint8_t hysteresis; }; + struct amr_multirate_conf { uint8_t gsm48_ie[2]; - struct amr_mode mode[4]; + struct amr_mode ms_mode[4]; + struct amr_mode bts_mode[4]; uint8_t num_modes; }; /* /BTS ONLY */ diff --git a/openbsc/src/libbsc/abis_rsl.c b/openbsc/src/libbsc/abis_rsl.c index 526b97726..8e9258ca5 100644 --- a/openbsc/src/libbsc/abis_rsl.c +++ b/openbsc/src/libbsc/abis_rsl.c @@ -442,6 +442,13 @@ 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) +{ + if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) + msgb_tlv_put(msg, RSL_IE_MR_CONFIG, lchan->mr_bts_lv[0], + lchan->mr_bts_lv + 1); +} + /* Chapter 8.4.1 */ int rsl_chan_activate_lchan(struct gsm_lchan *lchan, uint8_t act_type, uint8_t ho_ref) @@ -518,10 +525,7 @@ int rsl_chan_activate_lchan(struct gsm_lchan *lchan, uint8_t act_type, msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power); msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power); msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta); - - if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) - msgb_tlv_put(msg, RSL_IE_MR_CONFIG, lchan->mr_bts_lv[0], - lchan->mr_bts_lv + 1); + mr_config_for_bts(lchan, msg); msg->dst = lchan->ts->trx->rsl_link; @@ -557,11 +561,7 @@ int rsl_chan_mode_modify_req(struct gsm_lchan *lchan) msgb_tlv_put(msg, RSL_IE_ENCR_INFO, rc, encr_info); } - if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) -{ - msgb_tlv_put(msg, RSL_IE_MR_CONFIG, lchan->mr_bts_lv[0], - lchan->mr_bts_lv + 1); -} + mr_config_for_bts(lchan, msg); msg->dst = lchan->ts->trx->rsl_link; diff --git a/openbsc/src/libbsc/bsc_api.c b/openbsc/src/libbsc/bsc_api.c index 78e7c8777..504f044fb 100644 --- a/openbsc/src/libbsc/bsc_api.c +++ b/openbsc/src/libbsc/bsc_api.c @@ -163,7 +163,7 @@ static void handle_mr_config(struct gsm_subscriber_connection *conn, struct gsm48_multi_rate_conf *mr_conf; if (api->mr_config) - return api->mr_config(conn, lchan->mr_ms_lv, lchan->mr_bts_lv); + return api->mr_config(conn, lchan, full_rate); if (full_rate) mr = &lchan->ts->trx->bts->mr_full; @@ -178,8 +178,8 @@ static void handle_mr_config(struct gsm_subscriber_connection *conn, mr_conf->icmi = 1; mr_conf->m5_90 = 1; } - gsm48_multirate_config(lchan->mr_ms_lv, mr, 1); - gsm48_multirate_config(lchan->mr_bts_lv, mr, 0); + gsm48_multirate_config(lchan->mr_ms_lv, mr, mr->ms_mode); + gsm48_multirate_config(lchan->mr_bts_lv, mr, mr->bts_mode); } /* diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c index 9b0f020f3..f8ef833d2 100644 --- a/openbsc/src/libbsc/bsc_vty.c +++ b/openbsc/src/libbsc/bsc_vty.c @@ -479,6 +479,21 @@ static void config_write_bts_model(struct vty *vty, struct gsm_bts *bts) config_write_trx_single(vty, trx); } +static void write_amr_modes(struct vty *vty, const char *prefix, + const char *name, struct amr_mode *modes, int num) +{ + int i; + + vty_out(vty, " %s threshold %s", prefix, name); + for (i = 0; i < num - 1; i++) + vty_out(vty, " %d", modes[i].threshold); + vty_out(vty, "%s", VTY_NEWLINE); + vty_out(vty, " %s hysteresis %s", prefix, name); + for (i = 0; i < num - 1; i++) + vty_out(vty, " %d", modes[i].hysteresis); + vty_out(vty, "%s", VTY_NEWLINE); +} + static void config_write_bts_amr(struct vty *vty, struct gsm_bts *bts, struct amr_multirate_conf *mr, int full) { @@ -503,26 +518,8 @@ static void config_write_bts_amr(struct vty *vty, struct gsm_bts *bts, if (num > 4) num = 4; if (num > 1) { - vty_out(vty, " %s threshold ms", prefix); - for (i = 0; i < num - 1; i++) { - vty_out(vty, " %d", mr->mode[i].threshold_ms); - } - vty_out(vty, "%s", VTY_NEWLINE); - vty_out(vty, " %s hysteresis ms", prefix); - for (i = 0; i < num - 1; i++) { - vty_out(vty, " %d", mr->mode[i].hysteresis_ms); - } - vty_out(vty, "%s", VTY_NEWLINE); - vty_out(vty, " %s threshold bts", prefix); - for (i = 0; i < num - 1; i++) { - vty_out(vty, " %d", mr->mode[i].threshold_bts); - } - vty_out(vty, "%s", VTY_NEWLINE); - vty_out(vty, " %s hysteresis bts", prefix); - for (i = 0; i < num - 1; i++) { - vty_out(vty, " %d", mr->mode[i].hysteresis_bts); - } - vty_out(vty, "%s", VTY_NEWLINE); + write_amr_modes(vty, prefix, "ms", mr->ms_mode, num); + write_amr_modes(vty, prefix, "bts", mr->bts_mode, num); } vty_out(vty, " %s start-mode ", prefix); if (mr_conf->icmi) { @@ -2953,30 +2950,24 @@ static void get_amr_th_from_arg(struct vty *vty, int argc, const char *argv[], i { struct gsm_bts *bts = vty->index; struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half; + struct amr_mode *modes; int i; - if (argv[0][0]=='m') { - for (i = 0; i < argc - 1; i++) - mr->mode[i].threshold_ms = atoi(argv[i + 1]); - } else { - for (i = 0; i < argc - 1; i++) - mr->mode[i].threshold_bts = atoi(argv[i + 1]); - } + modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode; + for (i = 0; i < argc - 1; i++) + modes[i].threshold = atoi(argv[i + 1]); } static void get_amr_hy_from_arg(struct vty *vty, int argc, const char *argv[], int full) { struct gsm_bts *bts = vty->index; struct amr_multirate_conf *mr = (full) ? &bts->mr_full: &bts->mr_half; + struct amr_mode *modes; int i; - if (argv[0][0]=='m') { - for (i = 0; i < argc - 1; i++) - mr->mode[i].hysteresis_ms = atoi(argv[i + 1]); - } else { - for (i = 0; i < argc - 1; i++) - mr->mode[i].hysteresis_bts = atoi(argv[i + 1]); - } + modes = argv[0][0]=='m' ? mr->ms_mode : mr->bts_mode; + for (i = 0; i < argc - 1; i++) + modes[i].hysteresis = atoi(argv[i + 1]); } static void get_amr_start_from_arg(struct vty *vty, const char *argv[], int full) diff --git a/openbsc/src/libbsc/gsm_04_08_utils.c b/openbsc/src/libbsc/gsm_04_08_utils.c index ef82555fe..4901912f5 100644 --- a/openbsc/src/libbsc/gsm_04_08_utils.c +++ b/openbsc/src/libbsc/gsm_04_08_utils.c @@ -214,6 +214,13 @@ 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) +{ + if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) + msgb_tlv_put(msg, GSM48_IE_MUL_RATE_CFG, lchan->mr_ms_lv[0], + lchan->mr_ms_lv + 1); +} + /* 7.1.7 and 9.1.7: RR CHANnel RELease */ int gsm48_send_rr_release(struct gsm_lchan *lchan) { @@ -357,7 +364,7 @@ void gsm48_lchan2chan_desc(struct gsm48_chan_desc *cd, } } -int gsm48_multirate_config(uint8_t *lv, struct amr_multirate_conf *mr, int ms) +int gsm48_multirate_config(uint8_t *lv, struct amr_multirate_conf *mr, struct amr_mode *modes) { int num = 0, i; @@ -380,33 +387,19 @@ int gsm48_multirate_config(uint8_t *lv, struct amr_multirate_conf *mr, int ms) memcpy(lv + 1, mr->gsm48_ie, 2); if (num == 1) return 0; - if (ms) { - lv[3] = mr->mode[0].threshold_ms & 0x3f; - lv[4] = mr->mode[0].hysteresis_ms << 4; - if (num == 2) - return 0; - lv[4] |= (mr->mode[1].threshold_ms & 0x3f) >> 2; - lv[5] = mr->mode[1].threshold_ms << 6; - lv[5] |= (mr->mode[1].hysteresis_ms & 0x0f) << 2; - if (num == 3) - return 0; - lv[5] |= (mr->mode[2].threshold_ms & 0x3f) >> 4; - lv[6] = mr->mode[2].threshold_ms << 4; - lv[6] |= mr->mode[2].hysteresis_ms & 0x0f; - } else { - lv[3] = mr->mode[0].threshold_bts & 0x3f; - lv[4] = mr->mode[0].hysteresis_bts << 4; - if (num == 2) - return 0; - lv[4] |= (mr->mode[1].threshold_bts & 0x3f) >> 2; - lv[5] = mr->mode[1].threshold_bts << 6; - lv[5] |= (mr->mode[1].hysteresis_bts & 0x0f) << 2; - if (num == 3) - return 0; - lv[5] |= (mr->mode[2].threshold_bts & 0x3f) >> 4; - lv[6] = mr->mode[2].threshold_bts << 4; - lv[6] |= mr->mode[2].hysteresis_bts & 0x0f; - } + + lv[3] = modes[0].threshold & 0x3f; + lv[4] = modes[0].hysteresis << 4; + if (num == 2) + return 0; + lv[4] |= (modes[1].threshold & 0x3f) >> 2; + lv[5] = modes[1].threshold << 6; + lv[5] |= (modes[1].hysteresis & 0x0f) << 2; + if (num == 3) + return 0; + lv[5] |= (modes[2].threshold & 0x3f) >> 4; + lv[6] = modes[2].threshold << 4; + lv[6] |= modes[2].hysteresis & 0x0f; return 0; } @@ -489,9 +482,7 @@ int gsm48_send_rr_ass_cmd(struct gsm_lchan *dest_lchan, struct gsm_lchan *lchan, } /* in case of multi rate we need to attach a config */ - if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) - msgb_tlv_put(msg, GSM48_IE_MUL_RATE_CFG, lchan->mr_ms_lv[0], - lchan->mr_ms_lv + 1); + mr_config_for_ms(lchan, msg); return gsm48_sendmsg(msg); } @@ -517,9 +508,7 @@ int gsm48_tx_chan_mode_modify(struct gsm_lchan *lchan, uint8_t mode) cmm->mode = mode; /* in case of multi rate we need to attach a config */ - if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) - msgb_tlv_put(msg, GSM48_IE_MUL_RATE_CFG, lchan->mr_ms_lv[0], - lchan->mr_ms_lv + 1); + mr_config_for_ms(lchan, msg); return gsm48_sendmsg(msg); } diff --git a/openbsc/src/osmo-bsc/osmo_bsc_api.c b/openbsc/src/osmo-bsc/osmo_bsc_api.c index 00a10b3a5..fbeed77b7 100644 --- a/openbsc/src/osmo-bsc/osmo_bsc_api.c +++ b/openbsc/src/osmo-bsc/osmo_bsc_api.c @@ -491,9 +491,10 @@ static void bsc_cm_update(struct gsm_subscriber_connection *conn, } static void bsc_mr_config(struct gsm_subscriber_connection *conn, - struct gsm48_multi_rate_conf *conf) + struct gsm_lchan *lchan, int full_rate) { struct osmo_msc_data *msc; + struct gsm48_multi_rate_conf *ms_conf, *bts_conf; if (!conn->sccp_con) { LOGP(DMSC, LOGL_ERROR, @@ -504,18 +505,31 @@ static void bsc_mr_config(struct gsm_subscriber_connection *conn, msc = conn->sccp_con->msc; - conf->ver = 1; - conf->icmi = 1; + /* initialize the data structure */ + lchan->mr_ms_lv[0] = sizeof(*ms_conf); + lchan->mr_bts_lv[0] = sizeof(*bts_conf); + ms_conf = (struct gsm48_multi_rate_conf *) &lchan->mr_ms_lv[1]; + bts_conf = (struct gsm48_multi_rate_conf *) &lchan->mr_bts_lv[1]; + memset(ms_conf, 0, sizeof(*ms_conf)); + memset(bts_conf, 0, sizeof(*bts_conf)); + + bts_conf->ver = ms_conf->ver = 1; + bts_conf->icmi = ms_conf->icmi = 1; /* maybe gcc see's it is copy of _one_ byte */ - conf->m4_75 = msc->amr_conf.m4_75; - conf->m5_15 = msc->amr_conf.m5_15; - conf->m5_90 = msc->amr_conf.m5_90; - conf->m6_70 = msc->amr_conf.m6_70; - conf->m7_40 = msc->amr_conf.m7_40; - conf->m7_95 = msc->amr_conf.m7_95; - conf->m10_2 = msc->amr_conf.m10_2; - conf->m12_2 = msc->amr_conf.m12_2; + bts_conf->m4_75 = ms_conf->m4_75 = msc->amr_conf.m4_75; + bts_conf->m5_15 = ms_conf->m5_15 = msc->amr_conf.m5_15; + bts_conf->m5_90 = ms_conf->m5_90 = msc->amr_conf.m5_90; + bts_conf->m6_70 = ms_conf->m6_70 = msc->amr_conf.m6_70; + bts_conf->m7_40 = ms_conf->m7_40 = msc->amr_conf.m7_40; + bts_conf->m7_95 = ms_conf->m7_95 = msc->amr_conf.m7_95; + if (full_rate) { + bts_conf->m10_2 = ms_conf->m10_2 = msc->amr_conf.m10_2; + bts_conf->m12_2 = ms_conf->m12_2 = msc->amr_conf.m12_2; + } + + /* now copy this into the bts structure */ + memcpy(lchan->mr_bts_lv, lchan->mr_ms_lv, sizeof(lchan->mr_ms_lv)); } static struct bsc_api bsc_handler = { |