• Stefan Knoblich's avatar
    ftmod_misdn: Use a per-span I/O thread to handle B-channel data. · 5b499e8a
    Stefan Knoblich 提交于
    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: 's avatarStefan Knoblich <stkn@openisdn.net>
    5b499e8a
名称
最后提交
最后更新
..
ftmod 正在载入提交数据...
include 正在载入提交数据...
isdn 正在载入提交数据...
ss7 正在载入提交数据...
detect_dtmf.c 正在载入提交数据...
detect_tones.c 正在载入提交数据...
fsk.c 正在载入提交数据...
ftdm_backtrace.c 正在载入提交数据...
ftdm_buffer.c 正在载入提交数据...
ftdm_call_utils.c 正在载入提交数据...
ftdm_callerid.c 正在载入提交数据...
ftdm_config.c 正在载入提交数据...
ftdm_cpu_monitor.c 正在载入提交数据...
ftdm_dso.c 正在载入提交数据...
ftdm_io.c 正在载入提交数据...
ftdm_queue.c 正在载入提交数据...
ftdm_sched.c 正在载入提交数据...
ftdm_state.c 正在载入提交数据...
ftdm_threadmutex.c 正在载入提交数据...
ftdm_variables.c 正在载入提交数据...
g711.c 正在载入提交数据...
hashtable.c 正在载入提交数据...
hashtable_itr.c 正在载入提交数据...
libteletone_detect.c 正在载入提交数据...
libteletone_generate.c 正在载入提交数据...
priserver.c 正在载入提交数据...
sangoma_pri.c 正在载入提交数据...
sangoma_pri.h 正在载入提交数据...
testanalog.c 正在载入提交数据...
testapp.c 正在载入提交数据...
testcid.c 正在载入提交数据...
testisdn.c 正在载入提交数据...
testpri.c 正在载入提交数据...
testr2.c 正在载入提交数据...
testtones.c 正在载入提交数据...
uart.c 正在载入提交数据...