aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/libmgcp/mgcp_network.c
diff options
context:
space:
mode:
Diffstat (limited to 'openbsc/src/libmgcp/mgcp_network.c')
-rw-r--r--openbsc/src/libmgcp/mgcp_network.c126
1 files changed, 87 insertions, 39 deletions
diff --git a/openbsc/src/libmgcp/mgcp_network.c b/openbsc/src/libmgcp/mgcp_network.c
index a2cfc2385..2d4755b84 100644
--- a/openbsc/src/libmgcp/mgcp_network.c
+++ b/openbsc/src/libmgcp/mgcp_network.c
@@ -35,6 +35,9 @@
#include <openbsc/mgcp.h>
#include <openbsc/mgcp_internal.h>
+#include <openbsc/mgcp.h>
+#include <openbsc/osmux.h>
+
#warning "Make use of the rtp proxy code"
/* attempt to determine byte order */
@@ -78,20 +81,11 @@ struct rtp_hdr {
#define RTP_MAX_DROPOUT 3000
#define RTP_MAX_MISORDER 100
-
-enum {
- DEST_NETWORK = 0,
- DEST_BTS = 1,
-};
-
enum {
PROTO_RTP,
PROTO_RTCP,
};
-#define DUMMY_LOAD 0x23
-
-
/**
* This does not need to be a precision timestamp and
* is allowed to wrap quite fast. The returned value is
@@ -115,7 +109,7 @@ uint32_t get_current_ts(void)
return ret;
}
-static int udp_send(int fd, struct in_addr *addr, int port, char *buf, int len)
+int udp_send(int fd, struct in_addr *addr, int port, char *buf, int len)
{
struct sockaddr_in out;
out.sin_family = AF_INET;
@@ -263,8 +257,8 @@ static int send_transcoder(struct mgcp_rtp_end *end, struct mgcp_config *cfg,
return rc;
}
-static int send_to(struct mgcp_endpoint *endp, int dest, int is_rtp,
- struct sockaddr_in *addr, char *buf, int rc)
+int mgcp_send(struct mgcp_endpoint *endp, int dest, int is_rtp,
+ struct sockaddr_in *addr, char *buf, int rc)
{
struct mgcp_trunk_config *tcfg = endp->tcfg;
/* For loop toggle the destination and then dispatch. */
@@ -275,13 +269,19 @@ static int send_to(struct mgcp_endpoint *endp, int dest, int is_rtp,
if (endp->conn_mode == MGCP_CONN_LOOPBACK)
dest = !dest;
- if (dest == DEST_NETWORK) {
+ if (dest == MGCP_DEST_NET) {
if (is_rtp) {
patch_and_count(endp, &endp->bts_state,
endp->net_end.payload_type,
addr, buf, rc);
forward_data(endp->net_end.rtp.fd,
&endp->taps[MGCP_TAP_NET_OUT], buf, rc);
+
+ LOGP(DMGCP, LOGL_DEBUG, "delivering RTP to Network"
+ "via addr=%s, port=%u\n",
+ inet_ntoa(endp->net_end.addr),
+ ntohs(endp->net_end.rtp_port));
+
return udp_send(endp->net_end.rtp.fd, &endp->net_end.addr,
endp->net_end.rtp_port, buf, rc);
} else if (!tcfg->omit_rtcp) {
@@ -295,6 +295,12 @@ static int send_to(struct mgcp_endpoint *endp, int dest, int is_rtp,
addr, buf, rc);
forward_data(endp->bts_end.rtp.fd,
&endp->taps[MGCP_TAP_BTS_OUT], buf, rc);
+
+ LOGP(DMGCP, LOGL_DEBUG, "delivering RTP to BTS"
+ "via addr=%s, port=%u\n",
+ inet_ntoa(endp->bts_end.addr),
+ ntohs(endp->bts_end.rtp_port));
+
return udp_send(endp->bts_end.rtp.fd, &endp->bts_end.addr,
endp->bts_end.rtp_port, buf, rc);
} else if (!tcfg->omit_rtcp) {
@@ -351,12 +357,20 @@ static int rtp_data_net(struct osmo_fd *fd, unsigned int what)
return -1;
}
- if (endp->net_end.rtp_port != addr.sin_port &&
- endp->net_end.rtcp_port != addr.sin_port) {
- LOGP(DMGCP, LOGL_ERROR,
- "Data from wrong source port %d on 0x%x\n",
- ntohs(addr.sin_port), ENDPOINT_NUMBER(endp));
- return -1;
+ switch(endp->type) {
+ case MGCP_RTP:
+ case MGCP_RTP_TRANSCODED:
+ if (endp->net_end.rtp_port != addr.sin_port &&
+ endp->net_end.rtcp_port != addr.sin_port) {
+ LOGP(DMGCP, LOGL_ERROR,
+ "Data from wrong source port %d on 0x%x\n",
+ ntohs(addr.sin_port), ENDPOINT_NUMBER(endp));
+ return -1;
+ }
+ break;
+ case MGCP_OSMUX_BSC:
+ case MGCP_OSMUX_BSC_NAT:
+ break;
}
/* throw away the dummy message */
@@ -371,10 +385,23 @@ static int rtp_data_net(struct osmo_fd *fd, unsigned int what)
endp->net_end.octets += rc;
forward_data(fd->fd, &endp->taps[MGCP_TAP_NET_IN], buf, rc);
- if (endp->is_transcoded)
- return send_transcoder(&endp->trans_net, endp->cfg, proto == PROTO_RTP, &buf[0], rc);
- else
- return send_to(endp, DEST_BTS, proto == PROTO_RTP, &addr, &buf[0], rc);
+ switch(endp->type) {
+ case MGCP_RTP_TRANSCODED:
+ rc = send_transcoder(&endp->trans_net, endp->cfg, proto == PROTO_RTP, &buf[0], rc);
+ break;
+ case MGCP_RTP:
+ rc = mgcp_send(endp, MGCP_DEST_BTS, proto == PROTO_RTP, &addr, &buf[0], rc);
+ break;
+ case MGCP_OSMUX_BSC_NAT:
+ /* BSC-NAT -> BSC: translate to OSMUX */
+ rc = osmux_xfrm_to_osmux(MGCP_DEST_BTS, buf, rc, endp);
+ break;
+ default:
+ LOGP(DMGCP, LOGL_ERROR, "unknown endpoint type %d\n",
+ endp->type);
+ break;
+ }
+ return rc;
}
static void discover_bts(struct mgcp_endpoint *endp, int proto, struct sockaddr_in *addr)
@@ -430,12 +457,20 @@ static int rtp_data_bts(struct osmo_fd *fd, unsigned int what)
return -1;
}
- if (endp->bts_end.rtp_port != addr.sin_port &&
- endp->bts_end.rtcp_port != addr.sin_port) {
- LOGP(DMGCP, LOGL_ERROR,
- "Data from wrong bts source port %d on 0x%x\n",
- ntohs(addr.sin_port), ENDPOINT_NUMBER(endp));
- return -1;
+ switch(endp->type) {
+ case MGCP_RTP:
+ case MGCP_RTP_TRANSCODED:
+ if (endp->bts_end.rtp_port != addr.sin_port &&
+ endp->bts_end.rtcp_port != addr.sin_port) {
+ LOGP(DMGCP, LOGL_ERROR,
+ "Data from wrong bts source port %d on 0x%x\n",
+ ntohs(addr.sin_port), ENDPOINT_NUMBER(endp));
+ return -1;
+ }
+ break;
+ case MGCP_OSMUX_BSC:
+ case MGCP_OSMUX_BSC_NAT:
+ break;
}
/* throw away the dummy message */
@@ -450,10 +485,23 @@ static int rtp_data_bts(struct osmo_fd *fd, unsigned int what)
endp->bts_end.octets += rc;
forward_data(fd->fd, &endp->taps[MGCP_TAP_BTS_IN], buf, rc);
- if (endp->is_transcoded)
- return send_transcoder(&endp->trans_bts, endp->cfg, proto == PROTO_RTP, &buf[0], rc);
- else
- return send_to(endp, DEST_NETWORK, proto == PROTO_RTP, &addr, &buf[0], rc);
+ switch(endp->type) {
+ case MGCP_RTP_TRANSCODED:
+ rc = send_transcoder(&endp->trans_bts, endp->cfg, proto == PROTO_RTP, &buf[0], rc);
+ break;
+ case MGCP_RTP:
+ rc = mgcp_send(endp, MGCP_DEST_NET, proto == PROTO_RTP, &addr, &buf[0], rc);
+ break;
+ case MGCP_OSMUX_BSC:
+ /* BTS -> BSC, translate to OSMUX */
+ rc = osmux_xfrm_to_osmux(MGCP_DEST_NET, buf, rc, endp);
+ break;
+ default:
+ LOGP(DMGCP, LOGL_ERROR, "unknown endpoit type %d\n",
+ endp->type);
+ break;
+ }
+ return rc;
}
static int rtp_data_transcoder(struct mgcp_rtp_end *end, struct mgcp_endpoint *_endp,
@@ -494,7 +542,7 @@ static int rtp_data_transcoder(struct mgcp_rtp_end *end, struct mgcp_endpoint *_
}
end->packets += 1;
- return send_to(_endp, dest, proto == PROTO_RTP, &addr, &buf[0], rc);
+ return mgcp_send(_endp, dest, proto == PROTO_RTP, &addr, &buf[0], rc);
}
static int rtp_data_trans_net(struct osmo_fd *fd, unsigned int what)
@@ -502,7 +550,7 @@ static int rtp_data_trans_net(struct osmo_fd *fd, unsigned int what)
struct mgcp_endpoint *endp;
endp = (struct mgcp_endpoint *) fd->data;
- return rtp_data_transcoder(&endp->trans_net, endp, DEST_NETWORK, fd);
+ return rtp_data_transcoder(&endp->trans_net, endp, MGCP_DEST_NET, fd);
}
static int rtp_data_trans_bts(struct osmo_fd *fd, unsigned int what)
@@ -510,10 +558,10 @@ static int rtp_data_trans_bts(struct osmo_fd *fd, unsigned int what)
struct mgcp_endpoint *endp;
endp = (struct mgcp_endpoint *) fd->data;
- return rtp_data_transcoder(&endp->trans_bts, endp, DEST_BTS, fd);
+ return rtp_data_transcoder(&endp->trans_bts, endp, MGCP_DEST_BTS, fd);
}
-static int create_bind(const char *source_addr, struct osmo_fd *fd, int port)
+int mgcp_create_bind(const char *source_addr, struct osmo_fd *fd, int port)
{
struct sockaddr_in addr;
int on = 1;
@@ -549,13 +597,13 @@ static int set_ip_tos(int fd, int tos)
static int bind_rtp(struct mgcp_config *cfg, struct mgcp_rtp_end *rtp_end, int endpno)
{
- if (create_bind(cfg->source_addr, &rtp_end->rtp, rtp_end->local_port) != 0) {
+ if (mgcp_create_bind(cfg->source_addr, &rtp_end->rtp, rtp_end->local_port) != 0) {
LOGP(DMGCP, LOGL_ERROR, "Failed to create RTP port: %s:%d on 0x%x\n",
cfg->source_addr, rtp_end->local_port, endpno);
goto cleanup0;
}
- if (create_bind(cfg->source_addr, &rtp_end->rtcp, rtp_end->local_port + 1) != 0) {
+ if (mgcp_create_bind(cfg->source_addr, &rtp_end->rtcp, rtp_end->local_port + 1) != 0) {
LOGP(DMGCP, LOGL_ERROR, "Failed to create RTCP port: %s:%d on 0x%x\n",
cfg->source_addr, rtp_end->local_port + 1, endpno);
goto cleanup1;