aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2012-03-08 14:39:19 +0100
committerAndreas Eversberg <jolly@eversberg.eu>2013-07-29 12:34:15 +0200
commitdbddc8877c58bfdcd287d1af3228582d3800ac0c (patch)
tree680d4bcfe21d6991a13703a75c204cd965445a71
parentedf41a2c2f4d498833fcd92731f87a20955e5366 (diff)
Finished support for all codecs (RTP bridge and MNCC interface)
The codes is not yet tested. AMR rate is currently fixed to 5.9k.
-rw-r--r--openbsc/include/openbsc/mncc.h5
-rw-r--r--openbsc/src/libmsc/gsm_04_08.c3
-rw-r--r--openbsc/src/libmsc/mncc.c5
-rw-r--r--openbsc/src/libmsc/mncc_builtin.c6
-rw-r--r--openbsc/src/libmsc/mncc_sock.c10
-rw-r--r--openbsc/src/libtrau/rtp_proxy.c31
-rw-r--r--openbsc/src/libtrau/trau_mux.c2
7 files changed, 42 insertions, 20 deletions
diff --git a/openbsc/include/openbsc/mncc.h b/openbsc/include/openbsc/mncc.h
index 5228ea6a8..0a4f2efb7 100644
--- a/openbsc/include/openbsc/mncc.h
+++ b/openbsc/include/openbsc/mncc.h
@@ -98,8 +98,9 @@ struct gsm_call {
#define GSM_TCHF_FRAME 0x0300
#define GSM_TCHF_FRAME_EFR 0x0301
-#define GSM_TCHF_FRAME_HR 0x0302
-#define GSM_TCHF_BAD_FRAME 0x03ff
+#define GSM_TCHH_FRAME 0x0302
+#define GSM_TCH_FRAME_AMR 0x0303
+#define GSM_BAD_FRAME 0x03ff
#define MNCC_SOCKET_HELLO 0x0400
diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c
index 2623510e6..0767c722f 100644
--- a/openbsc/src/libmsc/gsm_04_08.c
+++ b/openbsc/src/libmsc/gsm_04_08.c
@@ -3031,7 +3031,8 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg)
return mncc_rtp(net, data->callref, (struct gsm_mncc_rtp *) arg);
case GSM_TCHF_FRAME:
case GSM_TCHF_FRAME_EFR:
- case GSM_TCHF_FRAME_HR:
+ case GSM_TCHH_FRAME:
+ case GSM_TCH_FRAME_AMR:
return tch_frame_down(net, data->callref, (struct gsm_data_frame *) arg);
}
diff --git a/openbsc/src/libmsc/mncc.c b/openbsc/src/libmsc/mncc.c
index b48477225..01e9c67d2 100644
--- a/openbsc/src/libmsc/mncc.c
+++ b/openbsc/src/libmsc/mncc.c
@@ -84,7 +84,10 @@ static struct mncc_names {
{"MNCC_FRAME_DROP", 0x0202},
{"MNCC_LCHAN_MODIFY", 0x0203},
- {"GSM_TCH_FRAME", 0x0300},
+ {"GSM_TCHF_FRAME", 0x0300},
+ {"GSM_TCHF_FRAME_EFR", 0x0301},
+ {"GSM_TCHH_FRAME", 0x0302},
+ {"GSM_TCH_FRAME_AMR", 0x0303},
{NULL, 0} };
diff --git a/openbsc/src/libmsc/mncc_builtin.c b/openbsc/src/libmsc/mncc_builtin.c
index 5f909f739..665725b8a 100644
--- a/openbsc/src/libmsc/mncc_builtin.c
+++ b/openbsc/src/libmsc/mncc_builtin.c
@@ -342,7 +342,8 @@ int int_mncc_recv(struct gsm_network *net, struct msgb *msg)
switch (msg_type) {
case GSM_TCHF_FRAME:
case GSM_TCHF_FRAME_EFR:
- case GSM_TCHF_FRAME_HR:
+ case GSM_TCHH_FRAME:
+ case GSM_TCH_FRAME_AMR:
break;
default:
DEBUGP(DMNCC, "(call %x) Received message %s\n", call->callref,
@@ -411,7 +412,8 @@ int int_mncc_recv(struct gsm_network *net, struct msgb *msg)
break;
case GSM_TCHF_FRAME:
case GSM_TCHF_FRAME_EFR:
- case GSM_TCHF_FRAME_HR:
+ case GSM_TCHH_FRAME:
+ case GSM_TCH_FRAME_AMR:
rc = mncc_rcv_tchf(call, msg_type, arg);
break;
default:
diff --git a/openbsc/src/libmsc/mncc_sock.c b/openbsc/src/libmsc/mncc_sock.c
index da69dae34..5ae9cc402 100644
--- a/openbsc/src/libmsc/mncc_sock.c
+++ b/openbsc/src/libmsc/mncc_sock.c
@@ -56,8 +56,9 @@ int mncc_sock_from_cc(struct gsm_network *net, struct msgb *msg)
* otherwise we send it through MNCC interface */
if (msg_type == GSM_TCHF_FRAME
|| msg_type == GSM_TCHF_FRAME_EFR
- || msg_type == GSM_TCHF_FRAME_HR
- || msg_type == GSM_TCHF_BAD_FRAME) {
+ || msg_type == GSM_TCHH_FRAME
+ || msg_type == GSM_TCH_FRAME_AMR
+ || msg_type == GSM_BAD_FRAME) {
struct gsm_trans *trans = trans_find_by_callref(net, mncc_in->callref);
if (trans && trans->cc.rs) {
@@ -73,8 +74,9 @@ int mncc_sock_from_cc(struct gsm_network *net, struct msgb *msg)
"but socket is gone\n", get_mncc_name(msg_type));
if (msg_type != GSM_TCHF_FRAME
&& msg_type != GSM_TCHF_FRAME_EFR
- && msg_type != GSM_TCHF_FRAME_HR
- && msg_type != GSM_TCHF_BAD_FRAME) {
+ && msg_type != GSM_TCHH_FRAME
+ && msg_type != GSM_TCH_FRAME_AMR
+ && msg_type != GSM_BAD_FRAME) {
/* release the request */
struct gsm_mncc mncc_out;
memset(&mncc_out, 0, sizeof(mncc_out));
diff --git a/openbsc/src/libtrau/rtp_proxy.c b/openbsc/src/libtrau/rtp_proxy.c
index 58aadfc3c..92086ed1f 100644
--- a/openbsc/src/libtrau/rtp_proxy.c
+++ b/openbsc/src/libtrau/rtp_proxy.c
@@ -115,6 +115,7 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data, in
uint8_t *payload;
int payload_len;
int x_len;
+ int amr = 0;
if (msg->len < 12) {
DEBUGPC(DLMUX, "received RTP frame too short (len = %d)\n",
@@ -174,7 +175,7 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data, in
msg_type = GSM_TCHF_FRAME_EFR;
break;
case RTP_PT_GSM_HALF:
- msg_type = GSM_TCHF_FRAME_HR;
+ msg_type = GSM_TCHH_FRAME;
break;
default:
DEBUGPC(DLMUX, "received RTP frame with unknown "
@@ -200,7 +201,7 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data, in
return -EINVAL;
}
break;
- case GSM_TCHF_FRAME_HR:
+ case GSM_TCHH_FRAME:
if (payload_len != 14) {
DEBUGPC(DLMUX, "received RTP half rate frame with "
"payload length != 14 (len = %d)\n",
@@ -208,20 +209,25 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data, in
return -EINVAL;
}
break;
+ case GSM_TCH_FRAME_AMR:
+ amr = 1;
+ break;
default:
DEBUGPC(DLMUX, "Forced message type %x unknown\n", msg_type);
return -EINVAL;
}
- new_msg = msgb_alloc(sizeof(struct gsm_data_frame) + payload_len,
+ new_msg = msgb_alloc(sizeof(struct gsm_data_frame) + payload_len + 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 (amr)
+ frame->data[0] = payload_len;
+ memcpy(frame->data + amr, payload, payload_len);
+ msgb_put(new_msg, sizeof(struct gsm_data_frame) + amr + payload_len);
*data = new_msg;
return 0;
@@ -269,6 +275,7 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame)
int payload_len;
int duration; /* in samples */
uint8_t dynamic_pt = 0;
+ int amr = 0;
if (rs->rx_action == RTP_RECV_L4)
dynamic_pt = rs->receive.payload_type;
@@ -293,12 +300,18 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame)
payload_len = 31;
duration = 160;
break;
- case GSM_TCHF_FRAME_HR:
+ case GSM_TCHH_FRAME:
payload_type = (dynamic_pt) ? : RTP_PT_GSM_HALF;
payload_len = 14;
duration = 160;
break;
- case GSM_TCHF_BAD_FRAME:
+ case GSM_TCH_FRAME_AMR:
+ payload_type = (dynamic_pt) ? : RTP_PT_AMR;
+ payload_len = frame->data[0];
+ duration = 160;
+ amr = 1;
+ break;
+ case GSM_BAD_FRAME:
/* in case of a bad frame, just count and drop packt */
payload_type = 0;
payload_len = 0;
@@ -342,7 +355,7 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame)
}
}
- if (frame->msg_type == GSM_TCHF_BAD_FRAME)
+ if (frame->msg_type == GSM_BAD_FRAME)
return 0;
msg = msgb_alloc(sizeof(struct rtp_hdr) + payload_len, "RTP-GSM-FULL");
@@ -359,7 +372,7 @@ 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 + amr, payload_len);
msgb_put(msg, sizeof(struct rtp_hdr) + payload_len);
msgb_enqueue(&rss->tx_queue, msg);
rss->bfd.when |= BSC_FD_WRITE;
diff --git a/openbsc/src/libtrau/trau_mux.c b/openbsc/src/libtrau/trau_mux.c
index cc33a0ca0..b7334a0fc 100644
--- a/openbsc/src/libtrau/trau_mux.c
+++ b/openbsc/src/libtrau/trau_mux.c
@@ -216,7 +216,7 @@ int trau_mux_input(struct gsm_e1_subslot *src_e1_ss,
j++;
}
if (tf.c_bits[11]) /* BFI */
- frame->msg_type = GSM_TCHF_BAD_FRAME;
+ frame->msg_type = GSM_BAD_FRAME;
else
frame->msg_type = GSM_TCHF_FRAME;
frame->callref = ue->callref;