aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--openbsc/include/openbsc/mncc.h2
-rw-r--r--openbsc/include/openbsc/rtp_proxy.h2
-rw-r--r--openbsc/src/libmsc/gsm_04_08.c2
-rw-r--r--openbsc/src/libtrau/rtp_proxy.c52
4 files changed, 43 insertions, 15 deletions
diff --git a/openbsc/include/openbsc/mncc.h b/openbsc/include/openbsc/mncc.h
index 7e3fd957c..5228ea6a8 100644
--- a/openbsc/include/openbsc/mncc.h
+++ b/openbsc/include/openbsc/mncc.h
@@ -186,6 +186,8 @@ struct gsm_mncc_rtp {
uint32_t callref;
uint32_t ip;
uint16_t port;
+ uint32_t payload_type;
+ uint32_t payload_msg_type;
};
char *get_mncc_name(int value);
diff --git a/openbsc/include/openbsc/rtp_proxy.h b/openbsc/include/openbsc/rtp_proxy.h
index a7d692c56..462e27653 100644
--- a/openbsc/include/openbsc/rtp_proxy.h
+++ b/openbsc/include/openbsc/rtp_proxy.h
@@ -70,6 +70,8 @@ struct rtp_socket {
struct {
struct gsm_network *net;
uint32_t callref;
+ uint8_t payload_type; /* dynamic PT */
+ int msg_type; /* message type for dynamic PT */
} receive;
};
enum rtp_tx_action tx_action;
diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c
index 649a77090..2623510e6 100644
--- a/openbsc/src/libmsc/gsm_04_08.c
+++ b/openbsc/src/libmsc/gsm_04_08.c
@@ -1711,6 +1711,8 @@ static int mncc_rtp(struct gsm_network *net, uint32_t callref, struct gsm_mncc_r
mncc_recvmsg(net, trans, MNCC_RTP_CONNECT, (struct gsm_mncc *)mncc);
return -EIO;
}
+ rs->receive.msg_type = mncc->payload_msg_type;
+ rs->receive.payload_type = mncc->payload_type;
/* reply with local IP/port */
mncc->ip = ntohl(rs->rtp.sin_local.sin_addr.s_addr);
mncc->port = ntohs(rs->rtp.sin_local.sin_port);
diff --git a/openbsc/src/libtrau/rtp_proxy.c b/openbsc/src/libtrau/rtp_proxy.c
index f19ae9331..fdcd5254f 100644
--- a/openbsc/src/libtrau/rtp_proxy.c
+++ b/openbsc/src/libtrau/rtp_proxy.c
@@ -106,7 +106,7 @@ struct rtp_x_hdr {
#define RTP_VERSION 2
/* decode an rtp frame and create a new buffer with payload */
-static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data)
+static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data, int msg_type)
{
struct msgb *new_msg;
struct gsm_data_frame *frame;
@@ -114,7 +114,6 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data)
struct rtp_x_hdr *rtpxh;
uint8_t *payload;
int payload_len;
- int msg_type;
int x_len;
if (msg->len < 12) {
@@ -164,9 +163,28 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data)
}
}
- switch (rtph->payload_type) {
- case RTP_PT_GSM_FULL:
- msg_type = GSM_TCHF_FRAME;
+ /* If no explicit frame type is given, select frame type from
+ * payload type. */
+ if (!msg_type) {
+ switch (rtph->payload_type) {
+ case RTP_PT_GSM_FULL:
+ msg_type = GSM_TCHF_FRAME;
+ break;
+ case RTP_PT_GSM_EFR:
+ msg_type = GSM_TCHF_FRAME_EFR;
+ break;
+ case RTP_PT_GSM_HALF:
+ msg_type = GSM_TCHF_FRAME_HR;
+ break;
+ default:
+ DEBUGPC(DLMUX, "received RTP frame with unknown "
+ "payload type %d\n", rtph->payload_type);
+ return -EINVAL;
+ }
+ }
+
+ switch (msg_type) {
+ case GSM_TCHF_FRAME:
if (payload_len != 33) {
DEBUGPC(DLMUX, "received RTP full rate frame with "
"payload length != 33 (len = %d)\n",
@@ -174,8 +192,7 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data)
return -EINVAL;
}
break;
- case RTP_PT_GSM_EFR:
- msg_type = GSM_TCHF_FRAME_EFR;
+ case GSM_TCHF_FRAME_EFR:
if (payload_len != 31) {
DEBUGPC(DLMUX, "received RTP extended full rate frame "
"with payload length != 31 (len = %d)\n",
@@ -183,8 +200,7 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data)
return -EINVAL;
}
break;
- case RTP_PT_GSM_HALF:
- msg_type = GSM_TCHF_FRAME_HR;
+ case GSM_TCHF_FRAME_HR:
if (payload_len != 14) {
DEBUGPC(DLMUX, "received RTP half rate frame with "
"payload length != 14 (len = %d)\n",
@@ -193,8 +209,7 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data)
}
break;
default:
- DEBUGPC(DLMUX, "received RTP frame with unknown payload "
- "type %d\n", rtph->payload_type);
+ DEBUGPC(DLMUX, "Forced message type %x unknown\n", msg_type);
return -EINVAL;
}
@@ -239,6 +254,10 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame)
int payload_type;
int payload_len;
int duration; /* in samples */
+ uint8_t dynamic_pt = 0;
+
+ if (rs->rx_action == RTP_RECV_L4)
+ dynamic_pt = rs->receive.payload_type;
if (rs->tx_action != RTP_SEND_DOWNSTREAM) {
/* initialize sequences */
@@ -255,17 +274,19 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame)
duration = 160;
break;
case GSM_TCHF_FRAME_EFR:
- payload_type = RTP_PT_GSM_EFR;
+ payload_type = (dynamic_pt) ? : RTP_PT_GSM_EFR;
payload_len = 31;
duration = 160;
break;
case GSM_TCHF_FRAME_HR:
- payload_type = RTP_PT_GSM_HALF;
+ payload_type = (dynamic_pt) ? : RTP_PT_GSM_HALF;
payload_len = 14;
duration = 160;
break;
case GSM_TCHF_BAD_FRAME:
/* in case of a bad frame, just count and drop packt */
+ payload_type = 0;
+ payload_len = 0;
duration = 160;
rs->transmit.timestamp += duration;
rs->transmit.sequence++;
@@ -477,7 +498,7 @@ static int rtp_socket_read(struct rtp_socket *rs, struct rtp_sub_socket *rss)
rc = -EINVAL;
goto out_free;
}
- rc = rtp_decode(msg, rs->receive.callref, &new_msg);
+ rc = rtp_decode(msg, rs->receive.callref, &new_msg, 0);
if (rc < 0)
goto out_free;
msgb_free(msg);
@@ -493,7 +514,8 @@ static int rtp_socket_read(struct rtp_socket *rs, struct rtp_sub_socket *rss)
rc = ENOTSUP;
goto out_free;
}
- rc = rtp_decode(msg, rs->receive.callref, &new_msg);
+ rc = rtp_decode(msg, rs->receive.callref, &new_msg,
+ rs->receive.msg_type);
if (rc < 0)
goto out_free;
msgb_free(msg);