blob: aee73048cc200dbc7fe05d6ffca51d0c84bb7bbb [file] [log] [blame]
Jacob Erlbeck136a3192014-03-13 14:33:37 +01001#include <stdlib.h>
2#include <unistd.h>
3#include <stdio.h>
4#include <string.h>
5#include <err.h>
6
7#include <osmocom/core/talloc.h>
8#include <osmocom/core/application.h>
9
10#include <openbsc/debug.h>
11#include <openbsc/gsm_data.h>
12#include <openbsc/mgcp.h>
13#include <openbsc/mgcp_internal.h>
14
15#include "bscconfig.h"
16#ifndef BUILD_MGCP_TRANSCODING
17#error "Requires MGCP transcoding enabled (see --enable-mgcp-transcoding)"
18#endif
19
20#include "src/osmo-bsc_mgcp/mgcp_transcode.h"
21
22static int audio_name_to_type(const char *name)
23{
24 if (!strcasecmp(name, "gsm"))
25 return 3;
26#ifdef HAVE_BCG729
27 else if (!strcasecmp(name, "g729"))
28 return 18;
29#endif
30 else if (!strcasecmp(name, "pcma"))
31 return 8;
32 else if (!strcasecmp(name, "l16"))
33 return 11;
34 return -1;
35}
36
37int mgcp_get_trans_frame_size(void *state_, int nsamples, int dst);
38
39int main(int argc, char **argv)
40{
Jacob Erlbeck42a833e2014-04-14 10:31:47 +020041 char buf[4096] = {0x80, 0};
Jacob Erlbeck136a3192014-03-13 14:33:37 +010042 int cc, rc;
Jacob Erlbeck42a833e2014-04-14 10:31:47 +020043 struct mgcp_rtp_end *dst_end;
44 struct mgcp_rtp_end *src_end;
Jacob Erlbeck136a3192014-03-13 14:33:37 +010045 struct mgcp_trunk_config tcfg = {{0}};
46 struct mgcp_endpoint endp = {0};
47 struct mgcp_process_rtp_state *state;
48 int in_size;
49
50 osmo_init_logging(&log_info);
51
52 tcfg.endpoints = &endp;
53 tcfg.number_endpoints = 1;
54 endp.tcfg = &tcfg;
Jacob Erlbeck42a833e2014-04-14 10:31:47 +020055 mgcp_free_endp(&endp);
56
57 dst_end = &endp.bts_end;
58 src_end = &endp.net_end;
Jacob Erlbeck136a3192014-03-13 14:33:37 +010059
60 if (argc <= 2)
61 errx(1, "Usage: {gsm|g729|pcma|l16} {gsm|g729|pcma|l16}");
62
Jacob Erlbeck42a833e2014-04-14 10:31:47 +020063 if ((src_end->payload_type = audio_name_to_type(argv[1])) == -1)
Jacob Erlbeck136a3192014-03-13 14:33:37 +010064 errx(1, "invalid input format '%s'", argv[1]);
Jacob Erlbeck42a833e2014-04-14 10:31:47 +020065 if ((dst_end->payload_type = audio_name_to_type(argv[2])) == -1)
Jacob Erlbeck136a3192014-03-13 14:33:37 +010066 errx(1, "invalid output format '%s'", argv[2]);
67
Jacob Erlbeck42a833e2014-04-14 10:31:47 +020068 rc = mgcp_transcoding_setup(&endp, dst_end, src_end);
Jacob Erlbeck136a3192014-03-13 14:33:37 +010069 if (rc < 0)
70 errx(1, "setup failed: %s", strerror(-rc));
71
Jacob Erlbeck42a833e2014-04-14 10:31:47 +020072 state = dst_end->rtp_process_data;
Jacob Erlbeck136a3192014-03-13 14:33:37 +010073 OSMO_ASSERT(state != NULL);
74
75 in_size = mgcp_transcoding_get_frame_size(state, 160, 0);
76 OSMO_ASSERT(sizeof(buf) >= in_size + 12);
77
Jacob Erlbeck42a833e2014-04-14 10:31:47 +020078 buf[1] = src_end->payload_type;
79 *(uint16_t*)(buf+2) = htons(1);
80 *(uint32_t*)(buf+4) = htonl(0);
81 *(uint32_t*)(buf+8) = htonl(0xaabbccdd);
82
Jacob Erlbeck136a3192014-03-13 14:33:37 +010083 while ((cc = read(0, buf + 12, in_size))) {
Jacob Erlbeck42a833e2014-04-14 10:31:47 +020084 int cont;
85 int len;
86
Jacob Erlbeck136a3192014-03-13 14:33:37 +010087 if (cc != in_size)
88 err(1, "read");
89
90 cc += 12; /* include RTP header */
91
Jacob Erlbeck42a833e2014-04-14 10:31:47 +020092 len = cc;
Jacob Erlbeck136a3192014-03-13 14:33:37 +010093
Jacob Erlbeck42a833e2014-04-14 10:31:47 +020094 do {
95 cont = mgcp_transcoding_process_rtp(&endp, dst_end,
96 buf, &len, sizeof(buf));
97 if (cont == -EAGAIN) {
98 fprintf(stderr, "Got EAGAIN\n");
99 break;
100 }
101
102 if (cont < 0)
103 errx(1, "processing failed: %s", strerror(-cont));
104
105 len -= 12; /* ignore RTP header */
106
107 if (write(1, buf + 12, len) != len)
108 err(1, "write");
109
110 len = cont;
111 } while (len > 0);
Jacob Erlbeck136a3192014-03-13 14:33:37 +0100112 }
113 return 0;
114}
115