[lchan] RSL and RR need the multirate config, place it in the lchan

Both GSM 04.08 RR and GSM 08.58 RSL need the multirate config
in the channel modify. Place the config in the lchan, change
the gsm48 methods to not take the argument, change the RSL
implementation to make use of it with the right IE.

The other code should use the t(l)v_put routines as well but
were left untouched for now.
diff --git a/openbsc/include/openbsc/gsm_04_08.h b/openbsc/include/openbsc/gsm_04_08.h
index 5bd860b..40a7654 100644
--- a/openbsc/include/openbsc/gsm_04_08.h
+++ b/openbsc/include/openbsc/gsm_04_08.h
@@ -759,7 +759,7 @@
 int gsm48_send_rr_ciph_mode(struct gsm_lchan *lchan, int want_imeisv);
 int gsm48_send_rr_app_info(struct gsm_lchan *lchan, u_int8_t apdu_id,
 			   u_int8_t apdu_len, const u_int8_t *apdu);
-int gsm48_send_rr_ass_cmd(struct gsm_lchan *lchan, u_int8_t power_class, struct gsm48_multi_rate_conf *conf);
+int gsm48_send_rr_ass_cmd(struct gsm_lchan *lchan, u_int8_t power_class);
 
 int bsc_upqueue(struct gsm_network *net);
 
@@ -777,7 +777,7 @@
 int gsm48_paging_extract_mi(struct msgb *msg, char *mi_string, u_int8_t *mi_type);
 int gsm48_handle_paging_resp(struct msgb *msg, struct gsm_subscriber *subscr);
 
-int gsm48_lchan_modify(struct gsm_lchan *lchan, u_int8_t lchan_mode, struct gsm48_multi_rate_conf *conf);
+int gsm48_lchan_modify(struct gsm_lchan *lchan, u_int8_t lchan_mode);
 int gsm48_rx_rr_modif_ack(struct msgb *msg);
 
 #endif
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index c1b7b05..0ac8674 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -163,6 +163,9 @@
 		u_int8_t key_len;
 		u_int8_t key[MAX_A5_KEY_LEN];
 	} encr;
+
+	/* AMR bits */
+	struct gsm48_multi_rate_conf mr_conf;
 	
 	/* To whom we are allocated at the moment */
 	struct gsm_subscriber *subscr;
diff --git a/openbsc/src/abis_rsl.c b/openbsc/src/abis_rsl.c
index f6e0b87..0dee79b 100644
--- a/openbsc/src/abis_rsl.c
+++ b/openbsc/src/abis_rsl.c
@@ -648,6 +648,11 @@
 			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, sizeof(lchan->mr_conf),
+			     (u_int8_t *) &lchan->mr_conf);
+	}
+
 	msg->trx = lchan->ts->trx;
 
 	return abis_rsl_sendmsg(msg);
diff --git a/openbsc/src/chan_alloc.c b/openbsc/src/chan_alloc.c
index bd3ec85..7ba679c 100644
--- a/openbsc/src/chan_alloc.c
+++ b/openbsc/src/chan_alloc.c
@@ -215,6 +215,9 @@
 		/* clear sapis */
 		memset(lchan->sapis, 0, ARRAY_SIZE(lchan->sapis));
 
+		/* clear multi rate config */
+		memset(&lchan->mr_conf, 0, sizeof(lchan->mr_conf));
+
 		/* Configure the time and start it so it will be closed */
 		lchan->release_timer.cb = auto_release_channel;
 		lchan->release_timer.data = lchan;
diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c
index 4d352bc..1f82354 100644
--- a/openbsc/src/gsm_04_08.c
+++ b/openbsc/src/gsm_04_08.c
@@ -3139,7 +3139,7 @@
 {
 	struct gsm_mncc *mode = arg;
 
-	return gsm48_lchan_modify(trans->lchan, mode->lchan_mode, NULL);
+	return gsm48_lchan_modify(trans->lchan, mode->lchan_mode);
 }
 
 static struct downstate {
diff --git a/openbsc/src/gsm_04_08_utils.c b/openbsc/src/gsm_04_08_utils.c
index 1a0af37..b2fbdc2 100644
--- a/openbsc/src/gsm_04_08_utils.c
+++ b/openbsc/src/gsm_04_08_utils.c
@@ -504,8 +504,7 @@
 }
 
 /* Chapter 9.1.2: Assignment Command */
-int gsm48_send_rr_ass_cmd(struct gsm_lchan *lchan, u_int8_t power_command,
-			  struct gsm48_multi_rate_conf *conf)
+int gsm48_send_rr_ass_cmd(struct gsm_lchan *lchan, u_int8_t power_command)
 {
 	struct msgb *msg = gsm48_msgb_alloc();
 	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
@@ -536,13 +535,13 @@
 
 	/* in case of multi rate we need to attach a config */
 	if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) {
-		if (!conf) {
+		if (lchan->mr_conf.ver == 0) {
 			DEBUGP(DRR, "BUG: Using multirate codec without multirate config.\n");
 		} else {
 			u_int8_t *data = msgb_put(msg, 4);
 			data[0] = GSM48_IE_MUL_RATE_CFG;
 			data[1] = 0x2;
-			memcpy(&data[2], conf, 2);
+			memcpy(&data[2], &lchan->mr_conf, 2);
 		}
 	}
 
@@ -550,8 +549,7 @@
 }
 
 /* 9.1.5 Channel mode modify: Modify the mode on the MS side */
-int gsm48_tx_chan_mode_modify(struct gsm_lchan *lchan, u_int8_t mode,
-			      struct gsm48_multi_rate_conf *conf)
+int gsm48_tx_chan_mode_modify(struct gsm_lchan *lchan, u_int8_t mode)
 {
 	struct msgb *msg = gsm48_msgb_alloc();
 	struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
@@ -576,26 +574,25 @@
 	cmm->mode = mode;
 
 	/* in case of multi rate we need to attach a config */
-	if (mode == GSM48_CMODE_SPEECH_AMR) {
-		if (!conf) {
+	if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) {
+		if (lchan->mr_conf.ver == 0) {
 			DEBUGP(DRR, "BUG: Using multirate codec without multirate config.\n");
 		} else {
 			u_int8_t *data = msgb_put(msg, 4);
 			data[0] = GSM48_IE_MUL_RATE_CFG;
 			data[1] = 0x2;
-			memcpy(&data[2], conf, 2);
+			memcpy(&data[2], &lchan->mr_conf, 2);
 		}
 	}
 
 	return gsm48_sendmsg(msg, NULL);
 }
 
-int gsm48_lchan_modify(struct gsm_lchan *lchan, u_int8_t lchan_mode,
-		       struct gsm48_multi_rate_conf *conf)
+int gsm48_lchan_modify(struct gsm_lchan *lchan, u_int8_t lchan_mode)
 {
 	int rc;
 
-	rc = gsm48_tx_chan_mode_modify(lchan, lchan_mode, conf);
+	rc = gsm48_tx_chan_mode_modify(lchan, lchan_mode);
 	if (rc < 0)
 		return rc;