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.
This commit is contained in:
parent
a43f789a0a
commit
2c82899135
|
@ -185,6 +185,14 @@ struct gsm_lchan {
|
||||||
|
|
||||||
/* use count. how many users use this channel */
|
/* use count. how many users use this channel */
|
||||||
unsigned int use_count;
|
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 {
|
struct gsm_e1_subslot {
|
||||||
|
@ -212,13 +220,6 @@ struct gsm_bts_trx_ts {
|
||||||
|
|
||||||
/* To which E1 subslot are we connected */
|
/* To which E1 subslot are we connected */
|
||||||
struct gsm_e1_subslot e1_link;
|
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];
|
struct gsm_lchan lchan[TS_MAX_LCHAN];
|
||||||
};
|
};
|
||||||
|
|
|
@ -1555,7 +1555,7 @@ static int abis_rsl_rx_ipacc_crcx_ack(struct msgb *msg)
|
||||||
{
|
{
|
||||||
struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
|
struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
|
||||||
struct tlv_parsed tv;
|
struct tlv_parsed tv;
|
||||||
struct gsm_bts_trx_ts *ts = msg->lchan->ts;
|
struct gsm_lchan *lchan = msg->lchan;
|
||||||
struct in_addr ip;
|
struct in_addr ip;
|
||||||
u_int16_t port, attr_f8;
|
u_int16_t port, attr_f8;
|
||||||
|
|
||||||
|
@ -1578,16 +1578,16 @@ static int abis_rsl_rx_ipacc_crcx_ack(struct msgb *msg)
|
||||||
inet_ntoa(ip), ntohs(port), ntohs(attr_f8));
|
inet_ntoa(ip), ntohs(port), ntohs(attr_f8));
|
||||||
|
|
||||||
if (TLVP_PRESENT(&tv, RSL_IE_IPAC_RTP_PAYLOAD2)) {
|
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);
|
*TLVP_VAL(&tv, RSL_IE_IPAC_RTP_PAYLOAD2);
|
||||||
DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
|
DEBUGPC(DRSL, "RTP_PAYLOAD2=0x%02x ",
|
||||||
ts->abis_ip.rtp_payload2);
|
lchan->abis_ip.rtp_payload2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* update our local information about this TS */
|
/* update our local information about this TS */
|
||||||
ts->abis_ip.bound_ip = ntohl(ip.s_addr);
|
lchan->abis_ip.bound_ip = ntohl(ip.s_addr);
|
||||||
ts->abis_ip.bound_port = ntohs(port);
|
lchan->abis_ip.bound_port = ntohs(port);
|
||||||
ts->abis_ip.conn_id = ntohs(attr_f8);
|
lchan->abis_ip.conn_id = ntohs(attr_f8);
|
||||||
|
|
||||||
dispatch_signal(SS_ABISIP, S_ABISIP_CRCX_ACK, msg->lchan);
|
dispatch_signal(SS_ABISIP, S_ABISIP_CRCX_ACK, msg->lchan);
|
||||||
|
|
||||||
|
|
|
@ -1844,7 +1844,6 @@ static int handle_abisip_signal(unsigned int subsys, unsigned int signal,
|
||||||
void *handler_data, void *signal_data)
|
void *handler_data, void *signal_data)
|
||||||
{
|
{
|
||||||
struct gsm_lchan *lchan = signal_data;
|
struct gsm_lchan *lchan = signal_data;
|
||||||
struct gsm_bts_trx_ts *ts;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (subsys != SS_ABISIP)
|
if (subsys != SS_ABISIP)
|
||||||
|
@ -1854,32 +1853,30 @@ static int handle_abisip_signal(unsigned int subsys, unsigned int signal,
|
||||||
if (ipacc_rtp_direct)
|
if (ipacc_rtp_direct)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ts = lchan->ts;
|
|
||||||
|
|
||||||
switch (signal) {
|
switch (signal) {
|
||||||
case S_ABISIP_CRCX_ACK:
|
case S_ABISIP_CRCX_ACK:
|
||||||
/* the BTS has successfully bound a TCH to a local ip/port,
|
/* the BTS has successfully bound a TCH to a local ip/port,
|
||||||
* which means we can connect our UDP socket to it */
|
* which means we can connect our UDP socket to it */
|
||||||
if (ts->abis_ip.rtp_socket) {
|
if (lchan->abis_ip.rtp_socket) {
|
||||||
rtp_socket_free(ts->abis_ip.rtp_socket);
|
rtp_socket_free(lchan->abis_ip.rtp_socket);
|
||||||
ts->abis_ip.rtp_socket = NULL;
|
lchan->abis_ip.rtp_socket = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ts->abis_ip.rtp_socket = rtp_socket_create();
|
lchan->abis_ip.rtp_socket = rtp_socket_create();
|
||||||
if (!ts->abis_ip.rtp_socket)
|
if (!lchan->abis_ip.rtp_socket)
|
||||||
goto out_err;
|
goto out_err;
|
||||||
|
|
||||||
rc = rtp_socket_connect(ts->abis_ip.rtp_socket,
|
rc = rtp_socket_connect(lchan->abis_ip.rtp_socket,
|
||||||
ts->abis_ip.bound_ip,
|
lchan->abis_ip.bound_ip,
|
||||||
ts->abis_ip.bound_port);
|
lchan->abis_ip.bound_port);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
goto out_err;
|
goto out_err;
|
||||||
break;
|
break;
|
||||||
case S_ABISIP_DLCX_IND:
|
case S_ABISIP_DLCX_IND:
|
||||||
/* the BTS tells us a RTP stream has been disconnected */
|
/* the BTS tells us a RTP stream has been disconnected */
|
||||||
if (ts->abis_ip.rtp_socket) {
|
if (lchan->abis_ip.rtp_socket) {
|
||||||
rtp_socket_free(ts->abis_ip.rtp_socket);
|
rtp_socket_free(lchan->abis_ip.rtp_socket);
|
||||||
ts->abis_ip.rtp_socket = NULL;
|
lchan->abis_ip.rtp_socket = NULL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1893,15 +1890,14 @@ out_err:
|
||||||
/* bind rtp proxy to local IP/port and tell BTS to connect to it */
|
/* bind rtp proxy to local IP/port and tell BTS to connect to it */
|
||||||
static int ipacc_connect_proxy_bind(struct gsm_lchan *lchan)
|
static int ipacc_connect_proxy_bind(struct gsm_lchan *lchan)
|
||||||
{
|
{
|
||||||
struct gsm_bts_trx_ts *ts = lchan->ts;
|
struct rtp_socket *rs = lchan->abis_ip.rtp_socket;
|
||||||
struct rtp_socket *rs = ts->abis_ip.rtp_socket;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = rsl_ipacc_mdcx(lchan, ntohl(rs->rtp.sin_local.sin_addr.s_addr),
|
rc = rsl_ipacc_mdcx(lchan, ntohl(rs->rtp.sin_local.sin_addr.s_addr),
|
||||||
ntohs(rs->rtp.sin_local.sin_port),
|
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*/
|
/* FIXME: use RTP payload of bound socket, not BTS*/
|
||||||
ts->abis_ip.rtp_payload2);
|
lchan->abis_ip.rtp_payload2);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -1911,7 +1907,6 @@ static int tch_map(struct gsm_lchan *lchan, struct gsm_lchan *remote_lchan)
|
||||||
{
|
{
|
||||||
struct gsm_bts *bts = lchan->ts->trx->bts;
|
struct gsm_bts *bts = lchan->ts->trx->bts;
|
||||||
struct gsm_bts *remote_bts = remote_lchan->ts->trx->bts;
|
struct gsm_bts *remote_bts = remote_lchan->ts->trx->bts;
|
||||||
struct gsm_bts_trx_ts *ts;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
DEBUGP(DCC, "Setting up TCH map between (bts=%u,trx=%u,ts=%u) and (bts=%u,trx=%u,ts=%u)\n",
|
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 @@ static int tch_map(struct gsm_lchan *lchan, struct gsm_lchan *remote_lchan)
|
||||||
rc = ipacc_connect_proxy_bind(remote_lchan);
|
rc = ipacc_connect_proxy_bind(remote_lchan);
|
||||||
|
|
||||||
/* connect them with each other */
|
/* connect them with each other */
|
||||||
rtp_socket_proxy(lchan->ts->abis_ip.rtp_socket,
|
rtp_socket_proxy(lchan->abis_ip.rtp_socket,
|
||||||
remote_lchan->ts->abis_ip.rtp_socket);
|
remote_lchan->abis_ip.rtp_socket);
|
||||||
} else {
|
} else {
|
||||||
/* directly connect TCH RTP streams to each other */
|
/* directly connect TCH RTP streams to each other */
|
||||||
ts = remote_lchan->ts;
|
rc = rsl_ipacc_mdcx(lchan, remote_lchan->abis_ip.bound_ip,
|
||||||
rc = rsl_ipacc_mdcx(lchan, ts->abis_ip.bound_ip,
|
remote_lchan->abis_ip.bound_port,
|
||||||
ts->abis_ip.bound_port,
|
lchan->abis_ip.conn_id,
|
||||||
lchan->ts->abis_ip.conn_id,
|
remote_lchan->abis_ip.rtp_payload2);
|
||||||
ts->abis_ip.rtp_payload2);
|
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return rc;
|
return rc;
|
||||||
ts = lchan->ts;
|
rc = rsl_ipacc_mdcx(remote_lchan, lchan->abis_ip.bound_ip,
|
||||||
rc = rsl_ipacc_mdcx(remote_lchan, ts->abis_ip.bound_ip,
|
lchan->abis_ip.bound_port,
|
||||||
ts->abis_ip.bound_port,
|
remote_lchan->abis_ip.conn_id,
|
||||||
remote_lchan->ts->abis_ip.conn_id,
|
lchan->abis_ip.rtp_payload2);
|
||||||
ts->abis_ip.rtp_payload2);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GSM_BTS_TYPE_BS11:
|
case GSM_BTS_TYPE_BS11:
|
||||||
|
|
|
@ -365,24 +365,15 @@ DEFUN(show_trx,
|
||||||
|
|
||||||
static void ts_dump_vty(struct vty *vty, struct gsm_bts_trx_ts *ts)
|
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",
|
vty_out(vty, "Timeslot %u of TRX %u in BTS %u, phys cfg %s%s",
|
||||||
ts->nr, ts->trx->nr, ts->trx->bts->nr,
|
ts->nr, ts->trx->nr, ts->trx->bts->nr,
|
||||||
gsm_pchan_name(ts->pchan), VTY_NEWLINE);
|
gsm_pchan_name(ts->pchan), VTY_NEWLINE);
|
||||||
vty_out(vty, " NM State: ");
|
vty_out(vty, " NM State: ");
|
||||||
net_dump_nmstate(vty, &ts->nm_state);
|
net_dump_nmstate(vty, &ts->nm_state);
|
||||||
if (is_ipaccess_bts(ts->trx->bts)) {
|
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 {
|
|
||||||
vty_out(vty, " E1 Line %u, Timeslot %u, Subslot %u%s",
|
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_nr, ts->e1_link.e1_ts,
|
||||||
ts->e1_link.e1_ts_ss, VTY_NEWLINE);
|
ts->e1_link.e1_ts_ss, VTY_NEWLINE);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN(show_ts,
|
DEFUN(show_ts,
|
||||||
|
@ -471,6 +462,14 @@ static void lchan_dump_vty(struct vty *vty, struct gsm_lchan *lchan)
|
||||||
subscr_dump_vty(vty, lchan->subscr);
|
subscr_dump_vty(vty, lchan->subscr);
|
||||||
} else
|
} else
|
||||||
vty_out(vty, " No Subscriber%s", VTY_NEWLINE);
|
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
|
#if 0
|
||||||
|
|
Loading…
Reference in New Issue