<p>pespin has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-mgw/+/24860">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">mgcp_network.c: Reorder some functions in file<br><br>This is a preparation for next commit, where one of the function will<br>require an static function available before it in the file.<br><br>Moving the functions also make sense, in order to have the 3 mgcp send<br>functions together for more easy understanding.<br><br>Change-Id: Iff8dab942182a0d909519acddb86be75d9cda7ae<br>---<br>M src/libosmo-mgcp/mgcp_network.c<br>1 file changed, 243 insertions(+), 244 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-mgw refs/changes/60/24860/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/libosmo-mgcp/mgcp_network.c b/src/libosmo-mgcp/mgcp_network.c</span><br><span>index 1b7c3bd..a56bb31 100644</span><br><span>--- a/src/libosmo-mgcp/mgcp_network.c</span><br><span>+++ b/src/libosmo-mgcp/mgcp_network.c</span><br><span>@@ -170,74 +170,6 @@</span><br><span> return ret;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/*! send udp packet.</span><br><span style="color: hsl(0, 100%, 40%);">- * \param[in] fd associated file descriptor.</span><br><span style="color: hsl(0, 100%, 40%);">- * \param[in] addr destination ip-address.</span><br><span style="color: hsl(0, 100%, 40%);">- * \param[in] port destination UDP port (network byte order).</span><br><span style="color: hsl(0, 100%, 40%);">- * \param[in] buf buffer that holds the data to be send.</span><br><span style="color: hsl(0, 100%, 40%);">- * \param[in] len length of the data to be sent.</span><br><span style="color: hsl(0, 100%, 40%);">- * \returns bytes sent, -1 on error. */</span><br><span style="color: hsl(0, 100%, 40%);">-int mgcp_udp_send(int fd, struct osmo_sockaddr *addr, int port, const char *buf, int len)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- char ipbuf[INET6_ADDRSTRLEN];</span><br><span style="color: hsl(0, 100%, 40%);">- size_t addr_len;</span><br><span style="color: hsl(0, 100%, 40%);">- bool is_ipv6 = addr->u.sa.sa_family == AF_INET6;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- LOGP(DRTP, LOGL_DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">- "sending %i bytes length packet to %s:%u ...\n", len,</span><br><span style="color: hsl(0, 100%, 40%);">- osmo_sockaddr_ntop(&addr->u.sa, ipbuf),</span><br><span style="color: hsl(0, 100%, 40%);">- ntohs(port));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (is_ipv6) {</span><br><span style="color: hsl(0, 100%, 40%);">- addr->u.sin6.sin6_port = port;</span><br><span style="color: hsl(0, 100%, 40%);">- addr_len = sizeof(addr->u.sin6);</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- addr->u.sin.sin_port = port;</span><br><span style="color: hsl(0, 100%, 40%);">- addr_len = sizeof(addr->u.sin);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return sendto(fd, buf, len, 0, &addr->u.sa, addr_len);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*! send RTP dummy packet (to keep NAT connection open).</span><br><span style="color: hsl(0, 100%, 40%);">- * \param[in] endp mcgp endpoint that holds the RTP connection.</span><br><span style="color: hsl(0, 100%, 40%);">- * \param[in] conn associated RTP connection.</span><br><span style="color: hsl(0, 100%, 40%);">- * \returns bytes sent, -1 on error. */</span><br><span style="color: hsl(0, 100%, 40%);">-int mgcp_send_dummy(struct mgcp_endpoint *endp, struct mgcp_conn_rtp *conn)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- int rc;</span><br><span style="color: hsl(0, 100%, 40%);">- int was_rtcp = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- OSMO_ASSERT(endp);</span><br><span style="color: hsl(0, 100%, 40%);">- OSMO_ASSERT(conn);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPCONN(conn->conn, DRTP, LOGL_DEBUG,"sending dummy packet... %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">- mgcp_conn_dump(conn->conn));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- rc = mgcp_udp_send(conn->end.rtp.fd, &conn->end.addr,</span><br><span style="color: hsl(0, 100%, 40%);">- conn->end.rtp_port, rtp_dummy_payload, sizeof(rtp_dummy_payload));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (rc == -1)</span><br><span style="color: hsl(0, 100%, 40%);">- goto failed;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (endp->trunk->omit_rtcp)</span><br><span style="color: hsl(0, 100%, 40%);">- return rc;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- was_rtcp = 1;</span><br><span style="color: hsl(0, 100%, 40%);">- rc = mgcp_udp_send(conn->end.rtcp.fd, &conn->end.addr,</span><br><span style="color: hsl(0, 100%, 40%);">- conn->end.rtcp_port, rtp_dummy_payload, sizeof(rtp_dummy_payload));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (rc >= 0)</span><br><span style="color: hsl(0, 100%, 40%);">- return rc;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-failed:</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPCONN(conn->conn, DRTP, LOGL_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">- "Failed to send dummy %s packet.\n",</span><br><span style="color: hsl(0, 100%, 40%);">- was_rtcp ? "RTCP" : "RTP");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /* Compute timestamp alignment error */</span><br><span> static int32_t ts_alignment_error(struct mgcp_rtp_stream_state *sstate,</span><br><span> int ptime, uint32_t timestamp)</span><br><span>@@ -857,182 +789,6 @@</span><br><span> hdr->ssrc = state->alt_rtp_tx_ssrc;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*! Send RTP/RTCP data to a specified destination connection.</span><br><span style="color: hsl(0, 100%, 40%);">- * \param[in] endp associated endpoint (for configuration, logging).</span><br><span style="color: hsl(0, 100%, 40%);">- * \param[in] is_rtp flag to specify if the packet is of type RTP or RTCP.</span><br><span style="color: hsl(0, 100%, 40%);">- * \param[in] spoofed source address (set to NULL to disable).</span><br><span style="color: hsl(0, 100%, 40%);">- * \param[in] buf buffer that contains the RTP/RTCP data.</span><br><span style="color: hsl(0, 100%, 40%);">- * \param[in] len length of the buffer that contains the RTP/RTCP data.</span><br><span style="color: hsl(0, 100%, 40%);">- * \param[in] conn_src associated source connection.</span><br><span style="color: hsl(0, 100%, 40%);">- * \param[in] conn_dst associated destination connection.</span><br><span style="color: hsl(0, 100%, 40%);">- * \returns 0 on success, -1 on ERROR. */</span><br><span style="color: hsl(0, 100%, 40%);">-int mgcp_send(struct mgcp_endpoint *endp, int is_rtp, struct osmo_sockaddr *addr,</span><br><span style="color: hsl(0, 100%, 40%);">- struct msgb *msg, struct mgcp_conn_rtp *conn_src,</span><br><span style="color: hsl(0, 100%, 40%);">- struct mgcp_conn_rtp *conn_dst)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- /*! When no destination connection is available (e.g. when only one</span><br><span style="color: hsl(0, 100%, 40%);">- * connection in loopback mode exists), then the source connection</span><br><span style="color: hsl(0, 100%, 40%);">- * shall be specified as destination connection */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- struct mgcp_trunk *trunk = endp->trunk;</span><br><span style="color: hsl(0, 100%, 40%);">- struct mgcp_rtp_end *rtp_end;</span><br><span style="color: hsl(0, 100%, 40%);">- struct mgcp_rtp_state *rtp_state;</span><br><span style="color: hsl(0, 100%, 40%);">- char ipbuf[INET6_ADDRSTRLEN];</span><br><span style="color: hsl(0, 100%, 40%);">- char *dest_name;</span><br><span style="color: hsl(0, 100%, 40%);">- int rc;</span><br><span style="color: hsl(0, 100%, 40%);">- int len;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- OSMO_ASSERT(conn_src);</span><br><span style="color: hsl(0, 100%, 40%);">- OSMO_ASSERT(conn_dst);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (is_rtp) {</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPENDP(endp, DRTP, LOGL_DEBUG, "delivering RTP packet...\n");</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPENDP(endp, DRTP, LOGL_DEBUG, "delivering RTCP packet...\n");</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* FIXME: It is legal that the payload type on the egress connection is</span><br><span style="color: hsl(0, 100%, 40%);">- * different from the payload type that has been negotiated on the</span><br><span style="color: hsl(0, 100%, 40%);">- * ingress connection. Essentially the codecs are the same so we can</span><br><span style="color: hsl(0, 100%, 40%);">- * match them and patch the payload type. However, if we can not find</span><br><span style="color: hsl(0, 100%, 40%);">- * the codec pendant (everything ist equal except the PT), we are of</span><br><span style="color: hsl(0, 100%, 40%);">- * course unable to patch the payload type. A situation like this</span><br><span style="color: hsl(0, 100%, 40%);">- * should not occur if transcoding is consequently avoided. Until</span><br><span style="color: hsl(0, 100%, 40%);">- * we have transcoding support in osmo-mgw we can not resolve this. */</span><br><span style="color: hsl(0, 100%, 40%);">- if (is_rtp) {</span><br><span style="color: hsl(0, 100%, 40%);">- rc = mgcp_patch_pt(conn_src, conn_dst, msg);</span><br><span style="color: hsl(0, 100%, 40%);">- if (rc < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPENDP(endp, DRTP, LOGL_DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">- "can not patch PT because no suitable egress codec was found.\n");</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Note: In case of loopback configuration, both, the source and the</span><br><span style="color: hsl(0, 100%, 40%);">- * destination will point to the same connection. */</span><br><span style="color: hsl(0, 100%, 40%);">- rtp_end = &conn_dst->end;</span><br><span style="color: hsl(0, 100%, 40%);">- rtp_state = &conn_src->state;</span><br><span style="color: hsl(0, 100%, 40%);">- dest_name = conn_dst->conn->name;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Ensure we have an alternative SSRC in case we need it, see also</span><br><span style="color: hsl(0, 100%, 40%);">- * gen_rtp_header() */</span><br><span style="color: hsl(0, 100%, 40%);">- if (rtp_state->alt_rtp_tx_ssrc == 0)</span><br><span style="color: hsl(0, 100%, 40%);">- rtp_state->alt_rtp_tx_ssrc = rand();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!rtp_end->output_enabled) {</span><br><span style="color: hsl(0, 100%, 40%);">- rtpconn_rate_ctr_inc(conn_dst, endp, RTP_DROPPED_PACKETS_CTR);</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPENDP(endp, DRTP, LOGL_DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">- "output disabled, drop to %s %s "</span><br><span style="color: hsl(0, 100%, 40%);">- "rtp_port:%u rtcp_port:%u\n",</span><br><span style="color: hsl(0, 100%, 40%);">- dest_name,</span><br><span style="color: hsl(0, 100%, 40%);">- osmo_sockaddr_ntop(&rtp_end->addr.u.sa, ipbuf),</span><br><span style="color: hsl(0, 100%, 40%);">- ntohs(rtp_end->rtp_port), ntohs(rtp_end->rtcp_port)</span><br><span style="color: hsl(0, 100%, 40%);">- );</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (is_rtp) {</span><br><span style="color: hsl(0, 100%, 40%);">- int cont;</span><br><span style="color: hsl(0, 100%, 40%);">- int nbytes = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- int buflen = msgb_length(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Make sure we have a valid RTP header, in cases where no RTP</span><br><span style="color: hsl(0, 100%, 40%);">- * header is present, we will generate one. */</span><br><span style="color: hsl(0, 100%, 40%);">- gen_rtp_header(msg, rtp_end, rtp_state);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- do {</span><br><span style="color: hsl(0, 100%, 40%);">- /* Run transcoder */</span><br><span style="color: hsl(0, 100%, 40%);">- cont = endp->cfg->rtp_processing_cb(endp, rtp_end,</span><br><span style="color: hsl(0, 100%, 40%);">- (char*)msgb_data(msg), &buflen,</span><br><span style="color: hsl(0, 100%, 40%);">- RTP_BUF_SIZE);</span><br><span style="color: hsl(0, 100%, 40%);">- if (cont < 0)</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (addr)</span><br><span style="color: hsl(0, 100%, 40%);">- mgcp_patch_and_count(endp, rtp_state, rtp_end,</span><br><span style="color: hsl(0, 100%, 40%);">- addr, msg);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (amr_oa_bwe_convert_indicated(conn_dst->end.codec)) {</span><br><span style="color: hsl(0, 100%, 40%);">- rc = amr_oa_bwe_convert(endp, msg,</span><br><span style="color: hsl(0, 100%, 40%);">- conn_dst->end.codec->param.amr_octet_aligned);</span><br><span style="color: hsl(0, 100%, 40%);">- if (rc < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPENDP(endp, DRTP, LOGL_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">- "Error in AMR octet-aligned <-> bandwidth-efficient mode conversion\n");</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- else if (rtp_end->rfc5993_hr_convert</span><br><span style="color: hsl(0, 100%, 40%);">- && strcmp(conn_src->end.codec->subtype_name,</span><br><span style="color: hsl(0, 100%, 40%);">- "GSM-HR-08") == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- rc = rfc5993_hr_convert(endp, msg);</span><br><span style="color: hsl(0, 100%, 40%);">- if (rc < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPENDP(endp, DRTP, LOGL_ERROR, "Error while converting to GSM-HR-08\n");</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPENDP(endp, DRTP, LOGL_DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">- "process/send to %s %s "</span><br><span style="color: hsl(0, 100%, 40%);">- "rtp_port:%u rtcp_port:%u\n",</span><br><span style="color: hsl(0, 100%, 40%);">- dest_name,</span><br><span style="color: hsl(0, 100%, 40%);">- osmo_sockaddr_ntop(&rtp_end->addr.u.sa, ipbuf),</span><br><span style="color: hsl(0, 100%, 40%);">- ntohs(rtp_end->rtp_port), ntohs(rtp_end->rtcp_port)</span><br><span style="color: hsl(0, 100%, 40%);">- );</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Forward a copy of the RTP data to a debug ip/port */</span><br><span style="color: hsl(0, 100%, 40%);">- forward_data(rtp_end->rtp.fd, &conn_src->tap_out,</span><br><span style="color: hsl(0, 100%, 40%);">- msg);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* FIXME: HACK HACK HACK. See OS#2459.</span><br><span style="color: hsl(0, 100%, 40%);">- * The ip.access nano3G needs the first RTP payload's first two bytes to read hex</span><br><span style="color: hsl(0, 100%, 40%);">- * 'e400', or it will reject the RAB assignment. It seems to not harm other femto</span><br><span style="color: hsl(0, 100%, 40%);">- * cells (as long as we patch only the first RTP payload in each stream).</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">- if (!rtp_state->patched_first_rtp_payload</span><br><span style="color: hsl(0, 100%, 40%);">- && conn_src->conn->mode == MGCP_CONN_LOOPBACK) {</span><br><span style="color: hsl(0, 100%, 40%);">- uint8_t *data = msgb_data(msg) + 12;</span><br><span style="color: hsl(0, 100%, 40%);">- if (data[0] == 0xe0) {</span><br><span style="color: hsl(0, 100%, 40%);">- data[0] = 0xe4;</span><br><span style="color: hsl(0, 100%, 40%);">- data[1] = 0x00;</span><br><span style="color: hsl(0, 100%, 40%);">- rtp_state->patched_first_rtp_payload = true;</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPENDP(endp, DRTP, LOGL_DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">- "Patching over first two bytes"</span><br><span style="color: hsl(0, 100%, 40%);">- " to fake an IuUP Initialization Ack\n");</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- len = mgcp_udp_send(rtp_end->rtp.fd, &rtp_end->addr, rtp_end->rtp_port,</span><br><span style="color: hsl(0, 100%, 40%);">- (char*)msgb_data(msg), msgb_length(msg));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (len <= 0)</span><br><span style="color: hsl(0, 100%, 40%);">- return len;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- rtpconn_rate_ctr_inc(conn_dst, endp, RTP_PACKETS_TX_CTR);</span><br><span style="color: hsl(0, 100%, 40%);">- rtpconn_rate_ctr_add(conn_dst, endp, RTP_OCTETS_TX_CTR, len);</span><br><span style="color: hsl(0, 100%, 40%);">- rtp_state->alt_rtp_tx_sequence++;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- nbytes += len;</span><br><span style="color: hsl(0, 100%, 40%);">- buflen = cont;</span><br><span style="color: hsl(0, 100%, 40%);">- } while (buflen > 0);</span><br><span style="color: hsl(0, 100%, 40%);">- return nbytes;</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (!trunk->omit_rtcp) {</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPENDP(endp, DRTP, LOGL_DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">- "send to %s %s rtp_port:%u rtcp_port:%u\n",</span><br><span style="color: hsl(0, 100%, 40%);">- dest_name, osmo_sockaddr_ntop(&rtp_end->addr.u.sa, ipbuf),</span><br><span style="color: hsl(0, 100%, 40%);">- ntohs(rtp_end->rtp_port), ntohs(rtp_end->rtcp_port)</span><br><span style="color: hsl(0, 100%, 40%);">- );</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- len = mgcp_udp_send(rtp_end->rtcp.fd,</span><br><span style="color: hsl(0, 100%, 40%);">- &rtp_end->addr,</span><br><span style="color: hsl(0, 100%, 40%);">- rtp_end->rtcp_port, (char*)msgb_data(msg), msgb_length(msg));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- rtpconn_rate_ctr_inc(conn_dst, endp, RTP_PACKETS_TX_CTR);</span><br><span style="color: hsl(0, 100%, 40%);">- rtpconn_rate_ctr_add(conn_dst, endp, RTP_OCTETS_TX_CTR, len);</span><br><span style="color: hsl(0, 100%, 40%);">- rtp_state->alt_rtp_tx_sequence++;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return len;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /* Check if the origin (addr) matches the address/port data of the RTP</span><br><span> * connections. */</span><br><span> static int check_rtp_origin(struct mgcp_conn_rtp *conn, struct osmo_sockaddr *addr)</span><br><span>@@ -1236,6 +992,249 @@</span><br><span> return -1;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! send udp packet.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] fd associated file descriptor.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] addr destination ip-address.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] port destination UDP port (network byte order).</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] buf buffer that holds the data to be send.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] len length of the data to be sent.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \returns bytes sent, -1 on error. */</span><br><span style="color: hsl(120, 100%, 40%);">+int mgcp_udp_send(int fd, struct osmo_sockaddr *addr, int port, const char *buf, int len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ char ipbuf[INET6_ADDRSTRLEN];</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t addr_len;</span><br><span style="color: hsl(120, 100%, 40%);">+ bool is_ipv6 = addr->u.sa.sa_family == AF_INET6;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DRTP, LOGL_DEBUG,</span><br><span style="color: hsl(120, 100%, 40%);">+ "sending %i bytes length packet to %s:%u ...\n", len,</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_sockaddr_ntop(&addr->u.sa, ipbuf),</span><br><span style="color: hsl(120, 100%, 40%);">+ ntohs(port));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (is_ipv6) {</span><br><span style="color: hsl(120, 100%, 40%);">+ addr->u.sin6.sin6_port = port;</span><br><span style="color: hsl(120, 100%, 40%);">+ addr_len = sizeof(addr->u.sin6);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ addr->u.sin.sin_port = port;</span><br><span style="color: hsl(120, 100%, 40%);">+ addr_len = sizeof(addr->u.sin);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return sendto(fd, buf, len, 0, &addr->u.sa, addr_len);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! send RTP dummy packet (to keep NAT connection open).</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] endp mcgp endpoint that holds the RTP connection.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] conn associated RTP connection.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \returns bytes sent, -1 on error. */</span><br><span style="color: hsl(120, 100%, 40%);">+int mgcp_send_dummy(struct mgcp_endpoint *endp, struct mgcp_conn_rtp *conn)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ int was_rtcp = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(endp);</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(conn);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPCONN(conn->conn, DRTP, LOGL_DEBUG,"sending dummy packet... %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ mgcp_conn_dump(conn->conn));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = mgcp_udp_send(conn->end.rtp.fd, &conn->end.addr,</span><br><span style="color: hsl(120, 100%, 40%);">+ conn->end.rtp_port, rtp_dummy_payload, sizeof(rtp_dummy_payload));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc == -1)</span><br><span style="color: hsl(120, 100%, 40%);">+ goto failed;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (endp->trunk->omit_rtcp)</span><br><span style="color: hsl(120, 100%, 40%);">+ return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ was_rtcp = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = mgcp_udp_send(conn->end.rtcp.fd, &conn->end.addr,</span><br><span style="color: hsl(120, 100%, 40%);">+ conn->end.rtcp_port, rtp_dummy_payload, sizeof(rtp_dummy_payload));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc >= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+failed:</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPCONN(conn->conn, DRTP, LOGL_ERROR,</span><br><span style="color: hsl(120, 100%, 40%);">+ "Failed to send dummy %s packet.\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ was_rtcp ? "RTCP" : "RTP");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Send RTP/RTCP data to a specified destination connection.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] endp associated endpoint (for configuration, logging).</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] is_rtp flag to specify if the packet is of type RTP or RTCP.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] spoofed source address (set to NULL to disable).</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] buf buffer that contains the RTP/RTCP data.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] len length of the buffer that contains the RTP/RTCP data.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] conn_src associated source connection.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] conn_dst associated destination connection.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \returns 0 on success, -1 on ERROR. */</span><br><span style="color: hsl(120, 100%, 40%);">+int mgcp_send(struct mgcp_endpoint *endp, int is_rtp, struct osmo_sockaddr *addr,</span><br><span style="color: hsl(120, 100%, 40%);">+ struct msgb *msg, struct mgcp_conn_rtp *conn_src,</span><br><span style="color: hsl(120, 100%, 40%);">+ struct mgcp_conn_rtp *conn_dst)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! When no destination connection is available (e.g. when only one</span><br><span style="color: hsl(120, 100%, 40%);">+ * connection in loopback mode exists), then the source connection</span><br><span style="color: hsl(120, 100%, 40%);">+ * shall be specified as destination connection */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ struct mgcp_trunk *trunk = endp->trunk;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct mgcp_rtp_end *rtp_end;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct mgcp_rtp_state *rtp_state;</span><br><span style="color: hsl(120, 100%, 40%);">+ char ipbuf[INET6_ADDRSTRLEN];</span><br><span style="color: hsl(120, 100%, 40%);">+ char *dest_name;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ int len;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(conn_src);</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(conn_dst);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (is_rtp) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPENDP(endp, DRTP, LOGL_DEBUG, "delivering RTP packet...\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPENDP(endp, DRTP, LOGL_DEBUG, "delivering RTCP packet...\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* FIXME: It is legal that the payload type on the egress connection is</span><br><span style="color: hsl(120, 100%, 40%);">+ * different from the payload type that has been negotiated on the</span><br><span style="color: hsl(120, 100%, 40%);">+ * ingress connection. Essentially the codecs are the same so we can</span><br><span style="color: hsl(120, 100%, 40%);">+ * match them and patch the payload type. However, if we can not find</span><br><span style="color: hsl(120, 100%, 40%);">+ * the codec pendant (everything ist equal except the PT), we are of</span><br><span style="color: hsl(120, 100%, 40%);">+ * course unable to patch the payload type. A situation like this</span><br><span style="color: hsl(120, 100%, 40%);">+ * should not occur if transcoding is consequently avoided. Until</span><br><span style="color: hsl(120, 100%, 40%);">+ * we have transcoding support in osmo-mgw we can not resolve this. */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (is_rtp) {</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = mgcp_patch_pt(conn_src, conn_dst, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPENDP(endp, DRTP, LOGL_DEBUG,</span><br><span style="color: hsl(120, 100%, 40%);">+ "can not patch PT because no suitable egress codec was found.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Note: In case of loopback configuration, both, the source and the</span><br><span style="color: hsl(120, 100%, 40%);">+ * destination will point to the same connection. */</span><br><span style="color: hsl(120, 100%, 40%);">+ rtp_end = &conn_dst->end;</span><br><span style="color: hsl(120, 100%, 40%);">+ rtp_state = &conn_src->state;</span><br><span style="color: hsl(120, 100%, 40%);">+ dest_name = conn_dst->conn->name;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Ensure we have an alternative SSRC in case we need it, see also</span><br><span style="color: hsl(120, 100%, 40%);">+ * gen_rtp_header() */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rtp_state->alt_rtp_tx_ssrc == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ rtp_state->alt_rtp_tx_ssrc = rand();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!rtp_end->output_enabled) {</span><br><span style="color: hsl(120, 100%, 40%);">+ rtpconn_rate_ctr_inc(conn_dst, endp, RTP_DROPPED_PACKETS_CTR);</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPENDP(endp, DRTP, LOGL_DEBUG,</span><br><span style="color: hsl(120, 100%, 40%);">+ "output disabled, drop to %s %s "</span><br><span style="color: hsl(120, 100%, 40%);">+ "rtp_port:%u rtcp_port:%u\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ dest_name,</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_sockaddr_ntop(&rtp_end->addr.u.sa, ipbuf),</span><br><span style="color: hsl(120, 100%, 40%);">+ ntohs(rtp_end->rtp_port), ntohs(rtp_end->rtcp_port)</span><br><span style="color: hsl(120, 100%, 40%);">+ );</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (is_rtp) {</span><br><span style="color: hsl(120, 100%, 40%);">+ int cont;</span><br><span style="color: hsl(120, 100%, 40%);">+ int nbytes = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ int buflen = msgb_length(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Make sure we have a valid RTP header, in cases where no RTP</span><br><span style="color: hsl(120, 100%, 40%);">+ * header is present, we will generate one. */</span><br><span style="color: hsl(120, 100%, 40%);">+ gen_rtp_header(msg, rtp_end, rtp_state);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ do {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Run transcoder */</span><br><span style="color: hsl(120, 100%, 40%);">+ cont = endp->cfg->rtp_processing_cb(endp, rtp_end,</span><br><span style="color: hsl(120, 100%, 40%);">+ (char*)msgb_data(msg), &buflen,</span><br><span style="color: hsl(120, 100%, 40%);">+ RTP_BUF_SIZE);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (cont < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (addr)</span><br><span style="color: hsl(120, 100%, 40%);">+ mgcp_patch_and_count(endp, rtp_state, rtp_end,</span><br><span style="color: hsl(120, 100%, 40%);">+ addr, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (amr_oa_bwe_convert_indicated(conn_dst->end.codec)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = amr_oa_bwe_convert(endp, msg,</span><br><span style="color: hsl(120, 100%, 40%);">+ conn_dst->end.codec->param.amr_octet_aligned);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPENDP(endp, DRTP, LOGL_ERROR,</span><br><span style="color: hsl(120, 100%, 40%);">+ "Error in AMR octet-aligned <-> bandwidth-efficient mode conversion\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ else if (rtp_end->rfc5993_hr_convert</span><br><span style="color: hsl(120, 100%, 40%);">+ && strcmp(conn_src->end.codec->subtype_name,</span><br><span style="color: hsl(120, 100%, 40%);">+ "GSM-HR-08") == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = rfc5993_hr_convert(endp, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPENDP(endp, DRTP, LOGL_ERROR, "Error while converting to GSM-HR-08\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPENDP(endp, DRTP, LOGL_DEBUG,</span><br><span style="color: hsl(120, 100%, 40%);">+ "process/send to %s %s "</span><br><span style="color: hsl(120, 100%, 40%);">+ "rtp_port:%u rtcp_port:%u\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ dest_name,</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_sockaddr_ntop(&rtp_end->addr.u.sa, ipbuf),</span><br><span style="color: hsl(120, 100%, 40%);">+ ntohs(rtp_end->rtp_port), ntohs(rtp_end->rtcp_port)</span><br><span style="color: hsl(120, 100%, 40%);">+ );</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Forward a copy of the RTP data to a debug ip/port */</span><br><span style="color: hsl(120, 100%, 40%);">+ forward_data(rtp_end->rtp.fd, &conn_src->tap_out,</span><br><span style="color: hsl(120, 100%, 40%);">+ msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* FIXME: HACK HACK HACK. See OS#2459.</span><br><span style="color: hsl(120, 100%, 40%);">+ * The ip.access nano3G needs the first RTP payload's first two bytes to read hex</span><br><span style="color: hsl(120, 100%, 40%);">+ * 'e400', or it will reject the RAB assignment. It seems to not harm other femto</span><br><span style="color: hsl(120, 100%, 40%);">+ * cells (as long as we patch only the first RTP payload in each stream).</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!rtp_state->patched_first_rtp_payload</span><br><span style="color: hsl(120, 100%, 40%);">+ && conn_src->conn->mode == MGCP_CONN_LOOPBACK) {</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t *data = msgb_data(msg) + 12;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (data[0] == 0xe0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ data[0] = 0xe4;</span><br><span style="color: hsl(120, 100%, 40%);">+ data[1] = 0x00;</span><br><span style="color: hsl(120, 100%, 40%);">+ rtp_state->patched_first_rtp_payload = true;</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPENDP(endp, DRTP, LOGL_DEBUG,</span><br><span style="color: hsl(120, 100%, 40%);">+ "Patching over first two bytes"</span><br><span style="color: hsl(120, 100%, 40%);">+ " to fake an IuUP Initialization Ack\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ len = mgcp_udp_send(rtp_end->rtp.fd, &rtp_end->addr, rtp_end->rtp_port,</span><br><span style="color: hsl(120, 100%, 40%);">+ (char*)msgb_data(msg), msgb_length(msg));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (len <= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return len;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rtpconn_rate_ctr_inc(conn_dst, endp, RTP_PACKETS_TX_CTR);</span><br><span style="color: hsl(120, 100%, 40%);">+ rtpconn_rate_ctr_add(conn_dst, endp, RTP_OCTETS_TX_CTR, len);</span><br><span style="color: hsl(120, 100%, 40%);">+ rtp_state->alt_rtp_tx_sequence++;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ nbytes += len;</span><br><span style="color: hsl(120, 100%, 40%);">+ buflen = cont;</span><br><span style="color: hsl(120, 100%, 40%);">+ } while (buflen > 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ return nbytes;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (!trunk->omit_rtcp) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPENDP(endp, DRTP, LOGL_DEBUG,</span><br><span style="color: hsl(120, 100%, 40%);">+ "send to %s %s rtp_port:%u rtcp_port:%u\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ dest_name, osmo_sockaddr_ntop(&rtp_end->addr.u.sa, ipbuf),</span><br><span style="color: hsl(120, 100%, 40%);">+ ntohs(rtp_end->rtp_port), ntohs(rtp_end->rtcp_port)</span><br><span style="color: hsl(120, 100%, 40%);">+ );</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ len = mgcp_udp_send(rtp_end->rtcp.fd,</span><br><span style="color: hsl(120, 100%, 40%);">+ &rtp_end->addr,</span><br><span style="color: hsl(120, 100%, 40%);">+ rtp_end->rtcp_port, (char*)msgb_data(msg), msgb_length(msg));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rtpconn_rate_ctr_inc(conn_dst, endp, RTP_PACKETS_TX_CTR);</span><br><span style="color: hsl(120, 100%, 40%);">+ rtpconn_rate_ctr_add(conn_dst, endp, RTP_OCTETS_TX_CTR, len);</span><br><span style="color: hsl(120, 100%, 40%);">+ rtp_state->alt_rtp_tx_sequence++;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return len;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! dispatch incoming RTP packet to opposite RTP connection.</span><br><span> * \param[in] proto protocol (MGCP_CONN_TYPE_RTP or MGCP_CONN_TYPE_RTCP).</span><br><span> * \param[in] addr socket address where the RTP packet has been received from.</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-mgw/+/24860">change 24860</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/osmo-mgw/+/24860"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: osmo-mgw </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Iff8dab942182a0d909519acddb86be75d9cda7ae </div>
<div style="display:none"> Gerrit-Change-Number: 24860 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>