Initial GIT import
This commit is contained in:
commit
22dab51ab1
|
@ -0,0 +1,36 @@
|
|||
Makefile
|
||||
Makefile.in
|
||||
.deps
|
||||
.libs
|
||||
*.o
|
||||
*.lo
|
||||
*.la
|
||||
*.pc
|
||||
aclocal.m4
|
||||
acinclude.m4
|
||||
aminclude.am
|
||||
m4/*.m4
|
||||
autom4te.cache
|
||||
compile
|
||||
config.h*
|
||||
config.sub
|
||||
config.log
|
||||
config.status
|
||||
config.guess
|
||||
configure
|
||||
depcomp
|
||||
missing
|
||||
ltmain.sh
|
||||
install-sh
|
||||
stamp-h1
|
||||
libtool
|
||||
|
||||
.tarball-version
|
||||
.version
|
||||
.dirstamp
|
||||
|
||||
Doxyfile
|
||||
|
||||
.*.sw?
|
||||
|
||||
src/isdn/osmo-cc-misdn-endpoint
|
|
@ -0,0 +1,5 @@
|
|||
AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
SUBDIRS = src
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
AC_INIT([osmo-cc-misdn-endpoint],
|
||||
m4_esyscmd([./git-version-gen .tarball-version]),
|
||||
[jolly@eversberg.eu])
|
||||
|
||||
dnl *This* is the root dir, even if an install-sh exists in ../ or ../../
|
||||
AC_CONFIG_AUX_DIR([.])
|
||||
|
||||
AM_INIT_AUTOMAKE([subdir-objects dist-bzip2])
|
||||
AC_CONFIG_TESTDIR(tests)
|
||||
|
||||
dnl kernel style compile messages
|
||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||
|
||||
dnl include release helper
|
||||
RELMAKE='-include osmo-release.mk'
|
||||
AC_SUBST([RELMAKE])
|
||||
|
||||
dnl checks for programs
|
||||
AC_PROG_MAKE_SET
|
||||
AC_PROG_CC
|
||||
AC_PROG_INSTALL
|
||||
LT_INIT
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
AC_ARG_ENABLE(sanitize,
|
||||
[AS_HELP_STRING(
|
||||
[--enable-sanitize],
|
||||
[Compile with address sanitizer enabled],
|
||||
)],
|
||||
[sanitize=$enableval], [sanitize="no"])
|
||||
if test x"$sanitize" = x"yes"
|
||||
then
|
||||
CFLAGS="$CFLAGS -fsanitize=address -fsanitize=undefined"
|
||||
CPPFLAGS="$CPPFLAGS -fsanitize=address -fsanitize=undefined"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(werror,
|
||||
[AS_HELP_STRING(
|
||||
[--enable-werror],
|
||||
[Turn all compiler warnings into errors, with exceptions:
|
||||
a) deprecation (allow upstream to mark deprecation without breaking builds);
|
||||
b) "#warning" pragmas (allow to remind ourselves of errors without breaking builds)
|
||||
]
|
||||
)],
|
||||
[werror=$enableval], [werror="no"])
|
||||
if test x"$werror" = x"yes"
|
||||
then
|
||||
WERROR_FLAGS="-Werror"
|
||||
WERROR_FLAGS+=" -Wno-error=deprecated -Wno-error=deprecated-declarations"
|
||||
WERROR_FLAGS+=" -Wno-error=cpp" # "#warning"
|
||||
CFLAGS="$CFLAGS $WERROR_FLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $WERROR_FLAGS"
|
||||
fi
|
||||
|
||||
CFLAGS="$CFLAGS -Wall"
|
||||
CPPFLAGS="$CPPFLAGS -Wall"
|
||||
|
||||
dnl checks for header files
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS(execinfo.h sys/select.h sys/socket.h syslog.h ctype.h)
|
||||
|
||||
# The following test is taken from WebKit's webkit.m4
|
||||
saved_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -fvisibility=hidden "
|
||||
AC_MSG_CHECKING([if ${CC} supports -fvisibility=hidden])
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([char foo;])],
|
||||
[ AC_MSG_RESULT([yes])
|
||||
SYMBOL_VISIBILITY="-fvisibility=hidden"],
|
||||
AC_MSG_RESULT([no]))
|
||||
CFLAGS="$saved_CFLAGS"
|
||||
AC_SUBST(SYMBOL_VISIBILITY)
|
||||
|
||||
dnl Generate the output
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
|
||||
AC_CHECK_HEADERS([mISDN/mbuffer.h], , [AC_MSG_FAILURE(Missing mISDN user library. Please install mISDNuser!)])
|
||||
|
||||
AC_CHECK_LIB([m], [main])
|
||||
AC_CHECK_LIB([pthread], [main])
|
||||
|
||||
AC_OUTPUT(
|
||||
src/liboptions/Makefile
|
||||
src/libdebug/Makefile
|
||||
src/libsample/Makefile
|
||||
src/libtimer/Makefile
|
||||
src/libjitter/Makefile
|
||||
src/libosmocc/Makefile
|
||||
src/libg711/Makefile
|
||||
src/isdn/Makefile
|
||||
src/Makefile
|
||||
Makefile)
|
|
@ -0,0 +1,151 @@
|
|||
#!/bin/sh
|
||||
# Print a version string.
|
||||
scriptversion=2010-01-28.01
|
||||
|
||||
# Copyright (C) 2007-2010 Free Software Foundation, Inc.
|
||||
#
|
||||
# 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/>.
|
||||
|
||||
# This script is derived from GIT-VERSION-GEN from GIT: http://git.or.cz/.
|
||||
# It may be run two ways:
|
||||
# - from a git repository in which the "git describe" command below
|
||||
# produces useful output (thus requiring at least one signed tag)
|
||||
# - from a non-git-repo directory containing a .tarball-version file, which
|
||||
# presumes this script is invoked like "./git-version-gen .tarball-version".
|
||||
|
||||
# In order to use intra-version strings in your project, you will need two
|
||||
# separate generated version string files:
|
||||
#
|
||||
# .tarball-version - present only in a distribution tarball, and not in
|
||||
# a checked-out repository. Created with contents that were learned at
|
||||
# the last time autoconf was run, and used by git-version-gen. Must not
|
||||
# be present in either $(srcdir) or $(builddir) for git-version-gen to
|
||||
# give accurate answers during normal development with a checked out tree,
|
||||
# but must be present in a tarball when there is no version control system.
|
||||
# Therefore, it cannot be used in any dependencies. GNUmakefile has
|
||||
# hooks to force a reconfigure at distribution time to get the value
|
||||
# correct, without penalizing normal development with extra reconfigures.
|
||||
#
|
||||
# .version - present in a checked-out repository and in a distribution
|
||||
# tarball. Usable in dependencies, particularly for files that don't
|
||||
# want to depend on config.h but do want to track version changes.
|
||||
# Delete this file prior to any autoconf run where you want to rebuild
|
||||
# files to pick up a version string change; and leave it stale to
|
||||
# minimize rebuild time after unrelated changes to configure sources.
|
||||
#
|
||||
# It is probably wise to add these two files to .gitignore, so that you
|
||||
# don't accidentally commit either generated file.
|
||||
#
|
||||
# Use the following line in your configure.ac, so that $(VERSION) will
|
||||
# automatically be up-to-date each time configure is run (and note that
|
||||
# since configure.ac no longer includes a version string, Makefile rules
|
||||
# should not depend on configure.ac for version updates).
|
||||
#
|
||||
# AC_INIT([GNU project],
|
||||
# m4_esyscmd([build-aux/git-version-gen .tarball-version]),
|
||||
# [bug-project@example])
|
||||
#
|
||||
# Then use the following lines in your Makefile.am, so that .version
|
||||
# will be present for dependencies, and so that .tarball-version will
|
||||
# exist in distribution tarballs.
|
||||
#
|
||||
# BUILT_SOURCES = $(top_srcdir)/.version
|
||||
# $(top_srcdir)/.version:
|
||||
# echo $(VERSION) > $@-t && mv $@-t $@
|
||||
# dist-hook:
|
||||
# echo $(VERSION) > $(distdir)/.tarball-version
|
||||
|
||||
case $# in
|
||||
1) ;;
|
||||
*) echo 1>&2 "Usage: $0 \$srcdir/.tarball-version"; exit 1;;
|
||||
esac
|
||||
|
||||
tarball_version_file=$1
|
||||
nl='
|
||||
'
|
||||
|
||||
# First see if there is a tarball-only version file.
|
||||
# then try "git describe", then default.
|
||||
if test -f $tarball_version_file
|
||||
then
|
||||
v=`cat $tarball_version_file` || exit 1
|
||||
case $v in
|
||||
*$nl*) v= ;; # reject multi-line output
|
||||
[0-9]*) ;;
|
||||
*) v= ;;
|
||||
esac
|
||||
test -z "$v" \
|
||||
&& echo "$0: WARNING: $tarball_version_file seems to be damaged" 1>&2
|
||||
fi
|
||||
|
||||
if test -n "$v"
|
||||
then
|
||||
: # use $v
|
||||
elif
|
||||
v=`git describe --abbrev=4 --match='v*' HEAD 2>/dev/null \
|
||||
|| git describe --abbrev=4 HEAD 2>/dev/null` \
|
||||
&& case $v in
|
||||
[0-9]*) ;;
|
||||
v[0-9]*) ;;
|
||||
*) (exit 1) ;;
|
||||
esac
|
||||
then
|
||||
# Is this a new git that lists number of commits since the last
|
||||
# tag or the previous older version that did not?
|
||||
# Newer: v6.10-77-g0f8faeb
|
||||
# Older: v6.10-g0f8faeb
|
||||
case $v in
|
||||
*-*-*) : git describe is okay three part flavor ;;
|
||||
*-*)
|
||||
: git describe is older two part flavor
|
||||
# Recreate the number of commits and rewrite such that the
|
||||
# result is the same as if we were using the newer version
|
||||
# of git describe.
|
||||
vtag=`echo "$v" | sed 's/-.*//'`
|
||||
numcommits=`git rev-list "$vtag"..HEAD | wc -l`
|
||||
v=`echo "$v" | sed "s/\(.*\)-\(.*\)/\1-$numcommits-\2/"`;
|
||||
;;
|
||||
esac
|
||||
|
||||
# Change the first '-' to a '.', so version-comparing tools work properly.
|
||||
# Remove the "g" in git describe's output string, to save a byte.
|
||||
v=`echo "$v" | sed 's/-/./;s/\(.*\)-g/\1-/'`;
|
||||
else
|
||||
v=UNKNOWN
|
||||
fi
|
||||
|
||||
v=`echo "$v" |sed 's/^v//'`
|
||||
|
||||
# Don't declare a version "dirty" merely because a time stamp has changed.
|
||||
git status > /dev/null 2>&1
|
||||
|
||||
dirty=`sh -c 'git diff-index --name-only HEAD' 2>/dev/null` || dirty=
|
||||
case "$dirty" in
|
||||
'') ;;
|
||||
*) # Append the suffix only if there isn't one already.
|
||||
case $v in
|
||||
*-dirty) ;;
|
||||
*) v="$v-dirty" ;;
|
||||
esac ;;
|
||||
esac
|
||||
|
||||
# Omit the trailing newline, so that m4_esyscmd can use the result directly.
|
||||
echo "$v" | tr -d '\012'
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-end: "$"
|
||||
# End:
|
|
@ -0,0 +1,12 @@
|
|||
AUTOMAKE_OPTIONS = foreign
|
||||
|
||||
SUBDIRS = \
|
||||
liboptions \
|
||||
libdebug \
|
||||
libsample \
|
||||
libtimer \
|
||||
libjitter \
|
||||
libosmocc \
|
||||
libg711 \
|
||||
isdn
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
AM_CPPFLAGS = -Wall -Wextra -g $(all_includes)
|
||||
|
||||
bin_PROGRAMS = \
|
||||
osmo-cc-misdn-endpoint
|
||||
|
||||
osmo_cc_misdn_endpoint_SOURCES = \
|
||||
ie.c \
|
||||
dss1.c \
|
||||
isdn.c \
|
||||
main.c
|
||||
|
||||
osmo_cc_misdn_endpoint_LDADD = \
|
||||
$(COMMON_LA) \
|
||||
../libdebug/libdebug.a \
|
||||
../liboptions/liboptions.a \
|
||||
../libsample/libsample.a \
|
||||
../libtimer/libtimer.a \
|
||||
../libjitter/libjitter.a \
|
||||
../libosmocc/libosmocc.a \
|
||||
../libg711/libg711.a \
|
||||
-lmisdn
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,4 @@
|
|||
|
||||
int dss1_receive(isdn_t *isdn_ep, uint32_t cmd, uint32_t pid, struct l3_msg *l3m);
|
||||
void cc_message(osmo_cc_endpoint_t *ep, uint32_t callref, osmo_cc_msg_t *msg);
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,42 @@
|
|||
|
||||
#define CHANNEL_NO -2 /* incoming call on hold */
|
||||
#define CHANNEL_ANY -3 /* give me any channel */
|
||||
#define CHANNEL_FREE -100 /* select channel that is free */
|
||||
|
||||
void enc_ie_complete(struct l3_msg *l3m, int complete);
|
||||
void dec_ie_complete(struct l3_msg *l3m, int *complete);
|
||||
void enc_ie_bearer(struct l3_msg *l3m, uint8_t coding, uint8_t capability, int has_mode, uint8_t mode, uint8_t rate, int has_multi, uint8_t multi, int has_user, uint8_t user);
|
||||
int dec_ie_bearer(struct l3_msg *l3m, uint8_t *coding, uint8_t *capability, int *has_mode, uint8_t *mode, uint8_t *rate, int *has_multi, uint8_t *multi, int *has_user, uint8_t *user);
|
||||
void enc_ie_hlc(struct l3_msg *l3m, uint8_t coding, uint8_t interpretation, uint8_t presentation, uint8_t hlc, int has_exthlc, uint8_t exthlc);
|
||||
int dec_ie_hlc(struct l3_msg *l3m, uint8_t *coding, uint8_t *interpretation, uint8_t *presentation, uint8_t *hlc, int *has_exthlc, uint8_t *exthlc);
|
||||
void enc_ie_call_id(struct l3_msg *l3m, uint8_t *callid, int callid_len);
|
||||
int dec_ie_call_id(struct l3_msg *l3m, uint8_t *callid, int *callid_len);
|
||||
void enc_ie_called_pn(struct l3_msg *l3m, uint8_t type, uint8_t plan, char *number);
|
||||
int dec_ie_called_pn(struct l3_msg *l3m, uint8_t *type, uint8_t *plan, char *number, int number_len);
|
||||
void enc_ie_calling_pn(struct l3_msg *l3m, uint8_t type, uint8_t plan, int has_presen, uint8_t present, uint8_t screen, char *number);
|
||||
int dec_ie_calling_pn(struct l3_msg *l3m, int secondary_ie, uint8_t *type, uint8_t *plan, int *has_present, uint8_t *present, uint8_t *screen, char *number, int number_len);
|
||||
void enc_ie_connected_pn(struct l3_msg *l3m, uint8_t type, uint8_t plan, int has_present, uint8_t present, uint8_t screen, char *number);
|
||||
int dec_ie_connected_pn(struct l3_msg *l3m, uint8_t *type, uint8_t *plan, int *has_present, uint8_t *present, uint8_t *screen, char *number, int number_len);
|
||||
void enc_ie_cause(struct l3_msg *l3m, uint8_t location, uint8_t cause);
|
||||
int dec_ie_cause(struct l3_msg *l3m, uint8_t *location, uint8_t *cause);
|
||||
void enc_ie_channel_id(struct l3_msg *l3m, int pri, int exclusive, int channel);
|
||||
int dec_ie_channel_id(struct l3_msg *l3m, int pri, int *exclusive, int *channel);
|
||||
void enc_ie_date(struct l3_msg *l3m, time_t ti, int no_seconds);
|
||||
void enc_ie_display(struct l3_msg *l3m, char *display);
|
||||
int dec_ie_display(struct l3_msg *l3m, char *display, int display_len);
|
||||
void enc_ie_keypad(struct l3_msg *l3m, char *keypad);
|
||||
int dec_ie_keypad(struct l3_msg *l3m, char *keypad, int keypad_len);
|
||||
void enc_ie_notify(struct l3_msg *l3m, uint8_t notify);
|
||||
int dec_ie_notify(struct l3_msg *l3m, uint8_t *notify);
|
||||
void enc_ie_progress(struct l3_msg *l3m, uint8_t coding, uint8_t location, uint8_t progress);
|
||||
int dec_ie_progress(struct l3_msg *l3m, uint8_t *coding, uint8_t *location, uint8_t *progress);
|
||||
void enc_ie_redirecting(struct l3_msg *l3m, uint8_t type, uint8_t plan, int has_present, uint8_t present, uint8_t screen, int has_reason, uint8_t reason, char *number);
|
||||
int dec_ie_redirecting(struct l3_msg *l3m, uint8_t *type, uint8_t *plan, int *has_present, uint8_t *present, uint8_t *screen, int *has_reason, uint8_t *reason, char *number, int number_len);
|
||||
void enc_ie_redirection(struct l3_msg *l3m, uint8_t type, uint8_t plan, int has_present, uint8_t present, char *number);
|
||||
int dec_ie_redirection(struct l3_msg *l3m, uint8_t *type, uint8_t *plan, int *has_present, uint8_t *present, char *number, int number_len);
|
||||
void enc_ie_facility(struct l3_msg *l3m, uint8_t *facility, int facility_len);
|
||||
int dec_ie_facility(struct l3_msg *l3m, uint8_t *facility, int *facility_len);
|
||||
void enc_ie_useruser(struct l3_msg *l3m, uint8_t protocol, uint8_t *user, int user_len);
|
||||
int dec_ie_useruser(struct l3_msg *l3m, uint8_t *protocol, uint8_t *user, int *user_len);
|
||||
void enc_ie_signal(struct l3_msg *l3m, uint8_t signal);
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,201 @@
|
|||
|
||||
#include <pthread.h>
|
||||
#include "../libtimer/timer.h"
|
||||
#include "../libosmocc/endpoint.h"
|
||||
#include "../libosmocc/helper.h"
|
||||
#include "../libsample/sample.h"
|
||||
#include "../libjitter/jitter.h"
|
||||
|
||||
#define B_MODE_TRANSPARENT 0
|
||||
#define B_MODE_HDLC 1
|
||||
|
||||
#define B_STATE_IDLE 0 /* not open */
|
||||
#define B_STATE_ACTIVATING 1 /* DL_ESTABLISH sent */
|
||||
#define B_STATE_ACTIVE 2 /* channel active */
|
||||
#define B_STATE_DEACTIVATING 3 /* DL_RELEASE sent */
|
||||
|
||||
#define B_EVENT_USE 0 /* activate bchannel */
|
||||
#define B_EVENT_ACTIVATED 1 /* DL_ESTABLISH received */
|
||||
#define B_EVENT_DROP 2 /* deactivate bchannel */
|
||||
#define B_EVENT_DEACTIVATED 3 /* DL_RELEASE received */
|
||||
#define B_EVENT_TIMEOUT 4 /* timeout happed during (de)activation */
|
||||
|
||||
#define TONES_TYPE_AMERICAN 1
|
||||
#define TONES_TYPE_GERMAN 2
|
||||
#define TONES_TYPE_OLDGERMAN 3
|
||||
|
||||
enum isdn_state {
|
||||
ISDN_STATE_IDLE = 0, /* no call */
|
||||
ISDN_STATE_IN_SETUP, /* incoming connection */
|
||||
ISDN_STATE_OUT_SETUP, /* outgoing connection */
|
||||
ISDN_STATE_IN_OVERLAP, /* more informatiopn needed */
|
||||
ISDN_STATE_OUT_OVERLAP, /* more informatiopn needed */
|
||||
ISDN_STATE_IN_PROCEEDING,/* call is proceeding */
|
||||
ISDN_STATE_OUT_PROCEEDING,/* call is proceeding */
|
||||
ISDN_STATE_IN_ALERTING, /* call is ringing */
|
||||
ISDN_STATE_OUT_ALERTING,/* call is ringing */
|
||||
ISDN_STATE_IN_CONNECTING,/* wait for ack after answer */
|
||||
ISDN_STATE_OUT_CONNECTING,/* wait for ack after answer */
|
||||
ISDN_STATE_CONNECT, /* call is connected and transmission is enabled */
|
||||
ISDN_STATE_IN_DISCONNECT,/* incoming disconnected */
|
||||
ISDN_STATE_OUT_DISCONNECT,/* outgoing disconnected */
|
||||
ISDN_STATE_OUT_RELEASE, /* call released */
|
||||
ISDN_STATE_SUSPENDED, /* call suspended */
|
||||
};
|
||||
|
||||
struct isdn;
|
||||
|
||||
struct b_timer_inst {
|
||||
struct isdn *isdn_ep;
|
||||
int index;
|
||||
};
|
||||
|
||||
struct msn_list {
|
||||
struct msn_list *next;
|
||||
char msn[0];
|
||||
};
|
||||
|
||||
struct select_channel {
|
||||
struct select_channel *next;
|
||||
int channel;
|
||||
};
|
||||
|
||||
struct call_list;
|
||||
|
||||
typedef struct isdn {
|
||||
struct call_list *call_list;
|
||||
struct msn_list *msn_list;
|
||||
|
||||
/* settings */
|
||||
char law;
|
||||
struct select_channel *out_channel; /* list of outgoing channels to select */
|
||||
struct select_channel *in_channel; /* the same for incoming channels */
|
||||
int out_channel_exclusive; /* force channel */
|
||||
int serving_location; /* who we serve when sending causes towards interface */
|
||||
const char *timeouts;
|
||||
int tx_delay;
|
||||
int tx_gain;
|
||||
int rx_gain;
|
||||
const char *pipeline;
|
||||
int dtmf;
|
||||
int local_tones;
|
||||
|
||||
/* osmo-cc */
|
||||
struct osmo_cc_endpoint cc_ep;
|
||||
|
||||
/* mISDN */
|
||||
char *portname;
|
||||
int portnum;
|
||||
int ntmode;
|
||||
int ptp;
|
||||
int pri;
|
||||
int l1hold;
|
||||
int l2hold;
|
||||
int socket;
|
||||
pthread_mutex_t upqueue_lock;
|
||||
struct mqueue upqueue;
|
||||
int upqueue_initialized;
|
||||
struct mlayer3 *ml3;
|
||||
int los, ais, rdi, slip_rx, slip_tx;
|
||||
int l1link; /* current state */
|
||||
int l2link; /* current state */
|
||||
struct timer l2establish_timer;
|
||||
int b_num;
|
||||
int b_reserved;
|
||||
int b_mode[128];
|
||||
int b_state[128];
|
||||
int b_sock[128];
|
||||
struct call_list *b_call[128];
|
||||
struct timer b_timer[128];
|
||||
struct b_timer_inst b_timer_inst[128];
|
||||
uint8_t b_buffer[128][160];
|
||||
int b_buffer_pos[128];
|
||||
unsigned char l2mask[16]; /* 128 bits for each tei */
|
||||
} isdn_t;
|
||||
|
||||
typedef struct call_list {
|
||||
struct call_list *next;
|
||||
isdn_t *isdn_ep;
|
||||
|
||||
/* mISDN states */
|
||||
uint32_t l3_pid;
|
||||
uint16_t l3_ces;
|
||||
int tx_gain;
|
||||
int rx_gain;
|
||||
int mute;
|
||||
int txdata;
|
||||
int tx_delay;
|
||||
int echo;
|
||||
int conf;
|
||||
int tone;
|
||||
int rxoff;
|
||||
int dtmf;
|
||||
int dtmf_threshold;
|
||||
const char *pipeline;
|
||||
|
||||
/* osmo-cc states */
|
||||
uint32_t cc_callref;
|
||||
osmo_cc_session_t *cc_session;
|
||||
osmo_cc_session_codec_t *codec;
|
||||
const char *sdp;
|
||||
char codec_law;
|
||||
int codec_negotiated;
|
||||
int audio_path;
|
||||
|
||||
/* bchannel states */
|
||||
int b_index;
|
||||
int b_channel;
|
||||
int b_exclusive;
|
||||
int b_reserve;
|
||||
int b_mode;
|
||||
|
||||
/* call states */
|
||||
enum isdn_state state;
|
||||
int any_dialing; /* if any digit was dialed, we track this for dial tone */
|
||||
int channel_negotiated;
|
||||
int send_local_tones; /* using locally generated tones, because upper layer does not privide them */
|
||||
int send_remote_tones; /* using remote tones, as we received a progress indicator 1 or 8 from upper layer */
|
||||
int proceeding_sent;
|
||||
int sending_complete; /* send proceeding when osmo-cc requests overlap */
|
||||
int setup_comp_req_channel_assignment; /* must assign channel on setup comp req */
|
||||
uint8_t collect_cause, collect_location;
|
||||
int hold; /* if call is on hold */
|
||||
int conference_3pty; /* if call is the active call in a 3pty conference */
|
||||
int park_len;
|
||||
uint8_t park_callid[8];
|
||||
|
||||
/* jitter buffer for 3pty call */
|
||||
jitter_t dejitter;
|
||||
|
||||
} call_t;
|
||||
|
||||
int check_mISDN_dsp(void);
|
||||
|
||||
/* channel selection */
|
||||
int hunt_bchannel_in(isdn_t *isdn_ep, int channel, int exclusive);
|
||||
int hunt_bchannel_out(isdn_t *isdn_ep, int *channel, int *exclusive);
|
||||
int open_bchannel_in(call_t *call, int channel, int exclusive);
|
||||
int open_bchannel_out(call_t *call, unsigned int cmd, int channel, int exclusive);
|
||||
|
||||
/* isdn instance */
|
||||
isdn_t *isdn_create(void);
|
||||
void isdn_destroy(isdn_t *isdn_ep);
|
||||
int isdn_initialize(isdn_t *isdn_ep, char law, const char *portname, int ntmode, int ptp, int layer1hold, int layer2hold, const char *channel_out, const char *channel_in, const char *timeouts, int tx_delay, int tx_gain, int rx_gain, const char *pipeline, int dtmf, int local_tones, int serving_location);
|
||||
int isdn_open(isdn_t *isdn_ep);
|
||||
void isdn_close(isdn_t *isdn_ep);
|
||||
void isdn_add_msn(isdn_t *isdn_ep, const char *msn);
|
||||
int isdn_dchannel_work(isdn_t *isdn_ep);
|
||||
void isdn_bchannel_work(isdn_t *isdn_ep);
|
||||
void isdn_rtp_work(isdn_t *isdn_ep);
|
||||
|
||||
/* call instance */
|
||||
call_t *call_create(isdn_t *isdn_ep, int channel, int exclusive, int mode);
|
||||
void call_destroy(call_t *call);
|
||||
|
||||
/* channel allocation and handling */
|
||||
void bchannel_tone(call_t *call, int tone);
|
||||
void bchannel_event(isdn_t *isdn_ep, int index, int event);
|
||||
int seize_bchannel(call_t *call, int channel, int exclusive);
|
||||
void drop_bchannel(call_t *call);
|
||||
void bchannel_send(struct osmo_cc_session_codec *codec, uint16_t sequence_number, uint32_t timestamp, uint8_t *data, int len);
|
||||
|
|
@ -0,0 +1,378 @@
|
|||
/* osmo-cc-misdn-endpoint main
|
||||
*
|
||||
* (C) 2020 by Andreas Eversberg <jolly@eversberg.eu>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* 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 <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "../libdebug/debug.h"
|
||||
#include "../liboptions/options.h"
|
||||
#include "../libg711/g711.h"
|
||||
#include <mISDN/mbuffer.h>
|
||||
#include "isdn.h"
|
||||
#include "dss1.h"
|
||||
|
||||
isdn_t *isdn_ep = NULL;
|
||||
int num_kanal = 1;
|
||||
|
||||
static char law = 'a';
|
||||
static const char *portname = "0";
|
||||
static int ntmode = 0;
|
||||
static int ptp = 0;
|
||||
static int layer1hold = 0;
|
||||
static int layer2hold = 0;
|
||||
static const char *channel_out = NULL;
|
||||
static const char *channel_in = NULL;
|
||||
static const char *timeouts = NULL;
|
||||
static int tx_delay = 0;
|
||||
static int tx_gain = 0;
|
||||
static int rx_gain = 0;
|
||||
static const char *pipeline = NULL;
|
||||
static int dtmf = 1;
|
||||
static int local_tones = 0;
|
||||
static int debug_mISDN = 0;
|
||||
static int serving_location = 1; /* private network serving local user */
|
||||
#define MAX_CC_ARGS 1024
|
||||
static int cc_argc = 0;
|
||||
static const char *cc_argv[MAX_CC_ARGS];
|
||||
|
||||
static void print_usage(const char *app)
|
||||
{
|
||||
printf("Usage: %s [--port <misdn port>] [--nt] [<options>]\n", app);
|
||||
}
|
||||
|
||||
static void print_help()
|
||||
{
|
||||
/* - - */
|
||||
printf(" -h --help\n");
|
||||
printf(" This help\n");
|
||||
printf(" -v --verbose <level> | <level>,<category>[,<category>[,...]] | list\n");
|
||||
printf(" Use 'list' to get a list of all levels and categories\n");
|
||||
printf(" Verbose level: digit of debug level (default = '%d')\n", debuglevel);
|
||||
printf(" Verbose level+category: level digit followed by one or more categories\n");
|
||||
printf(" -> If no category is specified, all categories are selected\n");
|
||||
printf(" --ulaw\n");
|
||||
printf(" Use U-LAW for b-channel coding instead of alaw.\n");
|
||||
printf(" -p --port <portnr> | <portname>\n");
|
||||
printf(" Number or name of misdn port (see misdn_info). (Default = %s)\n", portname);
|
||||
printf(" -n --nt\n");
|
||||
printf(" The given port is configured as NT-mode, instead of TE-mode.\n");
|
||||
printf(" -0 --ptp\n");
|
||||
printf(" The given port is configured as point-to-point. PRI-Ports are always\n");
|
||||
printf(" configured as point-to-point.\n");
|
||||
printf(" -M --msn <msn1> [--msn <msn2> ...]\n");
|
||||
printf(" Give one or multiple MSN numbers. If MSN numbers are defined, only\n");
|
||||
printf(" MSN numbers that are defined are allowed. If a different MSN number\n");
|
||||
printf(" is received from a phone, it is replaced by the first MSN number.\n");
|
||||
printf(" This is only useful for NT-mode with point-to-mulipoint cofiguration.\n");
|
||||
printf(" (Any MSN is accepted and forwarded by default.).\n");
|
||||
printf(" -1 --layer-1-hold 0 | 1\n");
|
||||
printf(" Keep layer 1 always active. (Default for point-to-point)\n");
|
||||
printf(" -2 --layer-2-hold 0 | 1\n");
|
||||
printf(" Keep layer 2 always active. (Default for point-to-point)\n");
|
||||
printf(" --channel-out [force,][<number>][,...][,free][,any][,no]\n");
|
||||
printf(" Channel selection list for all outgoing calls to the interface.\n");
|
||||
printf(" A free channels is searched in order of appearance.\n");
|
||||
printf(" force - Forces the selected port with no acceptable alternative.\n");
|
||||
printf(" -> this will be automatically set for multipoint NT-mode ports\n");
|
||||
printf(" <number>[,...] - List of channels to search.\n");
|
||||
printf(" free - Select any free channel\n");
|
||||
printf(" any - On outgoing calls, signal 'any channel acceptable'. (see DSS1)\n");
|
||||
printf(" no - Signal 'no channel available' aka 'call waiting'. (see DSS1)\n");
|
||||
printf(" --channel-in [<number>][,...][,free]\n");
|
||||
printf(" Give list of channels to select for calls from ISDN\n");
|
||||
printf(" Channel selection list for all incoming calls from the interface.\n");
|
||||
printf(" A free channels is accepted if in the list.\n");
|
||||
printf(" If any channel was requested, the first free channel found is selected.\n");
|
||||
printf(" <number>[,...] - List of channels to accept.\n");
|
||||
printf(" free - Accept any free channel\n");
|
||||
|
||||
printf(" --timeouts <setup>,<overlap>,<proceeding>,<alerting>,<disconnect>\n");
|
||||
printf(" Alter ISDN protocol times.\n");
|
||||
printf(" The default is 120 seconds for all states. Use 0 to disable.\n");
|
||||
printf(" --tx-delay <ms>\n");
|
||||
printf(" Give a delay in milliseconds. This is required for modem/fax. Audio\n");
|
||||
printf(" toward ISDN interface is buffered with the given delay.\n");
|
||||
printf(" This feature turns off the dejittering.\n");
|
||||
printf(" --tx-gain <dB>\n");
|
||||
printf(" Changes gain of audio towards ISDN interface. Give Gain in steps of\n");
|
||||
printf(" 6 dB. (-48 .. 48)\n");
|
||||
printf(" --rx-gain <dB>\n");
|
||||
printf(" Changes gain of audio coming from ISDN interface. Give Gain in steps\n");
|
||||
printf(" of 6 dB. (-48 .. 48)\n");
|
||||
printf(" --pipeline <string>\n");
|
||||
printf(" mISDN allows to use echo cancelation modules. See mISDN documentation.\n");
|
||||
printf(" --dtmf 1 | 0\n");
|
||||
printf(" Turns DTMF detection on or off (default is %d).\n", dtmf);
|
||||
printf(" -T --local-tones german | oldgerman | american\n");
|
||||
printf(" Send locally generated tones, if not provided by remote interface.\n");
|
||||
printf(" -D --debug-misdn\n");
|
||||
printf(" Enables mISDN stack debugging.\n");
|
||||
printf(" --serving-location (see Q.931)\n");
|
||||
printf(" 0 = user, 1 = private network serving local user (default=%d)\n", serving_location);
|
||||
printf(" -C --cc \"<osmo-cc arg>\" [--cc ...]\n");
|
||||
printf(" Pass arguments to Osmo-CC endpoint. Use '-cc help' for description.\n");
|
||||
}
|
||||
|
||||
#define OPT_ULAW 256
|
||||
#define OPT_CHANNEL_OUT 257
|
||||
#define OPT_CHANNEL_IN 258
|
||||
#define OPT_TIMEOUTS 259
|
||||
#define OPT_TX_DELAY 260
|
||||
#define OPT_TX_GAIN 261
|
||||
#define OPT_RX_GAIN 262
|
||||
#define OPT_PIPELINE 263
|
||||
#define OPT_DTMF 264
|
||||
#define OPT_SERVING 265
|
||||
|
||||
static void add_options(void)
|
||||
{
|
||||
option_add('h', "help", 0);
|
||||
option_add('v', "verbose", 1);
|
||||
option_add(OPT_ULAW, "ulaw", 0);
|
||||
option_add('p', "port", 1);
|
||||
option_add('n', "nt", 0);
|
||||
option_add('0', "ptp", 0);
|
||||
option_add('M', "msn", 1);
|
||||
option_add('1', "layer-1-hold", 1);
|
||||
option_add('2', "layer-2-hold", 1);
|
||||
option_add(OPT_CHANNEL_OUT, "channel-out", 1);
|
||||
option_add(OPT_CHANNEL_IN, "channel-in", 1);
|
||||
option_add(OPT_TIMEOUTS, "timeouts", 1);
|
||||
option_add(OPT_TX_DELAY, "tx-delay", 1);
|
||||
option_add(OPT_TX_GAIN, "tx-gain", 1);
|
||||
option_add(OPT_RX_GAIN, "rx-gain", 1);
|
||||
option_add(OPT_PIPELINE, "pipeline", 1);
|
||||
option_add(OPT_DTMF, "dtmf", 1);
|
||||
option_add('T', "local-tones", 1);
|
||||
option_add('D', "debug-misdn", 0);
|
||||
option_add(OPT_SERVING, "serving-location", 0);
|
||||
option_add('C', "cc", 1);
|
||||
}
|
||||
|
||||
static int handle_options(int short_option, int argi, char **argv)
|
||||
{
|
||||
int rc;
|
||||
|
||||
switch (short_option) {
|
||||
case 'h':
|
||||
print_usage(argv[0]);
|
||||
print_help();
|
||||
return 0;
|
||||
case 'v':
|
||||
if (!strcasecmp(argv[argi], "list")) {
|
||||
debug_list_cat();
|
||||
return 0;
|
||||
}
|
||||
rc = parse_debug_opt(argv[argi]);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Failed to parse debug option, please use -h for help.\n");
|
||||
return rc;
|
||||
}
|
||||
break;
|
||||
case OPT_ULAW:
|
||||
law = 'u';
|
||||
break;
|
||||
case 'p':
|
||||
portname = strdup(argv[argi]);
|
||||
break;
|
||||
case 'n':
|
||||
ntmode = 1;
|
||||
break;
|
||||
case '0':
|
||||
ptp = 1;
|
||||
break;
|
||||
case 'm':
|
||||
isdn_add_msn(isdn_ep, argv[argi]);
|
||||
break;
|
||||
case '1':
|
||||
layer1hold = atoi(argv[argi]);
|
||||
break;
|
||||
case '2':
|
||||
layer2hold = atoi(argv[argi]);
|
||||
break;
|
||||
case OPT_CHANNEL_OUT:
|
||||
channel_out = strdup(argv[argi]);
|
||||
break;
|
||||
case OPT_CHANNEL_IN:
|
||||
channel_in = strdup(argv[argi]);
|
||||
break;
|
||||
case OPT_TIMEOUTS:
|
||||
timeouts = strdup(argv[argi]);
|
||||
break;
|
||||
case OPT_TX_DELAY:
|
||||
tx_delay = atoi(argv[argi]);
|
||||
break;
|
||||
case OPT_TX_GAIN:
|
||||
tx_gain = atoi(argv[argi]) / 6;
|
||||
break;
|
||||
case OPT_RX_GAIN:
|
||||
rx_gain = atoi(argv[argi]) / 6;
|
||||
break;
|
||||
case OPT_PIPELINE:
|
||||
pipeline = strdup(argv[argi]);
|
||||
break;
|
||||
case OPT_DTMF:
|
||||
dtmf = atoi(argv[argi]);
|
||||
break;
|
||||
case 'T':
|
||||
if (!strcasecmp(argv[argi], "american"))
|
||||
local_tones = TONES_TYPE_AMERICAN;
|
||||
else if (!strcasecmp(argv[argi], "german"))
|
||||
local_tones = TONES_TYPE_GERMAN;
|
||||
else if (!strcasecmp(argv[argi], "oldgerman"))
|
||||
local_tones = TONES_TYPE_OLDGERMAN;
|
||||
else {
|
||||
fprintf(stderr, "Invalid tones type given!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case 'D':
|
||||
debug_mISDN = 1;
|
||||
break;
|
||||
case OPT_SERVING:
|
||||
serving_location = atoi(argv[argi]);
|
||||
break;
|
||||
case 'C':
|
||||
if (!strcasecmp(argv[argi], "help")) {
|
||||
osmo_cc_help();
|
||||
return 0;
|
||||
}
|
||||
if (cc_argc == MAX_CC_ARGS) {
|
||||
fprintf(stderr, "Too many osmo-cc args!\n");
|
||||
break;
|
||||
}
|
||||
cc_argv[cc_argc++] = strdup(argv[argi]);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int quit = 0;
|
||||
void sighandler(int sigset)
|
||||
{
|
||||
if (sigset == SIGHUP || sigset == SIGPIPE)
|
||||
return;
|
||||
|
||||
fprintf(stderr, "\nSignal %d received.\n", sigset);
|
||||
|
||||
quit = 1;
|
||||
}
|
||||
|
||||
static struct mi_ext_fn_s mi_fn;
|
||||
|
||||
static int mISDNlib_debug(const char *file, int line, const char *func, int __attribute__((unused)) level, const char *fmt, va_list va)
|
||||
{
|
||||
char text[256];
|
||||
vsnprintf(text, sizeof(text) - 1, fmt, va);
|
||||
text[sizeof(text) - 1] = '\0';
|
||||
// PDEBUG(DDSS1, DEBUG_NOTICE, "libmisdn (file %s, line %d, func %s(), level %d): %s\n", file, line, func, level, text);
|
||||
_printdebug(file, func, line, DMISDN, DEBUG_NOTICE, NULL, "%s", text);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int argi, rc;
|
||||
int layer3_initialized = 0;
|
||||
|
||||
g711_init();
|
||||
|
||||
isdn_ep = isdn_create();
|
||||
if (!isdn_ep)
|
||||
goto error;
|
||||
|
||||
cc_argv[cc_argc++] = strdup("remote auto");
|
||||
|
||||
/* handle options / config file */
|
||||
add_options();
|
||||
rc = options_config_file("~/.osmocom/isdn/isdn.conf", handle_options);
|
||||
if (rc < 0)
|
||||
return 0;
|
||||
argi = options_command_line(argc, argv, handle_options);
|
||||
if (argi <= 0)
|
||||
return argi;
|
||||
|
||||
/* misdn init and debug */
|
||||
rc = check_mISDN_dsp();
|
||||
if (rc)
|
||||
goto error;
|
||||
mi_fn.prt_debug = mISDNlib_debug;
|
||||
init_layer3(4, &mi_fn);
|
||||
layer3_initialized = 1;
|
||||
mISDN_set_debug_level((debug_mISDN) ? 0xfffffeff : 0);
|
||||
|
||||
rc = isdn_initialize(isdn_ep, law, portname, ntmode, ptp, layer1hold, layer2hold, channel_out, channel_in, timeouts, tx_delay, tx_gain, rx_gain, pipeline, dtmf, local_tones, serving_location);
|
||||
if (rc) {
|
||||
PDEBUG(DISDN, DEBUG_ERROR, "mISDN initializing failed!\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = isdn_open(isdn_ep);
|
||||
if (rc) {
|
||||
PDEBUG(DISDN, DEBUG_ERROR, "mISDN open failed!\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = osmo_cc_new(&isdn_ep->cc_ep, OSMO_CC_VERSION, isdn_ep->portname, serving_location, cc_message, NULL, isdn_ep, cc_argc, cc_argv);
|
||||
if (rc < 0)
|
||||
goto error;
|
||||
|
||||
signal(SIGINT, sighandler);
|
||||
signal(SIGHUP, sighandler);
|
||||
signal(SIGTERM, sighandler);
|
||||
signal(SIGPIPE, sighandler);
|
||||
|
||||
while (!quit) {
|
||||
int w;
|
||||
process_timer();
|
||||
isdn_bchannel_work(isdn_ep);
|
||||
isdn_rtp_work(isdn_ep);
|
||||
do {
|
||||
w = 0;
|
||||
w |= osmo_cc_handle();
|
||||
w |= isdn_dchannel_work(isdn_ep);
|
||||
} while (w);
|
||||
usleep(1000);
|
||||
}
|
||||
|
||||
signal(SIGINT, SIG_DFL);
|
||||
signal(SIGTSTP, SIG_DFL);
|
||||
signal(SIGHUP, SIG_DFL);
|
||||
signal(SIGTERM, SIG_DFL);
|
||||
signal(SIGPIPE, SIG_DFL);
|
||||
|
||||
error:
|
||||
if (isdn_ep) {
|
||||
osmo_cc_delete(&isdn_ep->cc_ep);
|
||||
isdn_destroy(isdn_ep);
|
||||
}
|
||||
|
||||
if (layer3_initialized)
|
||||
cleanup_layer3();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue