<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>