Add support for AMR frames to MNCC/RTP interface
AMR rate is currently fixed to 5.9k.
This commit is contained in:
parent
72c0dbd753
commit
d8967f76a5
|
@ -2965,6 +2965,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) {
|
||||
|
|
|
@ -192,21 +192,41 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data)
|
|||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case RTP_PT_AMR:
|
||||
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");
|
||||
if (payload_len > 33) {
|
||||
DEBUGPC(DLMUX, "RTP payload too large (%d octets)\n",
|
||||
payload_len);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (rtph->payload_type == RTP_PT_AMR) {
|
||||
new_msg = msgb_alloc(sizeof(struct gsm_data_frame) + 1
|
||||
+ payload_len, "GSM-DATA (AMR)");
|
||||
} else {
|
||||
new_msg = msgb_alloc(sizeof(struct gsm_data_frame)
|
||||
+ payload_len, "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 (rtph->payload_type == RTP_PT_AMR) {
|
||||
frame->data[0] = payload_len;
|
||||
msgb_put(new_msg, sizeof(struct gsm_data_frame) + 1
|
||||
+ payload_len);
|
||||
memcpy(frame->data + 1, payload, payload_len);
|
||||
} else {
|
||||
msgb_put(new_msg, sizeof(struct gsm_data_frame) + payload_len);
|
||||
memcpy(frame->data, payload, payload_len);
|
||||
}
|
||||
|
||||
*data = new_msg;
|
||||
return 0;
|
||||
|
@ -264,6 +284,11 @@ 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;
|
||||
break;
|
||||
default:
|
||||
DEBUGPC(DLMUX, "unsupported message type %d\n",
|
||||
frame->msg_type);
|
||||
|
@ -291,7 +316,18 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame)
|
|||
}
|
||||
}
|
||||
|
||||
msg = msgb_alloc(sizeof(struct rtp_hdr) + payload_len, "RTP-GSM-FULL");
|
||||
if (payload_len > 33) {
|
||||
DEBUGPC(DLMUX, "RTP payload too large (%d octets)\n",
|
||||
payload_len);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (frame->msg_type == GSM_TCH_FRAME_AMR)
|
||||
msg = msgb_alloc(sizeof(struct rtp_hdr) + payload_len,
|
||||
"RTP-GSM (AMR)");
|
||||
else
|
||||
msg = msgb_alloc(sizeof(struct rtp_hdr) + payload_len,
|
||||
"RTP-GSM");
|
||||
if (!msg)
|
||||
return -ENOMEM;
|
||||
rtph = (struct rtp_hdr *)msg->data;
|
||||
|
@ -305,7 +341,12 @@ 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);
|
||||
if (frame->msg_type == GSM_TCH_FRAME_AMR)
|
||||
memcpy(msg->data + sizeof(struct rtp_hdr), frame->data + 1,
|
||||
payload_len);
|
||||
else
|
||||
memcpy(msg->data + sizeof(struct rtp_hdr), frame->data,
|
||||
payload_len);
|
||||
msgb_put(msg, sizeof(struct rtp_hdr) + payload_len);
|
||||
msgb_enqueue(&rss->tx_queue, msg);
|
||||
rss->bfd.when |= BSC_FD_WRITE;
|
||||
|
|
Loading…
Reference in New Issue