diff options
author | Harald Welte <laforge@osmocom.org> | 2020-08-06 22:39:30 +0200 |
---|---|---|
committer | Harald Welte <laforge@osmocom.org> | 2020-10-19 13:31:40 +0200 |
commit | 8e22379d7df6ef505b8f7c75c2ef119616461a3c (patch) | |
tree | 0595cb96ed19d6ed190da0a62f7f1b00cfb38712 | |
parent | 1bc597c7523800000865dd2f1d9e85522f67eb95 (diff) |
WIP: simcom2rtp bridge, interfacing SIMcom audio over USB to RTPlaforge/simcom
Change-Id: Id3f8633fae8881c2168d61732371e65eaff140ad
-rw-r--r-- | contrib/simcom2rtp/Makefile | 11 | ||||
-rw-r--r-- | contrib/simcom2rtp/g711.c | 313 | ||||
-rw-r--r-- | contrib/simcom2rtp/g711.h | 27 | ||||
-rw-r--r-- | contrib/simcom2rtp/g711_table.c | 102 | ||||
-rw-r--r-- | contrib/simcom2rtp/g711_table.h | 14 | ||||
-rw-r--r-- | contrib/simcom2rtp/simcom2rtp.c | 218 |
6 files changed, 685 insertions, 0 deletions
diff --git a/contrib/simcom2rtp/Makefile b/contrib/simcom2rtp/Makefile new file mode 100644 index 000000000..e6b299b6e --- /dev/null +++ b/contrib/simcom2rtp/Makefile @@ -0,0 +1,11 @@ +CFLAGS:= -O2 -g -Wall $(shell pkg-config --cflags libosmocore libosmotrau) +LIBS:= $(shell pkg-config --libs libosmocore libosmotrau) + +all: osmo-simcom2rtp + +osmo-simcom2rtp: g711.o g711_table.o simcom2rtp.o + $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) + +%.o: %.c + $(CC) $(CFLAGS) -o $@ -c $^ + diff --git a/contrib/simcom2rtp/g711.c b/contrib/simcom2rtp/g711.c new file mode 100644 index 000000000..7d0a73d1b --- /dev/null +++ b/contrib/simcom2rtp/g711.c @@ -0,0 +1,313 @@ +/* + * This source code is a product of Sun Microsystems, Inc. and is provided + * for unrestricted use. Users may copy or modify this source code without + * charge. + * + * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING + * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun source code is provided with no support and without any obligation on + * the part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +/* + * December 30, 1994: + * Functions linear2alaw, linear2ulaw have been updated to correctly + * convert unquantized 16 bit values. + * Tables for direct u- to A-law and A- to u-law conversions have been + * corrected. + * Borge Lindberg, Center for PersonKommunikation, Aalborg University. + * bli@cpk.auc.dk + * + */ +/* + * Downloaded from comp.speech site in Cambridge. + * + */ + +#include "g711.h" + +/* + * g711.c + * + * u-law, A-law and linear PCM conversions. + * Source: http://www.speech.kth.se/cost250/refsys/latest/src/g711.c + */ +#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */ +#define QUANT_MASK (0xf) /* Quantization field mask. */ +#define NSEGS (8) /* Number of A-law segments. */ +#define SEG_SHIFT (4) /* Left shift for segment number. */ +#define SEG_MASK (0x70) /* Segment field mask. */ + +static short seg_aend[8] = {0x1F, 0x3F, 0x7F, 0xFF, + 0x1FF, 0x3FF, 0x7FF, 0xFFF}; +static short seg_uend[8] = {0x3F, 0x7F, 0xFF, 0x1FF, + 0x3FF, 0x7FF, 0xFFF, 0x1FFF}; + +/* copy from CCITT G.711 specifications */ +unsigned char _u2a[128] = { /* u- to A-law conversions */ + 1, 1, 2, 2, 3, 3, 4, 4, + 5, 5, 6, 6, 7, 7, 8, 8, + 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, + 25, 27, 29, 31, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, + 46, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, + 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, +/* corrected: + 81, 82, 83, 84, 85, 86, 87, 88, + should be: */ + 80, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128}; + +unsigned char _a2u[128] = { /* A- to u-law conversions */ + 1, 3, 5, 7, 9, 11, 13, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 32, 33, 33, 34, 34, 35, 35, + 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 48, 49, 49, + 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 64, + 65, 66, 67, 68, 69, 70, 71, 72, +/* corrected: + 73, 74, 75, 76, 77, 78, 79, 79, + should be: */ + 73, 74, 75, 76, 77, 78, 79, 80, + 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127}; + +static short search( + short val, + short *table, + short size) +{ + short i; + + for (i = 0; i < size; i++) { + if (val <= *table++) + return (i); + } + return (size); +} + +/* + * linear2alaw() - Convert a 16-bit linear PCM value to 8-bit A-law + * + * linear2alaw() accepts an 16-bit integer and encodes it as A-law data. + * + * Linear Input Code Compressed Code + * ------------------------ --------------- + * 0000000wxyza 000wxyz + * 0000001wxyza 001wxyz + * 000001wxyzab 010wxyz + * 00001wxyzabc 011wxyz + * 0001wxyzabcd 100wxyz + * 001wxyzabcde 101wxyz + * 01wxyzabcdef 110wxyz + * 1wxyzabcdefg 111wxyz + * + * For further information see John C. Bellamy's Digital Telephony, 1982, + * John Wiley & Sons, pps 98-111 and 472-476. + */ +unsigned char +linear2alaw(short pcm_val) /* 2's complement (16-bit range) */ +{ + short mask; + short seg; + unsigned char aval; + + pcm_val = pcm_val >> 3; + + if (pcm_val >= 0) { + mask = 0xD5; /* sign (7th) bit = 1 */ + } else { + mask = 0x55; /* sign bit = 0 */ + pcm_val = -pcm_val - 1; + } + + /* Convert the scaled magnitude to segment number. */ + seg = search(pcm_val, seg_aend, 8); + + /* Combine the sign, segment, and quantization bits. */ + + if (seg >= 8) /* out of range, return maximum value. */ + return (unsigned char) (0x7F ^ mask); + else { + aval = (unsigned char) seg << SEG_SHIFT; + if (seg < 2) + aval |= (pcm_val >> 1) & QUANT_MASK; + else + aval |= (pcm_val >> seg) & QUANT_MASK; + return (aval ^ mask); + } +} + +/* + * alaw2linear() - Convert an A-law value to 16-bit linear PCM + * + */ +short +alaw2linear( + unsigned char a_val) +{ + short t; + short seg; + + a_val ^= 0x55; + + t = (a_val & QUANT_MASK) << 4; + seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT; + switch (seg) { + case 0: + t += 8; + break; + case 1: + t += 0x108; + break; + default: + t += 0x108; + t <<= seg - 1; + } + return ((a_val & SIGN_BIT) ? t : -t); +} + +#define BIAS (0x84) /* Bias for linear code. */ +#define CLIP 8159 + +/* +* linear2ulaw() - Convert a linear PCM value to u-law +* +* In order to simplify the encoding process, the original linear magnitude +* is biased by adding 33 which shifts the encoding range from (0 - 8158) to +* (33 - 8191). The result can be seen in the following encoding table: +* +* Biased Linear Input Code Compressed Code +* ------------------------ --------------- +* 00000001wxyza 000wxyz +* 0000001wxyzab 001wxyz +* 000001wxyzabc 010wxyz +* 00001wxyzabcd 011wxyz +* 0001wxyzabcde 100wxyz +* 001wxyzabcdef 101wxyz +* 01wxyzabcdefg 110wxyz +* 1wxyzabcdefgh 111wxyz +* +* Each biased linear code has a leading 1 which identifies the segment +* number. The value of the segment number is equal to 7 minus the number +* of leading 0's. The quantization interval is directly available as the +* four bits wxyz. * The trailing bits (a - h) are ignored. +* +* Ordinarily the complement of the resulting code word is used for +* transmission, and so the code word is complemented before it is returned. +* +* For further information see John C. Bellamy's Digital Telephony, 1982, +* John Wiley & Sons, pps 98-111 and 472-476. +*/ +unsigned char +linear2ulaw( + short pcm_val) /* 2's complement (16-bit range) */ +{ + short mask; + short seg; + unsigned char uval; + + /* Get the sign and the magnitude of the value. */ + pcm_val = pcm_val >> 2; + if (pcm_val < 0) { + pcm_val = -pcm_val; + mask = 0x7F; + } else { + mask = 0xFF; + } + if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */ + pcm_val += (BIAS >> 2); + + /* Convert the scaled magnitude to segment number. */ + seg = search(pcm_val, seg_uend, 8); + + /* + * Combine the sign, segment, quantization bits; + * and complement the code word. + */ + if (seg >= 8) /* out of range, return maximum value. */ + return (unsigned char) (0x7F ^ mask); + else { + uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF); + return (uval ^ mask); + } + +} + +/* + * ulaw2linear() - Convert a u-law value to 16-bit linear PCM + * + * First, a biased linear code is derived from the code word. An unbiased + * output can then be obtained by subtracting 33 from the biased code. + * + * Note that this function expects to be passed the complement of the + * original code word. This is in keeping with ISDN conventions. + */ +short +ulaw2linear( + unsigned char u_val) +{ + short t; + + /* Complement to obtain normal u-law value. */ + u_val = ~u_val; + + /* + * Extract and bias the quantization bits. Then + * shift up by the segment number and subtract out the bias. + */ + t = ((u_val & QUANT_MASK) << 3) + BIAS; + t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT; + + return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS)); +} + +/* A-law to u-law conversion */ +unsigned char +alaw2ulaw( + unsigned char aval) +{ + aval &= 0xff; + return (unsigned char) ((aval & 0x80) ? (0xFF ^ _a2u[aval ^ 0xD5]) : + (0x7F ^ _a2u[aval ^ 0x55])); +} + +/* u-law to A-law conversion */ +unsigned char +ulaw2alaw( + unsigned char uval) +{ + uval &= 0xff; + return (unsigned char) ((uval & 0x80) ? (0xD5 ^ (_u2a[0xFF ^ uval] - 1)) : + (0x55 ^ (_u2a[0x7F ^ uval] - 1))); +} + +/* ---------- end of g711.c ----------------------------------------------------- */
\ No newline at end of file diff --git a/contrib/simcom2rtp/g711.h b/contrib/simcom2rtp/g711.h new file mode 100644 index 000000000..8bf053a0c --- /dev/null +++ b/contrib/simcom2rtp/g711.h @@ -0,0 +1,27 @@ +/* + * g711.h + * + * u-law, A-law and linear PCM conversions. + * Source: http://www.speech.kth.se/cost250/refsys/latest/src/g711.h + */ + +#ifndef _G711_H_ +#define _G711_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +unsigned char linear2alaw(short pcm_val); +short alaw2linear(unsigned char a_val); +unsigned char linear2ulaw(short pcm_val); +short ulaw2linear(unsigned char u_val); +unsigned char alaw2ulaw(unsigned char aval); +unsigned char ulaw2alaw(unsigned char uval); + +#ifdef __cplusplus +} +#endif + +#endif /* _G711_H_ */
\ No newline at end of file diff --git a/contrib/simcom2rtp/g711_table.c b/contrib/simcom2rtp/g711_table.c new file mode 100644 index 000000000..465a5705e --- /dev/null +++ b/contrib/simcom2rtp/g711_table.c @@ -0,0 +1,102 @@ +#ifndef G711_TABLE_H +#define G711_TABLE_H + +#include "g711.h" + +/* 16384 entries per table (16 bit) */ +unsigned char linear_to_alaw[65536]; +unsigned char linear_to_ulaw[65536]; + +/* 16384 entries per table (8 bit) */ +unsigned short alaw_to_linear[256]; +unsigned short ulaw_to_linear[256]; + +static void build_linear_to_xlaw_table(unsigned char *linear_to_xlaw, + unsigned char (*linear2xlaw)(short)) +{ + int i; + + for (i=0; i<65536;i++){ + linear_to_xlaw[i] = linear2xlaw((short) i); + } +} + +static void build_xlaw_to_linear_table(unsigned short *xlaw_to_linear, + short (*xlaw2linear)(unsigned char)) +{ + int i; + + for (i=0; i<256;i++){ + xlaw_to_linear[i] = (unsigned short) xlaw2linear(i); + } +} + +static void pcm16_to_xlaw(unsigned char *linear_to_xlaw, int src_length, const char *src_samples, char *dst_samples) +{ + int i; + const unsigned short *s_samples; + + s_samples = (const unsigned short *)src_samples; + + for (i=0; i < src_length / 2; i++) + { + dst_samples[i] = linear_to_xlaw[s_samples[i]]; + } +} + +static void xlaw_to_pcm16(unsigned short *xlaw_to_linear, int src_length, const char *src_samples, char *dst_samples) +{ + int i; + unsigned char *s_samples; + unsigned short *d_samples; + + s_samples = (unsigned char *) src_samples; + d_samples = (unsigned short *)dst_samples; + + for (i=0; i < src_length; i++) + { + d_samples[i] = xlaw_to_linear[s_samples[i]]; + } +} + +void pcm16_to_alaw(int src_length, const char *src_samples, char *dst_samples) +{ + pcm16_to_xlaw(linear_to_alaw, src_length, src_samples, dst_samples); +} + +void pcm16_to_ulaw(int src_length, const char *src_samples, char *dst_samples) +{ + pcm16_to_xlaw(linear_to_ulaw, src_length, src_samples, dst_samples); +} + +void alaw_to_pcm16(int src_length, const char *src_samples, char *dst_samples) +{ + xlaw_to_pcm16(alaw_to_linear, src_length, src_samples, dst_samples); +} + +void ulaw_to_pcm16(int src_length, const char *src_samples, char *dst_samples) +{ + xlaw_to_pcm16(ulaw_to_linear, src_length, src_samples, dst_samples); +} + +void pcm16_alaw_tableinit() +{ + build_linear_to_xlaw_table(linear_to_alaw, linear2alaw); +} + +void pcm16_ulaw_tableinit() +{ + build_linear_to_xlaw_table(linear_to_ulaw, linear2ulaw); +} + +void alaw_pcm16_tableinit() +{ + build_xlaw_to_linear_table(alaw_to_linear, alaw2linear); +} + +void ulaw_pcm16_tableinit() +{ + build_xlaw_to_linear_table(ulaw_to_linear, ulaw2linear); +} + +#endif // G711_TABLE_H diff --git a/contrib/simcom2rtp/g711_table.h b/contrib/simcom2rtp/g711_table.h new file mode 100644 index 000000000..2557c3b8b --- /dev/null +++ b/contrib/simcom2rtp/g711_table.h @@ -0,0 +1,14 @@ +#ifndef G711_TABLE_H +#define G711_TABLE_H + +void pcm16_to_alaw(int length, const char *src_samples, char *dst_samples); +void pcm16_to_ulaw(int length, const char *src_samples, char *dst_samples); +void alaw_to_pcm16(int length, const char *src_samples, char *dst_samples); +void ulaw_to_pcm16(int length, const char *src_samples, char *dst_samples); + +void pcm16_alaw_tableinit(); +void pcm16_ulaw_tableinit(); +void alaw_pcm16_tableinit(); +void ulaw_pcm16_tableinit(); + +#endif // G711_TABLE_H
\ No newline at end of file diff --git a/contrib/simcom2rtp/simcom2rtp.c b/contrib/simcom2rtp/simcom2rtp.c new file mode 100644 index 000000000..08291e243 --- /dev/null +++ b/contrib/simcom2rtp/simcom2rtp.c @@ -0,0 +1,218 @@ +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <errno.h> +#include <limits.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> + + +#include <osmocom/core/select.h> +#include <osmocom/core/msgb.h> +#include <osmocom/core/fsm.h> +#include <osmocom/core/logging.h> +#include <osmocom/core/application.h> +#include <osmocom/core/serial.h> + +#include <osmocom/trau/osmo_ortp.h> + +#include "g711.h" + +#define RTP_PT_PCMU 0 +#define RTP_PT_PCMA 8 + +struct modem_state { + struct osmo_fd data_fd; + struct osmo_rtp_socket *rtp; + /* queue of linear PCM audio in RTP -> modem direction */ + struct llist_head rtp2modem; + /* message buffer used if samples insufficient for next RTP frame were received */ + struct msgb *modem2rtp; +}; + +static void *g_tall_ctx; + + +/* call-back on received RTP data */ +static void ortp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *payload, + unsigned int payload_len, uint16_t seq_nr, uint32_t timestamp, bool marker) +{ + /* we received a RTP frame */ + struct modem_state *ms = rs->priv; + struct msgb *msg = msgb_alloc(payload_len*2, "RTP Rx"); + unsigned int i; + int16_t *out; + + OSMO_ASSERT(msg); + + out = (int16_t *) msgb_put(msg, payload_len*2); + + if (payload_len != 160) { + fprintf(stderr, "RTP payload length %d != 160, dropping\n", payload_len); + msgb_free(msg); + return; + } + + /* convert from Alaw to linear PCM (160 -> 320 bytes) */ + for (i = 0; i < payload_len; i++) + out[i] = alaw2linear(payload[i]); + + /* append to the write queue */ + msgb_enqueue(&ms->rtp2modem, msg); + ms->data_fd.when |= OSMO_FD_WRITE; +} + +static void modem2rtp(struct modem_state *ms, const uint8_t *data, unsigned int len) +{ + const int16_t *data16 = (const int16_t *)data; + unsigned int samples = len / 2; + unsigned int offset = 0; + unsigned int i; + + /* samples are always 16bit, we cannot read half a sample */ + OSMO_ASSERT((len & 1) == 0); + + /* first complete any pending incomplete RTP frame */ + if (ms->modem2rtp) { + struct msgb *msg = ms->modem2rtp; + unsigned int missing_samples = 160 - msgb_length(msg); + for (i = 0; i < missing_samples; i++) { + if (i >= samples) + break; + msgb_put_u8(msg, linear2alaw(data16[i])); + } + offset = i; + if (msgb_length(msg) == 160) { + osmo_rtp_send_frame_ext(ms->rtp, msgb_data(msg), msgb_length(msg), 160, false); + msgb_free(msg); + } + } + + /* then send as many RTP frames as we have samples */ + for (offset = offset; offset + 160 <= samples; offset += 160) { + uint8_t buf[160]; + for (i = 0; i < sizeof(buf); i++) + buf[i] = linear2alaw(data16[offset + i]); + osmo_rtp_send_frame_ext(ms->rtp, buf, sizeof(buf), 160, false); + } + + /* store remainder in msgb */ + if (offset < samples) { + struct msgb *msg = msgb_alloc_c(ms, 160, "modem2rtp"); + OSMO_ASSERT(msg); + OSMO_ASSERT(len - offset < 160); + for (i = 0; i < len - offset; i++) + msgb_put_u8(msg, linear2alaw(data16[offset + i])); + ms->modem2rtp = msg; + } +} + + +/* call back on file descriptor events of the modem DATA ttyUSB device */ +static int modem_data_fd_cb(struct osmo_fd *ofd, unsigned int what) +{ + struct modem_state *ms = ofd->data; + int rc; + + if (what & OSMO_FD_READ) { + /* SIM5360 USB AUDIO Application Note v1.01 states 1600 bytes every 100ms */ + uint8_t rx_buf[1600]; + rc = read(ofd->fd, rx_buf, sizeof(rx_buf)); + OSMO_ASSERT(rc > 0); + modem2rtp(ms, rx_buf, rc); + } + + if (what & OSMO_FD_WRITE) { + struct msgb *msg = msgb_dequeue(&ms->rtp2modem); + if (!msg) + ofd->when &= ~OSMO_FD_WRITE; + else { + /* SIM5300 USB AUDIO Application Note v1.01 states 640 bytes every 40ms; + * we simply write every RTP frame individually (320 bytes every 20ms) */ + rc = write(ofd->fd, msgb_data(msg), msgb_length(msg)); + if (rc != msgb_length(msg)) + fprintf(stderr, "Short write: %d < %u\n", rc, msgb_length(msg)); + msgb_free(msg); + } + } + + return 0; +} + + +static int modem_data_open(struct modem_state *ms, const char *basepath) +{ + char fname[PATH_MAX+1]; + int fd; + + /* the assumption is that the caller provides something like + * "/dev/serial/by-path/pci-0000:00:14.0-usb-0:2:1" */ + snprintf(fname, sizeof(fname), "%s.0-port0", basepath); + + fd = osmo_serial_init(fname, 921600); + if (fd < 0) { + fprintf(stderr, "failed to open device '%s': %s\n", fname, strerror(errno)); + return -1; + } + osmo_fd_setup(&ms->data_fd, fd, OSMO_FD_READ, modem_data_fd_cb, ms, 0); + osmo_fd_register(&ms->data_fd); + + return 0; +} + +static struct modem_state *modem_create(void *ctx) +{ + struct modem_state *ms = talloc_zero(ctx, struct modem_state); + int rc; + + INIT_LLIST_HEAD(&ms->rtp2modem); + + ms->rtp = osmo_rtp_socket_create(ms, 0); + OSMO_ASSERT(ms->rtp); + osmo_rtp_socket_set_pt(ms->rtp, RTP_PT_PCMA); + ms->rtp->priv = ms; + ms->rtp->rx_cb = ortp_rx_cb; + + rc = osmo_rtp_socket_bind(ms->rtp, "0.0.0.0", 1111); + OSMO_ASSERT(rc == 0); + + rc = osmo_rtp_socket_connect(ms->rtp, "127.0.0.1", 2222); + //rc = osmo_rtp_socket_autoconnect(ms->rtp); + OSMO_ASSERT(rc == 0); + + osmo_rtp_set_source_desc(ms->rtp, "cname", "simcom2rtp", NULL, NULL, NULL, + "osmo-simcom2rtp", NULL); + + return ms; +} + + + + +int main(int argc, char **argv) +{ + + talloc_enable_null_tracking(); + g_tall_ctx = talloc_named_const(NULL, 1, "simcom2rtp"); + + msgb_talloc_ctx_init(g_tall_ctx, 0); + osmo_init_logging2(g_tall_ctx, NULL); + osmo_fsm_log_timeouts(true); + osmo_fsm_log_addr(true); + //osmo_stats_init(g_tall_ctx); + osmo_rtp_init(g_tall_ctx); + + struct modem_state *ms = modem_create(g_tall_ctx); + int rc; + + OSMO_ASSERT(ms); + rc = modem_data_open(ms, "/dev/serial/by-path/pci-0000:00:14.0-usb-0:2:1"); + OSMO_ASSERT(rc == 0); + + while (1) { + osmo_select_main(0); + } + +} |