move RTP socket information from timeslot to lchan

With ip.access, in case of TCH/H, we have one RTP stream for each half-slot
(lchan), not just one per on-air timeslot.  This is quite different from
a classic BTS where the TRAU frames of the two TCH/H channels would be
part of the same 16k sub-slot in a E1 timeslot.
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index fcd623f..bd7b79b 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -185,6 +185,14 @@
 
 	/* use count. how many users use this channel */
 	unsigned int use_count;
+
+	struct {
+		u_int32_t bound_ip;
+		u_int16_t bound_port;
+		u_int8_t rtp_payload2;
+		u_int16_t conn_id;
+		struct rtp_socket *rtp_socket;
+	} abis_ip;
 };
 
 struct gsm_e1_subslot {
@@ -212,13 +220,6 @@
 
 	/* To which E1 subslot are we connected */
 	struct gsm_e1_subslot e1_link;
-	struct {
-		u_int32_t bound_ip;
-		u_int16_t bound_port;
-		u_int8_t rtp_payload2;
-		u_int16_t conn_id;
-		struct rtp_socket *rtp_socket;
-	} abis_ip;
 
 	struct gsm_lchan lchan[TS_MAX_LCHAN];
 };
diff --git a/openbsc/src/abis_rsl.c b/openbsc/src/abis_rsl.c
index 1d41d2b..e7be9ba 100644
--- a/openbsc/src/abis_rsl.c
+++ b/openbsc/src/abis_rsl.c
@@ -1555,7 +1555,7 @@
 {
 	struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
 	struct tlv_parsed tv;
-	struct gsm_bts_trx_ts *ts = msg->lchan->ts;
+	struct gsm_lchan *lchan = msg->lchan;
 	struct in_addr ip;
 	u_int16_t port, attr_f8;
 
@@ -1578,16 +1578,16 @@
 		inet_ntoa(ip), ntohs(port), ntohs(attr_f8));
 
 	if (TLVP_PRESENT(&tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
-		ts->abis_ip.rtp_payload2 = 
+		lchan->abis_ip.rtp_payload2 =
 				*TLVP_VAL(&tv, RSL_IE_IPAC_RTP_PAYLOAD2);
 		DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
-			ts->abis_ip.rtp_payload2);
+			lchan->abis_ip.rtp_payload2);
 	}
 
 	/* update our local information about this TS */
-	ts->abis_ip.bound_ip = ntohl(ip.s_addr);
-	ts->abis_ip.bound_port = ntohs(port);
-	ts->abis_ip.conn_id = ntohs(attr_f8);
+	lchan->abis_ip.bound_ip = ntohl(ip.s_addr);
+	lchan->abis_ip.bound_port = ntohs(port);
+	lchan->abis_ip.conn_id = ntohs(attr_f8);
 
 	dispatch_signal(SS_ABISIP, S_ABISIP_CRCX_ACK, msg->lchan);
 
diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c
index e225bf3..f262dbe 100644
--- a/openbsc/src/gsm_04_08.c
+++ b/openbsc/src/gsm_04_08.c
@@ -1844,7 +1844,6 @@
 				 void *handler_data, void *signal_data)
 {
 	struct gsm_lchan *lchan = signal_data;
-	struct gsm_bts_trx_ts *ts;
 	int rc;
 
 	if (subsys != SS_ABISIP)
@@ -1854,32 +1853,30 @@
 	if (ipacc_rtp_direct)
 		return 0;
 
-	ts = lchan->ts;
-
 	switch (signal) {
 	case S_ABISIP_CRCX_ACK:
 		/* the BTS has successfully bound a TCH to a local ip/port,
 		 * which means we can connect our UDP socket to it */
-		if (ts->abis_ip.rtp_socket) {
-			rtp_socket_free(ts->abis_ip.rtp_socket);
-			ts->abis_ip.rtp_socket = NULL;
+		if (lchan->abis_ip.rtp_socket) {
+			rtp_socket_free(lchan->abis_ip.rtp_socket);
+			lchan->abis_ip.rtp_socket = NULL;
 		}
 
-		ts->abis_ip.rtp_socket = rtp_socket_create();
-		if (!ts->abis_ip.rtp_socket)
+		lchan->abis_ip.rtp_socket = rtp_socket_create();
+		if (!lchan->abis_ip.rtp_socket)
 			goto out_err;
 
-		rc = rtp_socket_connect(ts->abis_ip.rtp_socket,
-				   ts->abis_ip.bound_ip,
-				   ts->abis_ip.bound_port);
+		rc = rtp_socket_connect(lchan->abis_ip.rtp_socket,
+				   lchan->abis_ip.bound_ip,
+				   lchan->abis_ip.bound_port);
 		if (rc < 0)
 			goto out_err;
 		break;
 	case S_ABISIP_DLCX_IND:
 		/* the BTS tells us a RTP stream has been disconnected */
-		if (ts->abis_ip.rtp_socket) {
-			rtp_socket_free(ts->abis_ip.rtp_socket);
-			ts->abis_ip.rtp_socket = NULL;
+		if (lchan->abis_ip.rtp_socket) {
+			rtp_socket_free(lchan->abis_ip.rtp_socket);
+			lchan->abis_ip.rtp_socket = NULL;
 		}
 		break;
 	}
@@ -1893,15 +1890,14 @@
 /* bind rtp proxy to local IP/port and tell BTS to connect to it */
 static int ipacc_connect_proxy_bind(struct gsm_lchan *lchan)
 {
-	struct gsm_bts_trx_ts *ts = lchan->ts;
-	struct rtp_socket *rs = ts->abis_ip.rtp_socket;
+	struct rtp_socket *rs = lchan->abis_ip.rtp_socket;
 	int rc;
 
 	rc = rsl_ipacc_mdcx(lchan, ntohl(rs->rtp.sin_local.sin_addr.s_addr),
 				ntohs(rs->rtp.sin_local.sin_port),
-				ts->abis_ip.conn_id, 
+				lchan->abis_ip.conn_id, 
 			/* FIXME: use RTP payload of bound socket, not BTS*/
-				ts->abis_ip.rtp_payload2);
+				lchan->abis_ip.rtp_payload2);
 
 	return rc;
 }
@@ -1911,7 +1907,6 @@
 {
 	struct gsm_bts *bts = lchan->ts->trx->bts;
 	struct gsm_bts *remote_bts = remote_lchan->ts->trx->bts;
-	struct gsm_bts_trx_ts *ts;
 	int rc;
 
 	DEBUGP(DCC, "Setting up TCH map between (bts=%u,trx=%u,ts=%u) and (bts=%u,trx=%u,ts=%u)\n",
@@ -1933,22 +1928,20 @@
 			rc = ipacc_connect_proxy_bind(remote_lchan);
 
 			/* connect them with each other */
-			rtp_socket_proxy(lchan->ts->abis_ip.rtp_socket,
-					 remote_lchan->ts->abis_ip.rtp_socket);
+			rtp_socket_proxy(lchan->abis_ip.rtp_socket,
+					 remote_lchan->abis_ip.rtp_socket);
 		} else {
 			/* directly connect TCH RTP streams to each other */
-			ts = remote_lchan->ts;
-			rc = rsl_ipacc_mdcx(lchan, ts->abis_ip.bound_ip,
-						ts->abis_ip.bound_port,
-						lchan->ts->abis_ip.conn_id,
-						ts->abis_ip.rtp_payload2);
+			rc = rsl_ipacc_mdcx(lchan, remote_lchan->abis_ip.bound_ip,
+						remote_lchan->abis_ip.bound_port,
+						lchan->abis_ip.conn_id,
+						remote_lchan->abis_ip.rtp_payload2);
 			if (rc < 0)
 				return rc;
-			ts = lchan->ts;
-			rc = rsl_ipacc_mdcx(remote_lchan, ts->abis_ip.bound_ip,
-						ts->abis_ip.bound_port,
-						remote_lchan->ts->abis_ip.conn_id,
-						ts->abis_ip.rtp_payload2);
+			rc = rsl_ipacc_mdcx(remote_lchan, lchan->abis_ip.bound_ip,
+						lchan->abis_ip.bound_port,
+						remote_lchan->abis_ip.conn_id,
+						lchan->abis_ip.rtp_payload2);
 		}
 		break;
 	case GSM_BTS_TYPE_BS11:
diff --git a/openbsc/src/vty_interface.c b/openbsc/src/vty_interface.c
index 3b150b2..39fc414 100644
--- a/openbsc/src/vty_interface.c
+++ b/openbsc/src/vty_interface.c
@@ -365,24 +365,15 @@
 
 static void ts_dump_vty(struct vty *vty, struct gsm_bts_trx_ts *ts)
 {
-	struct in_addr ia;
-
 	vty_out(vty, "Timeslot %u of TRX %u in BTS %u, phys cfg %s%s",
 		ts->nr, ts->trx->nr, ts->trx->bts->nr,
 		gsm_pchan_name(ts->pchan), VTY_NEWLINE);
 	vty_out(vty, "  NM State: ");
 	net_dump_nmstate(vty, &ts->nm_state);
-	if (is_ipaccess_bts(ts->trx->bts)) {
-		ia.s_addr = ts->abis_ip.bound_ip;
-		vty_out(vty, "  Bound IP: %s Port %u RTP_TYPE2=%u CONN_ID=%u%s",
-			inet_ntoa(ia), ts->abis_ip.bound_port,
-			ts->abis_ip.rtp_payload2, ts->abis_ip.conn_id,
-			VTY_NEWLINE);
-	} else {
+	if (!is_ipaccess_bts(ts->trx->bts))
 		vty_out(vty, "  E1 Line %u, Timeslot %u, Subslot %u%s",
 			ts->e1_link.e1_nr, ts->e1_link.e1_ts,
 			ts->e1_link.e1_ts_ss, VTY_NEWLINE);
-	}
 }
 
 DEFUN(show_ts,
@@ -471,6 +462,14 @@
 		subscr_dump_vty(vty, lchan->subscr);
 	} else
 		vty_out(vty, "  No Subscriber%s", VTY_NEWLINE);
+	if (is_ipaccess_bts(lchan->ts->trx->bts)) {
+		struct in_addr ia;
+		ia.s_addr = lchan->abis_ip.bound_ip;
+		vty_out(vty, "  Bound IP: %s Port %u RTP_TYPE2=%u CONN_ID=%u%s",
+			inet_ntoa(ia), lchan->abis_ip.bound_port,
+			lchan->abis_ip.rtp_payload2, lchan->abis_ip.conn_id,
+			VTY_NEWLINE);
+	}
 }
 
 #if 0