summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2012-03-08 14:39:19 +0100
committerIvan Kluchnikov <kluchnikovi@gmail.com>2014-05-06 17:21:08 +0400
commitaf4777f8cd4fb166523104a8e2e34d27f88f9d91 (patch)
tree13d3d91b970f5c626d9b98c5ec0f13c28ee2e7c9
parenta7a9617daee6e6bd36c46eecc988face4b7d56ce (diff)
Add support for AMR frames to MNCC/RTP interface
AMR rate is currently fixed to 5.9k.
-rw-r--r--openbsc/src/libmsc/gsm_04_08.c1
-rw-r--r--openbsc/src/libtrau/rtp_proxy.c24
2 files changed, 20 insertions, 5 deletions
diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c
index df934330a..a0650abbf 100644
--- a/openbsc/src/libmsc/gsm_04_08.c
+++ b/openbsc/src/libmsc/gsm_04_08.c
@@ -2953,6 +2953,7 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg)
case GSM_TCHF_FRAME:
case GSM_TCHF_FRAME_EFR:
case GSM_TCHH_FRAME:
+ case GSM_TCH_FRAME_AMR:
/* Find callref */
trans = trans_find_by_callref(net, data->callref);
if (!trans) {
diff --git a/openbsc/src/libtrau/rtp_proxy.c b/openbsc/src/libtrau/rtp_proxy.c
index 143bfa006..9c16a95ad 100644
--- a/openbsc/src/libtrau/rtp_proxy.c
+++ b/openbsc/src/libtrau/rtp_proxy.c
@@ -116,6 +116,7 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data)
int payload_len;
int msg_type;
int x_len;
+ int is_amr = 0;
if (msg->len < 12) {
DEBUGPC(DLMUX, "received RTP frame too short (len = %d)\n",
@@ -192,21 +193,26 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data)
return -EINVAL;
}
break;
+ case RTP_PT_AMR:
+ is_amr = 1;
+ break;
default:
DEBUGPC(DLMUX, "received RTP frame with unknown payload "
"type %d\n", rtph->payload_type);
return -EINVAL;
}
- new_msg = msgb_alloc(sizeof(struct gsm_data_frame) + payload_len,
- "GSM-DATA");
+ new_msg = msgb_alloc(sizeof(struct gsm_data_frame) + payload_len +
+ is_amr, "GSM-DATA");
if (!new_msg)
return -ENOMEM;
frame = (struct gsm_data_frame *)(new_msg->data);
frame->msg_type = msg_type;
frame->callref = callref;
- memcpy(frame->data, payload, payload_len);
- msgb_put(new_msg, sizeof(struct gsm_data_frame) + payload_len);
+ if (is_amr)
+ frame->data[0] = payload_len;
+ memcpy(frame->data + is_amr, payload, payload_len);
+ msgb_put(new_msg, sizeof(struct gsm_data_frame) + is_amr + payload_len);
*data = new_msg;
return 0;
@@ -239,6 +245,7 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame)
int payload_type;
int payload_len;
int duration; /* in samples */
+ int is_amr = 0;
if (rs->tx_action != RTP_SEND_DOWNSTREAM) {
/* initialize sequences */
@@ -264,6 +271,12 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame)
payload_len = RTP_LEN_GSM_HALF;
duration = RTP_GSM_DURATION;
break;
+ case GSM_TCH_FRAME_AMR:
+ payload_type = RTP_PT_AMR;
+ payload_len = frame->data[0];
+ duration = RTP_GSM_DURATION;
+ is_amr = 1;
+ break;
default:
DEBUGPC(DLMUX, "unsupported message type %d\n",
frame->msg_type);
@@ -305,7 +318,8 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame)
rtph->timestamp = htonl(rs->transmit.timestamp);
rs->transmit.timestamp += duration;
rtph->ssrc = htonl(rs->transmit.ssrc);
- memcpy(msg->data + sizeof(struct rtp_hdr), frame->data, payload_len);
+ memcpy(msg->data + sizeof(struct rtp_hdr), frame->data + is_amr,
+ payload_len);
msgb_put(msg, sizeof(struct rtp_hdr) + payload_len);
msgb_enqueue(&rss->tx_queue, msg);
rss->bfd.when |= BSC_FD_WRITE;