blob: 6c95c5542d434d703cd94d672d9e077e2ac2069b [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
Jacob Erlbeck909fac62014-05-08 14:08:37 +020020#include "openbsc/mgcp_transcode.h"
Jacob Erlbeck136a3192014-03-13 14:33:37 +010021
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;
Jacob Erlbeck07886d92014-04-14 11:30:45 +020049 int in_samples = 160;
50 int out_samples = 0;
51 uint32_t ts = 0;
52 uint16_t seq = 0;
Jacob Erlbeck136a3192014-03-13 14:33:37 +010053
54 osmo_init_logging(&log_info);
55
56 tcfg.endpoints = &endp;
57 tcfg.number_endpoints = 1;
58 endp.tcfg = &tcfg;
Holger Hans Peter Freythercb6ad702014-07-22 15:00:52 +020059 mgcp_initialize_endp(&endp);
Jacob Erlbeck42a833e2014-04-14 10:31:47 +020060
61 dst_end = &endp.bts_end;
62 src_end = &endp.net_end;
Jacob Erlbeck136a3192014-03-13 14:33:37 +010063
64 if (argc <= 2)
Jacob Erlbeck07886d92014-04-14 11:30:45 +020065 errx(1, "Usage: {gsm|g729|pcma|l16} {gsm|g729|pcma|l16} [SPP]");
Jacob Erlbeck136a3192014-03-13 14:33:37 +010066
Holger Hans Peter Freythercac24382014-09-01 10:35:55 +020067 if ((src_end->codec.payload_type = audio_name_to_type(argv[1])) == -1)
Jacob Erlbeck136a3192014-03-13 14:33:37 +010068 errx(1, "invalid input format '%s'", argv[1]);
Holger Hans Peter Freythercac24382014-09-01 10:35:55 +020069 if ((dst_end->codec.payload_type = audio_name_to_type(argv[2])) == -1)
Jacob Erlbeck136a3192014-03-13 14:33:37 +010070 errx(1, "invalid output format '%s'", argv[2]);
Jacob Erlbeck07886d92014-04-14 11:30:45 +020071 if (argc > 3)
72 out_samples = atoi(argv[3]);
73
74 if (out_samples) {
Holger Hans Peter Freythercac24382014-09-01 10:35:55 +020075 dst_end->codec.frame_duration_den = dst_end->codec.rate;
76 dst_end->codec.frame_duration_num = out_samples;
Jacob Erlbeck07886d92014-04-14 11:30:45 +020077 dst_end->frames_per_packet = 1;
78 }
Jacob Erlbeck136a3192014-03-13 14:33:37 +010079
Jacob Erlbeck42a833e2014-04-14 10:31:47 +020080 rc = mgcp_transcoding_setup(&endp, dst_end, src_end);
Jacob Erlbeck136a3192014-03-13 14:33:37 +010081 if (rc < 0)
82 errx(1, "setup failed: %s", strerror(-rc));
83
Jacob Erlbeck42a833e2014-04-14 10:31:47 +020084 state = dst_end->rtp_process_data;
Jacob Erlbeck136a3192014-03-13 14:33:37 +010085 OSMO_ASSERT(state != NULL);
86
Jacob Erlbeck07886d92014-04-14 11:30:45 +020087 in_size = mgcp_transcoding_get_frame_size(state, in_samples, 0);
Jacob Erlbeck136a3192014-03-13 14:33:37 +010088 OSMO_ASSERT(sizeof(buf) >= in_size + 12);
89
Holger Hans Peter Freythercac24382014-09-01 10:35:55 +020090 buf[1] = src_end->codec.payload_type;
Jacob Erlbeck42a833e2014-04-14 10:31:47 +020091 *(uint16_t*)(buf+2) = htons(1);
92 *(uint32_t*)(buf+4) = htonl(0);
93 *(uint32_t*)(buf+8) = htonl(0xaabbccdd);
94
Jacob Erlbeck136a3192014-03-13 14:33:37 +010095 while ((cc = read(0, buf + 12, in_size))) {
Jacob Erlbeck42a833e2014-04-14 10:31:47 +020096 int cont;
97 int len;
98
Jacob Erlbeck136a3192014-03-13 14:33:37 +010099 if (cc != in_size)
100 err(1, "read");
101
Jacob Erlbeck07886d92014-04-14 11:30:45 +0200102 *(uint16_t*)(buf+2) = htonl(seq);
103 *(uint32_t*)(buf+4) = htonl(ts);
104
105 seq += 1;
106 ts += in_samples;
107
Jacob Erlbeck136a3192014-03-13 14:33:37 +0100108 cc += 12; /* include RTP header */
109
Jacob Erlbeck42a833e2014-04-14 10:31:47 +0200110 len = cc;
Jacob Erlbeck136a3192014-03-13 14:33:37 +0100111
Jacob Erlbeck42a833e2014-04-14 10:31:47 +0200112 do {
113 cont = mgcp_transcoding_process_rtp(&endp, dst_end,
Jacob Erlbeck07886d92014-04-14 11:30:45 +0200114 buf, &len, sizeof(buf));
Jacob Erlbeck42a833e2014-04-14 10:31:47 +0200115 if (cont == -EAGAIN) {
116 fprintf(stderr, "Got EAGAIN\n");
117 break;
118 }
119
120 if (cont < 0)
121 errx(1, "processing failed: %s", strerror(-cont));
122
123 len -= 12; /* ignore RTP header */
124
125 if (write(1, buf + 12, len) != len)
126 err(1, "write");
127
128 len = cont;
129 } while (len > 0);
Jacob Erlbeck136a3192014-03-13 14:33:37 +0100130 }
131 return 0;
132}
133