mncc: Implement CRCX->MDCX for handover for direct rtp mode

Implement sending MDCX on the newly allocated channel and send
the data to the same destination as the currently connected one.
This way the receiver can implement RTP RFC Appendix A.1 and
deal with the new source.
This commit is contained in:
Holger Hans Peter Freyther 2015-08-04 14:41:21 +02:00
parent c8a6c13e4e
commit c21dcb20e5
2 changed files with 29 additions and 6 deletions

View File

@ -123,6 +123,7 @@ struct gsm_subscriber_connection {
/* MNCC rtp bridge markers */
int mncc_rtp_bridge;
int mncc_rtp_create_pending;
int mncc_rtp_connect_pending;
/* bsc structures */
struct osmo_bsc_sccp_con *sccp_con;

View File

@ -1460,6 +1460,15 @@ static int switch_for_handover(struct gsm_lchan *old_lchan,
{
struct rtp_socket *old_rs, *new_rs, *other_rs;
/* Ask the new socket to send to the already known port. */
if (new_lchan->conn->mncc_rtp_bridge) {
LOGP(DHO, LOGL_DEBUG, "Forwarding RTP\n");
rsl_ipacc_mdcx(new_lchan,
old_lchan->abis_ip.connect_ip,
old_lchan->abis_ip.connect_port, 0);
return 0;
}
if (ipacc_rtp_direct) {
LOGP(DHO, LOGL_ERROR, "unable to handover in direct RTP mode\n");
return 0;
@ -1504,11 +1513,19 @@ static int switch_for_handover(struct gsm_lchan *old_lchan,
return 0;
}
static void maybe_switch_for_handover(struct gsm_lchan *lchan)
{
struct gsm_lchan *old_lchan;
old_lchan = bsc_handover_pending(lchan);
if (old_lchan)
switch_for_handover(old_lchan, lchan);
}
/* some other part of the code sends us a signal */
static int handle_abisip_signal(unsigned int subsys, unsigned int signal,
void *handler_data, void *signal_data)
{
struct gsm_lchan *lchan = signal_data, *old_lchan;
struct gsm_lchan *lchan = signal_data;
int rc;
struct gsm_network *net;
struct gsm_trans *trans;
@ -1561,9 +1578,7 @@ static int handle_abisip_signal(unsigned int subsys, unsigned int signal,
* Do we have a handover pending for this new lchan? In that
* case re-route the audio from the old channel to the new one.
*/
old_lchan = bsc_handover_pending(lchan);
if (old_lchan)
switch_for_handover(old_lchan, lchan);
maybe_switch_for_handover(lchan);
break;
case S_ABISIP_DLCX_IND:
/* the BTS tells us a RTP stream has been disconnected */
@ -3065,6 +3080,7 @@ static int tch_rtp_connect(struct gsm_network *net, void *arg)
* complains about both rtp and rtp payload2 being present in the
* same package!
*/
trans->conn->mncc_rtp_connect_pending = 1;
return rsl_ipacc_mdcx(lchan, rtp->ip, rtp->port, 0);
}
@ -3077,7 +3093,7 @@ static int tch_rtp_signal(struct gsm_lchan *lchan, int signal)
llist_for_each_entry(tmp, &net->trans_list, entry) {
if (!tmp->conn)
continue;
if (tmp->conn->lchan != lchan)
if (tmp->conn->lchan != lchan && tmp->conn->ho_lchan != lchan)
continue;
trans = tmp;
break;
@ -3097,9 +3113,15 @@ static int tch_rtp_signal(struct gsm_lchan *lchan, int signal)
gsm_lchan_name(lchan));
mncc_recv_rtp_sock(net, trans, MNCC_RTP_CREATE);
}
/*
* TODO: this appears to be too early? Why not until after
* the handover detect or the handover complete?
*/
maybe_switch_for_handover(lchan);
break;
case S_ABISIP_MDCX_ACK:
if (lchan->conn->mncc_rtp_bridge) {
if (lchan->conn->mncc_rtp_connect_pending) {
lchan->conn->mncc_rtp_connect_pending = 0;
LOGP(DMNCC, LOGL_NOTICE, "%s sending pending RTP connect ind.\n",
gsm_lchan_name(lchan));
mncc_recv_rtp_sock(net, trans, MNCC_RTP_CONNECT);