Use uint64_t and FTDM_UINT64_FMT for flagval and "%u" for unsigned int.
Extend invalid channel id check to cover chan_id == 0 case.
Use ftdm_strlen_zero() and ftdm_array_len() instead of open-coding them.
Move some variables from global scope into local subcommand scope.
Various other little format string and variable naming fixes.
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
Auto-loading can be toggled by setting the new autoload parameter
to FTDM_FALSE/FTDM_TRUE.
Update ftdm_span_create() and ftdm_api_execute() to use the new code.
NOTE: Auto-loading of missing I/O interfaces remains enabled in both cases,
but I guess we should disable it for ftdm_api_execute().
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
"x >> 1" is _NOT_ the reverse of "1 << x"...
Use code from Sean Eron Andersen's "Bit Twiddling Hacks"
(=> http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog)
to compute the log2 value (= position in the enum) of the bitflag.
This preserves the current behaviour, which is rather odd because
it is based on the position of the value in the enum, not its
actual (bit flag) value.
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
Simplify code by using shared string constants using bool (0/1) index,
!!-operator and negation-via-XOR.
Future optimization: Preallocate and re-use of iterators, to avoid
repeatedly allocating and freeing of memory.
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
Part of my ongoing effort to split ftdm_io.c into more manageable pieces.
This change (along with others in the future) allows decoupling of the
span registry and its users, in preparation of moving all span related
functions and data structures into ftdm_span.c.
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
ivrd doesn't use sigaction + SA_RESTART for SIGCHILD. An exiting
child process will interrupt accept() in the parent to handle
the signal, which makes accept() return -1 (errno = EINTR) after
the sighandler function returns.
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
Fixes repeatedly printing the 'Starting forking listener' message,
if stdout has been redirected into a logfile (for example).
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
Catch single channel RESTART/RESTART ACK events for non-B-channels,
that would lead to a NULL pointer dereference, because those do not have
per-channel private data (chan->call_data = chan_priv == NULL).
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
Full clang error message:
error: implicit conversion from enumeration type 'ftdm_bool_t' to
different enumeration type 'ftdm_status_t' [-Werror,-Wconversion]
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
Audio frame sizes were already being checked for overflow,
but video frame sizes were taken as-is, which would
lead to heap corruption.
In case an overflow has been detected, playback is aborted immediately as
there is no way we can ever recover from such a situation due to the lack
of a (well-known) frame header signature that could be used to skip over
the corrupted part of the streams.
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
Commit f913670e changed switch_core_session_sprintf() args
from sip->sip_to to sip->sip_from, but didn't update the enclosing if()
clause protecting the code from dereferencing NULL pointers.
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
Add support for "q921_all"/"q931_all" to parse_debug() ("debug" span parameter), taken from
ftmod_libpri.
Passive libpri's raw dump feature is broken (e.g. I-frames missing), so
add "q921_raw" hexdump support to the pritap I/O read/write function.
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
AM_CONFIG_HEADER is deprecated in automake 1.13.1 (and temporarily not available in 1.13),
the replacement is available in autoconf-2.59 (and maybe before).
NOTE: Remove sed hackery when upstream has released a fixed version
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
AM_CONFIG_HEADER is deprecated in automake 1.13.1 (and temporarily not available in 1.13),
the replacement is available in autoconf-2.59 (and maybe before).
NOTE: Remove sed hackery when upstream has released a fixed version (> 1.7.0)
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
Said function has been added in libpri-1.4.11 and breaks
building with older libpri versions (i.e. the passive one for ftmod_pritap).
Check for pri_maintenance_service() in configure and disable
the "maintenance" subcommand if it is not available.
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
Yeah, right, discard the incoming audio data when the b-channel is active...
Reverse the check, so ftdm_read() on an active mISDN b-channel will
be able to read audio data from the RX socketpair and not kill
the call from repeatedly timing out in poll().
Fixes:
[WARNING] mod_freetdm.c:775 Too many timeouts while waiting I/O in channel FreeTDM/1:1/XX device 1:1!
[ERR] mod_freetdm.c:820 clearing IO in channel FreeTDM/1:1/XX device 1:1!
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
epoll_wait() on the B-channel socket may indicate pending messages, but
recvfrom() returns EAGAIN. Retry a few more times (up to 5 retries)
to get the pending message.
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
Fixes:
src/ftmod/ftmod_misdn/ftmod_misdn.c:924:3: error: format '%lx' expects
argument of type 'long unsigned int', but argument 13 has type '__u64'
[-Werror=format]
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
Reported-by: hyper_ch #freetdm @ irc.freenode.net
"Safer" version of ftdm_clamp(), that swaps min/max parameters if
vmin happens to be larger than vmax, making sure the output will
always satisfy vmin <= x <= vmax.
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
Some people, it seems, were having sleepless nights from the
log messages this feature produces every 15 minutes.
Default disable the feature, because i hate repeating myself
over and over, explaining them this is a non-issue and intended
behaviour and how to disable it in the config.
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
FTDM_SIGEVENT_UP was falling through to FTDM_SIGEVENT_PROGRESS_MEDIA, which
does (almost) the same, so no harm, but still fix it.
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
Channels can be in DOWN state but reserved by an incoming call
(FTDM_CHANNEL_INUSE flag). Additionally check the flag in on_timeout_t3xx()
and skip those channels.
Reported-by: privi #freetdm @ irc.freenode.net
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
Do not try to send RESTART on BRI PTMP spans, libpri will just print
an error and do nothing, causing the channels to be stuck in RESTART
forever.
Add T316 (RESTART ACK timeout), which is not implemented by libpri.
The default timeout is 30 seconds (Q.931 recommends 2 minutes, but
that is a little long and libpri layer 2 is being stupid) and the
restart attempt limit to 3 (instead of 2).
Periodically send RESTART on idle b-channels in PTP NT mode.
Default interval is 15 minutes, feature can be disabled by setting
"idle_restart_interval" to 0 in the span configuration.
Allow timeout / interval values to have an additional time unit
suffix for convenience reasons, the default (no unit specified)
is milliseconds, valid units include:
w (week), d (day), h (hour), m (minute), s (second)
Only full integers are accepted, no fractional numbers, valid examples:
2w = two weeks
37m = 37 minutes
1h = 1 hour
Combinations of multiple numbers and units (e.g. "1w5d") are not supported.
New span configuration parameters:
idle_restart_interval (milliseconds / time unit suffix /
0 = disabled)
t316 / restart_timeout (milliseconds / time unit suffix)
t316_limit / restart_attempts (number of max. attempts)
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
Add per b-channel private data (ftdm_libpri_b_data_t), move the q.931 libpri
call pointer into it and use channel->call_data to make it accessible.
Use ftdm_channel_wait() instead of select() to wait for I/O events on
the D-Channel and rewrite the timeout handling, adding support for custom
timers that can be added to the b-channel private data and started/stopped
with lpwrap_timer_start()/_stop().
The (sorted) list of active lpwrap timers is protected by the timer_mutex,
which is initialized in the now unified lpwrap_init_pri() (see below) and
destroyed in the new lpwrap_destroy_pri() function.
Unify lpwrap_init_pri() and lpwrap_init_bri(). Use the span type to select
BRI/PRI and Point-to-Point vs. Multipoint settings.
Use the new custom lpwrap timer API to implement T302 (aka overlap receiving
digit timeout). The default T302 timeout is 3000 miliseconds and can be set
via the "digit_timeout" or "t302" span configuration parameter
(0 = disable timer, valid range = 3000 ... 30000 miliseconds).
The lpwrap_pri_init() changes made it neccessarry to rewrite the span runtime
thread event loop. The d-channel initialization and libpri event handler
registration have been moved out of the event loop. The b-channel restart
handling in the event loop has been left as-is, pending a further clean up in
the future.
Rename on_info() to on_information() and add a new on_keypad_digit() event
handler to convert incoming KEYPAD DIGIT messages to channel DTMF events
(only useful on BRI PTMP NT-mode).
The channel restart handling has been improved to distinguish between locally
triggered and restarts caused by the remote end (= incoming RESTART messages).
Restarts on the D-Channel now use pri_restart(), causing a Q.921 reset on
the span.
Large patch, i'd have loved to split this into smaller pieces and actually
test some of the bits more toroughly (restart handling), but some people
are f*cking annoying, so here it is.
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
Move the B-channel message handling into a per-span I/O thread,
to solve most of the problems caused by the intermixed data + control
socket interface of mISDN, missing write poll() support on
mISDN B-channels and the FreeTDM I/O model. This eliminates most of
the audio problems (except for a few minor glitches).
A unix stream socket pair is used as a bi-directional pipe replacement
(the pipe code is still included in this commit, but will be removed later),
with the RX and TX buffer sizes carefully tuned to avoid excessive buffering
(= latency) and a deadlock situation between the write() call in ftdm_write()
and the code in misdn_span_run() that needs a minimum amount of data in the
TX buffer, before sending out a PH_DATA_REQ to the mISDN socket
(see misdn_span_run() comments for more details).
The minimum size for pipes is PAGE_SIZE (4k), which is ~500 ms worth of
audio. A socket pair RX/TX buffer size of 3k, seems to hold a maximum
amount of around 500 bytes data in practice, giving us a much lower
maximum latency than a unix pipe. (The socket pair might be replaced by a
custom ring buffer / fifo data structure to get even more fine grained
control of the maximum latency.)
The newly introduced span_start / span_stop callbacks in
ftdm_io_interface_t are used to start / stop the I/O thread. The callback
functions will wait up to 10 seconds for the thread to successfully
start up or shut down (using a mutex + condition var).
NOTE: Using any of the locking ftdm_span_() functions in the I/O will cause
a deadlock between the I/O thread (trying to lock span->mutex) and the
thread calling ftdm_start()/_stop() (holding the span->mutex).
(The I/O thread currently uses direct span member access to avoid this.)
The I/O thread uses the epoll(7) family of functions for event handling.
An epoll context is created on startup and all B-channel sockets are
registered (READ, PRI and ERR). Before entering the event loop,
the I/O thread will send a signal on the condition variable, to
indicate it has completed the startup procedure.
Incoming b-channel and command pipe events are handled by the event loop.
Payload of incoming PH_DATA_IND frames (= audio data) is sent to the
rx_audio_pipe_in end of the b-channel's socket pair and, if enough data is
available, a PH_DATA_REQ of the same size is sent to the b-channel mISDN socket
to transmit audio.
A MISDN_CMD_STOP command on the event pipe will wake up the I/O thread and
cause it to shut down. All b-channels will be unregistered from the epoll context
and the epoll fd closed. The I/O thread terminates itself after signalling the
successfull shutdown on the condition variable.
TODOs:
- Move D-Channel into I/O thread too
- Custom FIFO/ring buffer for data (even lower latency)
- Improve epoll() code (per-channel struct w/ callback, for epfd.data.ptr)
- Use mISDN DSP for audio (e.g. tone generator, dtmf detector, echo cancel)
- Use a per-port / span control socket to execute channel commands
synchronously, or add misdn_commands (queue?) that can be used that way
- Name I/O threads 'mISDN-%SPAN_NAME%', e.g. 'mISDN-M_BRI1'
(= add ftdm_thread_set_namef(thread, fmt, ...) / ftdm_thread_set_name(thread, name))
TL;DR: "tweak", solves "booboo" with audio
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
Fixes:
cc1: warnings being treated as errors
src/switch_core_session.c: In function 'switch_core_session_thread_pool_worker':
src/switch_core_session.c:1478: warning: format '%ld' expects type 'long int', but argument 9 has type 'switch_size_t'
src/switch_core_session.c:1483: warning: format '%ld' expects type 'long int', but argument 9 has type 'switch_size_t'
gmake[2]: *** [libfreeswitch_la-switch_core_session.lo] Error 1
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
Hunt for a free channel for incoming calls that do not
preselect a channel (pevent->ring.channel == -1).
Verify the preselected channel for calls that do specify a channel
and in case the channel is already taken, hunt for a free one,
or abort with an error message (if the preselection was exclusive).
TE-mode channel selection is the same as before
(there's still room for improvement, though, but i'll save that for later).
The MSN/DDI filter code is moved into the TE-mode section (only useful there).
The duplicate ring detection had to be reworked. We now store the
call reference (CRV) in caller_data->call_reference of the selected channel
and do a CRV -> channel look up with find_channel_by_cref()
at the top of on_ring().
NOTE: This is only lightly tested (NT/TE mode), i'd either have to
write a lot of custom code to check it toroughly or the need for
a scriptable ISDN stack...
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
Callbacks are invoked from ftdm_span_start/_stop().
I/O is started before SIG and shut down in reverse order.
This is needed for ftmod_misdn, to move the mISDN message handling
into a separate thread (solving the mISDN socket vs. FreeTDM API issues).
With these callbacks, the I/O thread can be started after the span I/O configuration
has been (successfully) completed and stopped before destroying the span.
NOTE: Both SIG and I/O callbacks are called with the span mutex locked,
so threads created or destroyed synchronously in either of the custom
start/stop functions, can not use ftdm_span_*() functions that lock
the span mutex (e.g. ftdm_span_get_channel_count()).
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
The --enable-builtin-tiff option appends libs/tiff-3.8.2/libtiff/libtiff.la
to LIBS, causing the AC_CHECK_LIB([jpeg]...) check to fail, because
libtiff.la does not exist at configure time.
Temporarily store tiff and jpeg libs in TIFF_-/JPEG_LIBS variables and
append them to LIBS after all library checks have run.
Example error output:
configure:20049: checking for jpeg_start_compress in -ljpeg
configure:20074: cc -o conftest -O2 -pipe -fno-strict-aliasing -L/usr/local/lib conftest.c -ljpeg -lm /usr/home/ports/net/freeswitch-core-devel/work/freeswitch-1.2.1/libs/tiff-3.8.2/libtiff/libtiff.la >&5
cc: /usr/home/ports/net/freeswitch-core-devel/work/freeswitch-1.2.1/libs/tiff-3.8.2/libtiff/libtiff.la: No such file or directory
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
GNU variant of strerror_r() returns char *, while the XSI version returns int.
To make things worse, glibc ships both and added a unused result warning
in recent versions (2.16) causing the build to fail.
Add our own custom wrapper that always returns a pointer to the message buffer
and additionally make XSI versions of strerror_r() GNU compatible by
returning "Unknown error xxx" if no error message is available.
Fixes:
src/switch_rtp.c: In function 'rtp_common_read':
src/switch_rtp.c:3313:15: error: ignoring return value of 'strerror_r',
declared with attribute warn_unused_result [-Werror=unused-result]
cc1: all warnings being treated as errors
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
The len variable can, in certain situations (large burst of incoming non-SLIN audio),
exceed the size of the on-stack frame buffer, which causes ftdm_buffer_read_loop() to
overwrite the dt_buffer pointer.
Use ftdm_min() to make sure len (after conversion to SLIN units) isn't larger
than the frame buffer size.
Also adds are couple more code comments.
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
Resolves OPENZAP-189
Fixes:
src/ftmod/ftmod_isdn/ftmod_isdn.c: In function 'ftdm_isdn_931_34':
src/ftmod/ftmod_isdn/ftmod_isdn.c:902:21: error: variable 'status' set but not used [-Werror=unused-but-set-variable]
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
*sigh* of course there are two versions of strerror_r():
char *strerror_r() - GNU
int strerror_r() - non-GNU
Revert and back the drawing board...
This reverts commit 3c82033e53.
Fixes:
src/ftmod/ftmod_misdn/ftmod_misdn.c: In function 'misdn_handle_mph_information_ind':
src/ftmod/ftmod_misdn/ftmod_misdn.c:871:3: error: format '%lx' expects argument of type 'long unsigned int', but argument 13 has type 'uint64_t' [-Werror=format]
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
Do a "soft" wraparound with modulo, removes the ~0.5s tone glitch.
(Multiply ts.rate (samples) by two to match the offset unit (bytes, 2 per sample).)
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
Store the offset in the teletone buffer in the b-channel private data.
An NT-mode setup with ftmod_misdn showed severe (dial-)tone distortions
in a sound editor (330Hz sine wave phase errors), caused by
using a global teletone buffer offset.
Switching to a per-channel offset, that is advanced by the amount
of data actually written to the channel, removes (almost) all
distortions.
There is still a minimal phase error every ~500ms (audible) that
needs more investigating.
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
Might as well import these too...
ftdm_offset_of() - Get offset of member in structure.
ftdm_container_of() - Get pointer to enclosing structure from pointer to structure member.
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
ftdm_min(x,y) - Returns the smaller of the two values x and y.
ftdm_max(x,y) - Returns the larger of the two values x and y.
ftdm_clamp(val, min, max) - Returns value that is in the range [vmin,vmax].
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
Remove the 'state' variable of per-channel data, use active flag exclusively to track
open/close state.
Add misdn_activate_channel()/misdn_deactivate_channel() helper functions, rename old
one to _misdn_toggle_channel() (internal).
Add _nowait variant of channel de-/activation function, that just sends the mISDN request message.
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
Store call CRV in caller_data.call_reference and use call private to hold the
FreeTDM channel object.
Remove isdn_data->channels_{local,remote,outbound}_crv arrays.
Allow (and force) inbound call state transition DIALTONE -> DOWN for
incoming RELEASE COMPLETE messages in NT mode.
Dialtone in NT mode works, everything else needs more testing.
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
ftmod_misdn currently returns len == 0 if the incoming message,
that triggered the read() call, does not contain any data.
Users of ftdm_channel_read() need to handle this case, or they
may possibly end up in an endless loop.
This patch reworks the ftdm_channel_read() handling in ftmod_isdn
and prevents it from entering an endless loop. The read error counter
is reset on first sucessful read w/ data.
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
cc1: warnings being treated as errors
./src/ftmod/ftmod_libpri/ftmod_libpri.c: In function 'msn_filter_foreach':
./src/ftmod/ftmod_libpri/ftmod_libpri.c:422: warning: dereferencing type-punned pointer will break strict-aliasing rules
make: *** [ftmod_libpri_la-ftmod_libpri.lo] Error 1
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
Fixes:
cp ESL.so /var/tmp/por.../image/usr/lib64/php5.3/lib/extensions/no-debug-zts-20090626
cp: cannot create regular file `/var/tmp/por.../image/usr/lib64/php5.3/lib/extensions/no-debug-zts-20090626': No such file or directory
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
Debug builds add -std=c99 (or -xc99 for suncc) to CFLAGS
(AX_CFLAGS_WARN_ALL_ANSI configure macro).
Non-debug builds do not invoke AX_CFLAGS_WARN_ALL_ANSI checks and
therefore won't have C99 support enabled, which breaks the build of
mod_http_cache due to "for (int i... )"-style C99 loops.
NOTE: AC_PROG_CC_C99 would make a lot of sense here and MSVC (2005)
accepts "for (int ...)" constructs too.
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
Two fixes:
Use ftdm_set_string() instead of sprintf() (seriously, wtf?).
Drop invalid, needless argument to ftdm_log().
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
Neither of them accepts extra arguments and ftmod_sangoma_isdn is calling
ftmod_assert() with a char * msg argument.
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
Use switch_event_add_header_string() where needed and add a
dummy "%s" format string to switch_event_add_body() calls.
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
The format string checks already caught a couple crash-worthy bugs and this
commit fixes a couple more.
Also includes __ftdm_check_scanf(), for completeness (currently unused).
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>