Add libselect to use select instead of polling all file descriptors
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -32,6 +32,7 @@ src/libsquelch/libsquelch.a
|
|||||||
src/libhagelbarger/libhagelbarger.a
|
src/libhagelbarger/libhagelbarger.a
|
||||||
src/libdtmf/libdtmf.a
|
src/libdtmf/libdtmf.a
|
||||||
src/libtimer/libtimer.a
|
src/libtimer/libtimer.a
|
||||||
|
src/libselect/libselect.a
|
||||||
src/libsamplerate/libsamplerate.a
|
src/libsamplerate/libsamplerate.a
|
||||||
src/libscrambler/libscrambler.a
|
src/libscrambler/libscrambler.a
|
||||||
src/libemphasis/libemphasis.a
|
src/libemphasis/libemphasis.a
|
||||||
|
@@ -74,6 +74,7 @@ AC_OUTPUT(
|
|||||||
src/libhagelbarger/Makefile
|
src/libhagelbarger/Makefile
|
||||||
src/libdtmf/Makefile
|
src/libdtmf/Makefile
|
||||||
src/libtimer/Makefile
|
src/libtimer/Makefile
|
||||||
|
src/libselect/Makefile
|
||||||
src/libsamplerate/Makefile
|
src/libsamplerate/Makefile
|
||||||
src/libscrambler/Makefile
|
src/libscrambler/Makefile
|
||||||
src/libemphasis/Makefile
|
src/libemphasis/Makefile
|
||||||
|
@@ -15,6 +15,7 @@ SUBDIRS = \
|
|||||||
libhagelbarger \
|
libhagelbarger \
|
||||||
libdtmf \
|
libdtmf \
|
||||||
libtimer \
|
libtimer \
|
||||||
|
libselect \
|
||||||
libsamplerate \
|
libsamplerate \
|
||||||
libscrambler \
|
libscrambler \
|
||||||
libemphasis \
|
libemphasis \
|
||||||
|
@@ -38,6 +38,7 @@ amps_LDADD = \
|
|||||||
$(top_builddir)/src/libgoertzel/libgoertzel.a \
|
$(top_builddir)/src/libgoertzel/libgoertzel.a \
|
||||||
$(top_builddir)/src/libjitter/libjitter.a \
|
$(top_builddir)/src/libjitter/libjitter.a \
|
||||||
$(top_builddir)/src/libtimer/libtimer.a \
|
$(top_builddir)/src/libtimer/libtimer.a \
|
||||||
|
$(top_builddir)/src/libselect/libselect.a \
|
||||||
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
||||||
$(top_builddir)/src/libemphasis/libemphasis.a \
|
$(top_builddir)/src/libemphasis/libemphasis.a \
|
||||||
$(top_builddir)/src/libfm/libfm.a \
|
$(top_builddir)/src/libfm/libfm.a \
|
||||||
@@ -82,6 +83,7 @@ tacs_LDADD = \
|
|||||||
$(top_builddir)/src/libgoertzel/libgoertzel.a \
|
$(top_builddir)/src/libgoertzel/libgoertzel.a \
|
||||||
$(top_builddir)/src/libjitter/libjitter.a \
|
$(top_builddir)/src/libjitter/libjitter.a \
|
||||||
$(top_builddir)/src/libtimer/libtimer.a \
|
$(top_builddir)/src/libtimer/libtimer.a \
|
||||||
|
$(top_builddir)/src/libselect/libselect.a \
|
||||||
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
||||||
$(top_builddir)/src/libemphasis/libemphasis.a \
|
$(top_builddir)/src/libemphasis/libemphasis.a \
|
||||||
$(top_builddir)/src/libfm/libfm.a \
|
$(top_builddir)/src/libfm/libfm.a \
|
||||||
@@ -125,6 +127,7 @@ jtacs_LDADD = \
|
|||||||
$(top_builddir)/src/libgoertzel/libgoertzel.a \
|
$(top_builddir)/src/libgoertzel/libgoertzel.a \
|
||||||
$(top_builddir)/src/libjitter/libjitter.a \
|
$(top_builddir)/src/libjitter/libjitter.a \
|
||||||
$(top_builddir)/src/libtimer/libtimer.a \
|
$(top_builddir)/src/libtimer/libtimer.a \
|
||||||
|
$(top_builddir)/src/libselect/libselect.a \
|
||||||
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
||||||
$(top_builddir)/src/libemphasis/libemphasis.a \
|
$(top_builddir)/src/libemphasis/libemphasis.a \
|
||||||
$(top_builddir)/src/libfm/libfm.a \
|
$(top_builddir)/src/libfm/libfm.a \
|
||||||
|
@@ -27,6 +27,7 @@ anetz_LDADD = \
|
|||||||
$(top_builddir)/src/libjitter/libjitter.a \
|
$(top_builddir)/src/libjitter/libjitter.a \
|
||||||
$(top_builddir)/src/libsquelch/libsquelch.a \
|
$(top_builddir)/src/libsquelch/libsquelch.a \
|
||||||
$(top_builddir)/src/libtimer/libtimer.a \
|
$(top_builddir)/src/libtimer/libtimer.a \
|
||||||
|
$(top_builddir)/src/libselect/libselect.a \
|
||||||
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
||||||
$(top_builddir)/src/libemphasis/libemphasis.a \
|
$(top_builddir)/src/libemphasis/libemphasis.a \
|
||||||
$(top_builddir)/src/libfm/libfm.a \
|
$(top_builddir)/src/libfm/libfm.a \
|
||||||
|
@@ -23,6 +23,7 @@ bnetz_LDADD = \
|
|||||||
$(top_builddir)/src/libjitter/libjitter.a \
|
$(top_builddir)/src/libjitter/libjitter.a \
|
||||||
$(top_builddir)/src/libsquelch/libsquelch.a \
|
$(top_builddir)/src/libsquelch/libsquelch.a \
|
||||||
$(top_builddir)/src/libtimer/libtimer.a \
|
$(top_builddir)/src/libtimer/libtimer.a \
|
||||||
|
$(top_builddir)/src/libselect/libselect.a \
|
||||||
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
||||||
$(top_builddir)/src/libemphasis/libemphasis.a \
|
$(top_builddir)/src/libemphasis/libemphasis.a \
|
||||||
$(top_builddir)/src/libfsk/libfsk.a \
|
$(top_builddir)/src/libfsk/libfsk.a \
|
||||||
|
@@ -31,6 +31,7 @@ cnetz_LDADD = \
|
|||||||
$(top_builddir)/src/libcompandor/libcompandor.a \
|
$(top_builddir)/src/libcompandor/libcompandor.a \
|
||||||
$(top_builddir)/src/libjitter/libjitter.a \
|
$(top_builddir)/src/libjitter/libjitter.a \
|
||||||
$(top_builddir)/src/libtimer/libtimer.a \
|
$(top_builddir)/src/libtimer/libtimer.a \
|
||||||
|
$(top_builddir)/src/libselect/libselect.a \
|
||||||
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
||||||
$(top_builddir)/src/libscrambler/libscrambler.a \
|
$(top_builddir)/src/libscrambler/libscrambler.a \
|
||||||
$(top_builddir)/src/libemphasis/libemphasis.a \
|
$(top_builddir)/src/libemphasis/libemphasis.a \
|
||||||
|
@@ -22,6 +22,7 @@ eurosignal_LDADD = \
|
|||||||
$(top_builddir)/src/libdisplay/libdisplay.a \
|
$(top_builddir)/src/libdisplay/libdisplay.a \
|
||||||
$(top_builddir)/src/libjitter/libjitter.a \
|
$(top_builddir)/src/libjitter/libjitter.a \
|
||||||
$(top_builddir)/src/libtimer/libtimer.a \
|
$(top_builddir)/src/libtimer/libtimer.a \
|
||||||
|
$(top_builddir)/src/libselect/libselect.a \
|
||||||
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
||||||
$(top_builddir)/src/libemphasis/libemphasis.a \
|
$(top_builddir)/src/libemphasis/libemphasis.a \
|
||||||
$(top_builddir)/src/libfsk/libfsk.a \
|
$(top_builddir)/src/libfsk/libfsk.a \
|
||||||
|
@@ -19,6 +19,7 @@ bin_PROGRAMS = \
|
|||||||
$(top_builddir)/src/libgoertzel/libgoertzel.a \
|
$(top_builddir)/src/libgoertzel/libgoertzel.a \
|
||||||
$(top_builddir)/src/libjitter/libjitter.a \
|
$(top_builddir)/src/libjitter/libjitter.a \
|
||||||
$(top_builddir)/src/libtimer/libtimer.a \
|
$(top_builddir)/src/libtimer/libtimer.a \
|
||||||
|
$(top_builddir)/src/libselect/libselect.a \
|
||||||
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
||||||
$(top_builddir)/src/libemphasis/libemphasis.a \
|
$(top_builddir)/src/libemphasis/libemphasis.a \
|
||||||
$(top_builddir)/src/libfm/libfm.a \
|
$(top_builddir)/src/libfm/libfm.a \
|
||||||
|
@@ -22,6 +22,7 @@ fuvst_LDADD = \
|
|||||||
$(top_builddir)/src/libcompandor/libcompandor.a \
|
$(top_builddir)/src/libcompandor/libcompandor.a \
|
||||||
$(top_builddir)/src/libjitter/libjitter.a \
|
$(top_builddir)/src/libjitter/libjitter.a \
|
||||||
$(top_builddir)/src/libtimer/libtimer.a \
|
$(top_builddir)/src/libtimer/libtimer.a \
|
||||||
|
$(top_builddir)/src/libselect/libselect.a \
|
||||||
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
||||||
$(top_builddir)/src/libemphasis/libemphasis.a \
|
$(top_builddir)/src/libemphasis/libemphasis.a \
|
||||||
$(top_builddir)/src/libfm/libfm.a \
|
$(top_builddir)/src/libfm/libfm.a \
|
||||||
@@ -48,6 +49,7 @@ fuvst_sniffer_LDADD = \
|
|||||||
$(top_builddir)/src/libcompandor/libcompandor.a \
|
$(top_builddir)/src/libcompandor/libcompandor.a \
|
||||||
$(top_builddir)/src/libjitter/libjitter.a \
|
$(top_builddir)/src/libjitter/libjitter.a \
|
||||||
$(top_builddir)/src/libtimer/libtimer.a \
|
$(top_builddir)/src/libtimer/libtimer.a \
|
||||||
|
$(top_builddir)/src/libselect/libselect.a \
|
||||||
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
||||||
$(top_builddir)/src/libemphasis/libemphasis.a \
|
$(top_builddir)/src/libemphasis/libemphasis.a \
|
||||||
$(top_builddir)/src/libfm/libfm.a \
|
$(top_builddir)/src/libfm/libfm.a \
|
||||||
|
@@ -18,6 +18,7 @@ golay_LDADD = \
|
|||||||
$(top_builddir)/src/libdisplay/libdisplay.a \
|
$(top_builddir)/src/libdisplay/libdisplay.a \
|
||||||
$(top_builddir)/src/libjitter/libjitter.a \
|
$(top_builddir)/src/libjitter/libjitter.a \
|
||||||
$(top_builddir)/src/libtimer/libtimer.a \
|
$(top_builddir)/src/libtimer/libtimer.a \
|
||||||
|
$(top_builddir)/src/libselect/libselect.a \
|
||||||
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
||||||
$(top_builddir)/src/libemphasis/libemphasis.a \
|
$(top_builddir)/src/libemphasis/libemphasis.a \
|
||||||
$(top_builddir)/src/libfm/libfm.a \
|
$(top_builddir)/src/libfm/libfm.a \
|
||||||
|
@@ -20,6 +20,7 @@ imts_LDADD = \
|
|||||||
$(top_builddir)/src/libjitter/libjitter.a \
|
$(top_builddir)/src/libjitter/libjitter.a \
|
||||||
$(top_builddir)/src/libsquelch/libsquelch.a \
|
$(top_builddir)/src/libsquelch/libsquelch.a \
|
||||||
$(top_builddir)/src/libtimer/libtimer.a \
|
$(top_builddir)/src/libtimer/libtimer.a \
|
||||||
|
$(top_builddir)/src/libselect/libselect.a \
|
||||||
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
||||||
$(top_builddir)/src/libemphasis/libemphasis.a \
|
$(top_builddir)/src/libemphasis/libemphasis.a \
|
||||||
$(top_builddir)/src/libfm/libfm.a \
|
$(top_builddir)/src/libfm/libfm.a \
|
||||||
|
@@ -20,6 +20,7 @@ jollycom_LDADD = \
|
|||||||
$(top_builddir)/src/libsquelch/libsquelch.a \
|
$(top_builddir)/src/libsquelch/libsquelch.a \
|
||||||
$(top_builddir)/src/libdtmf/libdtmf.a \
|
$(top_builddir)/src/libdtmf/libdtmf.a \
|
||||||
$(top_builddir)/src/libtimer/libtimer.a \
|
$(top_builddir)/src/libtimer/libtimer.a \
|
||||||
|
$(top_builddir)/src/libselect/libselect.a \
|
||||||
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
||||||
$(top_builddir)/src/libemphasis/libemphasis.a \
|
$(top_builddir)/src/libemphasis/libemphasis.a \
|
||||||
$(top_builddir)/src/libfilter/libfilter.a \
|
$(top_builddir)/src/libfilter/libfilter.a \
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
#include "../libsample/sample.h"
|
#include "../libsample/sample.h"
|
||||||
#include "../libdebug/debug.h"
|
#include "../libdebug/debug.h"
|
||||||
#include "../libtimer/timer.h"
|
#include "../libtimer/timer.h"
|
||||||
|
#include "../libselect/select.h"
|
||||||
#include "../libosmocc/endpoint.h"
|
#include "../libosmocc/endpoint.h"
|
||||||
#include "../libosmocc/helper.h"
|
#include "../libosmocc/helper.h"
|
||||||
#include "../libg711/g711.h"
|
#include "../libg711/g711.h"
|
||||||
@@ -929,14 +930,3 @@ int call_handle(void)
|
|||||||
return osmo_cc_handle();
|
return osmo_cc_handle();
|
||||||
}
|
}
|
||||||
|
|
||||||
void call_media_handle(void)
|
|
||||||
{
|
|
||||||
process_t *process = process_head;
|
|
||||||
|
|
||||||
while(process) {
|
|
||||||
if (process->session)
|
|
||||||
osmo_cc_session_handle(process->session, process);
|
|
||||||
process = process->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@@ -29,6 +29,7 @@
|
|||||||
#include "../libjitter/jitter.h"
|
#include "../libjitter/jitter.h"
|
||||||
#include "../libdebug/debug.h"
|
#include "../libdebug/debug.h"
|
||||||
#include "../libtimer/timer.h"
|
#include "../libtimer/timer.h"
|
||||||
|
#include "../libselect/select.h"
|
||||||
#include "../libosmocc/endpoint.h"
|
#include "../libosmocc/endpoint.h"
|
||||||
#include "../libosmocc/helper.h"
|
#include "../libosmocc/helper.h"
|
||||||
#include "testton.h"
|
#include "testton.h"
|
||||||
@@ -568,9 +569,6 @@ void process_console(int c)
|
|||||||
if (!console.loopback && console.number_max_length)
|
if (!console.loopback && console.number_max_length)
|
||||||
process_ui(c);
|
process_ui(c);
|
||||||
|
|
||||||
if (console.session)
|
|
||||||
osmo_cc_session_handle(console.session, &console);
|
|
||||||
|
|
||||||
if (!console.sound)
|
if (!console.sound)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@@ -32,6 +32,7 @@
|
|||||||
#include "../libdebug/debug.h"
|
#include "../libdebug/debug.h"
|
||||||
#include "sender.h"
|
#include "sender.h"
|
||||||
#include "../libtimer/timer.h"
|
#include "../libtimer/timer.h"
|
||||||
|
#include "../libselect/select.h"
|
||||||
#include "call.h"
|
#include "call.h"
|
||||||
#include "../libosmocc/endpoint.h"
|
#include "../libosmocc/endpoint.h"
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
@@ -711,6 +712,7 @@ void main_mobile_loop(const char *name, int *quit, void (*myhandler)(void), cons
|
|||||||
*quit = 1;
|
*quit = 1;
|
||||||
|
|
||||||
while(!(*quit)) {
|
while(!(*quit)) {
|
||||||
|
int work;
|
||||||
begin_time = get_time();
|
begin_time = get_time();
|
||||||
|
|
||||||
/* process sound of all transceivers */
|
/* process sound of all transceivers */
|
||||||
@@ -803,9 +805,14 @@ next_char:
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* process call control */
|
/* handle all handlers until no more events */
|
||||||
call_media_handle();
|
do {
|
||||||
while (call_handle());
|
work = 0;
|
||||||
|
work |= osmo_cc_handle();
|
||||||
|
work |= (process_timer() == 0.0);
|
||||||
|
work |= osmo_fd_select(0.0);
|
||||||
|
} while (work);
|
||||||
|
|
||||||
if (!use_osmocc_sock)
|
if (!use_osmocc_sock)
|
||||||
process_console(c);
|
process_console(c);
|
||||||
|
|
||||||
|
@@ -24,6 +24,7 @@
|
|||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "../libtimer/timer.h"
|
#include "../libtimer/timer.h"
|
||||||
|
#include "../libselect/select.h"
|
||||||
#include "../libdebug/debug.h"
|
#include "../libdebug/debug.h"
|
||||||
#include "endpoint.h"
|
#include "endpoint.h"
|
||||||
|
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include "../libtimer/timer.h"
|
#include "../libtimer/timer.h"
|
||||||
|
#include "../libselect/select.h"
|
||||||
#include "../libdebug/debug.h"
|
#include "../libdebug/debug.h"
|
||||||
#include "endpoint.h"
|
#include "endpoint.h"
|
||||||
#include "helper.h"
|
#include "helper.h"
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include "../libdebug/debug.h"
|
#include "../libdebug/debug.h"
|
||||||
#include "../libtimer/timer.h"
|
#include "../libtimer/timer.h"
|
||||||
|
#include "../libselect/select.h"
|
||||||
#include "endpoint.h"
|
#include "endpoint.h"
|
||||||
|
|
||||||
#define RTP_VERSION 2
|
#define RTP_VERSION 2
|
||||||
@@ -132,6 +133,22 @@ static int rtp_receive(int sock, uint8_t **payload_p, int *payload_len_p, uint8_
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int rtcp_receive(int sock)
|
||||||
|
{
|
||||||
|
static uint8_t data[2048];
|
||||||
|
int len;
|
||||||
|
|
||||||
|
len = read(sock, data, sizeof(data));
|
||||||
|
if (len < 0) {
|
||||||
|
if (errno == EAGAIN)
|
||||||
|
return -EAGAIN;
|
||||||
|
PDEBUG(DCC, DEBUG_DEBUG, "Read errno = %d (%s)\n", errno, strerror(errno));
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void rtp_send(int sock, uint8_t *payload, int payload_len, uint8_t marker, uint8_t pt, uint16_t sequence, uint32_t timestamp, uint32_t ssrc)
|
static void rtp_send(int sock, uint8_t *payload, int payload_len, uint8_t marker, uint8_t pt, uint16_t sequence, uint32_t timestamp, uint32_t ssrc)
|
||||||
{
|
{
|
||||||
struct rtp_hdr *rtph;
|
struct rtp_hdr *rtph;
|
||||||
@@ -157,6 +174,9 @@ static void rtp_send(int sock, uint8_t *payload, int payload_len, uint8_t marker
|
|||||||
PDEBUG(DCC, DEBUG_DEBUG, "Write errno = %d (%s)\n", errno, strerror(errno));
|
PDEBUG(DCC, DEBUG_DEBUG, "Write errno = %d (%s)\n", errno, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int rtp_listen_cb(struct osmo_fd *ofd, unsigned int when);
|
||||||
|
static int rtcp_listen_cb(struct osmo_fd *ofd, unsigned int when);
|
||||||
|
|
||||||
/* open and bind RTP
|
/* open and bind RTP
|
||||||
* set local port to what we bound
|
* set local port to what we bound
|
||||||
*/
|
*/
|
||||||
@@ -221,15 +241,23 @@ socket_error:
|
|||||||
osmo_cc_rtp_close(media);
|
osmo_cc_rtp_close(media);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
media->rtp_socket = rc;
|
media->rtp_ofd.fd = rc;
|
||||||
|
media->rtp_ofd.cb = rtp_listen_cb;
|
||||||
|
media->rtp_ofd.data = media;
|
||||||
|
media->rtp_ofd.when = OSMO_FD_READ;
|
||||||
|
osmo_fd_register(&media->rtp_ofd);
|
||||||
rc = socket(domain, SOCK_DGRAM, IPPROTO_UDP);
|
rc = socket(domain, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
goto socket_error;
|
goto socket_error;
|
||||||
media->rtcp_socket = rc;
|
media->rtcp_ofd.fd = rc;
|
||||||
|
media->rtcp_ofd.cb = rtcp_listen_cb;
|
||||||
|
media->rtcp_ofd.data = media;
|
||||||
|
media->rtcp_ofd.when = OSMO_FD_READ;
|
||||||
|
osmo_fd_register(&media->rtcp_ofd);
|
||||||
|
|
||||||
/* bind sockets */
|
/* bind sockets */
|
||||||
*sport = htons(conf->rtp_port_next);
|
*sport = htons(conf->rtp_port_next);
|
||||||
rc = bind(media->rtp_socket, (struct sockaddr *)&sa, slen);
|
rc = bind(media->rtp_ofd.fd, (struct sockaddr *)&sa, slen);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
bind_error:
|
bind_error:
|
||||||
osmo_cc_rtp_close(media);
|
osmo_cc_rtp_close(media);
|
||||||
@@ -241,18 +269,18 @@ bind_error:
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
*sport = htons(conf->rtp_port_next + 1);
|
*sport = htons(conf->rtp_port_next + 1);
|
||||||
rc = bind(media->rtcp_socket, (struct sockaddr *)&sa, slen);
|
rc = bind(media->rtcp_ofd.fd, (struct sockaddr *)&sa, slen);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
goto bind_error;
|
goto bind_error;
|
||||||
media->description.port_local = conf->rtp_port_next;
|
media->description.port_local = conf->rtp_port_next;
|
||||||
conf->rtp_port_next = (conf->rtp_port_next + 2 > conf->rtp_port_to) ? conf->rtp_port_from : conf->rtp_port_next + 2;
|
conf->rtp_port_next = (conf->rtp_port_next + 2 > conf->rtp_port_to) ? conf->rtp_port_from : conf->rtp_port_next + 2;
|
||||||
/* set nonblocking io */
|
/* set nonblocking io, to prevent write to block */
|
||||||
flags = fcntl(media->rtp_socket, F_GETFL);
|
flags = fcntl(media->rtp_ofd.fd, F_GETFL);
|
||||||
flags |= O_NONBLOCK;
|
flags |= O_NONBLOCK;
|
||||||
fcntl(media->rtp_socket, F_SETFL, flags);
|
fcntl(media->rtp_ofd.fd, F_SETFL, flags);
|
||||||
flags = fcntl(media->rtcp_socket, F_GETFL);
|
flags = fcntl(media->rtcp_ofd.fd, F_GETFL);
|
||||||
flags |= O_NONBLOCK;
|
flags |= O_NONBLOCK;
|
||||||
fcntl(media->rtcp_socket, F_SETFL, flags);
|
fcntl(media->rtcp_ofd.fd, F_SETFL, flags);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,7 +333,7 @@ pton_error:
|
|||||||
}
|
}
|
||||||
|
|
||||||
*sport = htons(media->description.port_remote);
|
*sport = htons(media->description.port_remote);
|
||||||
rc = connect(media->rtp_socket, (struct sockaddr *)&sa, slen);
|
rc = connect(media->rtp_ofd.fd, (struct sockaddr *)&sa, slen);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
connect_error:
|
connect_error:
|
||||||
PDEBUG(DCC, DEBUG_NOTICE, "Cannot connect to address '%s'.\n", media->connection_data_remote.address);
|
PDEBUG(DCC, DEBUG_NOTICE, "Cannot connect to address '%s'.\n", media->connection_data_remote.address);
|
||||||
@@ -313,7 +341,7 @@ connect_error:
|
|||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
*sport = htons(media->description.port_remote + 1);
|
*sport = htons(media->description.port_remote + 1);
|
||||||
rc = connect(media->rtcp_socket, (struct sockaddr *)&sa, slen);
|
rc = connect(media->rtcp_ofd.fd, (struct sockaddr *)&sa, slen);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
goto connect_error;
|
goto connect_error;
|
||||||
|
|
||||||
@@ -326,7 +354,7 @@ void osmo_cc_rtp_send(osmo_cc_session_codec_t *codec, uint8_t *data, int len, ui
|
|||||||
uint8_t *payload = NULL;
|
uint8_t *payload = NULL;
|
||||||
int payload_len = 0;
|
int payload_len = 0;
|
||||||
|
|
||||||
if (!codec || !codec->media->rtp_socket)
|
if (!codec || !codec->media->rtp_ofd.fd)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (codec->encoder)
|
if (codec->encoder)
|
||||||
@@ -336,7 +364,7 @@ void osmo_cc_rtp_send(osmo_cc_session_codec_t *codec, uint8_t *data, int len, ui
|
|||||||
payload_len = len;
|
payload_len = len;
|
||||||
}
|
}
|
||||||
|
|
||||||
rtp_send(codec->media->rtp_socket, payload, payload_len, marker, codec->payload_type_remote, codec->media->tx_sequence, codec->media->tx_timestamp, codec->media->tx_ssrc);
|
rtp_send(codec->media->rtp_ofd.fd, payload, payload_len, marker, codec->payload_type_remote, codec->media->tx_sequence, codec->media->tx_timestamp, codec->media->tx_ssrc);
|
||||||
codec->media->tx_sequence += inc_sequence;
|
codec->media->tx_sequence += inc_sequence;
|
||||||
codec->media->tx_timestamp += inc_timestamp;
|
codec->media->tx_timestamp += inc_timestamp;
|
||||||
|
|
||||||
@@ -344,9 +372,9 @@ void osmo_cc_rtp_send(osmo_cc_session_codec_t *codec, uint8_t *data, int len, ui
|
|||||||
free(payload);
|
free(payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* receive rtp data for given media, return < 0, if there is nothing this time */
|
static int rtp_listen_cb(struct osmo_fd *ofd, unsigned int when)
|
||||||
int osmo_cc_rtp_receive(osmo_cc_session_media_t *media, void *priv)
|
|
||||||
{
|
{
|
||||||
|
osmo_cc_session_media_t *media = ofd->data;
|
||||||
int rc;
|
int rc;
|
||||||
uint8_t *payload = NULL;
|
uint8_t *payload = NULL;
|
||||||
int payload_len = 0;
|
int payload_len = 0;
|
||||||
@@ -356,49 +384,63 @@ int osmo_cc_rtp_receive(osmo_cc_session_media_t *media, void *priv)
|
|||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
if (!media || media->rtp_socket <= 0)
|
if (when & OSMO_FD_READ) {
|
||||||
return -EIO;
|
rc = rtp_receive(media->rtp_ofd.fd, &payload, &payload_len, &marker, &payload_type, &media->rx_sequence, &media->rx_timestamp, &media->rx_ssrc);
|
||||||
|
if (rc < 0)
|
||||||
|
return rc;
|
||||||
|
|
||||||
rc = rtp_receive(media->rtp_socket, &payload, &payload_len, &marker, &payload_type, &media->rx_sequence, &media->rx_timestamp, &media->rx_ssrc);
|
/* search for codec */
|
||||||
if (rc < 0)
|
for (codec = media->codec_list; codec; codec = codec->next) {
|
||||||
return rc;
|
if (codec->payload_type_local == payload_type)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!codec) {
|
||||||
|
PDEBUG(DCC, DEBUG_NOTICE, "Received RTP frame for unknown codec (payload_type = %d).\n", payload_type);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* search for codec */
|
if (codec->decoder)
|
||||||
for (codec = media->codec_list; codec; codec = codec->next) {
|
codec->decoder(payload, payload_len, &data, &len, media->session->priv);
|
||||||
|
else {
|
||||||
|
data = payload;
|
||||||
|
len = payload_len;
|
||||||
|
}
|
||||||
|
|
||||||
if (codec->payload_type_local == payload_type)
|
if (codec->media->receive)
|
||||||
break;
|
codec->media->receiver(codec, marker, media->rx_sequence, media->rx_timestamp, media->rx_ssrc, data, len);
|
||||||
}
|
|
||||||
if (!codec) {
|
if (codec->decoder)
|
||||||
PDEBUG(DCC, DEBUG_NOTICE, "Received RTP frame for unknown codec (payload_type = %d).\n", payload_type);
|
free(data);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (codec->decoder)
|
return 0;
|
||||||
codec->decoder(payload, payload_len, &data, &len, priv);
|
}
|
||||||
else {
|
|
||||||
data = payload;
|
static int rtcp_listen_cb(struct osmo_fd *ofd, unsigned int when)
|
||||||
len = payload_len;
|
{
|
||||||
|
osmo_cc_session_media_t *media = ofd->data;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (when & OSMO_FD_READ) {
|
||||||
|
rc = rtcp_receive(media->rtp_ofd.fd);
|
||||||
|
if (rc < 0)
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (codec->media->receive)
|
|
||||||
codec->media->receiver(codec, marker, media->rx_sequence, media->rx_timestamp, media->rx_ssrc, data, len);
|
|
||||||
|
|
||||||
if (codec->decoder)
|
|
||||||
free(data);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void osmo_cc_rtp_close(osmo_cc_session_media_t *media)
|
void osmo_cc_rtp_close(osmo_cc_session_media_t *media)
|
||||||
{
|
{
|
||||||
if (media->rtp_socket) {
|
if (media->rtp_ofd.fd) {
|
||||||
close(media->rtp_socket);
|
osmo_fd_unregister(&media->rtp_ofd);
|
||||||
media->rtp_socket = 0;
|
close(media->rtp_ofd.fd);
|
||||||
|
media->rtp_ofd.fd = 0;
|
||||||
}
|
}
|
||||||
if (media->rtcp_socket) {
|
if (media->rtcp_ofd.fd) {
|
||||||
close(media->rtcp_socket);
|
osmo_fd_unregister(&media->rtcp_ofd);
|
||||||
media->rtcp_socket = 0;
|
close(media->rtcp_ofd.fd);
|
||||||
|
media->rtcp_ofd.fd = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -3,6 +3,5 @@ void osmo_cc_set_rtp_ports(osmo_cc_session_config_t *conf, uint16_t from, uint16
|
|||||||
int osmo_cc_rtp_open(osmo_cc_session_media_t *media);
|
int osmo_cc_rtp_open(osmo_cc_session_media_t *media);
|
||||||
int osmo_cc_rtp_connect(osmo_cc_session_media_t *media);
|
int osmo_cc_rtp_connect(osmo_cc_session_media_t *media);
|
||||||
void osmo_cc_rtp_send(osmo_cc_session_codec_t *codec, uint8_t *data, int len, uint8_t marker, int inc_sequence, int inc_timestamp, void *priv);
|
void osmo_cc_rtp_send(osmo_cc_session_codec_t *codec, uint8_t *data, int len, uint8_t marker, int inc_sequence, int inc_timestamp, void *priv);
|
||||||
int osmo_cc_rtp_receive(osmo_cc_session_media_t *media, void *priv);
|
|
||||||
void osmo_cc_rtp_close(osmo_cc_session_media_t *media);
|
void osmo_cc_rtp_close(osmo_cc_session_media_t *media);
|
||||||
|
|
||||||
|
@@ -24,6 +24,7 @@
|
|||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "../libtimer/timer.h"
|
#include "../libtimer/timer.h"
|
||||||
|
#include "../libselect/select.h"
|
||||||
#include "../libdebug/debug.h"
|
#include "../libdebug/debug.h"
|
||||||
#include "endpoint.h"
|
#include "endpoint.h"
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "../libdebug/debug.h"
|
#include "../libdebug/debug.h"
|
||||||
#include "../libtimer/timer.h"
|
#include "../libtimer/timer.h"
|
||||||
|
#include "../libselect/select.h"
|
||||||
#include "endpoint.h"
|
#include "endpoint.h"
|
||||||
#include "sdp.h"
|
#include "sdp.h"
|
||||||
|
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include "../libtimer/timer.h"
|
#include "../libtimer/timer.h"
|
||||||
|
#include "../libselect/select.h"
|
||||||
#include "../libdebug/debug.h"
|
#include "../libdebug/debug.h"
|
||||||
#include "../liboptions/options.h"
|
#include "../liboptions/options.h"
|
||||||
#include "endpoint.h"
|
#include "endpoint.h"
|
||||||
@@ -622,19 +623,3 @@ int osmo_cc_session_if_codec(osmo_cc_session_codec_t *codec, const char *name, u
|
|||||||
&& codec->payload_channels == channels);
|
&& codec->payload_channels == channels);
|
||||||
}
|
}
|
||||||
|
|
||||||
int osmo_cc_session_handle(osmo_cc_session_t *session, void *codec_priv)
|
|
||||||
{
|
|
||||||
osmo_cc_session_media_t *media;
|
|
||||||
int w = 0, rc;
|
|
||||||
|
|
||||||
osmo_cc_session_for_each_media(session->media_list, media) {
|
|
||||||
do {
|
|
||||||
rc = osmo_cc_rtp_receive(media, codec_priv);
|
|
||||||
if (rc >= 0)
|
|
||||||
w = 1;
|
|
||||||
} while (rc >= 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return w;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@@ -80,8 +80,8 @@ typedef struct osmo_cc_session_media {
|
|||||||
struct osmo_cc_session_codec *codec_list;
|
struct osmo_cc_session_codec *codec_list;
|
||||||
int send, receive;
|
int send, receive;
|
||||||
void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len);
|
void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len);
|
||||||
int rtp_socket;
|
struct osmo_fd rtp_ofd;
|
||||||
int rtcp_socket;
|
struct osmo_fd rtcp_ofd;
|
||||||
uint32_t tx_ssrc, rx_ssrc;
|
uint32_t tx_ssrc, rx_ssrc;
|
||||||
uint16_t tx_sequence, rx_sequence;
|
uint16_t tx_sequence, rx_sequence;
|
||||||
uint32_t tx_timestamp, rx_timestamp;
|
uint32_t tx_timestamp, rx_timestamp;
|
||||||
@@ -126,5 +126,4 @@ const char *osmo_cc_session_addrtype2string(enum osmo_cc_session_addrtype addrty
|
|||||||
const char *osmo_cc_session_media_type2string(enum osmo_cc_session_media_type media_type);
|
const char *osmo_cc_session_media_type2string(enum osmo_cc_session_media_type media_type);
|
||||||
const char *osmo_cc_session_media_proto2string(enum osmo_cc_session_media_proto media_proto);
|
const char *osmo_cc_session_media_proto2string(enum osmo_cc_session_media_proto media_proto);
|
||||||
int osmo_cc_session_if_codec(osmo_cc_session_codec_t *codec, const char *name, uint32_t rate, int channels);
|
int osmo_cc_session_if_codec(osmo_cc_session_codec_t *codec, const char *name, uint32_t rate, int channels);
|
||||||
int osmo_cc_session_handle(osmo_cc_session_t *session, void *codec_priv);
|
|
||||||
|
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include "../libdebug/debug.h"
|
#include "../libdebug/debug.h"
|
||||||
#include "../libtimer/timer.h"
|
#include "../libtimer/timer.h"
|
||||||
|
#include "../libselect/select.h"
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
#include "cause.h"
|
#include "cause.h"
|
||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
@@ -101,12 +102,14 @@ static void rx_keepalive_timeout(void *data)
|
|||||||
close_conn(conn, OSMO_CC_SOCKET_CAUSE_TIMEOUT);
|
close_conn(conn, OSMO_CC_SOCKET_CAUSE_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int socket_listen_cb(struct osmo_fd *ofd, unsigned int when);
|
||||||
|
|
||||||
/* create socket process and bind socket */
|
/* create socket process and bind socket */
|
||||||
int osmo_cc_open_socket(osmo_cc_socket_t *os, const char *host, uint16_t port, void *priv, void (*recv_msg_cb)(void *priv, uint32_t callref, osmo_cc_msg_t *msg), uint8_t location)
|
int osmo_cc_open_socket(osmo_cc_socket_t *os, const char *host, uint16_t port, void *priv, void (*recv_msg_cb)(void *priv, uint32_t callref, osmo_cc_msg_t *msg), uint8_t location)
|
||||||
{
|
{
|
||||||
int try = 0, auto_port = 0;
|
int try = 0, auto_port = 0;
|
||||||
struct addrinfo *result, *rp;
|
struct addrinfo *result, *rp;
|
||||||
int rc, sock, flags;
|
int rc, sock;
|
||||||
|
|
||||||
memset(os, 0, sizeof(*os));
|
memset(os, 0, sizeof(*os));
|
||||||
|
|
||||||
@@ -148,15 +151,16 @@ try_again:
|
|||||||
rc = listen(sock, 10);
|
rc = listen(sock, 10);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
PDEBUG(DCC, DEBUG_ERROR, "Failed to listen on socket.\n");
|
PDEBUG(DCC, DEBUG_ERROR, "Failed to listen on socket.\n");
|
||||||
|
close(sock);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set nonblocking io */
|
/* register */
|
||||||
flags = fcntl(sock, F_GETFL);
|
os->ofd.fd = sock;
|
||||||
flags |= O_NONBLOCK;
|
os->ofd.cb = socket_listen_cb;
|
||||||
fcntl(sock, F_SETFL, flags);
|
os->ofd.data = os;
|
||||||
|
os->ofd.when = OSMO_FD_READ;
|
||||||
os->socket = sock;
|
osmo_fd_register(&os->ofd);
|
||||||
os->recv_msg_cb = recv_msg_cb;
|
os->recv_msg_cb = recv_msg_cb;
|
||||||
os->priv = priv;
|
os->priv = priv;
|
||||||
os->location = location;
|
os->location = location;
|
||||||
@@ -164,6 +168,8 @@ try_again:
|
|||||||
return port;
|
return port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int socket_conn_cb(struct osmo_fd *ofd, unsigned int when);
|
||||||
|
|
||||||
/* create a connection */
|
/* create a connection */
|
||||||
static osmo_cc_conn_t *open_conn(osmo_cc_socket_t *os, int sock, uint32_t callref, int read_setup)
|
static osmo_cc_conn_t *open_conn(osmo_cc_socket_t *os, int sock, uint32_t callref, int read_setup)
|
||||||
{
|
{
|
||||||
@@ -176,7 +182,11 @@ static osmo_cc_conn_t *open_conn(osmo_cc_socket_t *os, int sock, uint32_t callre
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
conn->os = os;
|
conn->os = os;
|
||||||
conn->socket = sock;
|
conn->ofd.fd = sock;
|
||||||
|
conn->ofd.cb = socket_conn_cb;
|
||||||
|
conn->ofd.data = conn;
|
||||||
|
conn->ofd.when = OSMO_FD_READ;
|
||||||
|
osmo_fd_register(&conn->ofd);
|
||||||
conn->read_version = 1;
|
conn->read_version = 1;
|
||||||
conn->write_version = 1;
|
conn->write_version = 1;
|
||||||
conn->read_setup = read_setup;
|
conn->read_setup = read_setup;
|
||||||
@@ -221,8 +231,10 @@ static void close_conn(osmo_cc_conn_t *conn, uint8_t socket_cause)
|
|||||||
PDEBUG(DCC, DEBUG_DEBUG, "Destroy socket connection (callref %d).\n", conn->callref);
|
PDEBUG(DCC, DEBUG_DEBUG, "Destroy socket connection (callref %d).\n", conn->callref);
|
||||||
|
|
||||||
/* close socket */
|
/* close socket */
|
||||||
if (conn->socket)
|
if (conn->ofd.fd) {
|
||||||
close(conn->socket);
|
osmo_fd_unregister(&conn->ofd);
|
||||||
|
close(conn->ofd.fd);
|
||||||
|
}
|
||||||
/* free partly received message */
|
/* free partly received message */
|
||||||
if (conn->read_msg)
|
if (conn->read_msg)
|
||||||
osmo_cc_free_msg(conn->read_msg);
|
osmo_cc_free_msg(conn->read_msg);
|
||||||
@@ -250,9 +262,10 @@ void osmo_cc_close_socket(osmo_cc_socket_t *os)
|
|||||||
while (os->conn_list)
|
while (os->conn_list)
|
||||||
close_conn(os->conn_list, 0);
|
close_conn(os->conn_list, 0);
|
||||||
/* close socket */
|
/* close socket */
|
||||||
if (os->socket > 0) {
|
if (os->ofd.fd > 0) {
|
||||||
close(os->socket);
|
osmo_fd_unregister(&os->ofd);
|
||||||
os->socket = 0;
|
close(os->ofd.fd);
|
||||||
|
os->ofd.fd = 0;
|
||||||
}
|
}
|
||||||
/* free send queue */
|
/* free send queue */
|
||||||
while ((ml = os->write_list)) {
|
while ((ml = os->write_list)) {
|
||||||
@@ -293,7 +306,7 @@ static int receive_conn(osmo_cc_conn_t *conn)
|
|||||||
|
|
||||||
/* get version from remote */
|
/* get version from remote */
|
||||||
if (conn->read_version) {
|
if (conn->read_version) {
|
||||||
rc = recv(conn->socket, conn->read_version_string + conn->read_version_pos, strlen(version_string) - conn->read_version_pos, 0);
|
rc = recv(conn->ofd.fd, conn->read_version_string + conn->read_version_pos, strlen(version_string) - conn->read_version_pos, 0);
|
||||||
if (rc < 0 && errno == EAGAIN)
|
if (rc < 0 && errno == EAGAIN)
|
||||||
return work;
|
return work;
|
||||||
work = 1;
|
work = 1;
|
||||||
@@ -320,7 +333,7 @@ static int receive_conn(osmo_cc_conn_t *conn)
|
|||||||
try_next_message:
|
try_next_message:
|
||||||
/* read message header from remote */
|
/* read message header from remote */
|
||||||
if (!conn->read_msg) {
|
if (!conn->read_msg) {
|
||||||
rc = recv(conn->socket, ((uint8_t *)&conn->read_hdr) + conn->read_pos, sizeof(conn->read_hdr) - conn->read_pos, 0);
|
rc = recv(conn->ofd.fd, ((uint8_t *)&conn->read_hdr) + conn->read_pos, sizeof(conn->read_hdr) - conn->read_pos, 0);
|
||||||
if (rc < 0 && errno == EAGAIN)
|
if (rc < 0 && errno == EAGAIN)
|
||||||
return work;
|
return work;
|
||||||
work = 1;
|
work = 1;
|
||||||
@@ -344,7 +357,7 @@ try_next_message:
|
|||||||
len = ntohs(msg->length_networkorder);
|
len = ntohs(msg->length_networkorder);
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
goto empty_message;
|
goto empty_message;
|
||||||
rc = recv(conn->socket, msg->data + conn->read_pos, len - conn->read_pos, 0);
|
rc = recv(conn->ofd.fd, msg->data + conn->read_pos, len - conn->read_pos, 0);
|
||||||
if (rc < 0 && errno == EAGAIN)
|
if (rc < 0 && errno == EAGAIN)
|
||||||
return work;
|
return work;
|
||||||
work = 1;
|
work = 1;
|
||||||
@@ -397,7 +410,7 @@ static int transmit_conn(osmo_cc_conn_t *conn)
|
|||||||
|
|
||||||
/* send socket version to remote */
|
/* send socket version to remote */
|
||||||
if (conn->write_version) {
|
if (conn->write_version) {
|
||||||
rc = write(conn->socket, version_string, strlen(version_string));
|
rc = write(conn->ofd.fd, version_string, strlen(version_string));
|
||||||
if (rc < 0 && errno == EAGAIN)
|
if (rc < 0 && errno == EAGAIN)
|
||||||
return work;
|
return work;
|
||||||
work = 1;
|
work = 1;
|
||||||
@@ -416,7 +429,7 @@ static int transmit_conn(osmo_cc_conn_t *conn)
|
|||||||
timer_stop(&conn->tx_keepalive_timer);
|
timer_stop(&conn->tx_keepalive_timer);
|
||||||
msg = conn->write_list->msg;
|
msg = conn->write_list->msg;
|
||||||
len = sizeof(*msg) + ntohs(msg->length_networkorder);
|
len = sizeof(*msg) + ntohs(msg->length_networkorder);
|
||||||
rc = write(conn->socket, msg, len);
|
rc = write(conn->ofd.fd, msg, len);
|
||||||
if (rc < 0 && errno == EAGAIN)
|
if (rc < 0 && errno == EAGAIN)
|
||||||
return work;
|
return work;
|
||||||
work = 1;
|
work = 1;
|
||||||
@@ -460,8 +473,6 @@ close:
|
|||||||
*/
|
*/
|
||||||
int osmo_cc_handle_socket(osmo_cc_socket_t *os)
|
int osmo_cc_handle_socket(osmo_cc_socket_t *os)
|
||||||
{
|
{
|
||||||
struct sockaddr_storage sa;
|
|
||||||
socklen_t slen = sizeof(sa);
|
|
||||||
int sock;
|
int sock;
|
||||||
osmo_cc_conn_t *conn;
|
osmo_cc_conn_t *conn;
|
||||||
osmo_cc_msg_list_t *ml, **mlp;
|
osmo_cc_msg_list_t *ml, **mlp;
|
||||||
@@ -487,6 +498,7 @@ int osmo_cc_handle_socket(osmo_cc_socket_t *os)
|
|||||||
while (*mlp)
|
while (*mlp)
|
||||||
mlp = &((*mlp)->next);
|
mlp = &((*mlp)->next);
|
||||||
*mlp = ml;
|
*mlp = ml;
|
||||||
|
conn->ofd.when |= OSMO_FD_WRITE;
|
||||||
/* done with message */
|
/* done with message */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -526,7 +538,7 @@ int osmo_cc_handle_socket(osmo_cc_socket_t *os)
|
|||||||
sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
|
sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
|
||||||
if (sock < 0)
|
if (sock < 0)
|
||||||
continue;
|
continue;
|
||||||
/* set nonblocking io */
|
/* set nonblocking io, to prevent connect() and subsequent reads from blocking */
|
||||||
flags = fcntl(sock, F_GETFL);
|
flags = fcntl(sock, F_GETFL);
|
||||||
flags |= O_NONBLOCK;
|
flags |= O_NONBLOCK;
|
||||||
fcntl(sock, F_SETFL, flags);
|
fcntl(sock, F_SETFL, flags);
|
||||||
@@ -550,34 +562,58 @@ int osmo_cc_handle_socket(osmo_cc_socket_t *os)
|
|||||||
conn = open_conn(os, sock, ml->callref, 0);
|
conn = open_conn(os, sock, ml->callref, 0);
|
||||||
/* attach to list */
|
/* attach to list */
|
||||||
conn->write_list = ml;
|
conn->write_list = ml;
|
||||||
|
conn->ofd.when |= OSMO_FD_WRITE;
|
||||||
/* done with (setup) message */
|
/* done with (setup) message */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* handle new socket connection */
|
|
||||||
while ((sock = accept(os->socket, (struct sockaddr *)&sa, &slen)) > 0) {
|
|
||||||
work = 1;
|
|
||||||
/* set nonblocking io */
|
|
||||||
flags = fcntl(sock, F_GETFL);
|
|
||||||
flags |= O_NONBLOCK;
|
|
||||||
fcntl(sock, F_SETFL, flags);
|
|
||||||
/* create connection */
|
|
||||||
open_conn(os, sock, 0, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* start with list after each read/write, because while handling (the message), one or more connections may be destroyed */
|
|
||||||
for (conn = os->conn_list; conn; conn=conn->next) {
|
|
||||||
/* check for rx */
|
|
||||||
work = receive_conn(conn);
|
|
||||||
/* if "change" is set, connection list might have changed, so we restart processing the list */
|
|
||||||
if (work)
|
|
||||||
break;
|
|
||||||
/* check for tx */
|
|
||||||
work = transmit_conn(conn);
|
|
||||||
/* if "change" is set, connection list might have changed, so we restart processing the list */
|
|
||||||
if (work)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return work;
|
return work;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int socket_listen_cb(struct osmo_fd *ofd, unsigned int when)
|
||||||
|
{
|
||||||
|
osmo_cc_socket_t *os = ofd->data;
|
||||||
|
struct sockaddr_storage sa;
|
||||||
|
socklen_t slen = sizeof(sa);
|
||||||
|
int sock;
|
||||||
|
int flags;
|
||||||
|
|
||||||
|
if (when & OSMO_FD_READ) {
|
||||||
|
/* handle new socket connection */
|
||||||
|
if ((sock = accept(os->ofd.fd, (struct sockaddr *)&sa, &slen)) > 0) {
|
||||||
|
/* set nonblocking io, to prevent subsequent reads from blocking */
|
||||||
|
flags = fcntl(sock, F_GETFL);
|
||||||
|
flags |= O_NONBLOCK;
|
||||||
|
fcntl(sock, F_SETFL, flags);
|
||||||
|
/* create connection */
|
||||||
|
open_conn(os, sock, 0, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int socket_conn_cb(struct osmo_fd *ofd, unsigned int when)
|
||||||
|
{
|
||||||
|
osmo_cc_conn_t *conn = ofd->data;
|
||||||
|
int work;
|
||||||
|
|
||||||
|
if (when & OSMO_FD_READ) {
|
||||||
|
/* check for rx */
|
||||||
|
work = receive_conn(conn);
|
||||||
|
/* if "change" is set, connection list might have changed, so we restart processing the list */
|
||||||
|
if (work)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (when & OSMO_FD_WRITE) {
|
||||||
|
/* check for tx */
|
||||||
|
work = transmit_conn(conn);
|
||||||
|
/* if "change" is set, connection list might have changed, so we restart processing the list */
|
||||||
|
if (work)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
conn->ofd.when &= ~OSMO_FD_WRITE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -12,7 +12,7 @@ struct osmo_cc_socket;
|
|||||||
typedef struct osmo_cc_conn {
|
typedef struct osmo_cc_conn {
|
||||||
struct osmo_cc_conn *next;
|
struct osmo_cc_conn *next;
|
||||||
struct osmo_cc_socket *os;
|
struct osmo_cc_socket *os;
|
||||||
int socket;
|
struct osmo_fd ofd;
|
||||||
uint32_t callref;
|
uint32_t callref;
|
||||||
int read_setup;
|
int read_setup;
|
||||||
int read_version;
|
int read_version;
|
||||||
@@ -28,7 +28,7 @@ typedef struct osmo_cc_conn {
|
|||||||
} osmo_cc_conn_t;
|
} osmo_cc_conn_t;
|
||||||
|
|
||||||
typedef struct osmo_cc_socket {
|
typedef struct osmo_cc_socket {
|
||||||
int socket;
|
struct osmo_fd ofd;
|
||||||
osmo_cc_conn_t *conn_list;
|
osmo_cc_conn_t *conn_list;
|
||||||
osmo_cc_msg_list_t *write_list;
|
osmo_cc_msg_list_t *write_list;
|
||||||
void (*recv_msg_cb)(void *priv, uint32_t callref, osmo_cc_msg_t *msg);
|
void (*recv_msg_cb)(void *priv, uint32_t callref, osmo_cc_msg_t *msg);
|
||||||
|
6
src/libselect/Makefile.am
Normal file
6
src/libselect/Makefile.am
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
AM_CPPFLAGS = -Wall -Wextra -g $(all_includes)
|
||||||
|
|
||||||
|
noinst_LIBRARIES = libselect.a
|
||||||
|
|
||||||
|
libselect_a_SOURCES = \
|
||||||
|
select.c
|
168
src/libselect/select.c
Normal file
168
src/libselect/select.c
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
/* Timer handling
|
||||||
|
*
|
||||||
|
* (C) 2023 by Andreas Eversberg <jolly@eversberg.eu>
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Inspired by libosmocore
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include "select.h"
|
||||||
|
|
||||||
|
//#define DEBUG
|
||||||
|
|
||||||
|
#define MAX_OFD 1024
|
||||||
|
|
||||||
|
struct osmo_fd *ofd_list = NULL;
|
||||||
|
int ofd_changed = 0;
|
||||||
|
|
||||||
|
int osmo_fd_register(struct osmo_fd *ofd)
|
||||||
|
{
|
||||||
|
struct osmo_fd **ofdp;
|
||||||
|
|
||||||
|
/* attach to list, if not already */
|
||||||
|
ofdp = &ofd_list;
|
||||||
|
while (*ofdp) {
|
||||||
|
if (*ofdp == ofd)
|
||||||
|
break;
|
||||||
|
ofdp = &((*ofdp)->next);
|
||||||
|
}
|
||||||
|
if (!*ofdp) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr, "%s: ofd=%p fd=%d registers.\n", __func__, ofd, ofd->fd);
|
||||||
|
#endif
|
||||||
|
ofd->next = NULL;
|
||||||
|
*ofdp = ofd;
|
||||||
|
ofd_changed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void osmo_fd_unregister(struct osmo_fd *ofd)
|
||||||
|
{
|
||||||
|
struct osmo_fd **ofdp;
|
||||||
|
|
||||||
|
/* detach from list, if not already */
|
||||||
|
ofdp = &ofd_list;
|
||||||
|
while (*ofdp) {
|
||||||
|
if (*ofdp == ofd)
|
||||||
|
break;
|
||||||
|
ofdp = &((*ofdp)->next);
|
||||||
|
}
|
||||||
|
if (*ofdp) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr, "%s: ofd=%p fd=%d unregisters.\n", __func__, ofd, ofd->fd);
|
||||||
|
#endif
|
||||||
|
*ofdp = ofd->next;
|
||||||
|
ofd->next = NULL;
|
||||||
|
ofd_changed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int osmo_fd_select(double timeout)
|
||||||
|
{
|
||||||
|
fd_set readset;
|
||||||
|
fd_set writeset;
|
||||||
|
fd_set exceptset;
|
||||||
|
struct osmo_fd *ofd;
|
||||||
|
struct timeval tv;
|
||||||
|
int max_fd;
|
||||||
|
unsigned int what;
|
||||||
|
int work = 0;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/* init event sets */
|
||||||
|
FD_ZERO(&readset);
|
||||||
|
FD_ZERO(&writeset);
|
||||||
|
FD_ZERO(&exceptset);
|
||||||
|
|
||||||
|
/* populate event set with all file descriptios */
|
||||||
|
ofd = ofd_list;
|
||||||
|
max_fd = 0;
|
||||||
|
while (ofd) {
|
||||||
|
if (ofd->fd > max_fd)
|
||||||
|
max_fd = ofd->fd;
|
||||||
|
if (ofd->when & OSMO_FD_READ)
|
||||||
|
FD_SET(ofd->fd, &readset);
|
||||||
|
if (ofd->when & OSMO_FD_WRITE)
|
||||||
|
FD_SET(ofd->fd, &writeset);
|
||||||
|
if (ofd->when & OSMO_FD_EXCEPT)
|
||||||
|
FD_SET(ofd->fd, &exceptset);
|
||||||
|
ofd = ofd->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timeout >= 0) {
|
||||||
|
/* prepare timeout */
|
||||||
|
tv.tv_sec = floor(timeout);
|
||||||
|
tv.tv_usec = (timeout - tv.tv_sec) * 1000000.0;
|
||||||
|
/* wait for event or timeout */
|
||||||
|
rc = select(max_fd + 1, &readset, &writeset, &exceptset, &tv);
|
||||||
|
} else {
|
||||||
|
/* wait for event */
|
||||||
|
rc = select(max_fd + 1, &readset, &writeset, &exceptset, NULL);
|
||||||
|
}
|
||||||
|
if (rc < 0) {
|
||||||
|
if (errno != EINTR)
|
||||||
|
fprintf(stderr, "%s: select() failed: '%d' with errno %d (%s) Please fix!\n", __func__, rc, errno, strerror(errno));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
again:
|
||||||
|
/* check the result and call handler */
|
||||||
|
ofd_changed = 0;
|
||||||
|
ofd = ofd_list;
|
||||||
|
while (ofd) {
|
||||||
|
what = 0;
|
||||||
|
if (FD_ISSET(ofd->fd, &readset)) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr, "%s: ofd=%p fd=%d get READ event.\n", __func__, ofd, ofd->fd);
|
||||||
|
#endif
|
||||||
|
what |= OSMO_FD_READ;
|
||||||
|
FD_CLR(ofd->fd, &readset);
|
||||||
|
}
|
||||||
|
if (FD_ISSET(ofd->fd, &writeset)) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr, "%s: ofd=%p fd=%d get WRITE event.\n", __func__, ofd, ofd->fd);
|
||||||
|
#endif
|
||||||
|
what |= OSMO_FD_WRITE;
|
||||||
|
FD_CLR(ofd->fd, &writeset);
|
||||||
|
}
|
||||||
|
if (FD_ISSET(ofd->fd, &exceptset)) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr, "%s: ofd=%p fd=%d get EXCEPTION event.\n", __func__, ofd, ofd->fd);
|
||||||
|
#endif
|
||||||
|
what |= OSMO_FD_EXCEPT;
|
||||||
|
FD_CLR(ofd->fd, &exceptset);
|
||||||
|
}
|
||||||
|
if (what) {
|
||||||
|
work = 1;
|
||||||
|
ofd->cb(ofd, what);
|
||||||
|
/* list has changed */
|
||||||
|
if (ofd_changed)
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
ofd = ofd->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return work;
|
||||||
|
}
|
||||||
|
|
20
src/libselect/select.h
Normal file
20
src/libselect/select.h
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
#define OSMO_FD_READ 0x0001
|
||||||
|
#define OSMO_FD_WRITE 0x0002
|
||||||
|
#define OSMO_FD_EXCEPT 0x0004
|
||||||
|
#define BSC_FD_READ 0x0001
|
||||||
|
#define BSC_FD_WRITE 0x0002
|
||||||
|
#define BSC_FD_EXCEPT 0x0004
|
||||||
|
|
||||||
|
struct osmo_fd {
|
||||||
|
struct osmo_fd *next;
|
||||||
|
int fd;
|
||||||
|
unsigned int when;
|
||||||
|
int (*cb)(struct osmo_fd *fd, unsigned int what);
|
||||||
|
void *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
int osmo_fd_register(struct osmo_fd *ofd);
|
||||||
|
void osmo_fd_unregister(struct osmo_fd *ofd);
|
||||||
|
int osmo_fd_select(double timeout);
|
||||||
|
|
@@ -20,6 +20,7 @@ mpt1327_LDADD = \
|
|||||||
$(top_builddir)/src/libsquelch/libsquelch.a \
|
$(top_builddir)/src/libsquelch/libsquelch.a \
|
||||||
$(top_builddir)/src/libdtmf/libdtmf.a \
|
$(top_builddir)/src/libdtmf/libdtmf.a \
|
||||||
$(top_builddir)/src/libtimer/libtimer.a \
|
$(top_builddir)/src/libtimer/libtimer.a \
|
||||||
|
$(top_builddir)/src/libselect/libselect.a \
|
||||||
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
||||||
$(top_builddir)/src/libemphasis/libemphasis.a \
|
$(top_builddir)/src/libemphasis/libemphasis.a \
|
||||||
$(top_builddir)/src/libfsk/libfsk.a \
|
$(top_builddir)/src/libfsk/libfsk.a \
|
||||||
|
@@ -33,6 +33,7 @@ nmt_LDADD = \
|
|||||||
$(top_builddir)/src/libhagelbarger/libhagelbarger.a \
|
$(top_builddir)/src/libhagelbarger/libhagelbarger.a \
|
||||||
$(top_builddir)/src/libdtmf/libdtmf.a \
|
$(top_builddir)/src/libdtmf/libdtmf.a \
|
||||||
$(top_builddir)/src/libtimer/libtimer.a \
|
$(top_builddir)/src/libtimer/libtimer.a \
|
||||||
|
$(top_builddir)/src/libselect/libselect.a \
|
||||||
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
||||||
$(top_builddir)/src/libemphasis/libemphasis.a \
|
$(top_builddir)/src/libemphasis/libemphasis.a \
|
||||||
$(top_builddir)/src/libfsk/libfsk.a \
|
$(top_builddir)/src/libfsk/libfsk.a \
|
||||||
|
@@ -19,6 +19,7 @@ pocsag_LDADD = \
|
|||||||
$(top_builddir)/src/libdisplay/libdisplay.a \
|
$(top_builddir)/src/libdisplay/libdisplay.a \
|
||||||
$(top_builddir)/src/libjitter/libjitter.a \
|
$(top_builddir)/src/libjitter/libjitter.a \
|
||||||
$(top_builddir)/src/libtimer/libtimer.a \
|
$(top_builddir)/src/libtimer/libtimer.a \
|
||||||
|
$(top_builddir)/src/libselect/libselect.a \
|
||||||
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
||||||
$(top_builddir)/src/libemphasis/libemphasis.a \
|
$(top_builddir)/src/libemphasis/libemphasis.a \
|
||||||
$(top_builddir)/src/libfm/libfm.a \
|
$(top_builddir)/src/libfm/libfm.a \
|
||||||
|
@@ -21,6 +21,7 @@ radiocom2000_LDADD = \
|
|||||||
$(top_builddir)/src/libjitter/libjitter.a \
|
$(top_builddir)/src/libjitter/libjitter.a \
|
||||||
$(top_builddir)/src/libhagelbarger/libhagelbarger.a \
|
$(top_builddir)/src/libhagelbarger/libhagelbarger.a \
|
||||||
$(top_builddir)/src/libtimer/libtimer.a \
|
$(top_builddir)/src/libtimer/libtimer.a \
|
||||||
|
$(top_builddir)/src/libselect/libselect.a \
|
||||||
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
||||||
$(top_builddir)/src/libemphasis/libemphasis.a \
|
$(top_builddir)/src/libemphasis/libemphasis.a \
|
||||||
$(top_builddir)/src/libfsk/libfsk.a \
|
$(top_builddir)/src/libfsk/libfsk.a \
|
||||||
|
@@ -67,6 +67,7 @@ test_dms_LDADD = \
|
|||||||
$(top_builddir)/src/nmt/libdmssms.a \
|
$(top_builddir)/src/nmt/libdmssms.a \
|
||||||
$(top_builddir)/src/libjitter/libjitter.a \
|
$(top_builddir)/src/libjitter/libjitter.a \
|
||||||
$(top_builddir)/src/libtimer/libtimer.a \
|
$(top_builddir)/src/libtimer/libtimer.a \
|
||||||
|
$(top_builddir)/src/libselect/libselect.a \
|
||||||
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
||||||
$(top_builddir)/src/libemphasis/libemphasis.a \
|
$(top_builddir)/src/libemphasis/libemphasis.a \
|
||||||
$(top_builddir)/src/libfilter/libfilter.a \
|
$(top_builddir)/src/libfilter/libfilter.a \
|
||||||
@@ -104,6 +105,7 @@ test_sms_LDADD = \
|
|||||||
$(top_builddir)/src/nmt/libdmssms.a \
|
$(top_builddir)/src/nmt/libdmssms.a \
|
||||||
$(top_builddir)/src/libjitter/libjitter.a \
|
$(top_builddir)/src/libjitter/libjitter.a \
|
||||||
$(top_builddir)/src/libtimer/libtimer.a \
|
$(top_builddir)/src/libtimer/libtimer.a \
|
||||||
|
$(top_builddir)/src/libselect/libselect.a \
|
||||||
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
||||||
$(top_builddir)/src/libemphasis/libemphasis.a \
|
$(top_builddir)/src/libemphasis/libemphasis.a \
|
||||||
$(top_builddir)/src/libfilter/libfilter.a \
|
$(top_builddir)/src/libfilter/libfilter.a \
|
||||||
|
@@ -17,6 +17,7 @@ zeitansage_LDADD = \
|
|||||||
$(top_builddir)/src/libdisplay/libdisplay.a \
|
$(top_builddir)/src/libdisplay/libdisplay.a \
|
||||||
$(top_builddir)/src/libjitter/libjitter.a \
|
$(top_builddir)/src/libjitter/libjitter.a \
|
||||||
$(top_builddir)/src/libtimer/libtimer.a \
|
$(top_builddir)/src/libtimer/libtimer.a \
|
||||||
|
$(top_builddir)/src/libselect/libselect.a \
|
||||||
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
$(top_builddir)/src/libsamplerate/libsamplerate.a \
|
||||||
$(top_builddir)/src/libemphasis/libemphasis.a \
|
$(top_builddir)/src/libemphasis/libemphasis.a \
|
||||||
$(top_builddir)/src/libfsk/libfsk.a \
|
$(top_builddir)/src/libfsk/libfsk.a \
|
||||||
|
Reference in New Issue
Block a user