mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-bsc.git
synced 2025-11-02 05:03:23 +00:00
This is the first step in creating this repository from the legacy openbsc.git. Like all other Osmocom repositories, keep the autoconf and automake files in the repository root. openbsc.git has been the sole exception, which ends now. Change-Id: I9c6f2a448d9cb1cc088cf1cf6918b69d7e69b4e7
134 lines
2.9 KiB
C
134 lines
2.9 KiB
C
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <err.h>
|
|
|
|
#include <osmocom/core/talloc.h>
|
|
#include <osmocom/core/application.h>
|
|
|
|
#include <openbsc/debug.h>
|
|
#include <openbsc/gsm_data.h>
|
|
#include <openbsc/mgcp.h>
|
|
#include <openbsc/mgcp_internal.h>
|
|
|
|
#include "bscconfig.h"
|
|
#ifndef BUILD_MGCP_TRANSCODING
|
|
#error "Requires MGCP transcoding enabled (see --enable-mgcp-transcoding)"
|
|
#endif
|
|
|
|
#include "openbsc/mgcp_transcode.h"
|
|
|
|
static int audio_name_to_type(const char *name)
|
|
{
|
|
if (!strcasecmp(name, "gsm"))
|
|
return 3;
|
|
#ifdef HAVE_BCG729
|
|
else if (!strcasecmp(name, "g729"))
|
|
return 18;
|
|
#endif
|
|
else if (!strcasecmp(name, "pcma"))
|
|
return 8;
|
|
else if (!strcasecmp(name, "l16"))
|
|
return 11;
|
|
return -1;
|
|
}
|
|
|
|
int mgcp_get_trans_frame_size(void *state_, int nsamples, int dst);
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
char buf[4096] = {0x80, 0};
|
|
int cc, rc;
|
|
struct mgcp_rtp_end *dst_end;
|
|
struct mgcp_rtp_end *src_end;
|
|
struct mgcp_trunk_config tcfg = {{0}};
|
|
struct mgcp_endpoint endp = {0};
|
|
struct mgcp_process_rtp_state *state;
|
|
int in_size;
|
|
int in_samples = 160;
|
|
int out_samples = 0;
|
|
uint32_t ts = 0;
|
|
uint16_t seq = 0;
|
|
|
|
osmo_init_logging(&log_info);
|
|
|
|
tcfg.endpoints = &endp;
|
|
tcfg.number_endpoints = 1;
|
|
endp.tcfg = &tcfg;
|
|
mgcp_initialize_endp(&endp);
|
|
|
|
dst_end = &endp.bts_end;
|
|
src_end = &endp.net_end;
|
|
|
|
if (argc <= 2)
|
|
errx(1, "Usage: {gsm|g729|pcma|l16} {gsm|g729|pcma|l16} [SPP]");
|
|
|
|
if ((src_end->codec.payload_type = audio_name_to_type(argv[1])) == -1)
|
|
errx(1, "invalid input format '%s'", argv[1]);
|
|
if ((dst_end->codec.payload_type = audio_name_to_type(argv[2])) == -1)
|
|
errx(1, "invalid output format '%s'", argv[2]);
|
|
if (argc > 3)
|
|
out_samples = atoi(argv[3]);
|
|
|
|
if (out_samples) {
|
|
dst_end->codec.frame_duration_den = dst_end->codec.rate;
|
|
dst_end->codec.frame_duration_num = out_samples;
|
|
dst_end->frames_per_packet = 1;
|
|
}
|
|
|
|
rc = mgcp_transcoding_setup(&endp, dst_end, src_end);
|
|
if (rc < 0)
|
|
errx(1, "setup failed: %s", strerror(-rc));
|
|
|
|
state = dst_end->rtp_process_data;
|
|
OSMO_ASSERT(state != NULL);
|
|
|
|
in_size = mgcp_transcoding_get_frame_size(state, in_samples, 0);
|
|
OSMO_ASSERT(sizeof(buf) >= in_size + 12);
|
|
|
|
buf[1] = src_end->codec.payload_type;
|
|
*(uint16_t*)(buf+2) = htons(1);
|
|
*(uint32_t*)(buf+4) = htonl(0);
|
|
*(uint32_t*)(buf+8) = htonl(0xaabbccdd);
|
|
|
|
while ((cc = read(0, buf + 12, in_size))) {
|
|
int cont;
|
|
int len;
|
|
|
|
if (cc != in_size)
|
|
err(1, "read");
|
|
|
|
*(uint16_t*)(buf+2) = htonl(seq);
|
|
*(uint32_t*)(buf+4) = htonl(ts);
|
|
|
|
seq += 1;
|
|
ts += in_samples;
|
|
|
|
cc += 12; /* include RTP header */
|
|
|
|
len = cc;
|
|
|
|
do {
|
|
cont = mgcp_transcoding_process_rtp(&endp, dst_end,
|
|
buf, &len, sizeof(buf));
|
|
if (cont == -EAGAIN) {
|
|
fprintf(stderr, "Got EAGAIN\n");
|
|
break;
|
|
}
|
|
|
|
if (cont < 0)
|
|
errx(1, "processing failed: %s", strerror(-cont));
|
|
|
|
len -= 12; /* ignore RTP header */
|
|
|
|
if (write(1, buf + 12, len) != len)
|
|
err(1, "write");
|
|
|
|
len = cont;
|
|
} while (len > 0);
|
|
}
|
|
return 0;
|
|
}
|
|
|