diff options
author | Andreas Eversberg <jolly@eversberg.eu> | 2012-03-08 14:39:19 +0100 |
---|---|---|
committer | Ivan Kluchnikov <kluchnikovi@gmail.com> | 2014-05-06 17:21:08 +0400 |
commit | af4777f8cd4fb166523104a8e2e34d27f88f9d91 (patch) | |
tree | 13d3d91b970f5c626d9b98c5ec0f13c28ee2e7c9 /openbsc | |
parent | a7a9617daee6e6bd36c46eecc988face4b7d56ce (diff) |
Add support for AMR frames to MNCC/RTP interface
AMR rate is currently fixed to 5.9k.
Diffstat (limited to 'openbsc')
-rw-r--r-- | openbsc/src/libmsc/gsm_04_08.c | 1 | ||||
-rw-r--r-- | openbsc/src/libtrau/rtp_proxy.c | 24 |
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; |