2021-12-29 16:59:00 +00:00
|
|
|
/*********************************************************************************
|
|
|
|
* sangoma_mgd.c -- Sangoma Media Gateway Daemon for Sangoma/Wanpipe Cards
|
|
|
|
*
|
2021-12-29 17:26:11 +00:00
|
|
|
* Copyright 05-09, Nenad Corbic <ncorbic@sangoma.com>
|
2021-12-29 16:59:00 +00:00
|
|
|
* Anthony Minessale II <anthmct@yahoo.com>
|
|
|
|
*
|
|
|
|
* This program is free software, distributed under the terms of
|
|
|
|
* the GNU General Public License
|
|
|
|
*
|
|
|
|
* =============================================
|
2021-12-29 17:26:11 +00:00
|
|
|
*
|
2021-12-29 17:29:00 +00:00
|
|
|
* v1.59 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Changed w1g1 to s1c1
|
|
|
|
*
|
|
|
|
* v1.58 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Added bridge tdm to ip functionality
|
|
|
|
*
|
|
|
|
* v1.57 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Support for woomera multiple profiles
|
|
|
|
*
|
|
|
|
* v1.56 David Yat Sin <dyatsin@sangoma.com>
|
|
|
|
* Changed BRI to run with HWEC in non-persist mode
|
|
|
|
*
|
|
|
|
* v1.55 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Updated the base media port to 10000 and max media ports to 5000
|
|
|
|
*
|
2021-12-29 17:28:39 +00:00
|
|
|
* v1.54 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Bug added in 1.51 release causing call on channel 31 to fail.
|
|
|
|
*
|
|
|
|
* v1.53 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Added progress message
|
2021-12-29 17:28:15 +00:00
|
|
|
*
|
2021-12-29 17:28:39 +00:00
|
|
|
* v1.52 David Yat Sin <dyatsin@sangoma.com>
|
|
|
|
* Changed sangoma_open_span_chan to __sangoma_span_chan
|
|
|
|
* to enabled shared used of file descriptors when using
|
|
|
|
* with PRI in NFAS mode
|
|
|
|
*
|
2021-12-29 17:28:15 +00:00
|
|
|
* v1.51 David Yat Sin <dyatsin@sangoma.com>
|
|
|
|
* MAX_SPANS increased to 32.
|
|
|
|
* Fix for server.process_table declared incorrectly
|
|
|
|
*
|
2021-12-29 17:27:14 +00:00
|
|
|
* v1.50 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Logic to support multiple woomera clients hanging up the
|
|
|
|
* channel. This feature now supprorts woomera loadbalancing
|
|
|
|
* with extension check on the client end. Example, two Asterisk
|
|
|
|
* systems setup where Asterisk with correct extension gets the
|
|
|
|
* call.
|
|
|
|
* Changed log levels: Loglevel 1 = production
|
|
|
|
* Loglevel 2 = Boost TX/RX EVENTS
|
|
|
|
* Loglevel 3 = Woomera RX Messages
|
|
|
|
* Loglevel 4 = call setup debugging
|
|
|
|
* Loglevel 5 = extra debugging
|
|
|
|
* Loglevel 10 = full debugging
|
|
|
|
*
|
|
|
|
* v1.49 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Removed tv from sigboost to make it binary compatible
|
|
|
|
* Updated release cause on double use return code.
|
|
|
|
*
|
|
|
|
* v1.48 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Konrad Hammel <konrad@sangoma.com>
|
|
|
|
* Jun 30 2009
|
|
|
|
* Added feature to disable/enable HWEC on channels that are
|
|
|
|
* passing a call with a "data" only transfer capability
|
|
|
|
*
|
2021-12-29 17:26:11 +00:00
|
|
|
* v1.47 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Apr 30 2009
|
|
|
|
* Updated hangup woomera events. Each event must
|
|
|
|
* be followed by a woomera error code 200=ok >299=no ok.
|
|
|
|
* This update fixes the chan_woomera socket write
|
|
|
|
* warnings.
|
|
|
|
*
|
|
|
|
* v1.46 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Mar 27 2009
|
|
|
|
* Major updates on socket handling. A bug was introducted
|
|
|
|
* when cmm and trunk was merged.
|
|
|
|
* Added configuration print in the logs.
|
|
|
|
*
|
|
|
|
* v1.45 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Mar 19 2009
|
|
|
|
* Outbound call timeout defaulted to 300 seconds.
|
|
|
|
* Timeout on answer instead of accept.
|
|
|
|
*
|
|
|
|
* v1.44 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Mar 19 2009
|
|
|
|
* Adjustable boost size. Added boost version check.
|
|
|
|
*
|
|
|
|
* v1.43 David Yat Sin <dyatsin@sangoma.com>
|
|
|
|
* Feb 25 2009
|
|
|
|
* Merged CMM and Trunk
|
|
|
|
*
|
|
|
|
* v1.42 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Jan 26 2008
|
|
|
|
* Call Bearer Capability
|
|
|
|
* BugFix: Hangup NACK was sent out with invalid cause 0
|
|
|
|
*
|
|
|
|
* v1.41 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Jan 12 2008
|
|
|
|
* Fixed the NACK with cause 0 bug.
|
|
|
|
* Added cause 19 on call timeout.
|
|
|
|
* Added configuration option call_timeout to timeout
|
|
|
|
* outbound calls.
|
|
|
|
*
|
|
|
|
* v1.40 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Dec 10 2008
|
|
|
|
* Check for Rx call overrun.
|
|
|
|
* In unlikely case sangoma_mgd goes out of
|
|
|
|
* sync with boost.
|
|
|
|
*
|
|
|
|
* v1.39 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Sep 17 2008
|
|
|
|
* Updated for Unit Test
|
|
|
|
* Bug fix in Loop Logic, possible race
|
|
|
|
* between media and woomera thread on loop end.
|
|
|
|
*
|
|
|
|
* v1.38 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Sep 5 2008
|
|
|
|
* Added a Double use of setup id logic.
|
|
|
|
* Currently double use call gets dropped.
|
|
|
|
*
|
|
|
|
* v1.37 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Sep 2 2008
|
|
|
|
* Bug fix in REMOVE LOOP logic continued
|
|
|
|
* The woomera->sock in loop logic was set to 0.
|
|
|
|
* Closing it failed the next call.
|
|
|
|
*
|
|
|
|
* v1.36 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Aug 28 2008
|
|
|
|
* Bug fix in REMOVE LOOP logic
|
|
|
|
* Remove F from incoming calls by default
|
|
|
|
* Check for errno on poll()
|
|
|
|
* Do not delay in closing socket on media down.
|
|
|
|
*
|
|
|
|
* v1.35cmm Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Jul 28 2008
|
|
|
|
* Bug fixes on ACK Timeout and trunk release
|
|
|
|
* Added a thread logger
|
|
|
|
* Increased max spans to 32
|
|
|
|
*
|
|
|
|
* v1.34cmm Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Jul 24 2008
|
|
|
|
* Clean up the setup id on CALL STOP ACK
|
|
|
|
*
|
|
|
|
* v1.33cmm Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Jul 24 2008
|
|
|
|
* The CALL STOP timeout function had a bug
|
|
|
|
* resulting in false blocking of tank ids
|
|
|
|
* due to STOP ACK Timeouts.
|
|
|
|
*
|
2021-12-29 17:22:11 +00:00
|
|
|
* v1.33 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Jul 18 2008
|
|
|
|
* Added UDP Sequencing to check for dropped frames
|
|
|
|
* Should only be used for debugging.
|
|
|
|
*
|
|
|
|
* v1.32 David Yat Sin <davidy@sangoma.com>
|
|
|
|
* Jul 17 2008
|
|
|
|
* Support for d-channel incoming digit
|
|
|
|
* passthrough to Asterisk
|
2021-12-29 17:26:11 +00:00
|
|
|
*
|
|
|
|
* v1.32cmm Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Jun 03 2008
|
|
|
|
* Implemented new Restart ACK Policy
|
|
|
|
* Split the Event packet into 2 types
|
|
|
|
*
|
|
|
|
* v1.31cmm Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Apr 04 2008
|
|
|
|
* New CMM Restart procedure for boost
|
|
|
|
* Block TRUNK ID on ACK Timeout
|
2021-12-29 17:22:11 +00:00
|
|
|
*
|
|
|
|
* v1.31 David Yat Sin <davidy@sangoma.com>
|
|
|
|
* Apr 29 2008
|
|
|
|
* Support for HW DTMF events.
|
|
|
|
*
|
2021-12-29 17:15:08 +00:00
|
|
|
* v1.30 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Feb 08 2008
|
|
|
|
* The fix in v1.26 causes double stop.
|
|
|
|
* I took out the v1.26 fix and added
|
|
|
|
* a big warning if that condition is
|
|
|
|
* ever reached.
|
|
|
|
*
|
|
|
|
* v1.29 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Feb 07 2008
|
|
|
|
* Added strip_cid_non_digits option
|
|
|
|
*
|
|
|
|
* v1.28 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Feb 06 2008
|
|
|
|
* Fixed a memory leak in clone event
|
|
|
|
* function. Added memory check subsystem
|
|
|
|
*
|
2021-12-29 17:14:45 +00:00
|
|
|
* v1.27 Nenad Corbic <ncorbic@sangoma.com>
|
2021-12-29 17:15:08 +00:00
|
|
|
* Jan 24 2008
|
2021-12-29 17:14:45 +00:00
|
|
|
* Fixed a memory leak on incoming calls
|
|
|
|
* Removed the use of server listener which
|
|
|
|
* was not used
|
|
|
|
*
|
2021-12-29 17:14:12 +00:00
|
|
|
* v1.26 Nenad Corbic <ncorbic@sangoma.com>
|
2021-12-29 17:15:08 +00:00
|
|
|
* Jan 18 2008
|
2021-12-29 17:14:12 +00:00
|
|
|
* Fixed hangup after invalid Answer or Ack Session
|
|
|
|
* Can cause double use of setup id - now fixed
|
|
|
|
* Update on autoacm on accept check for acked.
|
|
|
|
*
|
|
|
|
* v1.25 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Dec 31 2007
|
|
|
|
* Removed UDP Resync it can cause skb_over errors.
|
|
|
|
* Moved RDNIS message to higher debug level
|
|
|
|
*
|
|
|
|
* v1.24 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Nov 30 2007
|
|
|
|
* Bug fix on return code on ALL ckt busy
|
|
|
|
*
|
|
|
|
* v1.23 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Bug fix on socket open. Check for retun code >= 0
|
|
|
|
*
|
|
|
|
* v1.22 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Nov 27 2007
|
|
|
|
* Updated DTMF Tx function
|
|
|
|
* Fixed - dtmf tx without voice
|
|
|
|
* Fxied - dtmf clipping.
|
|
|
|
*
|
|
|
|
* v1.21 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Nov 25 2007
|
|
|
|
* Major unit testing of each state
|
|
|
|
* Numerous bug fixes for non autoacm mode.
|
|
|
|
* Changed "Channel-Name" to tg/cic
|
|
|
|
* Added compile option WANPIPE_CHAN_NAME to change Asterisk channel
|
|
|
|
* name of chan_woomera.so. So one can use Dial(SS7/g1/${EXTE})
|
|
|
|
* instead of WOOMERA (for example)
|
|
|
|
*
|
|
|
|
* v1.20 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Added option for Auto ACM response mode.
|
|
|
|
*
|
2021-12-29 17:12:33 +00:00
|
|
|
* v1.19 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Configurable DTMF
|
|
|
|
* Bug fix in release codes (all ckt busy)
|
|
|
|
*
|
|
|
|
* v1.18 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Added new rel cause support based on
|
|
|
|
* digits instead of strings.
|
|
|
|
*
|
2021-12-29 17:11:50 +00:00
|
|
|
* v1.17 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Added session support
|
|
|
|
*
|
2021-12-29 17:03:37 +00:00
|
|
|
* v1.16 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Added hwec disable on loop ccr
|
|
|
|
*
|
2021-12-29 17:03:04 +00:00
|
|
|
* v1.15 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Updated DTMF Locking
|
|
|
|
* Added delay between digits
|
|
|
|
*
|
|
|
|
* v1.14 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Updated DTMF Library
|
|
|
|
* Fixed DTMF synchronization
|
|
|
|
*
|
|
|
|
* v1.13 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Woomera OPAL Dialect
|
|
|
|
* Added Congestion control
|
|
|
|
* Added SCTP
|
|
|
|
* Added priority ISUP queue
|
|
|
|
* Fixed presentation
|
|
|
|
*
|
|
|
|
* v1.12 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Fixed CCR
|
|
|
|
* Removed socket shutdown on end call.
|
|
|
|
* Let Media thread shutodwn sockets.
|
|
|
|
*
|
2021-12-29 16:59:00 +00:00
|
|
|
* v1.11 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Fixed Remote asterisk/woomera connection
|
|
|
|
* Increased socket timeouts
|
|
|
|
*
|
|
|
|
* v1.10 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Added Woomera OPAL dialect.
|
|
|
|
* Start montor thread in priority
|
|
|
|
*
|
|
|
|
* v1.9 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Added Loop mode for ccr
|
|
|
|
* Added remote debug enable
|
|
|
|
* Fixed syslog logging.
|
|
|
|
*
|
|
|
|
* v1.8 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Added a ccr loop mode for each channel.
|
|
|
|
* Boost can set any channel in loop mode
|
|
|
|
*
|
|
|
|
* v1.7 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Pass trunk group number to incoming call
|
|
|
|
* chan woomera will use it to append to context
|
|
|
|
* name. Added presentation feature.
|
|
|
|
*
|
|
|
|
* v1.6 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Use only ALAW and MLAW not SLIN.
|
|
|
|
* This reduces the load quite a bit.
|
|
|
|
* Send out ALAW/ULAW format on HELLO message.
|
|
|
|
* RxTx Gain is done now in chan_woomera.
|
|
|
|
*
|
|
|
|
* v1.5 Nenad Corbic <ncorbic@sangoma.com>
|
|
|
|
* Bug fix in START_NACK_ACK handling.
|
|
|
|
* When we receive START_NACK we must alwasy pull tank before
|
|
|
|
* we send out NACK_ACK this way we will not try to send NACK
|
|
|
|
* ourself.
|
|
|
|
*********************************************************************************/
|
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
#include "sangoma_mgd.h"
|
2021-12-29 17:15:08 +00:00
|
|
|
#include "sangoma_mgd_memdbg.h"
|
2021-12-29 17:12:33 +00:00
|
|
|
#include "q931_cause.h"
|
2021-12-29 17:26:11 +00:00
|
|
|
#include "smg_capabilities.h"
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
int pipe_fd[2];
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
#ifdef CODEC_LAW_DEFAULT
|
|
|
|
static uint32_t codec_sample=8;
|
|
|
|
#else
|
|
|
|
static uint32_t codec_sample=16;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static char ps_progname[]="sangoma_mgd";
|
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
static struct woomera_interface woomera_dead_dev;
|
|
|
|
|
2021-12-29 17:29:00 +00:00
|
|
|
|
|
|
|
/* For 3.4. release always set to 1 */
|
|
|
|
#ifdef BRI_PROT
|
|
|
|
static unsigned char tdmv_hwec_persist = 1;
|
|
|
|
#else
|
|
|
|
static unsigned char tdmv_hwec_persist = 1;
|
|
|
|
#endif
|
2021-12-29 17:26:11 +00:00
|
|
|
struct woomera_server server;
|
|
|
|
|
2021-12-29 17:29:00 +00:00
|
|
|
struct smg_tdm_ip_bridge g_smg_ip_bridge_idx[MAX_SMG_BRIDGE];
|
|
|
|
pthread_mutex_t g_smg_ip_bridge_lock;
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
#if 0
|
|
|
|
#define DOTRACE
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2021-12-29 17:29:00 +00:00
|
|
|
#define SMG_VERSION "v1.59"
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
/* enable early media */
|
|
|
|
#if 1
|
|
|
|
#define WOOMERA_EARLY_MEDIA 1
|
|
|
|
#endif
|
2021-12-29 17:22:11 +00:00
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
|
|
|
|
#define SMG_DTMF_ON 60
|
|
|
|
#define SMG_DTMF_OFF 10
|
|
|
|
#define SMG_DTMF_RATE 8000
|
2021-12-29 17:26:11 +00:00
|
|
|
#define SMG_DEFAULT_CALL_TIMEOUT 300
|
2021-12-29 17:03:04 +00:00
|
|
|
|
|
|
|
#if 0
|
|
|
|
#define MEDIA_SOCK_SHUTDOWN 1
|
|
|
|
#endif
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
#ifdef DOTRACE
|
|
|
|
static int tc = 0;
|
|
|
|
#endif
|
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
#if 0
|
|
|
|
#warning "NENAD: HPTDM API"
|
|
|
|
#define WP_HPTDM_API 1
|
|
|
|
#else
|
|
|
|
#undef WP_HPTDM_API
|
|
|
|
#endif
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
#ifdef WP_HPTDM_API
|
|
|
|
hp_tdm_api_span_t *hptdmspan[WOOMERA_MAX_SPAN];
|
|
|
|
#endif
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:22:11 +00:00
|
|
|
#if 0
|
|
|
|
#define SMG_DROP_SEQ 1
|
|
|
|
#warning "SMG Debug feature Drop Seq Enabled"
|
|
|
|
static int drop_seq=0;
|
|
|
|
#else
|
|
|
|
#undef SMG_DROP_SEQ
|
|
|
|
#endif
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 17:28:39 +00:00
|
|
|
|
|
|
|
#if 0
|
|
|
|
#define SMG_NO_MEDIA
|
|
|
|
#warning "SMG No Media Defined"
|
|
|
|
#else
|
|
|
|
#undef SMG_NO_MEDIA
|
|
|
|
#endif
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
const char WELCOME_TEXT[] =
|
|
|
|
"================================================================================\n"
|
2021-12-29 17:29:00 +00:00
|
|
|
"Sangoma Media Gateway Daemon v1.59 \n"
|
2021-12-29 17:26:11 +00:00
|
|
|
"\n"
|
2021-12-29 16:59:00 +00:00
|
|
|
"TDM Signal Media Gateway for Sangoma/Wanpipe Cards\n"
|
|
|
|
"Copyright 2005, 2006, 2007 \n"
|
2021-12-29 17:03:04 +00:00
|
|
|
"Nenad Corbic <ncorbic@sangoma.com>, Anthony Minessale II <anthmct@yahoo.com>\n"
|
2021-12-29 16:59:00 +00:00
|
|
|
"This program is free software, distributed under the terms of\n"
|
|
|
|
"the GNU General Public License\n"
|
|
|
|
"================================================================================\n"
|
|
|
|
"";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int coredump=1;
|
2021-12-29 17:26:11 +00:00
|
|
|
static int autoacm=0;
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:20:09 +00:00
|
|
|
/* FIXME: Should be done in cfg file */
|
|
|
|
#if defined(BRI_PROT)
|
|
|
|
int max_spans=WOOMERA_BRI_MAX_SPAN;
|
|
|
|
int max_chans=WOOMERA_BRI_MAX_CHAN;
|
|
|
|
#else
|
2021-12-29 17:27:14 +00:00
|
|
|
/* PRI_PROT uses these defines as well */
|
2021-12-29 17:20:09 +00:00
|
|
|
int max_spans=WOOMERA_MAX_SPAN;
|
|
|
|
int max_chans=WOOMERA_MAX_CHAN;
|
|
|
|
#endif
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
static int launch_media_tdm_thread(struct woomera_interface *woomera);
|
|
|
|
static int launch_woomera_thread(struct woomera_interface *woomera);
|
2021-12-29 17:22:11 +00:00
|
|
|
static void woomera_check_digits (struct woomera_interface *woomera);
|
2021-12-29 17:11:50 +00:00
|
|
|
static struct woomera_interface *alloc_woomera(void);
|
2021-12-29 17:22:11 +00:00
|
|
|
static void handle_event_dtmf(struct woomera_interface *woomera, unsigned char dtmf_digit);
|
2021-12-29 17:02:04 +00:00
|
|
|
|
2021-12-29 17:12:33 +00:00
|
|
|
q931_cause_to_str_array_t q931_cause_to_str_array[255];
|
2021-12-29 17:26:11 +00:00
|
|
|
bearer_cap_to_str_array_t bearer_cap_to_str_array[255];
|
|
|
|
uil1p_to_str_array_t uil1p_to_str_array[255];
|
2021-12-29 17:12:33 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
static int isup_exec_command(int span, int chan, int id, int cmd, int cause)
|
2021-12-29 16:59:00 +00:00
|
|
|
{
|
2021-12-29 17:26:11 +00:00
|
|
|
short_signal_event_t oevent;
|
|
|
|
int retry=5;
|
|
|
|
|
2021-12-29 17:28:39 +00:00
|
|
|
call_signal_event_init((short_signal_event_t*)&oevent, cmd, chan, span);
|
2021-12-29 17:26:11 +00:00
|
|
|
oevent.release_cause = cause;
|
|
|
|
|
|
|
|
if (id >= 0) {
|
|
|
|
oevent.call_setup_id = id;
|
|
|
|
}
|
|
|
|
isup_exec_cmd_retry:
|
|
|
|
if (call_signal_connection_write(&server.mcon, (call_signal_event_t*)&oevent) < 0){
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
--retry;
|
|
|
|
if (retry <= 0) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log,
|
2021-12-29 17:26:11 +00:00
|
|
|
"Critical System Error: Failed to tx on ISUP socket: %s\n",
|
|
|
|
strerror(errno));
|
|
|
|
return -1;
|
|
|
|
} else {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log,
|
2021-12-29 17:26:11 +00:00
|
|
|
"System Warning: Failed to tx on ISUP socket: %s :retry %i\n",
|
|
|
|
strerror(errno),retry);
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
goto isup_exec_cmd_retry;
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
return 0;
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
2021-12-29 17:28:39 +00:00
|
|
|
static int isup_exec_event(call_signal_event_t *event)
|
|
|
|
{
|
|
|
|
int retry=5;
|
|
|
|
|
|
|
|
isup_exec_cmd_retry:
|
|
|
|
if (call_signal_connection_write(&server.mcon, event) < 0){
|
|
|
|
|
|
|
|
--retry;
|
|
|
|
if (retry <= 0) {
|
|
|
|
log_printf(SMG_LOG_ALL, server.log,
|
|
|
|
"Critical System Error: Failed to tx on ISUP socket: %s\n",
|
|
|
|
strerror(errno));
|
|
|
|
return -1;
|
|
|
|
} else {
|
|
|
|
log_printf(SMG_LOG_ALL, server.log,
|
|
|
|
"System Warning: Failed to tx on ISUP socket: %s :retry %i\n",
|
|
|
|
strerror(errno),retry);
|
|
|
|
}
|
|
|
|
|
|
|
|
goto isup_exec_cmd_retry;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:02:04 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
static int isup_exec_commandp(int span, int chan, int id, int cmd, int cause)
|
2021-12-29 16:59:00 +00:00
|
|
|
{
|
2021-12-29 17:26:11 +00:00
|
|
|
short_signal_event_t oevent;
|
|
|
|
int retry=5;
|
2021-12-29 17:15:08 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
call_signal_event_init(&oevent, cmd, chan, span);
|
|
|
|
oevent.release_cause = cause;
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
if (id >= 0) {
|
|
|
|
oevent.call_setup_id = id;
|
|
|
|
}
|
|
|
|
isup_exec_cmd_retry:
|
|
|
|
if (call_signal_connection_writep(&server.mconp, (call_signal_event_t*)&oevent) < 0){
|
|
|
|
|
|
|
|
--retry;
|
|
|
|
if (retry <= 0) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log,
|
2021-12-29 17:26:11 +00:00
|
|
|
"Critical System Error: Failed to tx on ISUP socket: %s\n",
|
|
|
|
strerror(errno));
|
|
|
|
return -1;
|
|
|
|
} else {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log,
|
2021-12-29 17:26:11 +00:00
|
|
|
"System Warning: Failed to tx on ISUP socket: %s :retry %i\n",
|
|
|
|
strerror(errno),retry);
|
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
goto isup_exec_cmd_retry;
|
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
return 0;
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
|
2021-12-29 17:22:11 +00:00
|
|
|
static int get_span_chan_from_interface(char* interface, int *span_ptr, int *chan_ptr)
|
|
|
|
{
|
|
|
|
int span, chan;
|
2021-12-29 17:29:00 +00:00
|
|
|
int err;
|
2021-12-29 17:22:11 +00:00
|
|
|
|
2021-12-29 17:29:00 +00:00
|
|
|
err=sscanf(interface, "s%dc%d", &span, &chan);
|
|
|
|
if (err!=2) {
|
|
|
|
err=sscanf(interface, "w%dg%d", &span, &chan);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (err==2) {
|
2021-12-29 17:22:11 +00:00
|
|
|
if (smg_validate_span_chan(span,chan) != 0) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, server.log,
|
2021-12-29 17:22:11 +00:00
|
|
|
"WOOMERA Warning invalid span chan in interface %s\n",
|
|
|
|
interface);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
*span_ptr = span;
|
|
|
|
*chan_ptr = chan;
|
|
|
|
return 0;
|
|
|
|
}
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "ERROR: Failed to get span chan from interface:[%s]\n", interface, span, chan);
|
2021-12-29 17:22:11 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2021-12-29 17:12:33 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
static int socket_printf(int socket, char *fmt, ...)
|
|
|
|
{
|
|
|
|
char *data;
|
|
|
|
int ret = 0;
|
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
if (socket < 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
va_start(ap, fmt);
|
|
|
|
#ifdef SOLARIS
|
2021-12-29 17:15:08 +00:00
|
|
|
data = (char *) smg_malloc(2048);
|
2021-12-29 16:59:00 +00:00
|
|
|
vsnprintf(data, 2048, fmt, ap);
|
|
|
|
#else
|
|
|
|
ret = vasprintf(&data, fmt, ap);
|
|
|
|
#endif
|
|
|
|
va_end(ap);
|
|
|
|
if (ret == -1) {
|
|
|
|
fprintf(stderr, "Memory Error\n");
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Crtical ERROR: Memory Error!\n");
|
2021-12-29 16:59:00 +00:00
|
|
|
} else {
|
|
|
|
int err;
|
|
|
|
int len = strlen(data);
|
|
|
|
err=send(socket, data, strlen(data), 0);
|
|
|
|
if (err != strlen(data)) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_8, server.log, "ERROR: Failed to send data to woomera socket(%i): err=%i len=%d %s\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
socket,err,len,strerror(errno));
|
|
|
|
ret = err;
|
|
|
|
} else {
|
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
free(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int woomera_next_pair(struct woomera_config *cfg, char **var, char **val)
|
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
char *p, *end;
|
|
|
|
|
|
|
|
*var = *val = NULL;
|
|
|
|
|
|
|
|
for(;;) {
|
|
|
|
cfg->lineno++;
|
|
|
|
|
|
|
|
if (!fgets(cfg->buf, sizeof(cfg->buf), cfg->file)) {
|
|
|
|
ret = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
*var = cfg->buf;
|
|
|
|
|
|
|
|
if (**var == '[' && (end = strchr(*var, ']'))) {
|
|
|
|
*end = '\0';
|
|
|
|
(*var)++;
|
|
|
|
strncpy(cfg->category, *var, sizeof(cfg->category) - 1);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (**var == '#' || **var == '\n' || **var == '\r') {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((end = strchr(*var, '#'))) {
|
|
|
|
*end = '\0';
|
|
|
|
end--;
|
|
|
|
} else if ((end = strchr(*var, '\n'))) {
|
|
|
|
if (*end - 1 == '\r') {
|
|
|
|
end--;
|
|
|
|
}
|
|
|
|
*end = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
p = *var;
|
|
|
|
while ((*p == ' ' || *p == '\t') && p != end) {
|
|
|
|
*p = '\0';
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
*var = p;
|
|
|
|
|
|
|
|
if (!(*val = strchr(*var, '='))) {
|
|
|
|
ret = -1;
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Invalid syntax on %s: line %d\n", cfg->path, cfg->lineno);
|
2021-12-29 16:59:00 +00:00
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
p = *val - 1;
|
|
|
|
*(*val) = '\0';
|
|
|
|
(*val)++;
|
|
|
|
if (*(*val) == '>') {
|
|
|
|
*(*val) = '\0';
|
|
|
|
(*val)++;
|
|
|
|
}
|
|
|
|
|
|
|
|
while ((*p == ' ' || *p == '\t') && p != *var) {
|
|
|
|
*p = '\0';
|
|
|
|
p--;
|
|
|
|
}
|
|
|
|
|
|
|
|
p = *val;
|
|
|
|
while ((*p == ' ' || *p == '\t') && p != end) {
|
|
|
|
*p = '\0';
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
*val = p;
|
|
|
|
ret = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
static void woomera_set_span_chan(struct woomera_interface *woomera, int span, int chan)
|
|
|
|
{
|
|
|
|
pthread_mutex_lock(&woomera->vlock);
|
|
|
|
woomera->span = span;
|
|
|
|
woomera->chan = chan;
|
|
|
|
pthread_mutex_unlock(&woomera->vlock);
|
|
|
|
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
static struct woomera_event *new_woomera_event_printf(struct woomera_event *ebuf, char *fmt, ...)
|
|
|
|
{
|
|
|
|
struct woomera_event *event = NULL;
|
|
|
|
int ret = 0;
|
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
if (ebuf) {
|
|
|
|
event = ebuf;
|
|
|
|
} else if (!(event = new_woomera_event())) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Memory Error queuing event!\n");
|
2021-12-29 16:59:00 +00:00
|
|
|
return NULL;
|
|
|
|
} else {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
va_start(ap, fmt);
|
|
|
|
#ifdef SOLARIS
|
2021-12-29 17:15:08 +00:00
|
|
|
event->data = (char *) smg_malloc(2048);
|
2021-12-29 16:59:00 +00:00
|
|
|
vsnprintf(event->data, 2048, fmt, ap);
|
|
|
|
#else
|
2021-12-29 17:15:08 +00:00
|
|
|
ret = smg_vasprintf(&event->data, fmt, ap);
|
2021-12-29 16:59:00 +00:00
|
|
|
#endif
|
|
|
|
va_end(ap);
|
|
|
|
if (ret == -1) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Memory Error queuing event!\n");
|
2021-12-29 16:59:00 +00:00
|
|
|
destroy_woomera_event(&event, EVENT_FREE_DATA);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return event;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct woomera_event *woomera_clone_event(struct woomera_event *event)
|
|
|
|
{
|
|
|
|
struct woomera_event *clone;
|
|
|
|
|
|
|
|
if (!(clone = new_woomera_event())) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:15:08 +00:00
|
|
|
/* This overwrites the MALLOC in clone causing a memory leak */
|
2021-12-29 16:59:00 +00:00
|
|
|
memcpy(clone, event, sizeof(*event));
|
2021-12-29 17:15:08 +00:00
|
|
|
|
|
|
|
/* We must set the malloc flag back so that this event
|
|
|
|
* will be deleted */
|
|
|
|
_woomera_set_flag(clone, WFLAG_MALLOC);
|
2021-12-29 16:59:00 +00:00
|
|
|
clone->next = NULL;
|
2021-12-29 17:15:08 +00:00
|
|
|
clone->data = smg_strdup(event->data);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
return clone;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void enqueue_event(struct woomera_interface *woomera,
|
|
|
|
struct woomera_event *event,
|
|
|
|
event_args free_data)
|
|
|
|
{
|
|
|
|
struct woomera_event *ptr, *clone = NULL;
|
|
|
|
|
|
|
|
assert(woomera != NULL);
|
|
|
|
assert(event != NULL);
|
|
|
|
|
|
|
|
if (!(clone = woomera_clone_event(event))) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Error Cloning Event\n");
|
2021-12-29 16:59:00 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
pthread_mutex_lock(&woomera->queue_lock);
|
|
|
|
|
|
|
|
for (ptr = woomera->event_queue; ptr && ptr->next ; ptr = ptr->next);
|
|
|
|
|
|
|
|
if (ptr) {
|
|
|
|
ptr->next = clone;
|
|
|
|
} else {
|
|
|
|
woomera->event_queue = clone;
|
|
|
|
}
|
|
|
|
|
|
|
|
pthread_mutex_unlock(&woomera->queue_lock);
|
|
|
|
|
|
|
|
woomera_set_flag(woomera, WFLAG_EVENT);
|
|
|
|
|
|
|
|
if (free_data && event->data) {
|
|
|
|
/* The event has been duplicated, the original data
|
|
|
|
* should be freed */
|
2021-12-29 17:15:08 +00:00
|
|
|
smg_free(event->data);
|
2021-12-29 16:59:00 +00:00
|
|
|
event->data=NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *dequeue_event(struct woomera_interface *woomera)
|
|
|
|
{
|
|
|
|
struct woomera_event *event;
|
|
|
|
char *data = NULL;
|
|
|
|
|
|
|
|
if (!woomera) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
pthread_mutex_lock(&woomera->queue_lock);
|
|
|
|
if (woomera->event_queue) {
|
|
|
|
event = woomera->event_queue;
|
|
|
|
woomera->event_queue = event->next;
|
|
|
|
data = event->data;
|
|
|
|
pthread_mutex_unlock(&woomera->queue_lock);
|
|
|
|
|
|
|
|
destroy_woomera_event(&event, EVENT_KEEP_DATA);
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
pthread_mutex_unlock(&woomera->queue_lock);
|
|
|
|
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int enqueue_event_on_listeners(struct woomera_event *event)
|
|
|
|
{
|
|
|
|
struct woomera_listener *ptr;
|
|
|
|
int x = 0;
|
|
|
|
|
|
|
|
assert(event != NULL);
|
|
|
|
|
|
|
|
pthread_mutex_lock(&server.listen_lock);
|
|
|
|
for (ptr = server.listeners ; ptr ; ptr = ptr->next) {
|
|
|
|
enqueue_event(ptr->woomera, event, EVENT_KEEP_DATA);
|
|
|
|
x++;
|
|
|
|
}
|
|
|
|
pthread_mutex_unlock(&server.listen_lock);
|
|
|
|
|
|
|
|
return x;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void del_listener(struct woomera_interface *woomera)
|
|
|
|
{
|
|
|
|
struct woomera_listener *ptr, *last = NULL;
|
|
|
|
|
|
|
|
pthread_mutex_lock(&server.listen_lock);
|
|
|
|
for (ptr = server.listeners ; ptr ; ptr = ptr->next) {
|
|
|
|
if (ptr->woomera == woomera) {
|
|
|
|
if (last) {
|
|
|
|
last->next = ptr->next;
|
|
|
|
} else {
|
|
|
|
server.listeners = ptr->next;
|
|
|
|
}
|
2021-12-29 17:15:08 +00:00
|
|
|
smg_free(ptr);
|
2021-12-29 16:59:00 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
last = ptr;
|
|
|
|
}
|
|
|
|
pthread_mutex_unlock(&server.listen_lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void add_listener(struct woomera_interface *woomera)
|
|
|
|
{
|
|
|
|
struct woomera_listener *new;
|
|
|
|
|
|
|
|
pthread_mutex_lock(&server.listen_lock);
|
|
|
|
|
2021-12-29 17:15:08 +00:00
|
|
|
if ((new = smg_malloc(sizeof(*new)))) {
|
2021-12-29 16:59:00 +00:00
|
|
|
memset(new, 0, sizeof(*new));
|
|
|
|
new->woomera = woomera;
|
|
|
|
new->next = server.listeners;
|
|
|
|
server.listeners = new;
|
|
|
|
} else {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Memory Error adding listener!\n");
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pthread_mutex_unlock(&server.listen_lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
static int wanpipe_send_dtmf(struct woomera_interface *woomera, char *digits)
|
|
|
|
{
|
|
|
|
struct media_session *ms = woomera_get_ms(woomera);
|
|
|
|
char *cur = NULL;
|
|
|
|
int wrote = 0;
|
2021-12-29 17:03:04 +00:00
|
|
|
int err;
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
if (!ms) {
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!ms->dtmf_buffer) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_MISC, woomera->log, "Allocate DTMF Buffer....");
|
2021-12-29 17:03:04 +00:00
|
|
|
|
2021-12-29 17:12:33 +00:00
|
|
|
err=switch_buffer_create_dynamic(&ms->dtmf_buffer, 1024, server.dtmf_size, 0);
|
2021-12-29 17:03:04 +00:00
|
|
|
|
|
|
|
if (err != 0) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, woomera->log, "Failed to allocate DTMF Buffer!\n");
|
2021-12-29 16:59:00 +00:00
|
|
|
return -ENOMEM;
|
|
|
|
} else {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_MISC, woomera->log, "SUCCESS!\n");
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
2021-12-29 17:03:04 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_MISC, woomera->log, "Sending DTMF %s\n",digits);
|
2021-12-29 16:59:00 +00:00
|
|
|
for (cur = digits; *cur; cur++) {
|
2021-12-29 17:03:04 +00:00
|
|
|
if ((wrote = teletone_mux_tones(&ms->tone_session,
|
|
|
|
&ms->tone_session.TONES[(int)*cur]))) {
|
|
|
|
|
|
|
|
pthread_mutex_lock(&woomera->dtmf_lock);
|
|
|
|
|
|
|
|
err=switch_buffer_write(ms->dtmf_buffer, ms->tone_session.buffer, wrote * 2);
|
|
|
|
|
|
|
|
pthread_mutex_unlock(&woomera->dtmf_lock);
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_MISC, woomera->log, "Sending DTMF %s Wrote=%i (err=%i)\n",
|
2021-12-29 17:03:04 +00:00
|
|
|
digits,wrote*2,err);
|
|
|
|
} else {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, woomera->log, "Error: Sending DTMF %s (err=%i)\n",
|
2021-12-29 17:03:04 +00:00
|
|
|
digits,wrote);
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ms->skip_read_frames = 200;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
static struct woomera_interface *alloc_woomera(void)
|
|
|
|
{
|
|
|
|
struct woomera_interface *woomera = NULL;
|
|
|
|
|
2021-12-29 17:15:08 +00:00
|
|
|
if ((woomera = smg_malloc(sizeof(struct woomera_interface)))) {
|
2021-12-29 17:11:50 +00:00
|
|
|
|
|
|
|
memset(woomera, 0, sizeof(struct woomera_interface));
|
|
|
|
|
|
|
|
woomera->chan = -1;
|
|
|
|
woomera->span = -1;
|
|
|
|
woomera->log = server.log;
|
|
|
|
woomera->debug = server.debug;
|
|
|
|
woomera->call_id = 1;
|
|
|
|
woomera->event_queue = NULL;
|
2021-12-29 17:12:33 +00:00
|
|
|
woomera->q931_rel_cause_topbx=SIGBOOST_RELEASE_CAUSE_NORMAL;
|
|
|
|
woomera->q931_rel_cause_tosig=SIGBOOST_RELEASE_CAUSE_NORMAL;
|
2021-12-29 17:11:50 +00:00
|
|
|
|
|
|
|
woomera_set_interface(woomera, "w-1g-1");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return woomera;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
static struct woomera_interface *new_woomera_interface(int socket, struct sockaddr_in *sock_addr, int len)
|
|
|
|
{
|
|
|
|
struct woomera_interface *woomera = NULL;
|
|
|
|
|
|
|
|
if (socket < 0) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Critical: Invalid Socket on new interface!\n");
|
2021-12-29 16:59:00 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
if ((woomera = alloc_woomera())) {
|
2021-12-29 16:59:00 +00:00
|
|
|
if (socket >= 0) {
|
|
|
|
no_nagle(socket);
|
|
|
|
woomera->socket = socket;
|
|
|
|
}
|
2021-12-29 17:11:50 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
if (sock_addr && len) {
|
|
|
|
memcpy(&woomera->addr, sock_addr, len);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return woomera;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *woomera_message_header(struct woomera_message *wmsg, char *key)
|
|
|
|
{
|
|
|
|
int x = 0;
|
|
|
|
char *value = NULL;
|
|
|
|
|
|
|
|
for (x = 0 ; x < wmsg->last ; x++) {
|
|
|
|
if (!strcasecmp(wmsg->names[x], key)) {
|
|
|
|
value = wmsg->values[x];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
#define SMG_DECODE_POLL_ERRORS(err) \
|
|
|
|
(err & POLLERR) ? "POLLERR" : \
|
|
|
|
(err & POLLHUP) ? "POLLHUP" : \
|
|
|
|
(err & POLLNVAL) ? "POLLNVAL" : "UNKNOWN"
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
static int waitfor_socket(int fd, int timeout, int flags, int *flags_out)
|
2021-12-29 17:14:12 +00:00
|
|
|
{
|
|
|
|
struct pollfd pfds[1];
|
|
|
|
int res;
|
2021-12-29 17:26:11 +00:00
|
|
|
int errflags = (POLLERR | POLLHUP | POLLNVAL);
|
|
|
|
|
|
|
|
waitfor_socket_tryagain:
|
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
memset(&pfds[0], 0, sizeof(pfds[0]));
|
2021-12-29 17:26:11 +00:00
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
pfds[0].fd = fd;
|
2021-12-29 17:26:11 +00:00
|
|
|
pfds[0].events = flags | errflags;
|
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
res = poll(pfds, 1, timeout);
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
if (res == 0) {
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
if (res > 0) {
|
2021-12-29 17:26:11 +00:00
|
|
|
res=-1;
|
|
|
|
*flags_out = pfds[0].revents;
|
|
|
|
if (pfds[0].revents & errflags) {
|
|
|
|
res=-1;
|
2021-12-29 17:14:12 +00:00
|
|
|
#if 0
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_10,server.log, "Wait for socket Error in revents 0x%X %s Error=%s!\n",
|
2021-12-29 17:26:11 +00:00
|
|
|
pfds[0].revents,strerror(errno),SMG_DECODE_POLL_ERRORS(pfds[0].revents));
|
2021-12-29 17:14:12 +00:00
|
|
|
#endif
|
2021-12-29 17:26:11 +00:00
|
|
|
return res;
|
|
|
|
} else {
|
|
|
|
if (pfds[0].revents & flags) {
|
|
|
|
res=1;
|
|
|
|
} else {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log, "Wait for socket invalid poll event in revents 0x%X Error=%s Errno=%s !\n",
|
2021-12-29 17:26:11 +00:00
|
|
|
pfds[0].revents,SMG_DECODE_POLL_ERRORS(pfds[0].revents),strerror(errno));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if ((errno == EINTR || errno == EAGAIN)) {
|
|
|
|
goto waitfor_socket_tryagain;
|
|
|
|
}
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log, "Wait for socket error!\n");
|
2021-12-29 17:14:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-12-29 17:29:00 +00:00
|
|
|
int waitfor_2sockets(int fda, int fdb, char *a, char *b, int timeout)
|
2021-12-29 16:59:00 +00:00
|
|
|
{
|
|
|
|
struct pollfd pfds[2];
|
|
|
|
int res = 0;
|
|
|
|
int errflags = (POLLERR | POLLHUP | POLLNVAL);
|
|
|
|
|
|
|
|
if (fda < 0 || fdb < 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
|
|
|
|
waitfor_2sockets_tryagain:
|
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
*a=0;
|
|
|
|
*b=0;
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
memset(pfds, 0, sizeof(pfds));
|
2021-12-29 17:26:11 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
pfds[0].fd = fda;
|
|
|
|
pfds[1].fd = fdb;
|
|
|
|
pfds[0].events = POLLIN | errflags;
|
|
|
|
pfds[1].events = POLLIN | errflags;
|
2021-12-29 17:26:11 +00:00
|
|
|
|
|
|
|
res = poll(pfds, 2, timeout);
|
|
|
|
|
|
|
|
if (res > 0) {
|
2021-12-29 16:59:00 +00:00
|
|
|
res = 1;
|
|
|
|
if ((pfds[0].revents & errflags) || (pfds[1].revents & errflags)) {
|
|
|
|
res = -1;
|
|
|
|
} else {
|
|
|
|
if ((pfds[0].revents & POLLIN)) {
|
2021-12-29 17:03:04 +00:00
|
|
|
*a=1;
|
|
|
|
res++;
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
if ((pfds[1].revents & POLLIN)) {
|
2021-12-29 17:03:04 +00:00
|
|
|
*b=1;
|
|
|
|
res++;
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
}
|
2021-12-29 17:03:04 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
if (res == 1) {
|
|
|
|
/* No event found what to do */
|
2021-12-29 17:03:04 +00:00
|
|
|
res=-1;
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
2021-12-29 17:26:11 +00:00
|
|
|
} else if (res < 0) {
|
|
|
|
|
|
|
|
if (errno == EINTR || errno == EAGAIN) {
|
|
|
|
goto waitfor_2sockets_tryagain;
|
|
|
|
}
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static struct media_session *media_session_new(struct woomera_interface *woomera)
|
|
|
|
{
|
|
|
|
struct media_session *ms = NULL;
|
|
|
|
int x;
|
|
|
|
char *p;
|
|
|
|
int span,chan;
|
2021-12-29 17:11:50 +00:00
|
|
|
|
|
|
|
span=woomera->span;
|
|
|
|
chan=woomera->chan;
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, server.log,"Starting new MEDIA session [%s] [%s]\n",
|
2021-12-29 17:11:50 +00:00
|
|
|
woomera->interface,woomera->raw?woomera->raw:"N/A");
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:15:08 +00:00
|
|
|
if ((ms = smg_malloc(sizeof(struct media_session)))) {
|
2021-12-29 16:59:00 +00:00
|
|
|
memset(ms, 0, sizeof(struct media_session));
|
|
|
|
|
|
|
|
if (woomera->loop_tdm != 1) {
|
|
|
|
for(x = 0; x < strlen(woomera->raw) ; x++) {
|
2021-12-29 17:03:04 +00:00
|
|
|
if (woomera->raw[x] == ':') {
|
|
|
|
break;
|
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
if (woomera->raw[x] == '/') {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:15:08 +00:00
|
|
|
ms->ip = smg_strndup(woomera->raw, x);
|
2021-12-29 16:59:00 +00:00
|
|
|
time(&ms->started);
|
|
|
|
p = woomera->raw + (x+1);
|
|
|
|
ms->port = atoi(p);
|
2021-12-29 17:03:04 +00:00
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
time(&ms->started);
|
|
|
|
woomera_set_ms(woomera,ms);
|
|
|
|
ms->woomera = woomera;
|
|
|
|
|
|
|
|
/* Setup artificial DTMF stuff */
|
|
|
|
memset(&ms->tone_session, 0, sizeof(ms->tone_session));
|
2021-12-29 17:03:04 +00:00
|
|
|
if (teletone_init_session(&ms->tone_session, 0, NULL, NULL)) {
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "ERROR: Failed to initialize TONE [s%ic%i]!\n",
|
2021-12-29 17:03:04 +00:00
|
|
|
span+1,chan+1);
|
|
|
|
}
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
ms->tone_session.rate = SMG_DTMF_RATE;
|
2021-12-29 17:12:33 +00:00
|
|
|
ms->tone_session.duration = server.dtmf_on * (ms->tone_session.rate / 1000);
|
|
|
|
ms->tone_session.wait = server.dtmf_off * (ms->tone_session.rate / 1000);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
teletone_dtmf_detect_init (&ms->dtmf_detect, SMG_DTMF_RATE);
|
|
|
|
|
|
|
|
} else {
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "ERROR: Memory Alloc Failed [s%ic%i]!\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
span+1,chan+1);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ms;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void media_session_free(struct media_session *ms)
|
|
|
|
{
|
|
|
|
if (ms->ip) {
|
2021-12-29 17:15:08 +00:00
|
|
|
smg_free(ms->ip);
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
teletone_destroy_session(&ms->tone_session);
|
2021-12-29 17:03:04 +00:00
|
|
|
switch_buffer_destroy(&ms->dtmf_buffer);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
ms->woomera = NULL;
|
|
|
|
|
2021-12-29 17:15:08 +00:00
|
|
|
smg_free(ms);
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int create_udp_socket(struct media_session *ms, char *local_ip, int local_port, char *ip, int port)
|
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
struct hostent *result, *local_result;
|
|
|
|
char buf[512], local_buf[512];
|
|
|
|
int err = 0;
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_9,server.log,"LocalIP %s:%d IP %s:%d \n",local_ip, local_port, ip, port);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
memset(&ms->remote_hp, 0, sizeof(ms->remote_hp));
|
|
|
|
memset(&ms->local_hp, 0, sizeof(ms->local_hp));
|
2021-12-29 17:14:12 +00:00
|
|
|
if ((ms->socket = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) {
|
2021-12-29 16:59:00 +00:00
|
|
|
gethostbyname_r(ip, &ms->remote_hp, buf, sizeof(buf), &result, &err);
|
|
|
|
gethostbyname_r(local_ip, &ms->local_hp, local_buf, sizeof(local_buf), &local_result, &err);
|
|
|
|
if (result && local_result) {
|
|
|
|
ms->remote_addr.sin_family = ms->remote_hp.h_addrtype;
|
|
|
|
memcpy((char *) &ms->remote_addr.sin_addr.s_addr, ms->remote_hp.h_addr_list[0], ms->remote_hp.h_length);
|
|
|
|
ms->remote_addr.sin_port = htons(port);
|
|
|
|
|
|
|
|
ms->local_addr.sin_family = ms->local_hp.h_addrtype;
|
|
|
|
memcpy((char *) &ms->local_addr.sin_addr.s_addr, ms->local_hp.h_addr_list[0], ms->local_hp.h_length);
|
|
|
|
ms->local_addr.sin_port = htons(local_port);
|
|
|
|
|
|
|
|
rc = bind(ms->socket, (struct sockaddr *) &ms->local_addr, sizeof(ms->local_addr));
|
|
|
|
if (rc < 0) {
|
|
|
|
close(ms->socket);
|
|
|
|
ms->socket = -1;
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_9,server.log,
|
2021-12-29 16:59:00 +00:00
|
|
|
"Failed to bind LocalIP %s:%d IP %s:%d (%s)\n",
|
|
|
|
local_ip, local_port, ip, port,strerror(errno));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* OK */
|
|
|
|
|
|
|
|
} else {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log,
|
2021-12-29 16:59:00 +00:00
|
|
|
"Failed to get hostbyname LocalIP %s:%d IP %s:%d (%s)\n",
|
|
|
|
local_ip, local_port, ip, port,strerror(errno));
|
|
|
|
}
|
|
|
|
} else {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log,
|
2021-12-29 16:59:00 +00:00
|
|
|
"Failed to create/allocate UDP socket\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
return ms->socket;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int next_media_port(void)
|
|
|
|
{
|
|
|
|
int port;
|
|
|
|
|
|
|
|
pthread_mutex_lock(&server.media_udp_port_lock);
|
|
|
|
port = ++server.next_media_port;
|
2021-12-29 17:26:11 +00:00
|
|
|
if (port > server.max_media_port) {
|
|
|
|
server.next_media_port = server.base_media_port;
|
|
|
|
port = server.base_media_port;
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
pthread_mutex_unlock(&server.media_udp_port_lock);
|
|
|
|
|
|
|
|
return port;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
static int woomera_dtmf_transmit(struct media_session *ms, int mtu)
|
|
|
|
{
|
|
|
|
struct woomera_interface *woomera = ms->woomera;
|
|
|
|
int bread;
|
|
|
|
unsigned char dtmf[1024];
|
|
|
|
unsigned char dtmf_law[1024];
|
|
|
|
sangoma_api_hdr_t hdrframe;
|
|
|
|
int i;
|
|
|
|
int slin_len = mtu*2;
|
|
|
|
short *data;
|
2021-12-29 17:03:04 +00:00
|
|
|
int used;
|
2021-12-29 17:14:12 +00:00
|
|
|
int res;
|
|
|
|
int err;
|
|
|
|
int txdtmf=0;
|
2021-12-29 17:26:11 +00:00
|
|
|
int flags_out;
|
2021-12-29 16:59:00 +00:00
|
|
|
memset(&hdrframe,0,sizeof(hdrframe));
|
2021-12-29 17:03:04 +00:00
|
|
|
|
|
|
|
if (!ms->dtmf_buffer) {
|
|
|
|
return -1;
|
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
for (;;) {
|
2021-12-29 17:14:12 +00:00
|
|
|
|
|
|
|
if ((used=switch_buffer_inuse(ms->dtmf_buffer)) <= 0) {
|
|
|
|
break;
|
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
res = waitfor_socket(ms->sangoma_sock, -1, POLLOUT, &flags_out);
|
2021-12-29 17:14:12 +00:00
|
|
|
if (res <= 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef CODEC_LAW_DEFAULT
|
2021-12-29 17:03:04 +00:00
|
|
|
|
|
|
|
pthread_mutex_lock(&woomera->dtmf_lock);
|
|
|
|
if ((used=switch_buffer_inuse(ms->dtmf_buffer)) <= 0) {
|
|
|
|
pthread_mutex_unlock(&woomera->dtmf_lock);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
bread = switch_buffer_read(ms->dtmf_buffer, dtmf, slin_len);
|
|
|
|
pthread_mutex_unlock(&woomera->dtmf_lock);
|
|
|
|
|
|
|
|
if (bread <= 0) {
|
|
|
|
break;
|
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_MISC,woomera->log,"%s: Write DTMF Got %d bytes MTU=%i Coding=%i Used=%i\n",
|
2021-12-29 17:03:04 +00:00
|
|
|
woomera->interface,bread,mtu,ms->hw_coding,used);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
data=(short*)dtmf;
|
|
|
|
for (i=0;i<mtu;i++) {
|
|
|
|
if (ms->hw_coding) {
|
|
|
|
/* ALAW */
|
|
|
|
dtmf_law[i] = linear_to_alaw((int)data[i]);
|
|
|
|
} else {
|
|
|
|
/* ULAW */
|
|
|
|
dtmf_law[i] = linear_to_ulaw((int)data[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
err=sangoma_sendmsg_socket(ms->sangoma_sock,
|
2021-12-29 16:59:00 +00:00
|
|
|
&hdrframe,
|
|
|
|
sizeof(hdrframe),
|
|
|
|
dtmf_law, mtu, 0);
|
2021-12-29 17:14:12 +00:00
|
|
|
|
|
|
|
if (err != mtu) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, woomera->log, "Error: Failed to TX to TDM API on DTMF (err=%i mtu=%i)!\n",err,mtu);
|
2021-12-29 17:14:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
txdtmf++;
|
|
|
|
ms->skip_write_frames++;
|
2021-12-29 16:59:00 +00:00
|
|
|
#else
|
2021-12-29 17:03:04 +00:00
|
|
|
...
|
|
|
|
pthread_mutex_lock(&woomera->dtmf_lock);
|
|
|
|
bread = switch_buffer_read(ms->dtmf_buffer, dtmf, mtu);
|
|
|
|
pthread_mutex_unlock(&woomera->dtmf_lock);
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_MISC,woomera->log,"%s: Write DTMF Got %d bytes\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
woomera->interface,bread);
|
|
|
|
|
|
|
|
sangoma_sendmsg_socket(ms->sangoma_sock,
|
|
|
|
&hdrframe,
|
|
|
|
sizeof(hdrframe),
|
|
|
|
dtmf, mtu, 0);
|
2021-12-29 17:14:12 +00:00
|
|
|
txdtmf++;
|
2021-12-29 16:59:00 +00:00
|
|
|
ms->skip_write_frames++;
|
|
|
|
#endif
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
}
|
2021-12-29 17:14:12 +00:00
|
|
|
|
|
|
|
if (txdtmf) {
|
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
return -1;
|
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
2021-12-29 17:22:11 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
static void media_loop_run(struct media_session *ms)
|
|
|
|
{
|
|
|
|
struct woomera_interface *woomera = ms->woomera;
|
|
|
|
int sangoma_frame_len = 160;
|
|
|
|
int errs=0;
|
|
|
|
int res=0;
|
|
|
|
wanpipe_tdm_api_t tdm_api;
|
|
|
|
unsigned char circuit_frame[1024];
|
|
|
|
char filename[100];
|
|
|
|
FILE *filed=NULL;
|
2021-12-29 17:26:11 +00:00
|
|
|
int loops=0,flags_out=0;
|
2021-12-29 17:28:39 +00:00
|
|
|
int open_cnt = 0;
|
|
|
|
|
|
|
|
open_cnt=0;
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
sangoma_api_hdr_t hdrframe;
|
|
|
|
memset(&hdrframe,0,sizeof(hdrframe));
|
|
|
|
memset(circuit_frame,0,sizeof(circuit_frame));
|
2021-12-29 17:03:04 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
retry_loop:
|
2021-12-29 17:28:39 +00:00
|
|
|
ms->sangoma_sock = open_span_chan(woomera->span+1, woomera->chan+1);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_PROD, server.log, "Media Loop Started %s fd=%i\n",
|
2021-12-29 17:03:04 +00:00
|
|
|
woomera->interface,ms->sangoma_sock);
|
|
|
|
|
|
|
|
if (ms->sangoma_sock < 0) {
|
2021-12-29 17:26:11 +00:00
|
|
|
errs++;
|
|
|
|
if (errs < 5) {
|
|
|
|
usleep(500000);
|
|
|
|
goto retry_loop;
|
|
|
|
}
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "WANPIPE MEDIA Socket Error (%s) if=[%s] [s%ic%i]\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
strerror(errno), woomera->interface, woomera->span+1, woomera->chan+1);
|
2021-12-29 17:26:11 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
} else {
|
2021-12-29 17:26:11 +00:00
|
|
|
errs=0;
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
if (sangoma_tdm_set_codec(ms->sangoma_sock, &tdm_api, WP_NONE) < 0 ) {
|
|
|
|
errs++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sangoma_tdm_flush_bufs(ms->sangoma_sock, &tdm_api)) {
|
|
|
|
errs++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sangoma_tdm_set_usr_period(ms->sangoma_sock, &tdm_api, 20) < 0 ) {
|
|
|
|
errs++;
|
|
|
|
}
|
|
|
|
|
|
|
|
sangoma_frame_len = sangoma_tdm_get_usr_mtu_mru(ms->sangoma_sock,&tdm_api);
|
2021-12-29 17:03:37 +00:00
|
|
|
|
|
|
|
sangoma_tdm_disable_hwec(ms->sangoma_sock,&tdm_api);
|
2021-12-29 17:28:39 +00:00
|
|
|
ms->oob_disable = 0;
|
|
|
|
#ifdef LIBSANGOMA_VERSION
|
|
|
|
open_cnt = sangoma_get_open_cnt(ms->sangoma_sock, &tdm_api);
|
|
|
|
if (open_cnt > 1) {
|
|
|
|
ms->oob_disable = 1;
|
|
|
|
}
|
|
|
|
#endif
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
2021-12-29 17:28:39 +00:00
|
|
|
if (errs) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Media Loop: failed to open tdm device %s\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
woomera->interface);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (server.loop_trace) {
|
2021-12-29 17:29:00 +00:00
|
|
|
sprintf(filename,"/smg/s%ic%i-loop.trace",woomera->span+1,woomera->chan+1);
|
2021-12-29 16:59:00 +00:00
|
|
|
unlink(filename);
|
|
|
|
filed = safe_fopen(filename, "w");
|
|
|
|
}
|
|
|
|
|
|
|
|
while ( woomera_test_flag(&server.master_connection, WFLAG_RUNNING) &&
|
|
|
|
!woomera_test_flag(woomera, WFLAG_MEDIA_END) &&
|
2021-12-29 17:26:11 +00:00
|
|
|
((res = waitfor_socket(ms->sangoma_sock, 1000, POLLIN, &flags_out)) >= 0)) {
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:22:11 +00:00
|
|
|
if (res == SMG_SOCKET_EVENT_TIMEOUT) {
|
2021-12-29 17:27:14 +00:00
|
|
|
//log_printf(SMG_LOG_DEBUG_8, server.log, "%s: TDM UDP Timeout !!!\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
// woomera->interface);
|
|
|
|
/* NENAD Timeout thus just continue */
|
2021-12-29 17:03:04 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
res = sangoma_readmsg_socket(ms->sangoma_sock,
|
|
|
|
&hdrframe,
|
|
|
|
sizeof(hdrframe),
|
|
|
|
circuit_frame,
|
|
|
|
sizeof(circuit_frame), 0);
|
|
|
|
if (res < 0) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "TDM Loop ReadMsg Error: %s\n",
|
2021-12-29 17:03:37 +00:00
|
|
|
strerror(errno), woomera->interface);
|
2021-12-29 16:59:00 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (server.loop_trace && filed != NULL) {
|
|
|
|
int i;
|
|
|
|
for (i=0;i<res;i++) {
|
|
|
|
fprintf(filed,"%02X ", circuit_frame[i]);
|
|
|
|
if (i && (i % 16) == 0) {
|
|
|
|
fprintf(filed,"\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fprintf(filed,"\n");
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
sangoma_sendmsg_socket(ms->sangoma_sock,
|
2021-12-29 16:59:00 +00:00
|
|
|
&hdrframe,
|
|
|
|
sizeof(hdrframe),
|
|
|
|
circuit_frame,
|
|
|
|
res, 0);
|
2021-12-29 17:03:04 +00:00
|
|
|
|
|
|
|
res=0;
|
|
|
|
|
|
|
|
loops++;
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (res < 0) {
|
2021-12-29 17:26:11 +00:00
|
|
|
if (!woomera_test_flag(woomera, WFLAG_MEDIA_END)) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Media Loop: socket error %s (fd=%i) %s\n",
|
2021-12-29 17:26:11 +00:00
|
|
|
woomera->interface, ms->sangoma_sock, strerror(errno));
|
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (server.loop_trace && filed != NULL) {
|
|
|
|
fclose(filed);
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:03:37 +00:00
|
|
|
sangoma_tdm_enable_hwec(ms->sangoma_sock,&tdm_api);
|
|
|
|
|
2021-12-29 17:28:39 +00:00
|
|
|
close_span_chan(&ms->sangoma_sock, woomera->span+1, woomera->chan+1);
|
2021-12-29 17:03:04 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
if (loops < 1) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Media Loop FAILED %s Master=%i MediaEnd=%i Loops=%i\n",
|
2021-12-29 17:03:04 +00:00
|
|
|
woomera->interface,
|
|
|
|
woomera_test_flag(&server.master_connection, WFLAG_RUNNING),
|
|
|
|
woomera_test_flag(woomera, WFLAG_MEDIA_END),loops);
|
2021-12-29 17:26:11 +00:00
|
|
|
} else {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_PROD, server.log, "Media Loop PASSED %s Master=%i MediaEnd=%i Loops=%i\n",
|
2021-12-29 17:26:11 +00:00
|
|
|
woomera->interface,
|
|
|
|
woomera_test_flag(&server.master_connection, WFLAG_RUNNING),
|
|
|
|
woomera_test_flag(woomera, WFLAG_MEDIA_END),loops);
|
|
|
|
}
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:22:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
#ifdef WP_HPTDM_API
|
|
|
|
static int media_rx_ready(void *p, unsigned char *data, int len)
|
|
|
|
{
|
|
|
|
struct media_session *ms = (struct media_session *)p;
|
|
|
|
|
|
|
|
if (ms->udp_sock < 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return sendto(ms->udp_sock,
|
|
|
|
data,len, 0,
|
|
|
|
(struct sockaddr *) &ms->remote_addr,
|
|
|
|
sizeof(ms->remote_addr));
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
static void *media_thread_run(void *obj)
|
|
|
|
{
|
|
|
|
struct media_session *ms = obj;
|
|
|
|
struct woomera_interface *woomera = ms->woomera;
|
|
|
|
int sangoma_frame_len = 160;
|
|
|
|
int local_port, x = 0, errs = 0, res = 0, packet_len = 0;
|
|
|
|
//int udp_cnt=0;
|
|
|
|
struct woomera_event wevent;
|
|
|
|
wanpipe_tdm_api_t tdm_api;
|
|
|
|
FILE *tx_fd=NULL;
|
2021-12-29 17:14:12 +00:00
|
|
|
int sock_timeout=200;
|
2021-12-29 17:29:00 +00:00
|
|
|
|
|
|
|
int hwec_enabled=0, hwec_reenable=0;
|
|
|
|
|
2021-12-29 17:28:39 +00:00
|
|
|
int open_cnt = 0;
|
|
|
|
|
|
|
|
open_cnt=0;
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
if (woomera_test_flag(woomera, WFLAG_MEDIA_END) ||
|
|
|
|
!woomera->interface ||
|
|
|
|
woomera_test_flag(woomera, WFLAG_HANGUP)) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, server.log,
|
2021-12-29 16:59:00 +00:00
|
|
|
"MEDIA session for [%s] Cancelled! (ptr=%p)\n",
|
|
|
|
woomera->interface,woomera);
|
|
|
|
/* In this case the call will be closed via woomera_thread_run
|
|
|
|
* function. And the process table will be cleard there */
|
|
|
|
woomera_set_flag(woomera, WFLAG_MEDIA_END);
|
|
|
|
woomera_clear_flag(woomera, WFLAG_MEDIA_RUNNING);
|
|
|
|
media_session_free(ms);
|
|
|
|
pthread_exit(NULL);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, server.log, "MEDIA session for [%s] started (ptr=%p loop=%i)\n",
|
2021-12-29 17:26:11 +00:00
|
|
|
woomera->interface,woomera,woomera->loop_tdm);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
if (woomera->loop_tdm) {
|
|
|
|
media_loop_run(ms);
|
|
|
|
ms->udp_sock=-1;
|
2021-12-29 17:03:04 +00:00
|
|
|
woomera_set_flag(woomera, WFLAG_HANGUP);
|
|
|
|
woomera_clear_flag(woomera, WFLAG_MEDIA_TDM_RUNNING);
|
2021-12-29 16:59:00 +00:00
|
|
|
goto media_thread_exit;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
for(x = 0; x < 1000 ; x++) {
|
2021-12-29 16:59:00 +00:00
|
|
|
local_port = next_media_port();
|
|
|
|
if ((ms->udp_sock = create_udp_socket(ms, server.media_ip, local_port, ms->ip, ms->port)) > -1) {
|
|
|
|
break;
|
|
|
|
}
|
2021-12-29 17:26:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Normal Temporary Failure */
|
|
|
|
woomera->q931_rel_cause_topbx = 41;
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
if (ms->udp_sock < 0) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "UDP Socket Error (%s) [%s] LocalPort=%d\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
strerror(errno), woomera->interface, local_port);
|
|
|
|
|
|
|
|
errs++;
|
2021-12-29 17:26:11 +00:00
|
|
|
} else {
|
|
|
|
int media_retry_cnt=0;
|
2021-12-29 17:03:04 +00:00
|
|
|
#ifdef WP_HPTDM_API
|
|
|
|
hp_tdm_api_span_t *span=hptdmspan[woomera->span+1];
|
|
|
|
if (!span || !span->init) {
|
|
|
|
errs++;
|
2021-12-29 17:26:11 +00:00
|
|
|
} else {
|
2021-12-29 17:03:04 +00:00
|
|
|
hp_tdm_api_usr_callback_t usr_callback;
|
|
|
|
memset(&usr_callback,0,sizeof(usr_callback));
|
|
|
|
usr_callback.p = ms;
|
|
|
|
usr_callback.rx_avail = media_rx_ready;
|
|
|
|
if (span->open_chan(span, &usr_callback, &ms->tdmchan,woomera->chan+1)) {
|
2021-12-29 17:26:11 +00:00
|
|
|
errs++;
|
|
|
|
/* Switch Congestion */
|
|
|
|
woomera->q931_rel_cause_topbx = 42;
|
2021-12-29 17:03:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
2021-12-29 17:26:11 +00:00
|
|
|
media_retry:
|
2021-12-29 17:28:39 +00:00
|
|
|
ms->sangoma_sock = open_span_chan(woomera->span+1, woomera->chan+1);
|
2021-12-29 17:26:11 +00:00
|
|
|
if (ms->sangoma_sock < 0) {
|
|
|
|
|
|
|
|
if (!woomera_test_flag(woomera, WFLAG_MEDIA_END)) {
|
|
|
|
media_retry_cnt++;
|
|
|
|
if (media_retry_cnt < 5) {
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "WANPIPE Socket Retry [s%ic%i]\n",
|
2021-12-29 17:26:11 +00:00
|
|
|
woomera->span+1, woomera->chan+1);
|
|
|
|
usleep(100000);
|
|
|
|
goto media_retry;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "WANPIPE Socket Error (%s) if=[%s] [s%ic%i]\n",
|
2021-12-29 17:26:11 +00:00
|
|
|
strerror(errno), woomera->interface, woomera->span+1, woomera->chan+1);
|
|
|
|
|
|
|
|
/* Switch Congestion */
|
|
|
|
woomera->q931_rel_cause_topbx = 42;
|
|
|
|
}
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
errs++;
|
|
|
|
} else {
|
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
# ifdef CODEC_LAW_DEFAULT
|
2021-12-29 16:59:00 +00:00
|
|
|
if (sangoma_tdm_set_codec(ms->sangoma_sock, &tdm_api, WP_NONE) < 0 ) {
|
|
|
|
errs++;
|
|
|
|
}
|
2021-12-29 17:03:04 +00:00
|
|
|
# else
|
2021-12-29 16:59:00 +00:00
|
|
|
if (sangoma_tdm_set_codec(ms->sangoma_sock, &tdm_api, WP_SLINEAR) < 0 ) {
|
|
|
|
errs++;
|
|
|
|
}
|
2021-12-29 17:03:04 +00:00
|
|
|
# endif
|
2021-12-29 16:59:00 +00:00
|
|
|
if (sangoma_tdm_flush_bufs(ms->sangoma_sock, &tdm_api)) {
|
|
|
|
errs++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sangoma_tdm_set_usr_period(ms->sangoma_sock, &tdm_api, 20) < 0 ) {
|
|
|
|
errs++;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
# ifdef CODEC_LAW_DEFAULT
|
|
|
|
# ifdef LIBSANGOMA_GET_HWCODING
|
2021-12-29 16:59:00 +00:00
|
|
|
ms->hw_coding=sangoma_tdm_get_hw_coding(ms->sangoma_sock, &tdm_api);
|
|
|
|
if (ms->hw_coding < 0) {
|
|
|
|
errs++;
|
|
|
|
}
|
2021-12-29 17:03:04 +00:00
|
|
|
# else
|
|
|
|
# error "libsangoma missing hwcoding feature: not up to date!"
|
|
|
|
# endif
|
|
|
|
# endif
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:22:11 +00:00
|
|
|
|
|
|
|
# ifdef LIBSANGOMA_GET_HWDTMF
|
|
|
|
ms->hw_dtmf=sangoma_tdm_get_hw_dtmf(ms->sangoma_sock, &tdm_api);
|
|
|
|
if (ms->hw_dtmf) {
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_9, server.log, "HW DTMF Supported [s%ic%i]\n",
|
2021-12-29 17:22:11 +00:00
|
|
|
strerror(errno), woomera->interface, woomera->span+1, woomera->chan+1);
|
|
|
|
} else {
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_9, server.log, "HW DTMF Not Supported [s%ic%i]\n",
|
2021-12-29 17:22:11 +00:00
|
|
|
strerror(errno), woomera->interface, woomera->span+1, woomera->chan+1);
|
|
|
|
}
|
|
|
|
#else
|
2021-12-29 17:26:11 +00:00
|
|
|
ms->hw_dtmf=0;
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_9, server.log, "HW DTMF Not Supported [s%ic%i]\n",
|
2021-12-29 17:26:11 +00:00
|
|
|
strerror(errno), woomera->interface, woomera->span+1, woomera->chan+1);
|
|
|
|
# warning "libsangoma missing hwdtmf feature: not up to date!"
|
|
|
|
|
2021-12-29 17:22:11 +00:00
|
|
|
#endif
|
|
|
|
|
2021-12-29 17:28:39 +00:00
|
|
|
ms->oob_disable = 0;
|
|
|
|
#ifdef LIBSANGOMA_VERSION
|
|
|
|
open_cnt = sangoma_get_open_cnt(ms->sangoma_sock, &tdm_api);
|
|
|
|
if (open_cnt > 1) {
|
|
|
|
ms->oob_disable = 1;
|
|
|
|
}
|
|
|
|
#endif
|
2021-12-29 17:29:00 +00:00
|
|
|
|
|
|
|
if (!tdmv_hwec_persist) {
|
|
|
|
// BRI cards start with HWEC in bypass disable state
|
|
|
|
if (bearer_cap_is_audio(woomera->bearer_cap)) {
|
|
|
|
int err;
|
|
|
|
err=sangoma_tdm_enable_hwec(ms->sangoma_sock, &tdm_api);
|
|
|
|
if (err == 0) {
|
|
|
|
hwec_enabled=1;
|
|
|
|
log_printf(SMG_LOG_DEBUG_8, server.log, "MEDIA [%s] Enabling hwec Ok\n",woomera->interface);
|
|
|
|
} else {
|
|
|
|
log_printf(SMG_LOG_PROD, server.log, "MEDIA [%s] Enabling hwec Failed (%s)\n",woomera->interface, strerror(errno));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (!bearer_cap_is_audio(woomera->bearer_cap)) {
|
|
|
|
int err;
|
|
|
|
err=sangoma_tdm_disable_hwec(ms->sangoma_sock, &tdm_api);
|
|
|
|
if (err == 0) {
|
|
|
|
hwec_reenable=1;
|
|
|
|
log_printf(SMG_LOG_DEBUG_8, server.log, "MEDIA [%s] Disabling hwec Ok\n",woomera->interface);
|
|
|
|
} else {
|
|
|
|
log_printf(SMG_LOG_PROD, server.log, "MEDIA [%s] Disabling hwec Failed (%s)\n",woomera->interface, strerror(errno));
|
|
|
|
}
|
2021-12-29 17:27:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
sangoma_frame_len = sangoma_tdm_get_usr_mtu_mru(ms->sangoma_sock,&tdm_api);
|
|
|
|
|
|
|
|
}
|
2021-12-29 17:03:04 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef WP_HPTDM_API
|
|
|
|
/* No tdm thread */
|
|
|
|
#else
|
2021-12-29 17:28:39 +00:00
|
|
|
#ifndef SMG_NO_MEDIA
|
2021-12-29 16:59:00 +00:00
|
|
|
if (!errs &&
|
|
|
|
launch_media_tdm_thread(woomera)) {
|
|
|
|
errs++;
|
|
|
|
}
|
2021-12-29 17:28:39 +00:00
|
|
|
#endif
|
2021-12-29 17:03:04 +00:00
|
|
|
#endif
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
if (errs) {
|
|
|
|
|
|
|
|
woomera->q931_rel_cause_topbx = 42;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
unsigned char udp_frame[4096];
|
2021-12-29 17:26:11 +00:00
|
|
|
unsigned int fromlen = sizeof(struct sockaddr_in);
|
|
|
|
int flags_out=0;
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
sangoma_api_hdr_t hdrframe;
|
|
|
|
memset(&hdrframe,0,sizeof(hdrframe));
|
|
|
|
memset(udp_frame,0,sizeof(udp_frame));
|
|
|
|
#ifdef DOTRACE
|
|
|
|
int fdin, fdout;
|
|
|
|
char path_in[512], path_out[512];
|
|
|
|
#endif
|
|
|
|
|
|
|
|
new_woomera_event_printf(&wevent,
|
2021-12-29 17:26:11 +00:00
|
|
|
"EVENT MEDIA %s AUDIO%s"
|
|
|
|
"Unique-Call-Id: %s%s"
|
|
|
|
"Raw-Audio: %s:%d%s"
|
|
|
|
"Call-ID: %s%s"
|
|
|
|
"Raw-Format: PCM-16%s"
|
|
|
|
"DTMF: %s%s"
|
|
|
|
,
|
|
|
|
woomera->interface,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
woomera->session,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
server.media_ip,
|
|
|
|
local_port,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
woomera->interface,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
(ms->hw_dtmf)? "OutofBand": "InBand",
|
2021-12-29 17:22:11 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
WOOMERA_RECORD_SEPERATOR
|
|
|
|
);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
enqueue_event(woomera, &wevent, EVENT_FREE_DATA);
|
|
|
|
|
|
|
|
#ifdef DOTRACE
|
|
|
|
sprintf(path_in, "/tmp/debug-in.%d.raw", tc);
|
|
|
|
sprintf(path_out, "/tmp/debug-out.%d.raw", tc++);
|
|
|
|
fdin = open(path_in, O_WRONLY | O_CREAT, O_TRUNC, 0600);
|
|
|
|
fdout = open(path_out, O_WRONLY | O_CREAT, O_TRUNC, 0600);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (server.out_tx_test) {
|
|
|
|
tx_fd=fopen("/smg/sound.raw","rb");
|
2021-12-29 17:26:11 +00:00
|
|
|
if (!tx_fd) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log, "FAILED TO OPEN Sound file!\n");
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
}
|
2021-12-29 17:26:11 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
for (;;) {
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING) ||
|
|
|
|
woomera_test_flag(&server.master_connection, WFLAG_SYSTEM_RESET) ||
|
|
|
|
woomera_test_flag(woomera, WFLAG_MEDIA_END) ||
|
|
|
|
woomera_test_flag(woomera, WFLAG_HANGUP)) {
|
|
|
|
res=0;
|
|
|
|
break;
|
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
res = waitfor_socket(ms->udp_sock, sock_timeout, POLLIN, &flags_out);
|
|
|
|
|
|
|
|
if (res < 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:28:39 +00:00
|
|
|
#ifdef SMG_NO_MEDIA
|
|
|
|
continue;
|
|
|
|
#endif
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
if (res == 0) {
|
2021-12-29 17:14:12 +00:00
|
|
|
|
|
|
|
if (woomera_dtmf_transmit(ms,sangoma_frame_len) == 0) {
|
|
|
|
sock_timeout=(sangoma_frame_len/codec_sample);
|
|
|
|
} else {
|
|
|
|
sock_timeout=200;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ms->skip_write_frames > 0) {
|
|
|
|
ms->skip_write_frames--;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_8, server.log, "%s: UDP Sock Timeout !!!\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
woomera->interface);
|
|
|
|
/* NENAD Timeout thus just continue */
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((packet_len = recvfrom(ms->udp_sock, udp_frame, sizeof(udp_frame),
|
|
|
|
MSG_DONTWAIT, (struct sockaddr *) &ms->local_addr, &fromlen)) < 1) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, server.log, "UDP Recv Error: %s\n",strerror(errno));
|
2021-12-29 16:59:00 +00:00
|
|
|
break;
|
|
|
|
}
|
2021-12-29 17:22:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
#ifdef SMG_DROP_SEQ
|
|
|
|
if (drop_seq) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log,"Dropping TX Sequence! %i\n",drop_seq);
|
2021-12-29 17:22:11 +00:00
|
|
|
drop_seq--;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
#if 0
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_10, server.log, "%s: UDP Receive %i !!!\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
woomera->interface,packet_len);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (packet_len > 0) {
|
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
#if 0
|
|
|
|
/* NC: This can cause skb_over panic must be retested */
|
2021-12-29 16:59:00 +00:00
|
|
|
if (packet_len != sangoma_frame_len && ms->udp_sync_cnt <= 5) {
|
|
|
|
/* Assume that we will always receive SLINEAR here */
|
|
|
|
sangoma_tdm_set_usr_period(ms->sangoma_sock,
|
|
|
|
&tdm_api, packet_len/codec_sample);
|
|
|
|
sangoma_frame_len =
|
|
|
|
sangoma_tdm_get_usr_mtu_mru(ms->sangoma_sock,&tdm_api);
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_MISC, server.log,
|
2021-12-29 16:59:00 +00:00
|
|
|
"%s: UDP TDM Period ReSync to Len=%i %ims (udp=%i) \n",
|
|
|
|
woomera->interface,sangoma_frame_len,
|
|
|
|
sangoma_frame_len/codec_sample,packet_len);
|
|
|
|
|
|
|
|
|
|
|
|
if (++ms->udp_sync_cnt >= 6) {
|
|
|
|
sangoma_tdm_set_usr_period(ms->sangoma_sock,
|
|
|
|
&tdm_api, 20);
|
|
|
|
sangoma_frame_len =
|
|
|
|
sangoma_tdm_get_usr_mtu_mru(ms->sangoma_sock,&tdm_api);
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log,
|
2021-12-29 16:59:00 +00:00
|
|
|
"%s: UDP TDM Period Force ReSync to 20ms \n",
|
|
|
|
woomera->interface);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2021-12-29 17:14:12 +00:00
|
|
|
#endif
|
|
|
|
if (!server.out_tx_test) {
|
|
|
|
|
|
|
|
if (woomera_dtmf_transmit(ms,sangoma_frame_len) == 0) {
|
|
|
|
sock_timeout=(sangoma_frame_len/codec_sample);
|
|
|
|
/* For sanity sake if we are doing the out test
|
|
|
|
* dont take any chances force tx udp data */
|
2021-12-29 16:59:00 +00:00
|
|
|
if (ms->skip_write_frames > 0) {
|
2021-12-29 17:14:12 +00:00
|
|
|
ms->skip_write_frames--;
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
continue;
|
2021-12-29 17:14:12 +00:00
|
|
|
} else {
|
|
|
|
sock_timeout=200;
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
2021-12-29 17:14:12 +00:00
|
|
|
|
|
|
|
if (ms->skip_write_frames > 0) {
|
|
|
|
ms->skip_write_frames--;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
if (server.out_tx_test && tx_fd &&
|
|
|
|
fread((void*)udp_frame,
|
|
|
|
sizeof(char),
|
|
|
|
packet_len,tx_fd) <= 0) {
|
|
|
|
|
|
|
|
sangoma_get_full_cfg(ms->sangoma_sock,&tdm_api);
|
|
|
|
fclose(tx_fd);
|
|
|
|
tx_fd=NULL;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
#ifdef WP_HPTDM_API
|
|
|
|
if (ms->tdmchan->push) {
|
|
|
|
ms->tdmchan->push(ms->tdmchan,udp_frame,packet_len);
|
|
|
|
}
|
|
|
|
#else
|
2021-12-29 17:22:11 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
sangoma_sendmsg_socket(ms->sangoma_sock,
|
|
|
|
&hdrframe,
|
|
|
|
sizeof(hdrframe),
|
|
|
|
udp_frame,
|
|
|
|
packet_len, 0);
|
2021-12-29 17:03:04 +00:00
|
|
|
#endif
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
if (woomera->span == 1 && woomera->chan == 1) {
|
|
|
|
udp_cnt++;
|
|
|
|
if (udp_cnt && udp_cnt % 1000 == 0) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "%s: MEDIA UDP TX RX CNT %i %i\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
woomera->interface,udp_cnt,packet_len);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
if (res < 0) {
|
2021-12-29 17:26:11 +00:00
|
|
|
if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING) ||
|
|
|
|
woomera_test_flag(&server.master_connection, WFLAG_SYSTEM_RESET) ||
|
|
|
|
woomera_test_flag(woomera, WFLAG_MEDIA_END) ||
|
|
|
|
woomera_test_flag(woomera, WFLAG_HANGUP)) {
|
|
|
|
res=0;
|
|
|
|
} else {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Media Thread: socket error %s SockID=%i %s Poll=%s!\n",
|
2021-12-29 17:26:11 +00:00
|
|
|
woomera->interface,ms->sangoma_sock,strerror(errno),SMG_DECODE_POLL_ERRORS(flags_out));
|
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
2021-12-29 17:26:11 +00:00
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
new_woomera_event_printf(&wevent,
|
2021-12-29 16:59:00 +00:00
|
|
|
"EVENT HANGUP %s%s"
|
|
|
|
"Unique-Call-Id: %s%s"
|
|
|
|
"Start-Time: %ld%s"
|
|
|
|
"End-Time: %ld%s"
|
|
|
|
"Answer-Time: %ld%s"
|
|
|
|
"Call-ID: %s%s"
|
2021-12-29 17:12:33 +00:00
|
|
|
"Cause: %s%s"
|
|
|
|
"Q931-Cause-Code: %d%s",
|
2021-12-29 16:59:00 +00:00
|
|
|
woomera->interface,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
2021-12-29 17:11:50 +00:00
|
|
|
|
|
|
|
woomera->session,
|
2021-12-29 16:59:00 +00:00
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
|
|
|
|
time(&ms->started),
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
|
|
|
|
time(NULL),
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
|
|
|
|
time(&ms->answered),
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
|
|
|
|
woomera->interface,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
2021-12-29 17:12:33 +00:00
|
|
|
|
|
|
|
q931_rel_to_str(woomera->q931_rel_cause_topbx),
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:12:33 +00:00
|
|
|
woomera->q931_rel_cause_topbx,
|
2021-12-29 16:59:00 +00:00
|
|
|
WOOMERA_RECORD_SEPERATOR
|
|
|
|
);
|
|
|
|
|
|
|
|
enqueue_event(woomera, &wevent,EVENT_FREE_DATA);
|
|
|
|
|
|
|
|
|
|
|
|
media_thread_exit:
|
2021-12-29 17:27:14 +00:00
|
|
|
|
2021-12-29 17:29:00 +00:00
|
|
|
if (!tdmv_hwec_persist) {
|
|
|
|
if (hwec_enabled) {
|
|
|
|
int err;
|
|
|
|
err=sangoma_tdm_disable_hwec(ms->sangoma_sock, &tdm_api);
|
|
|
|
if (err==0) {
|
|
|
|
log_printf(SMG_LOG_DEBUG_8, server.log, "MEDIA [%s] disabling hwec ok\n",woomera->interface);
|
|
|
|
} else {
|
|
|
|
log_printf(SMG_LOG_PROD, server.log, "MEDIA [%s] disabling hwec Failed (%s)\n",woomera->interface, strerror(errno));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (hwec_reenable) {
|
|
|
|
int err;
|
|
|
|
err=sangoma_tdm_enable_hwec(ms->sangoma_sock, &tdm_api);
|
|
|
|
if (err==0) {
|
|
|
|
log_printf(SMG_LOG_DEBUG_8, server.log, "MEDIA [%s] Re-enabling hwec ok\n",woomera->interface);
|
|
|
|
} else {
|
|
|
|
log_printf(SMG_LOG_PROD, server.log, "MEDIA [%s] Re-enabling hwec Failed (%s)\n",woomera->interface, strerror(errno));
|
|
|
|
}
|
2021-12-29 17:27:14 +00:00
|
|
|
}
|
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
if (woomera_test_flag(woomera, WFLAG_MEDIA_TDM_RUNNING)) {
|
|
|
|
woomera_set_flag(woomera, WFLAG_MEDIA_END);
|
2021-12-29 17:26:11 +00:00
|
|
|
|
|
|
|
/* Dont wait for the other thread */
|
|
|
|
close_socket(&ms->udp_sock);
|
2021-12-29 17:28:39 +00:00
|
|
|
close_span_chan(&ms->sangoma_sock, woomera->span+1, woomera->chan+1);
|
2021-12-29 16:59:00 +00:00
|
|
|
while(woomera_test_flag(woomera, WFLAG_MEDIA_TDM_RUNNING)) {
|
|
|
|
usleep(1000);
|
|
|
|
sched_yield();
|
|
|
|
}
|
2021-12-29 17:26:11 +00:00
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
close_socket(&ms->udp_sock);
|
2021-12-29 17:28:39 +00:00
|
|
|
close_span_chan(&ms->sangoma_sock, woomera->span+1, woomera->chan+1);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
if (tx_fd){
|
|
|
|
fclose(tx_fd);
|
|
|
|
tx_fd=NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
woomera_set_flag(woomera, WFLAG_MEDIA_END);
|
|
|
|
|
|
|
|
woomera_set_ms(woomera,NULL);
|
|
|
|
woomera_clear_flag(woomera, WFLAG_MEDIA_RUNNING);
|
|
|
|
|
|
|
|
media_session_free(ms);
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, server.log, "MEDIA session for [%s] ended (ptr=%p)\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
woomera->interface,woomera);
|
|
|
|
|
|
|
|
|
|
|
|
pthread_exit(NULL);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void *media_tdm_thread_run(void *obj)
|
|
|
|
{
|
2021-12-29 17:22:11 +00:00
|
|
|
wanpipe_tdm_api_t tdm_api;
|
|
|
|
wp_tdm_api_event_t *rx_event;
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
struct media_session *ms = obj;
|
|
|
|
struct woomera_interface *woomera = ms->woomera;
|
|
|
|
int res = 0;
|
|
|
|
unsigned char circuit_frame[1024];
|
|
|
|
sangoma_api_hdr_t hdrframe;
|
2021-12-29 17:26:11 +00:00
|
|
|
int flags_out;
|
2021-12-29 17:28:39 +00:00
|
|
|
int poll_opt = POLLIN | POLLPRI;
|
2021-12-29 17:22:11 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
memset(&hdrframe,0,sizeof(hdrframe));
|
|
|
|
memset(circuit_frame,0,sizeof(circuit_frame));
|
|
|
|
|
2021-12-29 17:22:11 +00:00
|
|
|
memset(&tdm_api, 0, sizeof(wanpipe_tdm_api_t));
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
if (woomera_test_flag(woomera, WFLAG_MEDIA_END) || !woomera->interface) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, server.log, "MEDIA TDM session for [%s] Cancelled! (ptr=%p)\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
woomera->interface,woomera);
|
|
|
|
/* In this case the call will be closed via woomera_thread_run
|
|
|
|
* function. And the process table will be cleard there */
|
|
|
|
woomera_set_flag(woomera, WFLAG_MEDIA_END);
|
|
|
|
woomera_clear_flag(woomera, WFLAG_MEDIA_TDM_RUNNING);
|
|
|
|
pthread_exit(NULL);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, server.log, "MEDIA TDM session for [%s] started (ptr=%p)\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
woomera->interface,woomera);
|
|
|
|
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
for (;;) {
|
|
|
|
|
|
|
|
if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING) ||
|
|
|
|
woomera_test_flag(&server.master_connection, WFLAG_SYSTEM_RESET) ||
|
|
|
|
woomera_test_flag(woomera, WFLAG_MEDIA_END)) {
|
|
|
|
res=0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:28:39 +00:00
|
|
|
if (ms->oob_disable) {
|
|
|
|
poll_opt = POLLIN;
|
|
|
|
} else {
|
|
|
|
poll_opt = POLLIN | POLLPRI;
|
|
|
|
}
|
|
|
|
res = waitfor_socket(ms->sangoma_sock, 1000, poll_opt, &flags_out);
|
2021-12-29 17:22:11 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
|
|
|
|
if (res < 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (res == 0) {
|
2021-12-29 17:22:11 +00:00
|
|
|
#if 0
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_8, server.log, "%s: TDM UDP Timeout !!!\n",
|
2021-12-29 17:22:11 +00:00
|
|
|
woomera->interface);
|
|
|
|
/* NENAD Timeout thus just continue */
|
|
|
|
#endif
|
2021-12-29 17:26:11 +00:00
|
|
|
continue;
|
|
|
|
}
|
2021-12-29 17:22:11 +00:00
|
|
|
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
if (flags_out & POLLIN) {
|
2021-12-29 17:22:11 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
res = sangoma_readmsg_socket(ms->sangoma_sock,
|
|
|
|
&hdrframe,
|
|
|
|
sizeof(hdrframe),
|
|
|
|
circuit_frame,
|
|
|
|
sizeof(circuit_frame), 0);
|
|
|
|
|
|
|
|
if (res < 0) {
|
|
|
|
if (!woomera_test_flag(woomera, WFLAG_MEDIA_END)) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "TDM Read Data Error: %s %s Sockid=%i\n",
|
2021-12-29 17:26:11 +00:00
|
|
|
woomera->interface,
|
|
|
|
strerror(errno),ms->sangoma_sock);
|
2021-12-29 17:22:11 +00:00
|
|
|
}
|
2021-12-29 17:26:11 +00:00
|
|
|
break;
|
|
|
|
}
|
2021-12-29 17:22:11 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
res = sendto(ms->udp_sock,
|
|
|
|
circuit_frame,
|
|
|
|
res, 0,
|
|
|
|
(struct sockaddr *) &ms->remote_addr,
|
|
|
|
sizeof(ms->remote_addr));
|
|
|
|
|
|
|
|
if (res < 0) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, server.log, "UDP Sento Error: %s\n", strerror(errno));
|
2021-12-29 17:26:11 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flags_out & POLLPRI) {
|
|
|
|
|
|
|
|
res = sangoma_tdm_read_event(ms->sangoma_sock, &tdm_api);
|
|
|
|
if (res < 0) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "TDM Read Event Error: %s %s Sockid=%i\n",
|
2021-12-29 17:26:11 +00:00
|
|
|
woomera->interface,
|
|
|
|
strerror(errno),ms->sangoma_sock);
|
2021-12-29 17:22:11 +00:00
|
|
|
break;
|
2021-12-29 17:26:11 +00:00
|
|
|
}
|
2021-12-29 17:22:11 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
rx_event = &tdm_api.wp_tdm_cmd.event;
|
2021-12-29 17:22:11 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
switch (rx_event->wp_tdm_api_event_type){
|
2021-12-29 17:22:11 +00:00
|
|
|
# ifdef LIBSANGOMA_GET_HWDTMF
|
2021-12-29 17:26:11 +00:00
|
|
|
case WP_TDMAPI_EVENT_DTMF:
|
2021-12-29 17:22:11 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
/* Only handle hw dtmf if hw_dtmf option is enabled */
|
|
|
|
if (!ms->hw_dtmf) {
|
2021-12-29 17:22:11 +00:00
|
|
|
break;
|
2021-12-29 17:26:11 +00:00
|
|
|
}
|
2021-12-29 17:22:11 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
/* PORT_SOUT = 1 */
|
|
|
|
if (rx_event->wp_tdm_api_event_dtmf_port == WAN_EC_CHANNEL_PORT_SOUT &&
|
|
|
|
rx_event->wp_tdm_api_event_dtmf_type == WAN_EC_TONE_PRESENT) {
|
2021-12-29 17:22:11 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
handle_event_dtmf(woomera, rx_event->wp_tdm_api_event_dtmf_digit);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
default:
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "TDM API Unknown OOB Event %i\n",
|
2021-12-29 17:26:11 +00:00
|
|
|
rx_event->wp_tdm_api_event_type);
|
|
|
|
break;
|
|
|
|
}
|
2021-12-29 17:22:11 +00:00
|
|
|
}
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
#if 0
|
|
|
|
if (woomera->span == 1 && woomera->chan == 1) {
|
|
|
|
tdm_cnt++;
|
|
|
|
if (tdm_cnt && tdm_cnt % 1000 == 0) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "%s: MEDIA TDM TX RX CNT %i %i\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
woomera->interface,tdm_cnt,res);
|
|
|
|
}
|
|
|
|
}
|
2021-12-29 17:26:11 +00:00
|
|
|
#endif
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
2021-12-29 17:03:04 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
if (res < 0) {
|
2021-12-29 17:26:11 +00:00
|
|
|
|
|
|
|
if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING) ||
|
|
|
|
woomera_test_flag(&server.master_connection, WFLAG_SYSTEM_RESET) ||
|
|
|
|
woomera_test_flag(woomera, WFLAG_MEDIA_END)) {
|
|
|
|
|
|
|
|
/* Good reason to exit */
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Media TDM Thread: socket error %s Sockid=%i %s Woomera Flags=0x%08X Poll=%s!\n",
|
2021-12-29 17:26:11 +00:00
|
|
|
woomera->interface,ms->sangoma_sock,strerror(errno),woomera->flags,SMG_DECODE_POLL_ERRORS(flags_out));
|
|
|
|
woomera_print_flags(woomera,0);
|
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, server.log, "MEDIA TDM session for [%s] ended (ptr=%p)\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
woomera->interface,woomera);
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
woomera_set_flag(woomera, WFLAG_MEDIA_END);
|
2021-12-29 16:59:00 +00:00
|
|
|
woomera_clear_flag(woomera, WFLAG_MEDIA_TDM_RUNNING);
|
|
|
|
|
|
|
|
pthread_exit(NULL);
|
2021-12-29 17:26:11 +00:00
|
|
|
return NULL;
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* This function must be called with process_lock
|
|
|
|
* because it modifies shared process_table */
|
|
|
|
|
|
|
|
static int launch_media_thread(struct woomera_interface *woomera)
|
|
|
|
{
|
|
|
|
pthread_attr_t attr;
|
|
|
|
int result = -1;
|
|
|
|
struct media_session *ms;
|
|
|
|
|
|
|
|
if ((ms = media_session_new(woomera))) {
|
|
|
|
result = pthread_attr_init(&attr);
|
|
|
|
//pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
|
|
|
|
//pthread_attr_setschedpolicy(&attr, SCHED_RR);
|
|
|
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
|
|
|
pthread_attr_setstacksize(&attr, MGD_STACK_SIZE);
|
|
|
|
|
|
|
|
woomera_set_flag(woomera, WFLAG_MEDIA_RUNNING);
|
|
|
|
result = pthread_create(&ms->thread, &attr, media_thread_run, ms);
|
|
|
|
if (result) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "%s: Error: Creating Thread! %s\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
__FUNCTION__,strerror(errno));
|
|
|
|
woomera_clear_flag(woomera, WFLAG_MEDIA_RUNNING);
|
|
|
|
media_session_free(woomera->ms);
|
|
|
|
|
|
|
|
}
|
|
|
|
pthread_attr_destroy(&attr);
|
|
|
|
|
|
|
|
} else {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Failed to start new media session\n");
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static int launch_media_tdm_thread(struct woomera_interface *woomera)
|
|
|
|
{
|
|
|
|
pthread_attr_t attr;
|
|
|
|
int result = -1;
|
|
|
|
struct media_session *ms = woomera_get_ms(woomera);
|
|
|
|
|
|
|
|
if (!ms) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
result = pthread_attr_init(&attr);
|
|
|
|
//pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
|
|
|
|
//pthread_attr_setschedpolicy(&attr, SCHED_RR);
|
|
|
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
|
|
|
pthread_attr_setstacksize(&attr, MGD_STACK_SIZE);
|
|
|
|
|
|
|
|
woomera_set_flag(woomera, WFLAG_MEDIA_TDM_RUNNING);
|
|
|
|
result = pthread_create(&ms->thread, &attr, media_tdm_thread_run, ms);
|
|
|
|
if (result) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "%s: Error: Creating Thread! %s\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
__FUNCTION__,strerror(errno));
|
|
|
|
woomera_clear_flag(woomera, WFLAG_MEDIA_TDM_RUNNING);
|
|
|
|
}
|
|
|
|
pthread_attr_destroy(&attr);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
static struct woomera_interface * launch_woomera_loop_thread(short_signal_event_t *event)
|
2021-12-29 16:59:00 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
struct woomera_interface *woomera = NULL;
|
|
|
|
char callid[20];
|
|
|
|
|
2021-12-29 17:29:00 +00:00
|
|
|
sprintf(callid, "s%dc%d", event->span+1,event->chan+1);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:29:00 +00:00
|
|
|
if ((woomera = alloc_woomera())) {
|
2021-12-29 17:11:50 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
woomera->chan = event->chan;
|
|
|
|
woomera->span = event->span;
|
|
|
|
woomera->log = server.log;
|
|
|
|
woomera->debug = server.debug;
|
|
|
|
woomera->call_id = 1;
|
|
|
|
woomera->event_queue = NULL;
|
|
|
|
woomera->loop_tdm=1;
|
2021-12-29 17:26:11 +00:00
|
|
|
woomera->socket=-1;
|
2021-12-29 17:11:50 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
} else {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Critical ERROR: memory/socket error\n");
|
2021-12-29 16:59:00 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
woomera_set_interface(woomera,callid);
|
2021-12-29 17:14:12 +00:00
|
|
|
|
|
|
|
pthread_mutex_lock(&server.process_lock);
|
|
|
|
server.process_table[event->span][event->chan].dev = woomera;
|
|
|
|
pthread_mutex_unlock(&server.process_lock);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
if (launch_woomera_thread(woomera)) {
|
|
|
|
pthread_mutex_lock(&server.process_lock);
|
2021-12-29 17:11:50 +00:00
|
|
|
server.process_table[event->span][event->chan].dev = NULL;
|
|
|
|
memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ);
|
2021-12-29 17:28:15 +00:00
|
|
|
pthread_mutex_unlock(&server.process_lock);
|
2021-12-29 17:15:08 +00:00
|
|
|
smg_free(woomera);
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Critical ERROR: memory/socket error\n");
|
2021-12-29 16:59:00 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return woomera;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int woomera_message_parse(struct woomera_interface *woomera, struct woomera_message *wmsg, int timeout)
|
|
|
|
{
|
|
|
|
char *cur, *cr, *next = NULL, *eor = NULL;
|
|
|
|
char buf[2048];
|
|
|
|
int res = 0, bytes = 0, sanity = 0;
|
|
|
|
struct timeval started, ended;
|
|
|
|
int elapsed, loops = 0;
|
|
|
|
int failto = 0;
|
|
|
|
int packet = 0;
|
2021-12-29 17:26:11 +00:00
|
|
|
int flags_out = 0;
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
memset(wmsg, 0, sizeof(*wmsg));
|
|
|
|
|
|
|
|
if (woomera->socket < 0 ) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, woomera->log, WOOMERA_DEBUG_PREFIX "%s Invalid Socket! %d\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
woomera->interface,woomera->socket);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (woomera_test_flag(woomera, WFLAG_MEDIA_END) ||
|
2021-12-29 17:26:11 +00:00
|
|
|
woomera_test_flag(woomera, WFLAG_HANGUP)) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_9, woomera->log, WOOMERA_DEBUG_PREFIX
|
|
|
|
"%s Woomera Message parse: Call Hangup - skipping message parse !\n",
|
2021-12-29 17:26:11 +00:00
|
|
|
woomera->interface);
|
2021-12-29 16:59:00 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
gettimeofday(&started, NULL);
|
|
|
|
memset(buf, 0, sizeof(buf));
|
|
|
|
|
|
|
|
if (timeout < 0) {
|
|
|
|
timeout = abs(timeout);
|
|
|
|
failto = 1;
|
|
|
|
} else if (timeout == 0) {
|
|
|
|
timeout = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
while (!(eor = strstr(buf, WOOMERA_RECORD_SEPERATOR))) {
|
|
|
|
if (sanity > 1000) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, woomera->log, WOOMERA_DEBUG_PREFIX "%s Failed Sanity Check!\n[%s]\n\n", woomera->interface, buf);
|
2021-12-29 16:59:00 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
if ((res = waitfor_socket(woomera->socket, 1000, POLLIN, &flags_out) > 0)) {
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
res = recv(woomera->socket, buf, sizeof(buf), MSG_PEEK);
|
|
|
|
|
|
|
|
if (res > 1) {
|
|
|
|
packet++;
|
|
|
|
}
|
|
|
|
if (!strncmp(buf, WOOMERA_LINE_SEPERATOR, 2)) {
|
|
|
|
res = read(woomera->socket, buf, 2);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (res == 0) {
|
|
|
|
sanity++;
|
|
|
|
/* Looks Like it's time to go! */
|
|
|
|
if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING) ||
|
|
|
|
woomera_test_flag(woomera, WFLAG_MEDIA_END) ||
|
|
|
|
woomera_test_flag(woomera, WFLAG_HANGUP)) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_9, woomera->log, WOOMERA_DEBUG_PREFIX
|
2021-12-29 16:59:00 +00:00
|
|
|
"%s MEDIA END or HANGUP \n", woomera->interface);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
ysleep(1000);
|
|
|
|
continue;
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
} else if (res < 0) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_MISC, woomera->log, WOOMERA_DEBUG_PREFIX
|
2021-12-29 17:14:12 +00:00
|
|
|
"%s error during packet retry (err=%i) Loops#%d (%s)\n",
|
|
|
|
woomera->interface, res, loops,
|
|
|
|
strerror(errno));
|
2021-12-29 16:59:00 +00:00
|
|
|
return res;
|
|
|
|
} else if (loops) {
|
|
|
|
ysleep(100000);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
gettimeofday(&ended, NULL);
|
|
|
|
elapsed = (((ended.tv_sec * 1000) + ended.tv_usec / 1000) - ((started.tv_sec * 1000) + started.tv_usec / 1000));
|
|
|
|
|
|
|
|
if (res < 0) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, woomera->log, WOOMERA_DEBUG_PREFIX "%s Bad RECV\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
woomera->interface);
|
|
|
|
return res;
|
|
|
|
} else if (res == 0) {
|
|
|
|
sanity++;
|
|
|
|
/* Looks Like it's time to go! */
|
|
|
|
if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING) ||
|
|
|
|
woomera_test_flag(woomera, WFLAG_MEDIA_END) ||
|
|
|
|
woomera_test_flag(woomera, WFLAG_HANGUP)) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_9, woomera->log, WOOMERA_DEBUG_PREFIX
|
2021-12-29 16:59:00 +00:00
|
|
|
"%s MEDIA END or HANGUP \n", woomera->interface);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
ysleep(1000);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (packet && loops > 150) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_PROD, woomera->log, WOOMERA_DEBUG_PREFIX
|
2021-12-29 17:03:04 +00:00
|
|
|
"%s Timeout waiting for packet.\n",
|
|
|
|
woomera->interface);
|
2021-12-29 16:59:00 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (timeout > 0 && (elapsed > timeout)) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_PROD, woomera->log, WOOMERA_DEBUG_PREFIX
|
2021-12-29 16:59:00 +00:00
|
|
|
"%s Timeout [%d] reached\n",
|
|
|
|
woomera->interface, timeout);
|
|
|
|
return failto ? -1 : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (woomera_test_flag(woomera, WFLAG_EVENT)) {
|
|
|
|
/* BRB! we have an Event to deliver....*/
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* what're we still doing here? */
|
|
|
|
if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING) ||
|
|
|
|
!woomera_test_flag(woomera, WFLAG_RUNNING)) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, woomera->log, WOOMERA_DEBUG_PREFIX
|
|
|
|
"%s Woomera Message Parse: Server or Woomera not Running\n", woomera->interface);
|
2021-12-29 16:59:00 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
loops++;
|
|
|
|
}
|
|
|
|
|
|
|
|
*eor = '\0';
|
|
|
|
bytes = strlen(buf) + 4;
|
|
|
|
|
|
|
|
memset(buf, 0, sizeof(buf));
|
|
|
|
res = read(woomera->socket, buf, bytes);
|
|
|
|
next = buf;
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_WOOMERA, woomera->log, "%s:WOOMERA RX MSG: %s\n",woomera->interface,buf);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
while ((cur = next)) {
|
|
|
|
|
|
|
|
if ((cr = strstr(cur, WOOMERA_LINE_SEPERATOR))) {
|
|
|
|
*cr = '\0';
|
|
|
|
next = cr + (sizeof(WOOMERA_LINE_SEPERATOR) - 1);
|
|
|
|
if (!strcmp(next, WOOMERA_RECORD_SEPERATOR)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!cur || !*cur) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!wmsg->last) {
|
|
|
|
char *cmd, *id, *args;
|
|
|
|
woomera_set_flag(wmsg, MFLAG_EXISTS);
|
|
|
|
cmd = cur;
|
|
|
|
|
|
|
|
if ((id = strchr(cmd, ' '))) {
|
|
|
|
*id = '\0';
|
|
|
|
id++;
|
|
|
|
if ((args = strchr(id, ' '))) {
|
|
|
|
*args = '\0';
|
|
|
|
args++;
|
|
|
|
strncpy(wmsg->command_args, args, sizeof(wmsg->command_args)-1);
|
|
|
|
}
|
|
|
|
strncpy(wmsg->callid, id, sizeof(wmsg->callid)-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
strncpy(wmsg->command, cmd, sizeof(wmsg->command)-1);
|
|
|
|
} else {
|
|
|
|
char *name, *val;
|
|
|
|
name = cur;
|
|
|
|
|
|
|
|
if ((val = strchr(name, ':'))) {
|
|
|
|
*val = '\0';
|
|
|
|
val++;
|
|
|
|
while (*val == ' ') {
|
|
|
|
*val = '\0';
|
|
|
|
val++;
|
|
|
|
}
|
|
|
|
strncpy(wmsg->values[wmsg->last-1], val, WOOMERA_STRLEN);
|
|
|
|
}
|
|
|
|
strncpy(wmsg->names[wmsg->last-1], name, WOOMERA_STRLEN);
|
|
|
|
if (name && val && !strcasecmp(name, "content-type")) {
|
|
|
|
woomera_set_flag(wmsg, MFLAG_CONTENT);
|
|
|
|
bytes = atoi(val);
|
|
|
|
}
|
2021-12-29 17:03:04 +00:00
|
|
|
if (name && val && !strcasecmp(name, "content-length")) {
|
|
|
|
woomera_set_flag(wmsg, MFLAG_CONTENT);
|
|
|
|
bytes = atoi(val);
|
|
|
|
}
|
|
|
|
|
2021-12-29 16:59:42 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
wmsg->last++;
|
|
|
|
}
|
|
|
|
|
|
|
|
wmsg->last--;
|
|
|
|
|
|
|
|
if (bytes && woomera_test_flag(wmsg, MFLAG_CONTENT)) {
|
2021-12-29 17:26:11 +00:00
|
|
|
int terr;
|
|
|
|
terr=read(woomera->socket, wmsg->body,
|
2021-12-29 16:59:00 +00:00
|
|
|
(bytes > sizeof(wmsg->body)) ? sizeof(wmsg->body) : bytes);
|
|
|
|
}
|
|
|
|
|
|
|
|
return woomera_test_flag(wmsg, MFLAG_EXISTS);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
static struct woomera_interface *pull_from_holding_tank(int index, int span , int chan)
|
2021-12-29 16:59:00 +00:00
|
|
|
{
|
2021-12-29 17:11:50 +00:00
|
|
|
struct woomera_interface *woomera = NULL;
|
|
|
|
|
|
|
|
if (index < 1 || index >= CORE_TANK_LEN) {
|
2021-12-29 17:14:12 +00:00
|
|
|
if (index != 0) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "%s Error on invalid TANK INDEX = %i\n",
|
2021-12-29 17:14:12 +00:00
|
|
|
__FUNCTION__,index);
|
|
|
|
}
|
2021-12-29 17:11:50 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
pthread_mutex_lock(&server.ht_lock);
|
|
|
|
if (server.holding_tank[index] &&
|
|
|
|
server.holding_tank[index] != &woomera_dead_dev) {
|
|
|
|
woomera = server.holding_tank[index];
|
|
|
|
|
|
|
|
/* Block this index until the call is completed */
|
|
|
|
server.holding_tank[index] = &woomera_dead_dev;
|
|
|
|
|
|
|
|
woomera->index = 0;
|
|
|
|
woomera->span=span;
|
|
|
|
woomera->chan=chan;
|
|
|
|
}
|
|
|
|
pthread_mutex_unlock(&server.ht_lock);
|
|
|
|
|
|
|
|
return woomera;
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
static void clear_all_holding_tank(void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
pthread_mutex_lock(&server.ht_lock);
|
|
|
|
for (i=0;i<CORE_TANK_LEN;i++){
|
|
|
|
server.holding_tank[i] = NULL;
|
|
|
|
}
|
|
|
|
pthread_mutex_unlock(&server.ht_lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static struct woomera_interface *check_tank_index(int index)
|
|
|
|
{
|
|
|
|
struct woomera_interface *woomera = NULL;
|
|
|
|
|
|
|
|
if (index < 1 || index >= CORE_TANK_LEN) {
|
|
|
|
if (index != 0) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "%s Error on invalid TANK INDEX = %i\n",
|
2021-12-29 17:26:11 +00:00
|
|
|
__FUNCTION__,index);
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
pthread_mutex_lock(&server.ht_lock);
|
|
|
|
woomera = server.holding_tank[index];
|
|
|
|
pthread_mutex_unlock(&server.ht_lock);
|
|
|
|
|
|
|
|
return woomera;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
static void clear_from_holding_tank(int index, struct woomera_interface *woomera)
|
2021-12-29 16:59:00 +00:00
|
|
|
{
|
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
if (index < 1 || index >= CORE_TANK_LEN) {
|
2021-12-29 17:14:12 +00:00
|
|
|
if (index != 0) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "%s Error on invalid TANK INDEX = %i\n",
|
2021-12-29 17:14:12 +00:00
|
|
|
__FUNCTION__,index);
|
|
|
|
}
|
2021-12-29 17:11:50 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
pthread_mutex_lock(&server.ht_lock);
|
2021-12-29 17:26:11 +00:00
|
|
|
if (server.holding_tank[index] == &woomera_dead_dev) {
|
|
|
|
#if 0
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log, "%s Clearing DEAD id=%i OK\n",
|
2021-12-29 17:26:11 +00:00
|
|
|
__FUNCTION__,index);
|
|
|
|
#endif
|
|
|
|
server.holding_tank[index] = NULL;
|
|
|
|
} else if (woomera && server.holding_tank[index] == woomera) {
|
|
|
|
#if 0
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log, "%s Clearing ACTIVE Woomera id=%i OK\n",
|
2021-12-29 17:26:11 +00:00
|
|
|
__FUNCTION__,index);
|
|
|
|
#endif
|
|
|
|
server.holding_tank[index] = NULL;
|
|
|
|
} else if (server.holding_tank[index]) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Critical Error: Holding tank index %i not cleared %p !\n",
|
2021-12-29 17:26:11 +00:00
|
|
|
index, server.holding_tank[index]);
|
|
|
|
}
|
2021-12-29 17:11:50 +00:00
|
|
|
pthread_mutex_unlock(&server.ht_lock);
|
|
|
|
|
|
|
|
return;
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static struct woomera_interface *peek_from_holding_tank(int index)
|
|
|
|
{
|
2021-12-29 17:11:50 +00:00
|
|
|
struct woomera_interface *woomera = NULL;
|
|
|
|
|
|
|
|
if (index < 1 || index >= CORE_TANK_LEN) {
|
2021-12-29 17:14:12 +00:00
|
|
|
if (index != 0) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "%s Error on invalid TANK INDEX = %i\n",
|
2021-12-29 17:14:12 +00:00
|
|
|
__FUNCTION__,index);
|
|
|
|
}
|
2021-12-29 17:11:50 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
pthread_mutex_lock(&server.ht_lock);
|
|
|
|
if (server.holding_tank[index] &&
|
|
|
|
server.holding_tank[index] != &woomera_dead_dev) {
|
|
|
|
woomera = server.holding_tank[index];
|
|
|
|
}
|
|
|
|
pthread_mutex_unlock(&server.ht_lock);
|
|
|
|
|
|
|
|
return woomera;
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int add_to_holding_tank(struct woomera_interface *woomera)
|
|
|
|
{
|
2021-12-29 17:11:50 +00:00
|
|
|
int next, i, found=0;
|
|
|
|
|
|
|
|
pthread_mutex_lock(&server.ht_lock);
|
|
|
|
|
|
|
|
for (i=0;i<CORE_TANK_LEN;i++) {
|
|
|
|
next = ++server.holding_tank_index;
|
|
|
|
if (server.holding_tank_index >= CORE_TANK_LEN) {
|
|
|
|
next = server.holding_tank_index = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (next == 0) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "\nCritical Error on TANK INDEX == 0\n");
|
2021-12-29 17:11:50 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (server.holding_tank[next]) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
found=1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!found) {
|
|
|
|
/* This means all tank vales are busy
|
|
|
|
* should never happend */
|
|
|
|
pthread_mutex_unlock(&server.ht_lock);
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "\nCritical Error failed to obtain a TANK INDEX\n");
|
2021-12-29 17:11:50 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
server.holding_tank[next] = woomera;
|
2021-12-29 17:26:11 +00:00
|
|
|
woomera->timeout = time(NULL) + server.call_timeout;
|
2021-12-29 17:11:50 +00:00
|
|
|
|
|
|
|
pthread_mutex_unlock(&server.ht_lock);
|
|
|
|
return next;
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
2021-12-29 17:22:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
static void handle_event_dtmf(struct woomera_interface *woomera, unsigned char dtmf_digit)
|
|
|
|
{
|
|
|
|
struct woomera_event wevent;
|
|
|
|
|
|
|
|
memset(&wevent, 0, sizeof(struct woomera_event));
|
|
|
|
|
|
|
|
new_woomera_event_printf(&wevent, "EVENT DTMF %sUnique-Call-Id:%s%sContent-Length:%d%s%s%c%s",
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
woomera->session,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
1,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
dtmf_digit,
|
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
|
|
|
|
|
|
|
|
|
|
|
enqueue_event(woomera, &wevent,EVENT_FREE_DATA);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:28:39 +00:00
|
|
|
static int handle_woomera_progress(struct woomera_interface *woomera,
|
|
|
|
struct woomera_message *wmsg)
|
|
|
|
{
|
|
|
|
call_signal_event_t event;
|
|
|
|
int err=-1;
|
|
|
|
|
|
|
|
memset(&event, 0, sizeof(event));
|
2021-12-29 17:22:11 +00:00
|
|
|
|
2021-12-29 17:28:39 +00:00
|
|
|
call_signal_event_init((short_signal_event_t*)&event, SIGBOOST_EVENT_CALL_PROGRESS, woomera->chan, woomera->span);
|
|
|
|
sprintf(event.isup_in_rdnis,"SMG003-EVI-2");
|
|
|
|
event.isup_in_rdnis_size=strlen(event.isup_in_rdnis);
|
|
|
|
if (woomera->index >= 0) {
|
|
|
|
event.call_setup_id = woomera->index;
|
|
|
|
}
|
|
|
|
|
|
|
|
log_printf(SMG_LOG_WOOMERA, woomera->log, "WOOMERA CMD: %s [%s]\n",
|
|
|
|
wmsg->command, woomera->interface);
|
|
|
|
|
|
|
|
if (!woomera_check_running(woomera)) {
|
|
|
|
socket_printf(woomera->socket, "405 PROGRESS Channel already hungup%s"
|
|
|
|
"Unique-Call-Id: %s%s",
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
woomera->session,
|
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!woomera_test_flag(woomera,WFLAG_CALL_ACKED)) {
|
|
|
|
|
|
|
|
socket_printf(woomera->socket, "405 PROGRESS Channel not aceked%s"
|
|
|
|
"Unique-Call-Id: %s%s",
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
woomera->session,
|
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
err=isup_exec_event(&event);
|
|
|
|
if (err == 0) {
|
|
|
|
socket_printf(woomera->socket,
|
|
|
|
"200 %s PROGRESS OK%s"
|
|
|
|
"Unique-Call-Id: %s%s",
|
|
|
|
wmsg->callid,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
woomera->session,
|
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
|
|
|
} else {
|
|
|
|
socket_printf(woomera->socket, "405 PROGRESS Boost failure%s"
|
|
|
|
"Unique-Call-Id: %s%s",
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
woomera->session,
|
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
|
|
|
}
|
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
2021-12-29 17:22:11 +00:00
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
static int handle_woomera_media_accept_answer(struct woomera_interface *woomera,
|
|
|
|
struct woomera_message *wmsg,
|
|
|
|
int media, int answer, int accept)
|
|
|
|
{
|
|
|
|
char *raw = woomera_message_header(wmsg, "raw-audio");
|
2021-12-29 17:27:14 +00:00
|
|
|
struct woomera_event wevent;
|
2021-12-29 17:03:04 +00:00
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_WOOMERA, woomera->log, "WOOMERA CMD: %s [%s]\n",
|
2021-12-29 17:03:04 +00:00
|
|
|
wmsg->command, woomera->interface);
|
|
|
|
|
2021-12-29 17:28:39 +00:00
|
|
|
if (!woomera_check_running(woomera)) {
|
2021-12-29 17:11:50 +00:00
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, server.log,
|
2021-12-29 17:03:04 +00:00
|
|
|
"ERROR! call was cancelled MEDIA on HANGUP or MEDIA END!\n");
|
2021-12-29 17:27:14 +00:00
|
|
|
|
|
|
|
new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s"
|
|
|
|
"Unique-Call-Id: %s%s"
|
|
|
|
"Cause: %s%s"
|
|
|
|
"Q931-Cause-Code: %d%s",
|
|
|
|
wmsg->callid,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
woomera->session,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
q931_rel_to_str(woomera->q931_rel_cause_topbx),
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
woomera->q931_rel_cause_topbx,
|
|
|
|
WOOMERA_RECORD_SEPERATOR
|
|
|
|
);
|
|
|
|
|
|
|
|
enqueue_event(woomera, &wevent,EVENT_FREE_DATA);
|
|
|
|
|
|
|
|
new_woomera_event_printf(&wevent, "501 call already hungup!%s"
|
|
|
|
"Unique-Call-Id: %s%s",
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
woomera->session,
|
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
|
|
|
|
|
|
|
enqueue_event(woomera, &wevent,EVENT_FREE_DATA);
|
2021-12-29 17:11:50 +00:00
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
woomera->timeout=0;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_MISC, server.log,"WOOMERA: GOT %s EVENT: [%s] RAW=%s\n",
|
2021-12-29 17:03:04 +00:00
|
|
|
wmsg->command,wmsg->callid,raw);
|
|
|
|
|
|
|
|
|
|
|
|
if (raw &&
|
|
|
|
woomera->raw == NULL &&
|
|
|
|
!woomera_test_flag(woomera, WFLAG_RAW_MEDIA_STARTED)) {
|
|
|
|
|
|
|
|
woomera_set_flag(woomera, WFLAG_RAW_MEDIA_STARTED);
|
|
|
|
|
|
|
|
woomera_set_raw(woomera, raw);
|
2021-12-29 17:11:50 +00:00
|
|
|
|
|
|
|
if (launch_media_thread(woomera)) {
|
2021-12-29 17:03:04 +00:00
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_8, server.log,"ERROR: Failed to Launch Call [%s]\n",
|
2021-12-29 17:03:04 +00:00
|
|
|
woomera->interface);
|
2021-12-29 17:11:50 +00:00
|
|
|
|
2021-12-29 17:12:33 +00:00
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s"
|
|
|
|
"Unique-Call-Id: %s%s"
|
2021-12-29 17:12:33 +00:00
|
|
|
"Cause: %s%s"
|
|
|
|
"Q931-Cause-Code: %d%s",
|
2021-12-29 17:03:04 +00:00
|
|
|
wmsg->callid,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
2021-12-29 17:11:50 +00:00
|
|
|
woomera->session,
|
2021-12-29 17:03:04 +00:00
|
|
|
WOOMERA_LINE_SEPERATOR,
|
2021-12-29 17:12:33 +00:00
|
|
|
q931_rel_to_str(21),
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
21,
|
2021-12-29 17:03:04 +00:00
|
|
|
WOOMERA_RECORD_SEPERATOR
|
|
|
|
);
|
|
|
|
|
|
|
|
enqueue_event(woomera, &wevent,EVENT_FREE_DATA);
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
new_woomera_event_printf(&wevent, "501 call was cancelled!%s"
|
|
|
|
"Unique-Call-Id: %s%s",
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
woomera->session,
|
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
|
|
|
|
|
|
|
enqueue_event(woomera, &wevent,EVENT_FREE_DATA);
|
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
woomera_set_flag(woomera, WFLAG_MEDIA_END);
|
2021-12-29 17:03:04 +00:00
|
|
|
woomera_clear_flag(woomera, WFLAG_RUNNING);
|
|
|
|
|
|
|
|
woomera->timeout=0;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log,"ERROR! Monitor Thread not running!\n");
|
|
|
|
new_woomera_event_printf(&wevent, "501 call was cancelled!%s"
|
|
|
|
"Unique-Call-Id: %s%s",
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
woomera->session,
|
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
|
|
|
|
|
|
|
enqueue_event(woomera, &wevent,EVENT_FREE_DATA);
|
|
|
|
return -1;
|
2021-12-29 17:03:04 +00:00
|
|
|
|
|
|
|
} else {
|
2021-12-29 17:14:12 +00:00
|
|
|
|
|
|
|
if (accept) {
|
|
|
|
if (!autoacm && !woomera_test_flag(woomera,WFLAG_CALL_ACKED)) {
|
|
|
|
woomera_set_flag(woomera,WFLAG_CALL_ACKED);
|
|
|
|
isup_exec_command(woomera->span,
|
|
|
|
woomera->chan,
|
|
|
|
-1,
|
|
|
|
SIGBOOST_EVENT_CALL_START_ACK,
|
|
|
|
0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
if (answer) {
|
|
|
|
struct media_session *ms;
|
|
|
|
|
|
|
|
pthread_mutex_lock(&woomera->ms_lock);
|
|
|
|
if ((ms=woomera->ms)) {
|
|
|
|
time(&woomera->ms->answered);
|
|
|
|
}
|
|
|
|
pthread_mutex_unlock(&woomera->ms_lock);
|
|
|
|
|
|
|
|
if (ms) {
|
2021-12-29 17:14:12 +00:00
|
|
|
|
|
|
|
if (!autoacm && !woomera_test_flag(woomera,WFLAG_CALL_ACKED)) {
|
|
|
|
woomera_set_flag(woomera,WFLAG_CALL_ACKED);
|
|
|
|
isup_exec_command(woomera->span,
|
|
|
|
woomera->chan,
|
|
|
|
-1,
|
|
|
|
SIGBOOST_EVENT_CALL_START_ACK,
|
|
|
|
0);
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
isup_exec_command(woomera->span,
|
|
|
|
woomera->chan,
|
|
|
|
-1,
|
|
|
|
SIGBOOST_EVENT_CALL_ANSWERED,
|
|
|
|
0);
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, server.log,
|
2021-12-29 17:29:00 +00:00
|
|
|
"Sent SIGBOOST_EVENT_CALL_ANSWERED [s%dc%d]\n",
|
2021-12-29 17:11:50 +00:00
|
|
|
woomera->span+1,woomera->chan+1);
|
2021-12-29 17:03:04 +00:00
|
|
|
} else {
|
|
|
|
struct woomera_event wevent;
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log,
|
2021-12-29 17:03:04 +00:00
|
|
|
"WOOMERA ANSWER: FAILED [%s] no Media \n",
|
|
|
|
wmsg->command,wmsg->callid);
|
|
|
|
|
|
|
|
|
|
|
|
new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s"
|
|
|
|
"Unique-Call-Id: %s%s"
|
2021-12-29 17:12:33 +00:00
|
|
|
"Cause: %s%s"
|
|
|
|
"Q931-Cause-Code: %d%s",
|
2021-12-29 17:03:04 +00:00
|
|
|
wmsg->callid,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
2021-12-29 17:11:50 +00:00
|
|
|
woomera->session,
|
2021-12-29 17:03:04 +00:00
|
|
|
WOOMERA_LINE_SEPERATOR,
|
2021-12-29 17:12:33 +00:00
|
|
|
q931_rel_to_str(21),
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
21,
|
2021-12-29 17:03:04 +00:00
|
|
|
WOOMERA_RECORD_SEPERATOR
|
|
|
|
);
|
|
|
|
|
|
|
|
enqueue_event(woomera, &wevent,EVENT_FREE_DATA);
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
new_woomera_event_printf(&wevent, "501 call was cancelled!%s"
|
2021-12-29 17:26:11 +00:00
|
|
|
"Unique-Call-Id: %s%s",
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
woomera->session,
|
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
|
|
|
|
|
|
|
enqueue_event(woomera, &wevent,EVENT_FREE_DATA);
|
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
woomera_set_flag(woomera, WFLAG_MEDIA_END);
|
|
|
|
woomera_clear_flag(woomera, WFLAG_RUNNING);
|
|
|
|
woomera->timeout=0;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2021-12-29 17:27:14 +00:00
|
|
|
}
|
2021-12-29 17:03:04 +00:00
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
new_woomera_event_printf(&wevent, "200 %s OK%s"
|
|
|
|
"Unique-Call-Id: %s%s",
|
|
|
|
answer ? "ANSWER" :
|
|
|
|
accept ? "ACCEPT" : "MEDIA",
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
woomera->session,
|
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
|
|
|
|
|
|
|
enqueue_event(woomera, &wevent,EVENT_FREE_DATA);
|
2021-12-29 17:03:04 +00:00
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
return 0;
|
2021-12-29 17:03:04 +00:00
|
|
|
}
|
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
static int handle_woomera_call_start (struct woomera_interface *woomera,
|
|
|
|
struct woomera_message *wmsg)
|
2021-12-29 17:03:04 +00:00
|
|
|
{
|
2021-12-29 17:26:11 +00:00
|
|
|
char *raw = woomera_message_header(wmsg, "raw-audio");
|
|
|
|
call_signal_event_t event;
|
|
|
|
char *calling = woomera_message_header(wmsg, "local-number");
|
|
|
|
#ifdef SMG_CALLING_NAME
|
|
|
|
char *calling_name = woomera_message_header(wmsg, "local-name");
|
2021-12-29 17:14:12 +00:00
|
|
|
#endif
|
2021-12-29 17:03:04 +00:00
|
|
|
char *presentation = woomera_message_header(wmsg, "Presentation");
|
|
|
|
char *screening = woomera_message_header(wmsg, "Screening");
|
|
|
|
char *rdnis = woomera_message_header(wmsg, "RDNIS");
|
2021-12-29 17:26:11 +00:00
|
|
|
char *bearer_cap = woomera_message_header(wmsg, "Bearer-Cap");
|
|
|
|
char *uil1p = woomera_message_header(wmsg, "uil1p");
|
2021-12-29 17:03:04 +00:00
|
|
|
char *called = wmsg->callid;
|
|
|
|
char *grp = wmsg->callid;
|
2021-12-29 17:29:00 +00:00
|
|
|
char *profile;
|
2021-12-29 17:03:04 +00:00
|
|
|
char *p;
|
2021-12-29 17:14:12 +00:00
|
|
|
int cause = 34;
|
2021-12-29 17:03:04 +00:00
|
|
|
int tg = 0;
|
2021-12-29 17:26:11 +00:00
|
|
|
int huntgroup = SIGBOOST_HUNTGRP_SEQ_ASC;
|
|
|
|
|
|
|
|
if (smg_check_all_busy() ||
|
|
|
|
woomera_test_flag(&server.master_connection, WFLAG_SYSTEM_RESET)){
|
|
|
|
|
|
|
|
|
|
|
|
socket_printf(woomera->socket, "EVENT HANGUP %s"
|
|
|
|
"Cause: %s%s"
|
|
|
|
"Q931-Cause-Code: %d%s",
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
q931_rel_to_str(cause),
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
cause,
|
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
2021-12-29 17:03:04 +00:00
|
|
|
|
|
|
|
socket_printf(woomera->socket,
|
|
|
|
"405 SMG Server All Ckt Busy!%s", WOOMERA_RECORD_SEPERATOR);
|
2021-12-29 17:26:11 +00:00
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_MISC, woomera->log, "SMG Server Full %d (ckt busy cnt=%i)\n",
|
2021-12-29 17:03:04 +00:00
|
|
|
server.call_count, server.all_ckt_busy);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
|
2021-12-29 17:29:00 +00:00
|
|
|
/* Remove profile name out of destiantion */
|
|
|
|
if ((profile = strchr(called, ':'))) {
|
|
|
|
profile++;
|
|
|
|
called=profile;
|
|
|
|
grp=profile;
|
|
|
|
}
|
|
|
|
|
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, woomera->log, "New Call %d/%d origdest=%s newdest=%s\n",
|
|
|
|
server.call_count, server.max_calls, wmsg->callid, called);
|
2021-12-29 17:03:04 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
switch(called[0]) {
|
|
|
|
case 'g':
|
|
|
|
huntgroup = SIGBOOST_HUNTGRP_SEQ_ASC;
|
|
|
|
break;
|
|
|
|
case 'G':
|
|
|
|
huntgroup = SIGBOOST_HUNTGRP_SEQ_DESC;
|
|
|
|
break;
|
|
|
|
case 'r':
|
|
|
|
huntgroup = SIGBOOST_HUNTGRP_RR_ASC;
|
|
|
|
break;
|
|
|
|
case 'R':
|
|
|
|
huntgroup = SIGBOOST_HUNTGRP_RR_DESC;
|
|
|
|
break;
|
|
|
|
default:
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, woomera->log,
|
2021-12-29 17:26:11 +00:00
|
|
|
"Warning: Failed to determine huntgroup (%s)\n",
|
|
|
|
called);
|
|
|
|
huntgroup = SIGBOOST_HUNTGRP_SEQ_ASC;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
if ((p = strchr(called, '/'))) {
|
|
|
|
*p = '\0';
|
|
|
|
called = p+1;
|
|
|
|
tg = atoi(grp+1) - 1;
|
|
|
|
if (tg < 0) {
|
|
|
|
tg=0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
woomera->trunk_group=tg;
|
2021-12-29 17:03:04 +00:00
|
|
|
if (raw) {
|
|
|
|
woomera_set_raw(woomera, raw);
|
|
|
|
}
|
|
|
|
|
|
|
|
woomera->index = add_to_holding_tank(woomera);
|
|
|
|
if (woomera->index < 1) {
|
2021-12-29 17:14:12 +00:00
|
|
|
socket_printf(woomera->socket, "EVENT HANGUP %s"
|
2021-12-29 17:26:11 +00:00
|
|
|
"Cause: %s%s"
|
|
|
|
"Q931-Cause-Code: %d%s",
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
q931_rel_to_str(cause),
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
cause,
|
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
2021-12-29 17:03:04 +00:00
|
|
|
socket_printf(woomera->socket,
|
|
|
|
"405 SMG Server All Tanks Busy!%s",
|
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, woomera->log, "Error: Call Tank Full (Call Cnt=%i)\n",
|
2021-12-29 17:03:04 +00:00
|
|
|
server.call_count);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
woomera->index_hold = woomera->index;
|
|
|
|
|
|
|
|
call_signal_call_init(&event, calling, called, woomera->index);
|
|
|
|
|
|
|
|
if (presentation) {
|
|
|
|
event.calling_number_presentation = atoi(presentation);
|
|
|
|
} else {
|
|
|
|
event.calling_number_presentation = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (screening) {
|
|
|
|
event.calling_number_screening_ind = atoi(screening);
|
|
|
|
} else {
|
|
|
|
event.calling_number_screening_ind = 0;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
event.isup_in_rdnis_size=0;
|
|
|
|
event.isup_in_rdnis[0]=0;
|
|
|
|
|
|
|
|
if (rdnis && strlen(rdnis) ) {
|
|
|
|
|
|
|
|
if (strlen(rdnis) > sizeof(event.isup_in_rdnis)){
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log,"Error: RDNIS Overflow (in size=%i max=%i)\n",
|
2021-12-29 17:26:11 +00:00
|
|
|
strlen(rdnis), sizeof(event.isup_in_rdnis));
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
strncpy(event.isup_in_rdnis,rdnis,
|
|
|
|
sizeof(event.isup_in_rdnis)-1);
|
|
|
|
event.isup_in_rdnis_size=strlen(rdnis)+1;
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_MISC,server.log,"RDNIS %s\n", rdnis);
|
2021-12-29 17:26:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2021-12-29 17:03:04 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
if (bearer_cap && strlen(bearer_cap)) {
|
|
|
|
event.bearer.capability = bearer_cap_to_code(bearer_cap);
|
2021-12-29 17:27:14 +00:00
|
|
|
woomera->bearer_cap = event.bearer.capability;
|
2021-12-29 17:03:04 +00:00
|
|
|
}
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
if (uil1p && strlen(uil1p)) {
|
|
|
|
event.bearer.uil1p = uil1p_to_code(uil1p);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef SMG_CALLING_NAME
|
2021-12-29 17:14:12 +00:00
|
|
|
if (calling_name) {
|
|
|
|
strncpy((char*)event.calling_name,calling_name,
|
|
|
|
sizeof(event.calling_name)-1);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
event.trunk_group = tg;
|
2021-12-29 17:26:11 +00:00
|
|
|
event.hunt_group = huntgroup;
|
2021-12-29 16:59:42 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
if (call_signal_connection_write(&server.mcon, &event) < 0) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log,
|
2021-12-29 17:03:04 +00:00
|
|
|
"Critical System Error: Failed to tx on ISUP socket [%s]: %s\n",
|
|
|
|
strerror(errno));
|
2021-12-29 17:14:12 +00:00
|
|
|
|
|
|
|
socket_printf(woomera->socket, "EVENT HANGUP %s"
|
|
|
|
"Cause: %s%s"
|
|
|
|
"Q931-Cause-Code: %d%s",
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
q931_rel_to_str(cause),
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
cause,
|
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
socket_printf(woomera->socket,
|
|
|
|
"405 SMG Signalling Contestion!%s",
|
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
socket_printf(woomera->socket, "100 Trying%s", WOOMERA_RECORD_SEPERATOR);
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, server.log, "Call Called Event [Setup ID: %d] TG=%d\n",
|
2021-12-29 17:26:11 +00:00
|
|
|
woomera->index,tg);
|
2021-12-29 17:03:04 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
static void interpret_command(struct woomera_interface *woomera, struct woomera_message *wmsg)
|
|
|
|
{
|
2021-12-29 17:11:50 +00:00
|
|
|
int answer = 0, media = 0, accept=0;
|
|
|
|
char *unique_id;
|
2021-12-29 17:14:12 +00:00
|
|
|
int cause=0;
|
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
|
|
|
|
|
|
|
|
if (!strcasecmp(wmsg->command, "call")) {
|
|
|
|
int err;
|
2021-12-29 17:26:11 +00:00
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
if (strlen(woomera->session) != 0) {
|
|
|
|
/* Call has already been placed */
|
|
|
|
socket_printf(woomera->socket, "400 Error Call already in progress %s",
|
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log,"Woomera RX Call Even while call in progress!\n");
|
2021-12-29 17:26:11 +00:00
|
|
|
woomera_set_flag(woomera, WFLAG_HANGUP);
|
2021-12-29 17:11:50 +00:00
|
|
|
return;
|
|
|
|
}
|
2021-12-29 17:26:11 +00:00
|
|
|
|
|
|
|
if (woomera_test_flag(&server.master_connection, WFLAG_SYSTEM_RESET)){
|
|
|
|
socket_printf(woomera->socket, "EVENT HANGUP %s"
|
|
|
|
"Cause: %s%s"
|
|
|
|
"Q931-Cause-Code: %d%s",
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
q931_rel_to_str(34),
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
34,
|
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
|
|
|
socket_printf(woomera->socket,
|
|
|
|
"405 SMG Server All Ckt Reset!%s", WOOMERA_RECORD_SEPERATOR);
|
|
|
|
|
|
|
|
woomera_set_flag(woomera, WFLAG_HANGUP);
|
|
|
|
return;
|
|
|
|
}
|
2021-12-29 17:11:50 +00:00
|
|
|
|
|
|
|
err=handle_woomera_call_start(woomera,wmsg);
|
|
|
|
if (err) {
|
2021-12-29 17:14:12 +00:00
|
|
|
woomera_set_flag(woomera, WFLAG_HANGUP);
|
2021-12-29 17:11:50 +00:00
|
|
|
}
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
return;
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
} else if (!strcasecmp(wmsg->command, "bye") || !strcasecmp(wmsg->command, "quit")) {
|
2021-12-29 16:59:00 +00:00
|
|
|
char *cause = woomera_message_header(wmsg, "cause");
|
2021-12-29 17:12:33 +00:00
|
|
|
char *q931cause = woomera_message_header(wmsg, "Q931-Cause-Code");
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
if (cause) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_MISC, woomera->log, "Bye Cause Received: [%s]\n", cause);
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
2021-12-29 17:12:33 +00:00
|
|
|
if (q931cause && atoi(q931cause)) {
|
|
|
|
woomera_set_cause_tosig(woomera,atoi(q931cause));
|
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_WOOMERA, woomera->log, "WOOMERA CMD: Bye Received: [%s]\n", woomera->interface);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
woomera_clear_flag(woomera, WFLAG_RUNNING);
|
|
|
|
socket_printf(woomera->socket, "200 Connection closed%s"
|
|
|
|
"Unique-Call-Id: %s%s",
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
2021-12-29 17:11:50 +00:00
|
|
|
woomera->session,
|
2021-12-29 16:59:00 +00:00
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
2021-12-29 17:11:50 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
} else if (!strcasecmp(wmsg->command, "listen")) {
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
if (woomera_test_flag(woomera, WFLAG_LISTENING)) {
|
|
|
|
socket_printf(woomera->socket, "405 Listener already started%s"
|
|
|
|
"Unique-Call-Id: %s%s",
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
2021-12-29 17:11:50 +00:00
|
|
|
woomera->session,
|
2021-12-29 16:59:00 +00:00
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
|
|
|
} else {
|
2021-12-29 17:14:45 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
woomera_set_flag(woomera, WFLAG_LISTENING);
|
|
|
|
add_listener(woomera);
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,woomera->log, "Starting Listen Device!\n");
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
socket_printf(woomera->socket, "%s",
|
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
|
|
|
|
|
|
|
socket_printf(woomera->socket, "200 Listener enabled%s"
|
|
|
|
"Unique-Call-Id: %s%s",
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
2021-12-29 17:11:50 +00:00
|
|
|
woomera->session,
|
2021-12-29 16:59:00 +00:00
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
|
|
|
}
|
2021-12-29 17:11:50 +00:00
|
|
|
return;
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
} else if ((media = !strcasecmp(wmsg->command, "debug"))) {
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
int debug_level=atoi(wmsg->callid);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
if (debug_level < 10) {
|
|
|
|
server.debug=debug_level;
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log,"SMG Debugging set to %i (window=%i)\n",server.debug,server.mcon.txwindow);
|
2021-12-29 17:11:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
if (!strcasecmp(wmsg->command, "hangup")) {
|
|
|
|
char *q931cause = woomera_message_header(wmsg, "Q931-Cause-Code");
|
|
|
|
|
|
|
|
|
|
|
|
if (q931cause && atoi(q931cause)) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_8,server.log,"Woomera Hangup setting cause to %s %i\n",
|
2021-12-29 17:26:11 +00:00
|
|
|
q931cause,atoi(q931cause));
|
|
|
|
woomera_set_cause_tosig(woomera,atoi(q931cause));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Continue Through */
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
unique_id = woomera_message_header(wmsg, "Unique-Call-Id");
|
|
|
|
if (!unique_id) {
|
2021-12-29 17:14:12 +00:00
|
|
|
|
|
|
|
cause=111;
|
|
|
|
socket_printf(woomera->socket, "EVENT HANGUP %s"
|
|
|
|
"Cause: %s%s"
|
|
|
|
"Q931-Cause-Code: %d%s",
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
q931_rel_to_str(cause),
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
cause,
|
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
|
|
|
socket_printf(woomera->socket, "400 Woomera cmd without uniquie id%s"
|
2021-12-29 17:11:50 +00:00
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL,server.log,"Woomera RX Event (%s) without unique id!\n",wmsg->command);
|
2021-12-29 17:14:12 +00:00
|
|
|
woomera_set_flag(woomera, WFLAG_HANGUP);
|
2021-12-29 17:11:50 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strlen(woomera->session) == 0) {
|
|
|
|
struct woomera_interface *session_woomera=NULL;
|
|
|
|
char *session=NULL;
|
|
|
|
int span, chan;
|
|
|
|
char ifname[100];
|
2021-12-29 17:29:00 +00:00
|
|
|
int err;
|
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
/* If session does not exist this is an incoming call */
|
2021-12-29 17:29:00 +00:00
|
|
|
err=sscanf(unique_id, "s%dc%d", &span, &chan);
|
|
|
|
if (err!=2) {
|
|
|
|
err=sscanf(unique_id, "w%dg%d", &span, &chan);
|
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
span--;
|
|
|
|
chan--;
|
2021-12-29 17:11:50 +00:00
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_MISC, woomera->log,
|
2021-12-29 17:11:50 +00:00
|
|
|
"WOOMERA Got CMD %s Span=%d Chan=%d from session %s\n",
|
|
|
|
wmsg->command,span,chan,unique_id);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
if (smg_validate_span_chan(span,chan) != 0) {
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
cause=81;
|
|
|
|
socket_printf(woomera->socket, "EVENT HANGUP %s"
|
2021-12-29 17:14:12 +00:00
|
|
|
"Cause: %s%s"
|
|
|
|
"Q931-Cause-Code: %d%s",
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
q931_rel_to_str(cause),
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
cause,
|
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
|
|
|
socket_printf(woomera->socket, "404 Invalid span/chan in session%s"
|
2021-12-29 17:11:50 +00:00
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, woomera->log,
|
2021-12-29 17:14:12 +00:00
|
|
|
"WOOMERA Warning invalid span chan in session %s %s\n",
|
2021-12-29 17:11:50 +00:00
|
|
|
wmsg->command,unique_id);
|
2021-12-29 17:14:12 +00:00
|
|
|
woomera_set_flag(woomera, WFLAG_HANGUP);
|
2021-12-29 17:11:50 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
pthread_mutex_lock(&server.process_lock);
|
|
|
|
session = server.process_table[span][chan].session;
|
|
|
|
session_woomera = server.process_table[span][chan].dev;
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
/* This scenario is very common when we have multile clients
|
|
|
|
where multiple clients race get the incoming call */
|
2021-12-29 17:11:50 +00:00
|
|
|
if (session_woomera) {
|
2021-12-29 16:59:00 +00:00
|
|
|
pthread_mutex_unlock(&server.process_lock);
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
cause=81;
|
|
|
|
socket_printf(woomera->socket, "EVENT HANGUP %s"
|
2021-12-29 17:14:12 +00:00
|
|
|
"Cause: %s%s"
|
|
|
|
"Q931-Cause-Code: %d%s",
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
q931_rel_to_str(cause),
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
cause,
|
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
|
|
|
socket_printf(woomera->socket, "404 Session not found%s"
|
2021-12-29 17:11:50 +00:00
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_8, woomera->log, "WOOMERA Error channel in use %s %s\n",
|
2021-12-29 17:11:50 +00:00
|
|
|
wmsg->command,unique_id);
|
2021-12-29 17:14:12 +00:00
|
|
|
woomera_set_flag(woomera, WFLAG_HANGUP);
|
2021-12-29 17:11:50 +00:00
|
|
|
return;
|
|
|
|
}
|
2021-12-29 17:03:04 +00:00
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
if (!session || strlen(session) == 0 ||
|
|
|
|
strncmp(session,unique_id,sizeof(woomera->session))){
|
|
|
|
pthread_mutex_unlock(&server.process_lock);
|
2021-12-29 17:03:04 +00:00
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
/* Invalid call reference */
|
|
|
|
cause=81;
|
|
|
|
socket_printf(woomera->socket, "event hangup %s"
|
|
|
|
"cause: %s%s"
|
|
|
|
"q931-cause-code: %d%s",
|
2021-12-29 17:14:12 +00:00
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
q931_rel_to_str(cause),
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
cause,
|
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
|
|
|
|
|
|
|
socket_printf(woomera->socket, "404 Invalid/Expired Session%s"
|
2021-12-29 17:11:50 +00:00
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_MISC, woomera->log,
|
2021-12-29 17:11:50 +00:00
|
|
|
"WOOMERA Warning: Cmd=%s with invalid session %s (orig=%s)\n",
|
|
|
|
wmsg->command,unique_id,session?session:"N/A");
|
2021-12-29 17:14:12 +00:00
|
|
|
woomera_set_flag(woomera, WFLAG_HANGUP);
|
2021-12-29 17:11:50 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
#if 1
|
|
|
|
if (!strcasecmp(wmsg->command, "hangup")) {
|
|
|
|
int clients=server.process_table[span][chan].clients;
|
|
|
|
if (server.process_table[span][chan].clients < 0) {
|
|
|
|
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_ALL, woomera->log, "WOOMERA CMD: Warning Clients (%i) Race condition on Hangup [s%dc%d]\n",
|
2021-12-29 17:27:14 +00:00
|
|
|
clients, span+1,chan+1);
|
|
|
|
|
|
|
|
} else if (server.process_table[span][chan].clients > 1) {
|
|
|
|
server.process_table[span][chan].clients--;
|
|
|
|
pthread_mutex_unlock(&server.process_lock);
|
|
|
|
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_MISC, woomera->log, "WOOMERA CMD: Got Hungup on Multiple Clients %i, skipping hangup [s%dc%d]\n",
|
2021-12-29 17:27:14 +00:00
|
|
|
clients, span+1,chan+1);
|
|
|
|
|
|
|
|
cause=16;
|
|
|
|
socket_printf(woomera->socket, "event hangup %s"
|
|
|
|
"cause: %s%s"
|
|
|
|
"q931-cause-code: %d%s",
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
q931_rel_to_str(cause),
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
cause,
|
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
|
|
|
|
|
|
|
socket_printf(woomera->socket, "404 Hangup on multiple session%s"
|
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
|
|
|
|
|
|
|
woomera_set_flag(woomera, WFLAG_HANGUP);
|
|
|
|
return;
|
|
|
|
}
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_MISC, woomera->log, "WOOMERA CMD: Hanging up channel [s%dc%d]\n",
|
2021-12-29 17:27:14 +00:00
|
|
|
span+1,chan+1);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
server.process_table[span][chan].dev=woomera;
|
|
|
|
strncpy(woomera->session,unique_id,sizeof(woomera->session));
|
2021-12-29 17:29:00 +00:00
|
|
|
sprintf(ifname,"s%dc%d",span+1,chan+1);
|
2021-12-29 17:11:50 +00:00
|
|
|
woomera_set_interface(woomera, ifname);
|
|
|
|
|
|
|
|
woomera->span=span;
|
|
|
|
woomera->chan=chan;
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
/* Save bearer cap that came in on incoming call event */
|
|
|
|
woomera->bearer_cap = server.process_table[span][chan].bearer_cap;
|
|
|
|
|
2021-12-29 17:22:11 +00:00
|
|
|
/* set it to 1 so that queued digits are checked on proceed message */
|
|
|
|
woomera->check_digits = 1;
|
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
pthread_mutex_unlock(&server.process_lock);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_MISC, woomera->log, "WOOMERA Got New If=%s Session %s\n",
|
2021-12-29 17:11:50 +00:00
|
|
|
woomera->interface, woomera->session);
|
2021-12-29 17:03:04 +00:00
|
|
|
|
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
} else if (strncmp(woomera->session,unique_id,sizeof(woomera->session))) {
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 17:28:39 +00:00
|
|
|
cause=81;
|
|
|
|
socket_printf(woomera->socket, "EVENT HANGUP %s"
|
|
|
|
"Cause: %s%s"
|
|
|
|
"Q931-Cause-Code: %d%s",
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
q931_rel_to_str(cause),
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
cause,
|
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
2021-12-29 17:14:12 +00:00
|
|
|
|
|
|
|
socket_printf(woomera->socket, "404 Session Mis-match%s"
|
2021-12-29 17:11:50 +00:00
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
2021-12-29 17:28:39 +00:00
|
|
|
woomera_set_flag(woomera, WFLAG_HANGUP);
|
2021-12-29 17:11:50 +00:00
|
|
|
return;
|
|
|
|
}
|
2021-12-29 17:28:39 +00:00
|
|
|
|
|
|
|
if (!strcasecmp(wmsg->command, "dtmf")) {
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:28:39 +00:00
|
|
|
log_printf(SMG_LOG_WOOMERA, woomera->log,
|
|
|
|
"WOOMERA CMD: DTMF Received: [%s] Digit %s Body %s\n",
|
|
|
|
woomera->interface, wmsg->command_args, wmsg->body);
|
2021-12-29 17:11:50 +00:00
|
|
|
|
|
|
|
wanpipe_send_dtmf(woomera,wmsg->body);
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
socket_printf(woomera->socket, "200 DTMF OK%s"
|
|
|
|
"Unique-Call-Id: %s%s",
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
woomera->session,
|
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
} else if (!strcasecmp(wmsg->command, "hangup")) {
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
int chan = -1, span = -1;
|
|
|
|
char *cause = woomera_message_header(wmsg, "cause");
|
2021-12-29 17:12:33 +00:00
|
|
|
char *q931cause = woomera_message_header(wmsg, "Q931-Cause-Code");
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:12:33 +00:00
|
|
|
if (q931cause && atoi(q931cause)) {
|
|
|
|
woomera_set_cause_tosig(woomera,atoi(q931cause));
|
|
|
|
}
|
2021-12-29 17:11:50 +00:00
|
|
|
|
|
|
|
span=woomera->span;
|
|
|
|
chan=woomera->chan;
|
2021-12-29 17:03:04 +00:00
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_MISC, woomera->log, "WOOMERA CMD: Hangup Received: [%s] MEDIA EXIST Cause=%s\n",
|
2021-12-29 17:12:33 +00:00
|
|
|
woomera->interface,cause);
|
2021-12-29 17:11:50 +00:00
|
|
|
|
|
|
|
if (smg_validate_span_chan(span,chan) != 0) {
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
socket_printf(woomera->socket, "405 No Such Channel%s"
|
2021-12-29 17:03:04 +00:00
|
|
|
"Unique-Call-Id: %s%s",
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
2021-12-29 17:11:50 +00:00
|
|
|
woomera->session,
|
2021-12-29 17:03:04 +00:00
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
2021-12-29 17:11:50 +00:00
|
|
|
return;
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
2021-12-29 17:11:50 +00:00
|
|
|
|
|
|
|
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, woomera->log, "Hangup Received: [s%dc%d]\n",
|
2021-12-29 17:11:50 +00:00
|
|
|
span+1,chan+1);
|
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
woomera_set_flag(woomera, WFLAG_MEDIA_END);
|
|
|
|
woomera_clear_flag(woomera, WFLAG_RUNNING);
|
|
|
|
|
|
|
|
|
|
|
|
socket_printf(woomera->socket, "200 HANGUP OK%s"
|
|
|
|
"Unique-Call-Id: %s%s",
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
woomera->session,
|
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
2021-12-29 17:28:39 +00:00
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
} else if (!strcasecmp(wmsg->command, "proceed")) {
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_WOOMERA, woomera->log, "WOOMERA CMD: %s [%s]\n",
|
2021-12-29 17:03:04 +00:00
|
|
|
wmsg->command, woomera->interface);
|
|
|
|
|
|
|
|
socket_printf(woomera->socket,
|
|
|
|
"200 %s PROCEED OK%s"
|
|
|
|
"Unique-Call-Id: %s%s",
|
|
|
|
wmsg->callid,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
2021-12-29 17:11:50 +00:00
|
|
|
woomera->session,
|
2021-12-29 17:03:04 +00:00
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
2021-12-29 17:28:39 +00:00
|
|
|
|
|
|
|
} else if (!strcasecmp(wmsg->command, "progress")) {
|
|
|
|
|
|
|
|
handle_woomera_progress(woomera,wmsg);
|
|
|
|
|
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
} else if ((media = !strcasecmp(wmsg->command, "media")) ||
|
|
|
|
(answer = !strcasecmp(wmsg->command, "answer")) ||
|
|
|
|
(accept = !strcasecmp(wmsg->command, "accept"))) {
|
|
|
|
|
|
|
|
handle_woomera_media_accept_answer(woomera, wmsg, media,answer,accept);
|
2021-12-29 17:11:50 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
} else {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log,"WOOMERA INVALID EVENT: %s [%s] \n",
|
2021-12-29 16:59:00 +00:00
|
|
|
wmsg->command,wmsg->callid);
|
|
|
|
socket_printf(woomera->socket, "501 Command '%s' not implemented%s",
|
|
|
|
wmsg->command, WOOMERA_RECORD_SEPERATOR);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
EVENT INCOMING 1
|
|
|
|
Remote-Address: 10.3.3.104
|
|
|
|
Remote-Number:
|
|
|
|
Remote-Name: Anthony Minessale!8668630501
|
|
|
|
Protocol: H.323
|
|
|
|
User-Agent: Post Increment Woomera 1.0alpha1 (OpenH323 v1.17.2) 9/61
|
|
|
|
H323-Call-Id: 887b1ff8-bb1f-da11-85c0-0007e98988c4
|
|
|
|
Local-Number: 996
|
|
|
|
Start-Time: Fri, 09 Sep 2005 12:25:14 -0400
|
|
|
|
Local-Name: root
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
static void handle_call_answer(short_signal_event_t *event)
|
2021-12-29 16:59:00 +00:00
|
|
|
{
|
|
|
|
struct woomera_interface *woomera = NULL;
|
|
|
|
int kill = 0;
|
|
|
|
|
|
|
|
pthread_mutex_lock(&server.process_lock);
|
2021-12-29 17:11:50 +00:00
|
|
|
woomera = server.process_table[event->span][event->chan].dev;
|
2021-12-29 16:59:00 +00:00
|
|
|
pthread_mutex_unlock(&server.process_lock);
|
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
if (woomera) {
|
2021-12-29 16:59:00 +00:00
|
|
|
char callid[80];
|
|
|
|
struct woomera_event wevent;
|
2021-12-29 17:26:11 +00:00
|
|
|
|
|
|
|
woomera->timeout = 0;
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
if (!woomera->raw) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_PROD, server.log, "Refusing to answer call with no media!\n");
|
2021-12-29 17:14:12 +00:00
|
|
|
kill++;
|
|
|
|
goto handle_call_answer_end;
|
|
|
|
}
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
if (woomera_test_flag(woomera, WFLAG_ANSWER)) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_PROD, server.log, "Refusing to double-answer a call!\n");
|
2021-12-29 17:14:12 +00:00
|
|
|
kill++;
|
|
|
|
goto handle_call_answer_end;
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
woomera_set_flag(woomera, WFLAG_ANSWER);
|
|
|
|
|
|
|
|
if (woomera->span != event->span || woomera->chan != event->chan) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_PROD, server.log, "Refusing to start media on a different channel from the one we agreed on.!\n");
|
2021-12-29 16:59:00 +00:00
|
|
|
kill++;
|
2021-12-29 17:14:12 +00:00
|
|
|
goto handle_call_answer_end;
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (woomera_test_flag(woomera, WFLAG_HANGUP)) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_PROD, server.log, "Refusing to answer a dead call!\n");
|
2021-12-29 16:59:00 +00:00
|
|
|
kill++;
|
|
|
|
} else {
|
|
|
|
int err;
|
|
|
|
err=0;
|
2021-12-29 17:29:00 +00:00
|
|
|
sprintf(callid, "s%dc%d", event->span + 1, event->chan + 1);
|
2021-12-29 16:59:00 +00:00
|
|
|
woomera_set_interface(woomera, callid);
|
|
|
|
#ifndef WOOMERA_EARLY_MEDIA
|
|
|
|
err=launch_media_thread(woomera);
|
|
|
|
if (err) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log,"ERROR: Failed to Launch Call [%s]\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
woomera->interface);
|
2021-12-29 17:11:50 +00:00
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s"
|
2021-12-29 17:26:11 +00:00
|
|
|
"Unique-Call-Id: %s%s"
|
|
|
|
"Q931-Cause-Code: %d%s"
|
|
|
|
"Cause: %s%s",
|
2021-12-29 16:59:00 +00:00
|
|
|
woomera->interface,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
2021-12-29 17:11:50 +00:00
|
|
|
woomera->session,
|
2021-12-29 16:59:00 +00:00
|
|
|
WOOMERA_LINE_SEPERATOR,
|
2021-12-29 17:12:33 +00:00
|
|
|
21,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
q931_rel_to_str(21),
|
2021-12-29 16:59:00 +00:00
|
|
|
WOOMERA_RECORD_SEPERATOR
|
|
|
|
);
|
|
|
|
|
|
|
|
enqueue_event(woomera, &wevent,EVENT_FREE_DATA);
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
new_woomera_event_printf(&wevent, "501 call was cancelled!%s"
|
|
|
|
"Unique-Call-Id: %s%s",
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
woomera->session,
|
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
|
|
|
|
|
|
|
enqueue_event(woomera, &wevent,EVENT_FREE_DATA);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
kill++;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (!kill) {
|
2021-12-29 17:29:00 +00:00
|
|
|
new_woomera_event_printf(&wevent, "EVENT CONNECT s%dc%d%s"
|
2021-12-29 17:11:50 +00:00
|
|
|
"Unique-Call-Id: %s%s",
|
2021-12-29 16:59:00 +00:00
|
|
|
event->span+1,
|
|
|
|
event->chan+1,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
2021-12-29 17:11:50 +00:00
|
|
|
woomera->session,
|
2021-12-29 16:59:00 +00:00
|
|
|
WOOMERA_RECORD_SEPERATOR
|
|
|
|
);
|
|
|
|
enqueue_event(woomera, &wevent,EVENT_FREE_DATA);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_PROD, server.log, "Answer requested on non-existant session. [s%dc%d]\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
event->span+1, event->chan+1);
|
|
|
|
kill++;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
handle_call_answer_end:
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
if (kill) {
|
|
|
|
if (woomera) {
|
2021-12-29 17:14:12 +00:00
|
|
|
woomera_set_flag(woomera,WFLAG_MEDIA_END);
|
|
|
|
} else {
|
2021-12-29 17:15:08 +00:00
|
|
|
|
|
|
|
/* This can casuse a double STOP
|
|
|
|
must be debugged further */
|
|
|
|
#if 0
|
2021-12-29 17:14:12 +00:00
|
|
|
isup_exec_command(event->span,
|
|
|
|
event->chan,
|
|
|
|
-1,
|
|
|
|
SIGBOOST_EVENT_CALL_STOPPED,
|
|
|
|
SIGBOOST_RELEASE_CAUSE_NORMAL);
|
|
|
|
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_PROD, server.log, "Sent CALL STOP to Answer without session [s%dc%d]\n",
|
2021-12-29 17:14:12 +00:00
|
|
|
event->span+1, event->chan+1);
|
2021-12-29 17:15:08 +00:00
|
|
|
#endif
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "WARNING: Received Answer with no session [s%dc%d]\n",
|
2021-12-29 17:15:08 +00:00
|
|
|
event->span+1, event->chan+1);
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
static void handle_call_start_ack(short_signal_event_t *event)
|
2021-12-29 16:59:00 +00:00
|
|
|
{
|
|
|
|
struct woomera_interface *woomera = NULL;
|
|
|
|
struct woomera_event wevent;
|
|
|
|
int kill = 0;
|
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
if ((woomera = peek_from_holding_tank(event->call_setup_id))) {
|
2021-12-29 16:59:00 +00:00
|
|
|
char callid[80];
|
2021-12-29 17:26:11 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
if (woomera_test_flag(woomera, WFLAG_HANGUP)) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_PROD, server.log, "Refusing to ack a dead call!\n");
|
2021-12-29 16:59:00 +00:00
|
|
|
kill++;
|
|
|
|
} else {
|
2021-12-29 17:11:50 +00:00
|
|
|
int err, span, chan;
|
2021-12-29 17:14:12 +00:00
|
|
|
|
|
|
|
pull_from_holding_tank(event->call_setup_id,event->span,event->chan);
|
2021-12-29 17:29:00 +00:00
|
|
|
sprintf(callid, "s%dc%d", event->span + 1, event->chan + 1);
|
2021-12-29 17:11:50 +00:00
|
|
|
|
|
|
|
span = event->span;
|
|
|
|
chan = event->chan;
|
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
woomera_set_flag(woomera,WFLAG_CALL_ACKED);
|
2021-12-29 16:59:00 +00:00
|
|
|
woomera_set_interface(woomera, callid);
|
2021-12-29 17:11:50 +00:00
|
|
|
|
|
|
|
pthread_mutex_lock(&server.process_lock);
|
2021-12-29 17:26:11 +00:00
|
|
|
|
|
|
|
if (server.process_table[span][chan].dev) {
|
|
|
|
struct woomera_interface *tmp_woomera = server.process_table[span][chan].dev;
|
|
|
|
woomera_set_flag(tmp_woomera,WFLAG_HANGUP);
|
|
|
|
woomera_set_flag(tmp_woomera,WFLAG_MEDIA_END);
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log,"Call Overrun on [s%dc%d] - Call ACK!\n", event->span+1, event->chan+1);
|
2021-12-29 17:26:11 +00:00
|
|
|
kill++;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
server.process_table[span][chan].dev = woomera;
|
|
|
|
sprintf(woomera->session,"%s-%i-%i",callid,rand(),rand());
|
|
|
|
sprintf(server.process_table[span][chan].session,"%s-%s",
|
2021-12-29 17:26:11 +00:00
|
|
|
callid,woomera->session);
|
|
|
|
|
2021-12-29 17:22:11 +00:00
|
|
|
|
|
|
|
memset(server.process_table[span][chan].digits, 0,
|
|
|
|
sizeof(server.process_table[span][chan].digits));
|
|
|
|
|
|
|
|
server.process_table[span][chan].digits_len = 0;
|
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
pthread_mutex_unlock(&server.process_lock);
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
if (kill) {
|
|
|
|
goto woomera_call_ack_skip;
|
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
#ifdef WOOMERA_EARLY_MEDIA
|
|
|
|
err=launch_media_thread(woomera);
|
|
|
|
if (err) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log,"ERROR: Failed to Launch Call [%s]\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
woomera->interface);
|
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s"
|
2021-12-29 17:11:50 +00:00
|
|
|
"Unique-Call-Id:%s%s"
|
2021-12-29 17:26:11 +00:00
|
|
|
"Q931-Cause-Code: %d%s"
|
2021-12-29 16:59:00 +00:00
|
|
|
"Cause: %s%s",
|
|
|
|
woomera->interface,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
2021-12-29 17:11:50 +00:00
|
|
|
woomera->session,
|
2021-12-29 16:59:00 +00:00
|
|
|
WOOMERA_LINE_SEPERATOR,
|
2021-12-29 17:12:33 +00:00
|
|
|
21,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
q931_rel_to_str(21),
|
2021-12-29 16:59:00 +00:00
|
|
|
WOOMERA_RECORD_SEPERATOR
|
|
|
|
);
|
|
|
|
|
|
|
|
enqueue_event(woomera, &wevent,EVENT_FREE_DATA);
|
2021-12-29 17:26:11 +00:00
|
|
|
|
|
|
|
new_woomera_event_printf(&wevent, "501 call was cancelled!%s"
|
|
|
|
"Unique-Call-Id: %s%s",
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
woomera->session,
|
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
|
|
|
|
|
|
|
enqueue_event(woomera, &wevent,EVENT_FREE_DATA);
|
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
kill++;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
if (!kill) {
|
2021-12-29 17:26:11 +00:00
|
|
|
|
2021-12-29 17:29:00 +00:00
|
|
|
new_woomera_event_printf(&wevent, "EVENT PROCEED s%dc%d%s"
|
2021-12-29 17:14:12 +00:00
|
|
|
"Channel-Name: g%d/%d%s"
|
2021-12-29 17:11:50 +00:00
|
|
|
"Unique-Call-Id: %s%s",
|
2021-12-29 16:59:00 +00:00
|
|
|
event->span+1,
|
|
|
|
event->chan+1,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
2021-12-29 17:14:12 +00:00
|
|
|
woomera->trunk_group+1,
|
2021-12-29 17:20:09 +00:00
|
|
|
(event->span*max_chans)+event->chan+1,
|
2021-12-29 17:14:12 +00:00
|
|
|
WOOMERA_LINE_SEPERATOR,
|
2021-12-29 17:11:50 +00:00
|
|
|
woomera->session,
|
2021-12-29 16:59:00 +00:00
|
|
|
WOOMERA_RECORD_SEPERATOR
|
|
|
|
);
|
|
|
|
|
|
|
|
enqueue_event(woomera, &wevent,EVENT_FREE_DATA);
|
2021-12-29 17:26:11 +00:00
|
|
|
|
|
|
|
new_woomera_event_printf(&wevent, "201 Accepted%s"
|
|
|
|
"Unique-Call-Id: %s%s",
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
woomera->session,
|
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
|
|
|
|
|
|
|
enqueue_event(woomera, &wevent,EVENT_FREE_DATA);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_MISC, server.log, "Call Answered Event ID = %d Device = s%dc%d!\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
event->call_setup_id,woomera->span+1,woomera->chan+1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_PROD, server.log,
|
2021-12-29 17:29:00 +00:00
|
|
|
"Event (START ACK) %d referrs to a non-existant session (%d) [s%dc%d]!\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
event->event_id, event->call_setup_id,event->span+1, event->chan+1);
|
|
|
|
kill++;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
woomera_call_ack_skip:
|
2021-12-29 16:59:00 +00:00
|
|
|
if (kill) {
|
|
|
|
if (woomera) {
|
2021-12-29 17:14:12 +00:00
|
|
|
woomera_set_flag(woomera,WFLAG_MEDIA_END);
|
|
|
|
} else {
|
|
|
|
isup_exec_command(event->span,
|
|
|
|
event->chan,
|
|
|
|
-1,
|
|
|
|
SIGBOOST_EVENT_CALL_STOPPED,
|
|
|
|
SIGBOOST_RELEASE_CAUSE_NORMAL);
|
|
|
|
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_PROD, server.log, "Sent CALL STOP to CALL START ACK without session [s%dc%d]\n",
|
2021-12-29 17:14:12 +00:00
|
|
|
event->span+1, event->chan+1);
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
static void handle_call_start_nack(short_signal_event_t *event)
|
2021-12-29 16:59:00 +00:00
|
|
|
{
|
|
|
|
struct woomera_interface *woomera = NULL;
|
2021-12-29 17:03:04 +00:00
|
|
|
int span=-1, chan=-1;
|
2021-12-29 16:59:00 +00:00
|
|
|
int ack=0;
|
|
|
|
|
|
|
|
/* Always ACK the incoming NACK
|
|
|
|
* Send out the NACK ACK before pulling the TANK, because
|
|
|
|
* if we send after the pull, the outgoing call could send
|
|
|
|
* a message to boost with the pulled TANK value before
|
|
|
|
* we send a NACK ACK */
|
|
|
|
|
|
|
|
if (smg_validate_span_chan(event->span,event->chan) == 0) {
|
|
|
|
span=event->span;
|
|
|
|
chan=event->chan;
|
|
|
|
}
|
2021-12-29 17:11:50 +00:00
|
|
|
|
|
|
|
if (event->call_setup_id > 0) {
|
2021-12-29 17:14:12 +00:00
|
|
|
woomera=peek_from_holding_tank(event->call_setup_id);
|
2021-12-29 17:11:50 +00:00
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
if (woomera) {
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
struct woomera_event wevent;
|
|
|
|
|
|
|
|
if (woomera_test_flag(woomera, WFLAG_HANGUP)) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Event CALL START NACK on hungup call [%d]!\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
event->call_setup_id);
|
2021-12-29 17:14:12 +00:00
|
|
|
ack++;
|
2021-12-29 16:59:00 +00:00
|
|
|
} else {
|
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
woomera_set_cause_topbx(woomera,event->release_cause);
|
|
|
|
woomera_set_flag(woomera, (WFLAG_HANGUP|WFLAG_HANGUP_NACK_ACK));
|
2021-12-29 17:11:50 +00:00
|
|
|
|
2021-12-29 17:29:00 +00:00
|
|
|
new_woomera_event_printf(&wevent, "EVENT HANGUP s%dc%d%s"
|
2021-12-29 17:11:50 +00:00
|
|
|
"Unique-Call-Id: %s%s"
|
2021-12-29 17:12:33 +00:00
|
|
|
"Cause: %s%s"
|
2021-12-29 17:26:11 +00:00
|
|
|
"Q931-Cause-Code: %d%s",
|
2021-12-29 16:59:00 +00:00
|
|
|
event->span+1,
|
|
|
|
event->chan+1,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
2021-12-29 17:11:50 +00:00
|
|
|
woomera->session,
|
2021-12-29 16:59:00 +00:00
|
|
|
WOOMERA_LINE_SEPERATOR,
|
2021-12-29 17:12:33 +00:00
|
|
|
q931_rel_to_str(woomera->q931_rel_cause_topbx),
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
woomera->q931_rel_cause_topbx,
|
2021-12-29 16:59:00 +00:00
|
|
|
WOOMERA_RECORD_SEPERATOR
|
|
|
|
);
|
|
|
|
enqueue_event(woomera, &wevent,EVENT_FREE_DATA);
|
2021-12-29 17:26:11 +00:00
|
|
|
|
|
|
|
new_woomera_event_printf(&wevent, "501 call was cancelled!%s"
|
|
|
|
"Unique-Call-Id: %s%s",
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
woomera->session,
|
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
|
|
|
|
|
|
|
enqueue_event(woomera, &wevent,EVENT_FREE_DATA);
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 17:02:04 +00:00
|
|
|
woomera_set_flag(woomera, WFLAG_HANGUP);
|
2021-12-29 17:03:04 +00:00
|
|
|
woomera_clear_flag(woomera, WFLAG_RUNNING);
|
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
/* Do not ack here, let woomera thread ack it */
|
|
|
|
ack=0;
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
} else if (event->call_setup_id == 0 &&
|
|
|
|
smg_validate_span_chan(event->span,event->chan) == 0) {
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
pthread_mutex_lock(&server.process_lock);
|
2021-12-29 17:11:50 +00:00
|
|
|
woomera = server.process_table[event->span][event->chan].dev;
|
2021-12-29 17:14:12 +00:00
|
|
|
|
|
|
|
if (woomera) {
|
|
|
|
if (!woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK_SENT) &&
|
|
|
|
!woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK_SENT)) {
|
|
|
|
/* Only if we are not already waiting for hangup */
|
|
|
|
server.process_table[event->span][event->chan].dev=NULL;
|
|
|
|
} else if (woomera_test_flag(woomera, WFLAG_HANGUP)) {
|
|
|
|
/* At this point call is already hang up */
|
|
|
|
woomera=NULL;
|
|
|
|
} else {
|
|
|
|
/* At this point call is already hang up */
|
|
|
|
woomera=NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
memset(server.process_table[event->span][event->chan].session,
|
|
|
|
0,SMG_SESSION_NAME_SZ);
|
2021-12-29 16:59:00 +00:00
|
|
|
pthread_mutex_unlock(&server.process_lock);
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
if (woomera) {
|
2021-12-29 17:11:50 +00:00
|
|
|
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, server.log, "Event START NACK on s%dc%d ptr=%p ms=%p\n",
|
2021-12-29 17:11:50 +00:00
|
|
|
woomera->span+1,woomera->chan+1,woomera,woomera->ms);
|
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
if (!woomera_test_flag(woomera,WFLAG_HANGUP)){
|
2021-12-29 17:27:14 +00:00
|
|
|
if (event->release_cause == SIGBOOST_CALL_SETUP_CSUPID_DBL_USE ||
|
|
|
|
event->release_cause == SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY) {
|
2021-12-29 17:26:11 +00:00
|
|
|
woomera_set_cause_topbx(woomera,17);
|
|
|
|
} else {
|
|
|
|
woomera_set_cause_topbx(woomera,event->release_cause);
|
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
2021-12-29 17:11:50 +00:00
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
woomera_set_flag(woomera,
|
|
|
|
(WFLAG_HANGUP|WFLAG_MEDIA_END|WFLAG_HANGUP_NACK_ACK));
|
|
|
|
|
|
|
|
/* Nack Ack will be sent by the woomera thread */
|
2021-12-29 17:11:50 +00:00
|
|
|
ack=0;
|
2021-12-29 16:59:00 +00:00
|
|
|
} else {
|
2021-12-29 17:14:12 +00:00
|
|
|
/* Valid state when we are not in autoacm mode */
|
2021-12-29 16:59:00 +00:00
|
|
|
ack++;
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_MISC, server.log, "Event: NACK no woomera on span chan [s%dc%d]!\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
event->span+1, event->chan+1);
|
|
|
|
}
|
2021-12-29 17:03:04 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
} else {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log,
|
2021-12-29 17:29:00 +00:00
|
|
|
"Error: Start Nack Invalid State Should not happen [%d] [s%dc%d]!\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
event->call_setup_id, event->span+1, event->chan+1);
|
|
|
|
ack++;
|
|
|
|
}
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
if (event->release_cause == SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY) {
|
|
|
|
smg_all_ckt_busy();
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "WARNING: All ckt busy Timeout=%i!\n",server.all_ckt_busy);
|
2021-12-29 17:26:11 +00:00
|
|
|
}
|
|
|
|
if (event->release_cause == SIGBOOST_CALL_SETUP_CSUPID_DBL_USE) {
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "WARNING: Double use on [s%ic%i] setup id %i!\n",
|
2021-12-29 17:26:11 +00:00
|
|
|
event->span+1,event->chan+1,event->call_setup_id);
|
2021-12-29 17:03:04 +00:00
|
|
|
}
|
2021-12-29 17:12:33 +00:00
|
|
|
|
|
|
|
#warning "Ignoring CALL GAP"
|
|
|
|
#if 0
|
2021-12-29 17:03:04 +00:00
|
|
|
if (event->release_cause == SIGBOOST_CALL_SETUP_NACK_AUTO_CALL_GAP) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "WARNING: Call Gapping Detected!\n");
|
2021-12-29 17:03:04 +00:00
|
|
|
smg_all_ckt_gap();
|
|
|
|
}
|
2021-12-29 17:12:33 +00:00
|
|
|
#endif
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
if (ack) {
|
2021-12-29 17:11:50 +00:00
|
|
|
span=0;
|
|
|
|
chan=0;
|
|
|
|
if (smg_validate_span_chan(event->span,event->chan) == 0) {
|
|
|
|
span=event->span;
|
|
|
|
chan=event->chan;
|
|
|
|
}
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
isup_exec_command(span,
|
|
|
|
chan,
|
2021-12-29 16:59:00 +00:00
|
|
|
event->call_setup_id,
|
|
|
|
SIGBOOST_EVENT_CALL_START_NACK_ACK,
|
|
|
|
0);
|
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
if (!woomera) {
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, server.log, "Event (NACK ACK) %d referrs to a non-existant session (%d) [s%dc%d]!\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
event->event_id,event->call_setup_id, event->span+1, event->chan+1);
|
2021-12-29 17:14:12 +00:00
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
static void handle_call_loop_start(short_signal_event_t *event)
|
2021-12-29 16:59:00 +00:00
|
|
|
{
|
|
|
|
struct woomera_interface *woomera;
|
2021-12-29 17:14:12 +00:00
|
|
|
char callid[20];
|
|
|
|
char *session;
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
pthread_mutex_lock(&server.process_lock);
|
2021-12-29 17:11:50 +00:00
|
|
|
if (server.process_table[event->span][event->chan].dev) {
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
isup_exec_command(event->span,
|
|
|
|
event->chan,
|
|
|
|
-1,
|
|
|
|
SIGBOOST_EVENT_CALL_START_NACK,
|
2021-12-29 17:26:11 +00:00
|
|
|
17);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_PROD, server.log,
|
2021-12-29 17:29:00 +00:00
|
|
|
"Sent (From Handle Loop START) Call Busy SIGBOOST_EVENT_CALL_START_NACK [s%dc%d] ptr=%d\n",
|
2021-12-29 17:11:50 +00:00
|
|
|
event->span+1, event->chan+1, server.process_table[event->span][event->chan].dev);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
pthread_mutex_unlock(&server.process_lock);
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 17:29:00 +00:00
|
|
|
sprintf(callid, "s%dc%d", event->span+1,event->chan+1);
|
2021-12-29 17:14:12 +00:00
|
|
|
sprintf(server.process_table[event->span][event->chan].session,
|
|
|
|
"%s-%i-%i",callid,rand(),rand());
|
|
|
|
session=server.process_table[event->span][event->chan].session;
|
|
|
|
server.process_table[event->span][event->chan].dev = NULL;
|
|
|
|
pthread_mutex_unlock(&server.process_lock);
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
woomera=launch_woomera_loop_thread(event);
|
|
|
|
if (woomera == NULL) {
|
|
|
|
isup_exec_command(event->span,
|
|
|
|
event->chan,
|
|
|
|
-1,
|
|
|
|
SIGBOOST_EVENT_CALL_START_NACK,
|
2021-12-29 17:26:11 +00:00
|
|
|
17);
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_PROD, server.log,
|
2021-12-29 17:29:00 +00:00
|
|
|
"Sent (From Handle Loop START) Call Busy SIGBOOST_EVENT_CALL_START_NACK [s%dc%d] ptr=%d\n",
|
2021-12-29 17:11:50 +00:00
|
|
|
event->span+1, event->chan+1, server.process_table[event->span][event->chan].dev);
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
woomera_set_flag(woomera,WFLAG_CALL_ACKED);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
static void handle_call_start(call_signal_event_t *event)
|
|
|
|
{
|
2021-12-29 17:26:11 +00:00
|
|
|
struct woomera_event wevent;
|
|
|
|
char callid[20];
|
2021-12-29 17:11:50 +00:00
|
|
|
char *session;
|
2021-12-29 17:28:39 +00:00
|
|
|
struct woomera_interface *tmp_woomera=NULL;
|
2021-12-29 17:27:14 +00:00
|
|
|
int clients;
|
2021-12-29 17:11:50 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
remove_end_of_digits_char((unsigned char*)event->called_number_digits);
|
|
|
|
remove_end_of_digits_char((unsigned char*)event->calling_number_digits);
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
if (server.strip_cid_non_digits) {
|
|
|
|
validate_number((unsigned char*)event->called_number_digits);
|
|
|
|
validate_number((unsigned char*)event->calling_number_digits);
|
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:28:39 +00:00
|
|
|
if (smg_validate_span_chan(event->span,event->chan)) {
|
|
|
|
log_printf(0,server.log,
|
2021-12-29 17:29:00 +00:00
|
|
|
"Error: invalid span=% chan=%i on incoming call [s%dc%d] - Call START!\n",
|
2021-12-29 17:28:39 +00:00
|
|
|
event->span+1, event->chan+1, event->span+1,event->chan+1);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
pthread_mutex_lock(&server.process_lock);
|
|
|
|
|
2021-12-29 17:28:39 +00:00
|
|
|
if ((tmp_woomera=server.process_table[event->span][event->chan].dev)) {
|
2021-12-29 17:26:11 +00:00
|
|
|
|
|
|
|
woomera_set_flag(tmp_woomera,WFLAG_HANGUP);
|
|
|
|
woomera_set_flag(tmp_woomera,WFLAG_MEDIA_END);
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log,"Call Overrun on [s%dc%d] - Call START!\n", event->span+1, event->chan+1);
|
2021-12-29 17:26:11 +00:00
|
|
|
|
|
|
|
isup_exec_command(event->span,
|
|
|
|
event->chan,
|
|
|
|
-1,
|
|
|
|
SIGBOOST_EVENT_CALL_START_NACK,
|
|
|
|
17);
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log,
|
2021-12-29 17:29:00 +00:00
|
|
|
"Sent (From Handle START) Call Busy SIGBOOST_EVENT_CALL_START_NACK [s%dc%d]\n",
|
2021-12-29 17:11:50 +00:00
|
|
|
event->span+1, event->chan+1);
|
2021-12-29 17:26:11 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
pthread_mutex_unlock(&server.process_lock);
|
|
|
|
return;
|
2021-12-29 17:26:11 +00:00
|
|
|
}
|
2021-12-29 17:11:50 +00:00
|
|
|
|
2021-12-29 17:29:00 +00:00
|
|
|
sprintf(callid, "s%dc%d", event->span+1,event->chan+1);
|
2021-12-29 17:11:50 +00:00
|
|
|
sprintf(server.process_table[event->span][event->chan].session,
|
|
|
|
"%s-%i-%i",callid,rand(),rand());
|
|
|
|
session=server.process_table[event->span][event->chan].session;
|
2021-12-29 17:26:11 +00:00
|
|
|
server.process_table[event->span][event->chan].dev = NULL;
|
2021-12-29 17:22:11 +00:00
|
|
|
memset(server.process_table[event->span][event->chan].digits, 0, sizeof(server.process_table[event->span][event->chan].digits));
|
|
|
|
server.process_table[event->span][event->chan].digits_len = 0;
|
2021-12-29 17:27:14 +00:00
|
|
|
server.process_table[event->span][event->chan].bearer_cap = event->bearer.capability;
|
|
|
|
server.process_table[event->span][event->chan].clients=0;
|
2021-12-29 17:26:11 +00:00
|
|
|
pthread_mutex_unlock(&server.process_lock);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
if (autoacm) {
|
|
|
|
isup_exec_command(event->span,
|
|
|
|
event->chan,
|
|
|
|
-1,
|
|
|
|
SIGBOOST_EVENT_CALL_START_ACK,
|
|
|
|
0);
|
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_8,server.log,"BEARER %i , UIL1P = %i\n",
|
2021-12-29 17:26:11 +00:00
|
|
|
event->bearer.capability,event->bearer.uil1p);
|
|
|
|
|
|
|
|
if (event->bearer.uil1p == 0) {
|
|
|
|
if (server.hw_coding) {
|
|
|
|
event->bearer.uil1p=BC_IE_UIL1P_G711_ALAW;
|
|
|
|
} else {
|
|
|
|
event->bearer.uil1p=BC_IE_UIL1P_G711_ULAW;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:29:00 +00:00
|
|
|
new_woomera_event_printf(&wevent, "EVENT INCOMING s%dc%d%s"
|
2021-12-29 17:11:50 +00:00
|
|
|
"Unique-Call-Id: %s%s"
|
2021-12-29 16:59:00 +00:00
|
|
|
"Remote-Number: %s%s"
|
|
|
|
"Remote-Name: %s%s"
|
2021-12-29 17:18:25 +00:00
|
|
|
#if defined(BRI_PROT)
|
|
|
|
"Protocol: BRI%s"
|
2021-12-29 17:27:14 +00:00
|
|
|
#else
|
|
|
|
#if defined(PRI_PROT)
|
|
|
|
"Protocol: PRI%s"
|
2021-12-29 17:18:25 +00:00
|
|
|
#else
|
2021-12-29 16:59:00 +00:00
|
|
|
"Protocol: SS7%s"
|
2021-12-29 17:27:14 +00:00
|
|
|
#endif
|
2021-12-29 17:18:25 +00:00
|
|
|
#endif
|
2021-12-29 16:59:00 +00:00
|
|
|
"User-Agent: sangoma_mgd%s"
|
|
|
|
"Local-Number: %s%s"
|
2021-12-29 17:14:12 +00:00
|
|
|
"Channel-Name: g%d/%d%s"
|
2021-12-29 16:59:00 +00:00
|
|
|
"Trunk-Group: %d%s"
|
|
|
|
"Presentation: %d%s"
|
2021-12-29 17:03:04 +00:00
|
|
|
"Screening: %d%s"
|
2021-12-29 16:59:00 +00:00
|
|
|
"RDNIS: %s%s"
|
2021-12-29 17:26:11 +00:00
|
|
|
"Bearer-Cap: %s%s"
|
|
|
|
"uil1p: %s%s"
|
2021-12-29 16:59:00 +00:00
|
|
|
,
|
|
|
|
event->span+1,
|
|
|
|
event->chan+1,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
2021-12-29 17:11:50 +00:00
|
|
|
session,
|
2021-12-29 16:59:00 +00:00
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
event->calling_number_digits,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
2021-12-29 17:14:12 +00:00
|
|
|
event->calling_name,
|
2021-12-29 16:59:00 +00:00
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
event->called_number_digits,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
event->trunk_group+1,
|
2021-12-29 17:20:09 +00:00
|
|
|
(event->span*max_chans)+event->chan+1,
|
2021-12-29 16:59:00 +00:00
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
event->trunk_group+1,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
event->calling_number_presentation,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
2021-12-29 17:03:04 +00:00
|
|
|
event->calling_number_screening_ind,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
2021-12-29 17:26:11 +00:00
|
|
|
event->isup_in_rdnis,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
bearer_cap_to_str(event->bearer.capability),
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
uil1p_to_str(event->bearer.uil1p),
|
2021-12-29 16:59:00 +00:00
|
|
|
WOOMERA_RECORD_SEPERATOR
|
|
|
|
);
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
clients=enqueue_event_on_listeners(&wevent);
|
|
|
|
if (!clients) {
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
pthread_mutex_lock(&server.process_lock);
|
2021-12-29 17:11:50 +00:00
|
|
|
server.process_table[event->span][event->chan].dev = NULL;
|
|
|
|
memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ);
|
2021-12-29 17:26:11 +00:00
|
|
|
pthread_mutex_unlock(&server.process_lock);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
if (autoacm) {
|
|
|
|
isup_exec_command(event->span,
|
|
|
|
event->chan,
|
|
|
|
-1,
|
|
|
|
SIGBOOST_EVENT_CALL_STOPPED,
|
2021-12-29 17:26:11 +00:00
|
|
|
17);
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log,
|
2021-12-29 17:29:00 +00:00
|
|
|
"CALL INCOMING: Enqueue Error Sent SIGBOOST_EVENT_CALL_STOPPED [s%dc%d]\n",
|
2021-12-29 17:18:25 +00:00
|
|
|
event->span+1, event->chan+1);
|
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
} else {
|
|
|
|
isup_exec_command(event->span,
|
|
|
|
event->chan,
|
|
|
|
-1,
|
|
|
|
SIGBOOST_EVENT_CALL_START_NACK,
|
2021-12-29 17:26:11 +00:00
|
|
|
17);
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log,
|
2021-12-29 17:29:00 +00:00
|
|
|
"CALL INCOMING: Enqueue Error Sent SIGBOOST_EVENT_CALL_START_NACK [s%dc%d]\n",
|
2021-12-29 17:18:25 +00:00
|
|
|
event->span+1, event->chan+1);
|
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
} else {
|
2021-12-29 17:29:00 +00:00
|
|
|
//pthread_mutex_lock(&server.process_lock);
|
|
|
|
server.process_table[event->span][event->chan].clients = clients;
|
|
|
|
//pthread_mutex_unlock(&server.process_lock);
|
2021-12-29 17:26:11 +00:00
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
destroy_woomera_event_data(&wevent);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:22:11 +00:00
|
|
|
static void handle_incoming_digit(call_signal_event_t *event)
|
|
|
|
{
|
|
|
|
struct woomera_interface *woomera;
|
|
|
|
int digits_len;
|
|
|
|
|
|
|
|
if (smg_validate_span_chan(event->span,event->chan)) {
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, server.log, "Event DTMF on invalid span chan [s%dc%d] !\n",
|
2021-12-29 17:22:11 +00:00
|
|
|
event->span+1, event->chan+1);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!event->called_number_digits_count) {
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Error Incoming digit with len %s %d [s%dc%d]\n",
|
2021-12-29 17:22:11 +00:00
|
|
|
event->called_number_digits,
|
|
|
|
event->called_number_digits_count,
|
|
|
|
event->span+1, event->chan+1);
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_9, server.log, "Queuing incoming digits %s [s%dc%d]\n",
|
2021-12-29 17:22:11 +00:00
|
|
|
event->called_number_digits,
|
|
|
|
event->span+1, event->chan+1);
|
|
|
|
|
|
|
|
pthread_mutex_lock(&server.digits_lock);
|
|
|
|
|
|
|
|
digits_len = server.process_table[event->span][event->chan].digits_len;
|
|
|
|
|
|
|
|
strncpy(&server.process_table[event->span][event->chan].digits[digits_len],
|
|
|
|
event->called_number_digits,
|
|
|
|
event->called_number_digits_count);
|
|
|
|
|
|
|
|
server.process_table[event->span][event->chan].digits_len += event->called_number_digits_count;
|
|
|
|
|
|
|
|
pthread_mutex_unlock(&server.digits_lock);
|
|
|
|
|
|
|
|
pthread_mutex_lock(&server.process_lock);
|
|
|
|
woomera = server.process_table[event->span][event->chan].dev;
|
|
|
|
pthread_mutex_unlock(&server.process_lock);
|
|
|
|
if (!woomera || !strlen(woomera->session)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
woomera_check_digits(woomera);
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
static void handle_gap_abate(short_signal_event_t *event)
|
2021-12-29 17:03:04 +00:00
|
|
|
{
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "NOTICE: GAP Cleared!\n",
|
2021-12-29 17:03:04 +00:00
|
|
|
event->span+1, event->chan+1);
|
|
|
|
smg_clear_ckt_gap();
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
static void handle_restart(call_signal_connection_t *mcon, short_signal_event_t *event)
|
|
|
|
{
|
|
|
|
if (!woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log,"ERROR! Monitor Thread not running!\n");
|
2021-12-29 17:26:11 +00:00
|
|
|
} else {
|
2021-12-29 17:27:14 +00:00
|
|
|
/* Clear Reset */
|
|
|
|
/* Tell all threads to go down */
|
2021-12-29 17:26:11 +00:00
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log,
|
|
|
|
"RESTART Received: resetting all threads\n");
|
2021-12-29 17:26:11 +00:00
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
smg_all_ckt_busy();
|
|
|
|
woomera_set_flag(&server.master_connection, WFLAG_SYSTEM_RESET);
|
|
|
|
gettimeofday(&server.restart_timeout,NULL);
|
2021-12-29 17:26:11 +00:00
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
#if 0
|
|
|
|
sleep(5);
|
|
|
|
|
|
|
|
clear_all_holding_tank();
|
|
|
|
|
|
|
|
sleep(2);
|
|
|
|
|
|
|
|
event->event_id = SIGBOOST_EVENT_SYSTEM_RESTART_ACK;
|
|
|
|
err=call_signal_connection_write(&server.mcon, (call_signal_event_t*)event);
|
|
|
|
if (err < 0) {
|
|
|
|
log_printf(SMG_LOG_ALL, server.log,
|
|
|
|
"Critical System Error: Failed to tx on ISUP socket [%s]: %s\n",
|
|
|
|
strerror(errno));
|
|
|
|
}
|
|
|
|
|
|
|
|
smg_all_ckt_busy();
|
|
|
|
woomera_clear_flag(&server.master_connection, WFLAG_SYSTEM_RESET);
|
|
|
|
#endif
|
2021-12-29 17:26:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static void handle_restart_ack(call_signal_connection_t *mcon, short_signal_event_t *event)
|
|
|
|
{
|
|
|
|
|
|
|
|
/* Do not reset WFLAG_SYSTEM_RESET flag here!. The flag should
|
|
|
|
only be reset on restart from boost */
|
|
|
|
//woomera_clear_flag(&server.master_connection, WFLAG_SYSTEM_RESET);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void handle_remove_loop(short_signal_event_t *event)
|
2021-12-29 16:59:00 +00:00
|
|
|
{
|
2021-12-29 17:26:11 +00:00
|
|
|
struct woomera_interface *woomera;
|
|
|
|
|
|
|
|
pthread_mutex_lock(&server.process_lock);
|
|
|
|
woomera = server.process_table[event->span][event->chan].dev;
|
|
|
|
memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ);
|
|
|
|
server.process_table[event->span][event->chan].dev=NULL;
|
|
|
|
pthread_mutex_unlock(&server.process_lock);
|
|
|
|
|
|
|
|
if (woomera) {
|
|
|
|
|
|
|
|
woomera_set_flag(woomera,
|
|
|
|
(WFLAG_MEDIA_END|WFLAG_HANGUP));
|
|
|
|
|
|
|
|
/* We have to close the socket because
|
|
|
|
At this point we are release span chan */
|
|
|
|
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_MISC, server.log, "Event REMOVE LOOP on s%dc%d ptr=%p ms=%p\n",
|
2021-12-29 17:26:11 +00:00
|
|
|
woomera->span+1,woomera->chan+1,woomera,woomera->ms);
|
|
|
|
|
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
|
|
|
|
static void handle_call_stop(short_signal_event_t *event)
|
2021-12-29 16:59:00 +00:00
|
|
|
{
|
2021-12-29 17:28:15 +00:00
|
|
|
struct woomera_interface *woomera;
|
2021-12-29 17:14:12 +00:00
|
|
|
int ack=0;
|
|
|
|
|
2021-12-29 17:28:15 +00:00
|
|
|
woomera = NULL;
|
|
|
|
pthread_mutex_lock(&server.process_lock);
|
|
|
|
woomera = server.process_table[event->span][event->chan].dev;
|
2021-12-29 17:14:12 +00:00
|
|
|
if (woomera) {
|
2021-12-29 17:26:11 +00:00
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
if (!woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK_SENT) &&
|
|
|
|
!woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK_SENT)) {
|
|
|
|
/* Only if we are not already waiting for hangup */
|
2021-12-29 17:26:11 +00:00
|
|
|
//server.process_table[event->span][event->chan].dev=NULL;
|
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
} else if (woomera_test_flag(woomera, WFLAG_HANGUP)) {
|
|
|
|
/* At this point call is already hangup */
|
|
|
|
woomera=NULL;
|
|
|
|
} else {
|
|
|
|
/* At this point call is already hangup */
|
|
|
|
woomera=NULL;
|
|
|
|
}
|
|
|
|
}
|
2021-12-29 17:11:50 +00:00
|
|
|
memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ);
|
|
|
|
pthread_mutex_unlock(&server.process_lock);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:28:15 +00:00
|
|
|
if (woomera) {
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 17:12:33 +00:00
|
|
|
woomera_set_cause_topbx(woomera,event->release_cause);
|
2021-12-29 17:14:12 +00:00
|
|
|
|
|
|
|
woomera_set_flag(woomera,
|
|
|
|
(WFLAG_MEDIA_END|WFLAG_HANGUP|WFLAG_HANGUP_ACK));
|
2021-12-29 17:11:50 +00:00
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
/* We have to close the socket because
|
|
|
|
At this point we are release span chan */
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_MISC, server.log, "Event CALL STOP on s%dc%d ptr=%p ms=%p\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
woomera->span+1,woomera->chan+1,woomera,woomera->ms);
|
|
|
|
|
|
|
|
} else {
|
2021-12-29 17:14:12 +00:00
|
|
|
ack++;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (ack) {
|
2021-12-29 16:59:00 +00:00
|
|
|
/* At this point we have already sent our STOP so its safe to ACK */
|
|
|
|
isup_exec_command(event->span,
|
2021-12-29 17:11:50 +00:00
|
|
|
event->chan,
|
|
|
|
-1,
|
|
|
|
SIGBOOST_EVENT_CALL_STOPPED_ACK,
|
|
|
|
0);
|
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
if (!woomera){
|
|
|
|
/* This is allowed on incoming call if remote app does not answer it */
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_MISC, server.log, "Event CALL STOP referrs to a non-existant session [s%dc%d]!\n",
|
2021-12-29 17:11:50 +00:00
|
|
|
event->span+1, event->chan+1);
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
static void handle_heartbeat(short_signal_event_t *event)
|
2021-12-29 16:59:00 +00:00
|
|
|
{
|
|
|
|
if (!woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log,"ERROR! Monitor Thread not running!\n");
|
2021-12-29 16:59:00 +00:00
|
|
|
} else {
|
2021-12-29 17:26:11 +00:00
|
|
|
int err=call_signal_connection_writep(&server.mconp, (call_signal_event_t*)event);
|
|
|
|
if (err < 0) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log,
|
2021-12-29 17:03:04 +00:00
|
|
|
"Critical System Error: Failed to tx on ISUP socket [%s]: %s\n",
|
|
|
|
strerror(errno));
|
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
|
|
|
|
static void handle_call_stop_ack(short_signal_event_t *event)
|
2021-12-29 16:59:00 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
struct woomera_interface *woomera = NULL;
|
2021-12-29 17:26:11 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
pthread_mutex_lock(&server.process_lock);
|
2021-12-29 17:11:50 +00:00
|
|
|
woomera = server.process_table[event->span][event->chan].dev;
|
|
|
|
server.process_table[event->span][event->chan].dev=NULL;
|
|
|
|
memset(server.process_table[event->span][event->chan].session,0,SMG_SESSION_NAME_SZ);
|
2021-12-29 16:59:00 +00:00
|
|
|
pthread_mutex_unlock(&server.process_lock);
|
|
|
|
|
|
|
|
|
|
|
|
if (woomera) {
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, server.log, "Stop Ack on [s%dc%d] [Setup ID: %d] [%s]!\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
event->span+1, event->chan+1, event->call_setup_id,
|
2021-12-29 17:03:04 +00:00
|
|
|
woomera->interface);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
woomera_clear_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK);
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
} else {
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, server.log, "Event CALL_STOP_ACK(%d) referrs to a non-existant session [s%dc%d] [Setup ID: %d]!\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
event->event_id, event->span+1, event->chan+1, event->call_setup_id);
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
if (event->call_setup_id > 0) {
|
|
|
|
clear_from_holding_tank(event->call_setup_id, NULL);
|
|
|
|
}
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
/* No need for us to do any thing here */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
static void handle_call_start_nack_ack(short_signal_event_t *event)
|
2021-12-29 16:59:00 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
struct woomera_interface *woomera = NULL;
|
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
if ((woomera=pull_from_holding_tank(event->call_setup_id,-1,-1))) {
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK);
|
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
} else if (event->call_setup_id == 0 &&
|
|
|
|
smg_validate_span_chan(event->span,event->chan) == 0) {
|
|
|
|
|
|
|
|
pthread_mutex_lock(&server.process_lock);
|
|
|
|
woomera = server.process_table[event->span][event->chan].dev;
|
|
|
|
server.process_table[event->span][event->chan].dev=NULL;
|
|
|
|
memset(server.process_table[event->span][event->chan].session,
|
|
|
|
0,SMG_SESSION_NAME_SZ);
|
|
|
|
pthread_mutex_unlock(&server.process_lock);
|
|
|
|
|
|
|
|
if (woomera) {
|
|
|
|
woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK);
|
|
|
|
} else {
|
2021-12-29 17:20:09 +00:00
|
|
|
/* Possible if incoming call is NACKed due to
|
|
|
|
* woomera client being down, in this case no
|
|
|
|
* woomera thread is created */
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_8, server.log,
|
2021-12-29 17:29:00 +00:00
|
|
|
"Event NACK ACK [s%dc%d] with valid span/chan no dev!\n",
|
2021-12-29 17:14:12 +00:00
|
|
|
event->span+1, event->chan+1);
|
|
|
|
}
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
} else {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, server.log,
|
2021-12-29 17:29:00 +00:00
|
|
|
"Event NACK ACK referrs to a non-existant session [s%dc%d] [Setup ID: %d]!\n",
|
2021-12-29 17:11:50 +00:00
|
|
|
event->span+1, event->chan+1, event->call_setup_id);
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
if (event->call_setup_id > 0) {
|
2021-12-29 17:14:12 +00:00
|
|
|
clear_from_holding_tank(event->call_setup_id, NULL);
|
2021-12-29 17:11:50 +00:00
|
|
|
}
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
/* No need for us to do any thing here */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
static int parse_ss7_event(call_signal_connection_t *mcon, short_signal_event_t *event)
|
2021-12-29 16:59:00 +00:00
|
|
|
{
|
|
|
|
int ret = 0;
|
2021-12-29 17:12:33 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
switch(event->event_id) {
|
|
|
|
|
|
|
|
case SIGBOOST_EVENT_CALL_START:
|
2021-12-29 17:26:11 +00:00
|
|
|
handle_call_start((call_signal_event_t*)event);
|
2021-12-29 16:59:00 +00:00
|
|
|
break;
|
|
|
|
case SIGBOOST_EVENT_CALL_STOPPED:
|
|
|
|
handle_call_stop(event);
|
|
|
|
break;
|
|
|
|
case SIGBOOST_EVENT_CALL_START_ACK:
|
|
|
|
handle_call_start_ack(event);
|
|
|
|
break;
|
|
|
|
case SIGBOOST_EVENT_CALL_START_NACK:
|
|
|
|
handle_call_start_nack(event);
|
|
|
|
break;
|
|
|
|
case SIGBOOST_EVENT_CALL_ANSWERED:
|
|
|
|
handle_call_answer(event);
|
|
|
|
break;
|
|
|
|
case SIGBOOST_EVENT_HEARTBEAT:
|
|
|
|
handle_heartbeat(event);
|
|
|
|
break;
|
|
|
|
case SIGBOOST_EVENT_CALL_START_NACK_ACK:
|
|
|
|
handle_call_start_nack_ack(event);
|
|
|
|
break;
|
|
|
|
case SIGBOOST_EVENT_CALL_STOPPED_ACK:
|
|
|
|
handle_call_stop_ack(event);
|
|
|
|
break;
|
|
|
|
case SIGBOOST_EVENT_INSERT_CHECK_LOOP:
|
|
|
|
handle_call_loop_start(event);
|
|
|
|
break;
|
2021-12-29 17:26:11 +00:00
|
|
|
case SIGBOOST_EVENT_SYSTEM_RESTART:
|
|
|
|
handle_restart(mcon,event);
|
|
|
|
break;
|
2021-12-29 16:59:00 +00:00
|
|
|
case SIGBOOST_EVENT_REMOVE_CHECK_LOOP:
|
2021-12-29 17:26:11 +00:00
|
|
|
handle_remove_loop(event);
|
2021-12-29 16:59:00 +00:00
|
|
|
break;
|
|
|
|
case SIGBOOST_EVENT_SYSTEM_RESTART_ACK:
|
2021-12-29 17:03:04 +00:00
|
|
|
handle_restart_ack(mcon,event);
|
|
|
|
break;
|
|
|
|
case SIGBOOST_EVENT_AUTO_CALL_GAP_ABATE:
|
|
|
|
handle_gap_abate(event);
|
2021-12-29 16:59:00 +00:00
|
|
|
break;
|
2021-12-29 17:22:11 +00:00
|
|
|
case SIGBOOST_EVENT_DIGIT_IN:
|
2021-12-29 17:26:11 +00:00
|
|
|
handle_incoming_digit((call_signal_event_t*)event);
|
2021-12-29 17:22:11 +00:00
|
|
|
break;
|
2021-12-29 16:59:00 +00:00
|
|
|
default:
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Warning no handler implemented for [%s val:%d]\n",
|
2021-12-29 17:26:11 +00:00
|
|
|
call_signal_event_id_name(event->event_id), event->event_id);
|
2021-12-29 16:59:00 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void *monitor_thread_run(void *obj)
|
|
|
|
{
|
|
|
|
int ss = 0;
|
|
|
|
int policy=0,priority=0;
|
2021-12-29 17:03:04 +00:00
|
|
|
char a=0,b=0;
|
|
|
|
call_signal_connection_t *mcon=&server.mcon;
|
|
|
|
call_signal_connection_t *mconp=&server.mconp;
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:29:00 +00:00
|
|
|
pthread_mutex_lock(&server.thread_count_lock);
|
2021-12-29 16:59:00 +00:00
|
|
|
server.thread_count++;
|
2021-12-29 17:29:00 +00:00
|
|
|
pthread_mutex_unlock(&server.thread_count_lock);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
woomera_set_flag(&server.master_connection, WFLAG_MONITOR_RUNNING);
|
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
if (call_signal_connection_open(mcon,
|
|
|
|
mcon->cfg.local_ip,
|
|
|
|
mcon->cfg.local_port,
|
|
|
|
mcon->cfg.remote_ip,
|
|
|
|
mcon->cfg.remote_port) < 0) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Error: Opening MCON Socket [%d] %s\n",
|
2021-12-29 17:03:04 +00:00
|
|
|
mcon->socket,strerror(errno));
|
|
|
|
exit(-1);
|
2021-12-29 17:22:11 +00:00
|
|
|
}
|
2021-12-29 17:03:04 +00:00
|
|
|
|
|
|
|
if (call_signal_connection_open(mconp,
|
|
|
|
mconp->cfg.local_ip,
|
|
|
|
mconp->cfg.local_port,
|
|
|
|
mconp->cfg.remote_ip,
|
|
|
|
mconp->cfg.remote_port) < 0) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Error: Opening MCONP Socket [%d] %s\n",
|
2021-12-29 17:03:04 +00:00
|
|
|
mconp->socket,strerror(errno));
|
2021-12-29 16:59:00 +00:00
|
|
|
exit(-1);
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
mcon->log = server.log;
|
|
|
|
mconp->log = server.log;
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
isup_exec_commandp(0,
|
2021-12-29 16:59:00 +00:00
|
|
|
0,
|
|
|
|
-1,
|
|
|
|
SIGBOOST_EVENT_SYSTEM_RESTART,
|
|
|
|
0);
|
2021-12-29 17:03:04 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
woomera_set_flag(&server.master_connection, WFLAG_SYSTEM_RESET);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
smg_get_current_priority(&policy,&priority);
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_PROD, server.log, "Open udp socket [%d] [%d]\n",
|
2021-12-29 17:03:04 +00:00
|
|
|
mcon->socket,mconp->socket);
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_PROD, server.log, "Monitor Thread Started (%i:%i)\n",policy,priority);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) &&
|
|
|
|
woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) {
|
2021-12-29 17:03:04 +00:00
|
|
|
#if 0
|
|
|
|
ss = waitfor_socket(server.mcon.socket, 1000, POLLERR | POLLIN);
|
|
|
|
#else
|
|
|
|
ss = waitfor_2sockets(mcon->socket,
|
|
|
|
mconp->socket,
|
|
|
|
&a, &b, 1000);
|
|
|
|
#endif
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
if (ss > 0) {
|
2021-12-29 17:03:04 +00:00
|
|
|
|
|
|
|
call_signal_event_t *event=NULL;
|
2021-12-29 16:59:00 +00:00
|
|
|
int i=0;
|
2021-12-29 17:03:04 +00:00
|
|
|
|
|
|
|
if (b) {
|
|
|
|
mcon_retry_priority:
|
|
|
|
if ((event = call_signal_connection_readp(mconp,i))) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_9, server.log, "Socket Event P [%s] \n",
|
|
|
|
call_signal_event_id_name(event->event_id));
|
|
|
|
parse_ss7_event(mconp,(short_signal_event_t*)event);
|
|
|
|
if (++i < 10) {
|
|
|
|
goto mcon_retry_priority;
|
|
|
|
}
|
2021-12-29 17:03:04 +00:00
|
|
|
|
|
|
|
} else if (errno != EAGAIN) {
|
2021-12-29 17:27:14 +00:00
|
|
|
ss=-1;
|
|
|
|
log_printf(SMG_LOG_ALL, server.log,
|
|
|
|
"Error: Reading from Boost P Socket! (%i) %s\n",
|
|
|
|
errno,strerror(errno));
|
|
|
|
break;
|
2021-12-29 17:03:04 +00:00
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
2021-12-29 17:03:04 +00:00
|
|
|
|
|
|
|
i=0;
|
|
|
|
|
|
|
|
if (a) {
|
|
|
|
if ((event = call_signal_connection_read(mcon,i))) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_9, server.log, "Socket Event [%s]\n",
|
|
|
|
call_signal_event_id_name(event->event_id));
|
|
|
|
parse_ss7_event(mcon,(short_signal_event_t*)event);
|
2021-12-29 17:03:04 +00:00
|
|
|
|
|
|
|
} else if (errno != EAGAIN) {
|
2021-12-29 17:27:14 +00:00
|
|
|
ss=-1;
|
|
|
|
log_printf(SMG_LOG_ALL, server.log,
|
|
|
|
"Error: Reading from Boost Socket! (%i) %s\n",
|
|
|
|
errno,strerror(errno));
|
|
|
|
break;
|
2021-12-29 17:03:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ss < 0){
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Thread Run: Select Socket Error!\n");
|
2021-12-29 16:59:00 +00:00
|
|
|
break;
|
|
|
|
}
|
2021-12-29 17:27:14 +00:00
|
|
|
|
|
|
|
if (woomera_test_flag(&server.master_connection, WFLAG_SYSTEM_RESET)) {
|
|
|
|
short_signal_event_t event;
|
|
|
|
struct timeval current;
|
|
|
|
int elapsed;
|
|
|
|
gettimeofday(¤t,NULL);
|
|
|
|
|
|
|
|
elapsed=smg_calc_elapsed(&server.restart_timeout, ¤t);
|
|
|
|
if (elapsed > 5000) {
|
|
|
|
int err;
|
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Reset Condition Cleared Elapsed=%i!\n",elapsed);
|
|
|
|
clear_all_holding_tank();
|
|
|
|
memset(&event,0,sizeof(event));
|
|
|
|
event.event_id = SIGBOOST_EVENT_SYSTEM_RESTART_ACK;
|
|
|
|
err=call_signal_connection_write(&server.mcon, (call_signal_event_t*)&event);
|
|
|
|
if (err < 0) {
|
|
|
|
log_printf(SMG_LOG_ALL, server.log,
|
|
|
|
"Critical System Error: Failed to tx on ISUP socket [%s]: %s\n",
|
|
|
|
strerror(errno));
|
|
|
|
}
|
|
|
|
smg_all_ckt_busy();
|
|
|
|
woomera_clear_flag(&server.master_connection, WFLAG_SYSTEM_RESET);
|
|
|
|
}
|
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
}
|
2021-12-29 17:03:04 +00:00
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_PROD, server.log, "Close udp socket [%d] [%d]\n",
|
2021-12-29 17:03:04 +00:00
|
|
|
mcon->socket,mconp->socket);
|
2021-12-29 16:59:00 +00:00
|
|
|
call_signal_connection_close(&server.mcon);
|
2021-12-29 17:03:04 +00:00
|
|
|
call_signal_connection_close(&server.mconp);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
pthread_mutex_lock(&server.thread_count_lock);
|
|
|
|
server.thread_count--;
|
|
|
|
pthread_mutex_unlock(&server.thread_count_lock);
|
|
|
|
|
|
|
|
woomera_clear_flag(&server.master_connection, WFLAG_MONITOR_RUNNING);
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Monitor Thread Ended\n");
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void woomera_loop_thread_run(struct woomera_interface *woomera)
|
|
|
|
{
|
|
|
|
int err=launch_media_thread(woomera);
|
|
|
|
if (err) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Failed to start loop media thread\n");
|
2021-12-29 16:59:00 +00:00
|
|
|
woomera_set_flag(woomera,
|
|
|
|
(WFLAG_HANGUP|WFLAG_MEDIA_END));
|
|
|
|
woomera_clear_flag(woomera, WFLAG_RUNNING);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) &&
|
2021-12-29 17:03:04 +00:00
|
|
|
woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING) &&
|
2021-12-29 17:26:11 +00:00
|
|
|
!woomera_test_flag(&server.master_connection, WFLAG_SYSTEM_RESET) &&
|
2021-12-29 17:03:04 +00:00
|
|
|
!woomera_test_flag(woomera, WFLAG_MEDIA_END) &&
|
|
|
|
!woomera_test_flag(woomera, WFLAG_HANGUP)) {
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
usleep(300000);
|
2021-12-29 16:59:00 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
2021-12-29 17:14:12 +00:00
|
|
|
|
|
|
|
woomera_clear_flag(woomera, WFLAG_RUNNING);
|
2021-12-29 17:03:04 +00:00
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, server.log, "Woomera Session: For Loop Test exiting %s\n",woomera->interface);
|
2021-12-29 17:03:04 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:22:11 +00:00
|
|
|
static void woomera_check_digits (struct woomera_interface *woomera)
|
|
|
|
{
|
|
|
|
int span, chan;
|
|
|
|
|
|
|
|
if (!strlen(woomera->session)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (get_span_chan_from_interface(woomera->interface, &span, &chan) == 0) {
|
|
|
|
pthread_mutex_lock(&server.digits_lock);
|
|
|
|
if (server.process_table[span-1][chan-1].digits_len > 0) {
|
|
|
|
int i;
|
|
|
|
unsigned char digit;
|
|
|
|
|
|
|
|
for (i=0; i < server.process_table[span-1][chan-1].digits_len; i++) {
|
|
|
|
digit = server.process_table[span-1][chan-1].digits[i];
|
|
|
|
|
|
|
|
handle_event_dtmf(woomera, digit);
|
|
|
|
}
|
|
|
|
|
|
|
|
server.process_table[span-1][chan-1].digits_len = 0;
|
|
|
|
}
|
|
|
|
pthread_mutex_unlock(&server.digits_lock);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
static void *woomera_thread_run(void *obj)
|
|
|
|
{
|
|
|
|
struct woomera_interface *woomera = obj;
|
|
|
|
struct woomera_message wmsg;
|
|
|
|
struct woomera_event wevent;
|
|
|
|
char *event_string;
|
|
|
|
int mwi;
|
|
|
|
int err;
|
|
|
|
int policy=0, priority=0;
|
2021-12-29 17:03:04 +00:00
|
|
|
int span = -1, chan = -1;
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
woomera_message_init(&wmsg);
|
|
|
|
|
2021-12-29 17:14:45 +00:00
|
|
|
smg_get_current_priority(&policy,&priority);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, server.log, "WOOMERA session started (ptr=%p : loop=%i)(%i:%i) Index=%i\n",
|
2021-12-29 17:14:12 +00:00
|
|
|
woomera,woomera->loop_tdm,policy,priority, woomera->index);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
pthread_mutex_lock(&server.thread_count_lock);
|
|
|
|
server.thread_count++;
|
|
|
|
pthread_mutex_unlock(&server.thread_count_lock);
|
|
|
|
|
|
|
|
pthread_mutex_init(&woomera->queue_lock, NULL);
|
|
|
|
pthread_mutex_init(&woomera->ms_lock, NULL);
|
2021-12-29 17:03:04 +00:00
|
|
|
pthread_mutex_init(&woomera->dtmf_lock, NULL);
|
2021-12-29 16:59:00 +00:00
|
|
|
pthread_mutex_init(&woomera->vlock, NULL);
|
|
|
|
pthread_mutex_init(&woomera->flags_lock, NULL);
|
|
|
|
|
|
|
|
if (woomera->loop_tdm) {
|
2021-12-29 17:26:11 +00:00
|
|
|
/* We must set woomera socket to -1 otherwise
|
|
|
|
a valid file descriptor will get closed */
|
|
|
|
woomera->socket = -1;
|
2021-12-29 16:59:00 +00:00
|
|
|
woomera_loop_thread_run(woomera);
|
|
|
|
goto woomera_session_close;
|
|
|
|
}
|
|
|
|
|
|
|
|
err=socket_printf(woomera->socket,
|
|
|
|
"EVENT HELLO Sangoma Media Gateway%s"
|
|
|
|
"Supported-Protocols: TDM%s"
|
|
|
|
"Version: %s%s"
|
|
|
|
"Remote-Address: %s%s"
|
|
|
|
"Remote-Port: %d%s"
|
|
|
|
"Raw-Format: %s%s",
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
SMG_VERSION, WOOMERA_LINE_SEPERATOR,
|
|
|
|
inet_ntoa(woomera->addr.sin_addr), WOOMERA_LINE_SEPERATOR,
|
|
|
|
ntohs(woomera->addr.sin_port), WOOMERA_LINE_SEPERATOR,
|
|
|
|
server.hw_coding?"ALAW":"ULAW", WOOMERA_RECORD_SEPERATOR
|
|
|
|
);
|
|
|
|
|
|
|
|
if (err) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Woomera session socket failure! (ptr=%p)\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
woomera);
|
2021-12-29 17:26:11 +00:00
|
|
|
woomera_clear_flag(woomera, WFLAG_RUNNING);
|
|
|
|
goto woomera_session_close;
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
2021-12-29 17:22:11 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
while ( woomera_test_flag(&server.master_connection, WFLAG_RUNNING) &&
|
|
|
|
woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING) &&
|
|
|
|
woomera_test_flag(woomera, WFLAG_RUNNING) &&
|
|
|
|
!woomera_test_flag(woomera, WFLAG_MEDIA_END) &&
|
2021-12-29 17:27:14 +00:00
|
|
|
!woomera_test_flag(woomera, WFLAG_HANGUP)) {
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
mwi = woomera_message_parse(woomera, &wmsg, WOOMERA_HARD_TIMEOUT);
|
|
|
|
if (mwi >= 0) {
|
|
|
|
|
|
|
|
if (mwi) {
|
|
|
|
interpret_command(woomera, &wmsg);
|
|
|
|
} else if (woomera_test_flag(woomera, WFLAG_EVENT)){
|
|
|
|
while ((event_string = dequeue_event(woomera))) {
|
|
|
|
if (socket_printf(woomera->socket, "%s", event_string)) {
|
|
|
|
woomera_set_flag(woomera, WFLAG_MEDIA_END);
|
|
|
|
woomera_clear_flag(woomera, WFLAG_RUNNING);
|
|
|
|
smg_free(event_string);
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_8, server.log,
|
2021-12-29 17:26:11 +00:00
|
|
|
"WOOMERA session (ptr=%p) print string error\n",
|
|
|
|
woomera);
|
|
|
|
break;
|
|
|
|
}
|
2021-12-29 17:15:08 +00:00
|
|
|
smg_free(event_string);
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
2021-12-29 17:26:11 +00:00
|
|
|
woomera_clear_flag(woomera, WFLAG_EVENT);
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
2021-12-29 17:26:11 +00:00
|
|
|
|
|
|
|
if(woomera->check_digits) {
|
|
|
|
woomera_check_digits(woomera);
|
|
|
|
woomera->check_digits = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (woomera->timeout > 0 && time(NULL) >= woomera->timeout) {
|
|
|
|
|
|
|
|
/* Sent the hangup only after we sent a NACK */
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, server.log,
|
2021-12-29 17:26:11 +00:00
|
|
|
"WOOMERA session Call Timedout ! [%s]\n",
|
|
|
|
woomera->interface);
|
|
|
|
|
|
|
|
/* Let the Index check below send a NACK */
|
|
|
|
if (woomera->index) {
|
|
|
|
woomera->q931_rel_cause_tosig=19;
|
|
|
|
woomera_set_flag(woomera, WFLAG_HANGUP);
|
|
|
|
}
|
|
|
|
break;
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
2021-12-29 17:26:11 +00:00
|
|
|
|
|
|
|
} else {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_MISC, server.log, "WOOMERA session (ptr=%p) [%s] READ MSG Error %i \n",
|
2021-12-29 17:26:11 +00:00
|
|
|
woomera,woomera->interface,mwi);
|
2021-12-29 16:59:00 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
woomera_session_close:
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, server.log, "WOOMERA session (ptr=%p) is dying [%s]: SR=%d WR=%d WF=0x%04X\n",
|
2021-12-29 17:26:11 +00:00
|
|
|
woomera,woomera->interface,
|
|
|
|
woomera_test_flag(&server.master_connection, WFLAG_RUNNING),
|
|
|
|
woomera_test_flag(woomera, WFLAG_RUNNING),
|
|
|
|
woomera->flags);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
if (woomera_test_flag(woomera, WFLAG_MEDIA_RUNNING)) {
|
2021-12-29 16:59:00 +00:00
|
|
|
woomera_set_flag(woomera, WFLAG_MEDIA_END);
|
|
|
|
while(woomera_test_flag(woomera, WFLAG_MEDIA_RUNNING)) {
|
2021-12-29 17:11:50 +00:00
|
|
|
usleep(100);
|
2021-12-29 16:59:00 +00:00
|
|
|
sched_yield();
|
|
|
|
}
|
2021-12-29 17:26:11 +00:00
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
|
|
|
|
/***********************************************
|
|
|
|
* Identify the SPAN CHAN to be used below
|
|
|
|
***********************************************/
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
chan = woomera->chan;
|
|
|
|
span = woomera->span;
|
2021-12-29 17:03:04 +00:00
|
|
|
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
if (!woomera_test_flag(woomera, WFLAG_HANGUP)) {
|
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
/* The call was not HUNGUP. This is the last check,
|
|
|
|
If the call is valid, hungup the call if the call
|
|
|
|
was never up the keep going */
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
if (smg_validate_span_chan(span,chan) == 0) {
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
if (!woomera->index) {
|
2021-12-29 17:02:04 +00:00
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
if (autoacm || woomera_test_flag(woomera,WFLAG_CALL_ACKED)) {
|
|
|
|
|
|
|
|
woomera_set_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK);
|
|
|
|
isup_exec_command(span,
|
|
|
|
chan,
|
|
|
|
-1,
|
|
|
|
SIGBOOST_EVENT_CALL_STOPPED,
|
|
|
|
woomera->q931_rel_cause_tosig);
|
|
|
|
woomera_set_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK_SENT);
|
|
|
|
|
|
|
|
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_MISC, woomera->log, "Woomera Sent SIGBOOST_EVENT_CALL_STOPPED [s%dc%d] [%s] ptr=%p\n",
|
2021-12-29 17:14:12 +00:00
|
|
|
span+1, chan+1,woomera->interface,woomera);
|
|
|
|
} else {
|
|
|
|
|
|
|
|
woomera_set_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK);
|
|
|
|
isup_exec_command(span,
|
|
|
|
chan,
|
|
|
|
-1,
|
|
|
|
SIGBOOST_EVENT_CALL_START_NACK,
|
|
|
|
woomera->q931_rel_cause_tosig);
|
|
|
|
woomera_set_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK_SENT);
|
|
|
|
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_MISC, woomera->log, "Woomera Sent SIGBOOST_EVENT_CALL_START_NACK [s%dc%d] [%s] ptr=%p\n",
|
2021-12-29 17:14:12 +00:00
|
|
|
span+1, chan+1,woomera->interface,woomera);
|
|
|
|
}
|
2021-12-29 17:03:04 +00:00
|
|
|
} else {
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_ALL, woomera->log, "Woomera Not Sent CALL STOPPED - Instead NACK [s%dc%d] [%s] ptr=%p\n",
|
2021-12-29 17:03:04 +00:00
|
|
|
span+1, chan+1,woomera->interface,woomera);
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
}else{
|
2021-12-29 17:03:04 +00:00
|
|
|
/* This can happend if an outgoing call times out
|
|
|
|
or gets hungup before it gets acked. Its not a
|
|
|
|
failure */
|
2021-12-29 17:14:12 +00:00
|
|
|
if (!woomera->index) {
|
|
|
|
/* In this case we really failed to tx STOP */
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_MISC, woomera->log, "FAILED: Woomera (R) SIGBOOST_EVENT_CALL_STOPPED [s%dc%d] [%s] Index=%d ptr=%p\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
span+1, chan+1, woomera->interface, woomera->index, woomera);
|
2021-12-29 17:14:12 +00:00
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
2021-12-29 17:14:12 +00:00
|
|
|
|
|
|
|
woomera_set_flag(woomera, WFLAG_HANGUP);
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
woo_re_hangup:
|
|
|
|
|
|
|
|
/* We must send a STOP ACK to boost telling it that we are done */
|
|
|
|
if (woomera_test_flag(woomera, WFLAG_HANGUP_ACK)) {
|
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
/* SMG received a HANGUP from boost.
|
|
|
|
We must now send back the ACK to the HANGUP.
|
|
|
|
Boost will not release channel until we
|
|
|
|
ACK the hangup */
|
|
|
|
|
2021-12-29 17:02:04 +00:00
|
|
|
if (smg_validate_span_chan(span,chan) == 0) {
|
2021-12-29 17:03:04 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
isup_exec_command(span,
|
|
|
|
chan,
|
|
|
|
-1,
|
|
|
|
SIGBOOST_EVENT_CALL_STOPPED_ACK,
|
2021-12-29 17:12:33 +00:00
|
|
|
woomera->q931_rel_cause_tosig);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_MISC, woomera->log,
|
2021-12-29 17:29:00 +00:00
|
|
|
"Sent (Ack) to SIGBOOST_EVENT_CALL_STOPPED_ACK [s%dc%d] [%s] ptr=%p\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
span+1,chan+1,woomera->interface,woomera);
|
|
|
|
|
|
|
|
}else{
|
2021-12-29 17:03:04 +00:00
|
|
|
/* This should never happen! If it does
|
|
|
|
we broke protocol */
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, woomera->log,
|
2021-12-29 17:29:00 +00:00
|
|
|
"FAILED: Woomera (R) SIGBOOST_EVENT_CALL_STOPPED_ACK [s%dc%d] [%s] Index=%d ptr=%p\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
span+1, chan+1, woomera->interface, woomera->index, woomera);
|
|
|
|
}
|
|
|
|
|
|
|
|
woomera_clear_flag(woomera, WFLAG_HANGUP_ACK);
|
2021-12-29 17:14:12 +00:00
|
|
|
woomera_set_flag(woomera, WFLAG_HANGUP);
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (woomera_test_flag(woomera, WFLAG_HANGUP_NACK_ACK)) {
|
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
/* SMG received a NACK from boost during call startup.
|
|
|
|
We must now send back the ACK to the NACK.
|
|
|
|
Boost will not release channel until we
|
|
|
|
ACK the NACK */
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
if (smg_validate_span_chan(span,chan) == 0) {
|
|
|
|
|
|
|
|
isup_exec_command(span,
|
|
|
|
chan,
|
|
|
|
-1,
|
|
|
|
SIGBOOST_EVENT_CALL_START_NACK_ACK,
|
2021-12-29 17:12:33 +00:00
|
|
|
woomera->q931_rel_cause_tosig);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_MISC, woomera->log,
|
2021-12-29 17:29:00 +00:00
|
|
|
"Sent (Nack Ack) to SIGBOOST_EVENT_CALL_START_NACK_ACK [s%dc%d] [%s] ptr=%p\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
span+1,chan+1,woomera->interface,woomera);
|
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
woomera->index=0;
|
|
|
|
|
|
|
|
} else if (woomera->index) {
|
|
|
|
isup_exec_command(0,
|
|
|
|
0,
|
|
|
|
woomera->index,
|
|
|
|
SIGBOOST_EVENT_CALL_START_NACK_ACK,
|
|
|
|
woomera->q931_rel_cause_tosig);
|
|
|
|
|
|
|
|
woomera->index=0;
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
} else {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, woomera->log,
|
2021-12-29 17:29:00 +00:00
|
|
|
"FAILED: Sent (Nack Ack) SIGBOOST_EVENT_CALL_START_NACK_ACK [s%dc%d] [%s] Index=%d ptr=%p\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
span+1, chan+1, woomera->interface, woomera->index, woomera);
|
|
|
|
}
|
|
|
|
|
|
|
|
woomera_clear_flag(woomera, WFLAG_HANGUP_NACK_ACK);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (woomera->index) {
|
|
|
|
|
|
|
|
int index = woomera->index;
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
new_woomera_event_printf(&wevent, "EVENT HANGUP %s%s"
|
2021-12-29 17:26:11 +00:00
|
|
|
"Unique-Call-Id: %s%s"
|
|
|
|
"Timeout: %ld%s"
|
|
|
|
"Cause: %s%s"
|
|
|
|
"Q931-Cause-Code: %d%s",
|
|
|
|
woomera->interface,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
woomera->session,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
woomera->timeout,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
q931_rel_to_str(18),
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
18,
|
|
|
|
WOOMERA_RECORD_SEPERATOR
|
|
|
|
);
|
|
|
|
enqueue_event(woomera, &wevent,EVENT_FREE_DATA);
|
|
|
|
|
|
|
|
new_woomera_event_printf(&wevent, "501 call was cancelled!%s"
|
|
|
|
"Unique-Call-Id: %s%s",
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
woomera->session,
|
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
|
|
|
|
|
|
|
enqueue_event(woomera, &wevent,EVENT_FREE_DATA);
|
2021-12-29 17:03:04 +00:00
|
|
|
|
|
|
|
while ((event_string = dequeue_event(woomera))) {
|
2021-12-29 17:26:11 +00:00
|
|
|
socket_printf(woomera->socket, "%s", event_string);
|
|
|
|
smg_free(event_string);
|
|
|
|
}
|
2021-12-29 17:03:04 +00:00
|
|
|
|
2021-12-29 17:11:50 +00:00
|
|
|
if (peek_from_holding_tank(index)) {
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
woomera_set_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK);
|
2021-12-29 16:59:00 +00:00
|
|
|
isup_exec_command(0,
|
|
|
|
0,
|
|
|
|
index,
|
|
|
|
SIGBOOST_EVENT_CALL_START_NACK,
|
2021-12-29 17:26:11 +00:00
|
|
|
woomera->q931_rel_cause_tosig);
|
2021-12-29 17:14:12 +00:00
|
|
|
woomera_set_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK_SENT);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, woomera->log,
|
2021-12-29 16:59:00 +00:00
|
|
|
"Sent SIGBOOST_EVENT_CALL_START_NACK [Setup ID: %d] .. WAITING FOR NACK ACK\n",
|
|
|
|
index);
|
2021-12-29 17:14:12 +00:00
|
|
|
} else {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_PROD, woomera->log,
|
2021-12-29 17:14:12 +00:00
|
|
|
"Error Failed to Sent SIGBOOST_EVENT_CALL_START_NACK [Setup ID: %d] - index stale!\n",
|
|
|
|
index);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK)) {
|
|
|
|
int timeout_cnt=0;
|
|
|
|
int overall_cnt=0;
|
|
|
|
|
|
|
|
/* SMG sent NACK to boost, however we have to wait
|
|
|
|
for boost to give us the ACK back before we
|
|
|
|
release resources. */
|
2021-12-29 17:26:11 +00:00
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
while (woomera_test_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK)) {
|
|
|
|
timeout_cnt++;
|
2021-12-29 17:26:11 +00:00
|
|
|
if (timeout_cnt > 100) { //5sec timeout
|
2021-12-29 17:14:12 +00:00
|
|
|
timeout_cnt=0;
|
|
|
|
overall_cnt++;
|
2021-12-29 17:26:11 +00:00
|
|
|
|
|
|
|
log_printf((overall_cnt==1)?0:4, woomera->log,
|
2021-12-29 17:14:12 +00:00
|
|
|
"Waiting for NACK ACK [Setup ID: %d] ... \n",
|
2021-12-29 17:26:11 +00:00
|
|
|
woomera->index_hold);
|
2021-12-29 17:14:12 +00:00
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
if (overall_cnt > 15) { //50sec timeout
|
2021-12-29 17:14:12 +00:00
|
|
|
woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK);
|
2021-12-29 17:26:11 +00:00
|
|
|
woomera_set_flag(woomera, WFLAG_WAIT_FOR_ACK_TIMEOUT);
|
2021-12-29 17:14:12 +00:00
|
|
|
break;
|
2021-12-29 17:11:50 +00:00
|
|
|
}
|
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING)) {
|
2021-12-29 17:26:11 +00:00
|
|
|
woomera_set_flag(woomera, WFLAG_WAIT_FOR_ACK_TIMEOUT);
|
2021-12-29 17:14:12 +00:00
|
|
|
break;
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
2021-12-29 17:26:11 +00:00
|
|
|
if (woomera_test_flag(&server.master_connection, WFLAG_SYSTEM_RESET)){
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If ACK comes in while we wait for NACK ACK, the ACk will
|
|
|
|
clear the tank causing NACK ACK never to clear the waiting flag
|
|
|
|
in this case we abort waiting for NACK ACK and we timeout
|
|
|
|
the wait */
|
|
|
|
if (woomera_test_flag(&server.master_connection, WFLAG_CALL_ACKED)){
|
|
|
|
woomera_set_flag(woomera, WFLAG_WAIT_FOR_ACK_TIMEOUT);
|
|
|
|
break;
|
|
|
|
}
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
usleep(50000);
|
2021-12-29 17:14:12 +00:00
|
|
|
sched_yield();
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
woomera_clear_flag(woomera, WFLAG_WAIT_FOR_NACK_ACK);
|
2021-12-29 17:26:11 +00:00
|
|
|
|
|
|
|
/* If ACK came in while waiting for NACK ACK, we TIMEOUT on purpose.
|
|
|
|
The ACK has blocked the tank id and now ony NACK ACK can unblock it.
|
|
|
|
THe only problem is that we blind and have to assume that NACK ACK
|
|
|
|
will eventually come in :) */
|
|
|
|
if (!woomera_test_flag(&server.master_connection, WFLAG_CALL_ACKED)) {
|
|
|
|
if (woomera_test_flag(woomera, WFLAG_WAIT_FOR_ACK_TIMEOUT)) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, woomera->log,
|
2021-12-29 17:26:11 +00:00
|
|
|
"Waiting for NACK ACK [Setup ID: %d] .. TIMEOUT on NACK ACK\n",
|
|
|
|
woomera->index_hold);
|
2021-12-29 17:14:12 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
} else {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_8, woomera->log,
|
2021-12-29 17:14:12 +00:00
|
|
|
"Waiting for NACK ACK [Setup ID: %d] .. GOT NACK ACK\n",
|
2021-12-29 17:26:11 +00:00
|
|
|
woomera->index_hold);
|
|
|
|
}
|
2021-12-29 17:14:12 +00:00
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
2021-12-29 17:03:04 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
if (woomera_test_flag(woomera, WFLAG_EVENT)){
|
|
|
|
while ((event_string = dequeue_event(woomera))) {
|
|
|
|
socket_printf(woomera->socket, "%s", event_string);
|
2021-12-29 17:15:08 +00:00
|
|
|
smg_free(event_string);
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
woomera_clear_flag(woomera, WFLAG_EVENT);
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
|
|
|
|
if (woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK)) {
|
2021-12-29 17:11:50 +00:00
|
|
|
int timeout_cnt=0;
|
|
|
|
int overall_cnt=0;
|
2021-12-29 17:03:04 +00:00
|
|
|
|
|
|
|
/* SMG sent HANGUP to boost, however we have to wait
|
|
|
|
for boost to give us the ACK back before we
|
|
|
|
release resources. */
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_8, woomera->log,
|
2021-12-29 17:03:04 +00:00
|
|
|
"Waiting for STOPPED ACK [%s] [id=%i]... \n",
|
|
|
|
woomera->interface,woomera->index_hold);
|
2021-12-29 17:11:50 +00:00
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
while (woomera_test_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK)) {
|
|
|
|
timeout_cnt++;
|
2021-12-29 17:26:11 +00:00
|
|
|
if (timeout_cnt > 100) { //5sec timeout
|
2021-12-29 17:03:04 +00:00
|
|
|
timeout_cnt=0;
|
2021-12-29 17:11:50 +00:00
|
|
|
overall_cnt++;
|
2021-12-29 17:26:11 +00:00
|
|
|
log_printf((overall_cnt==1)?0:4, woomera->log,
|
|
|
|
"Waiting for STOPPED ACK [%s] [id=%i] %i... \n",
|
|
|
|
woomera->interface,woomera->index_hold,overall_cnt);
|
2021-12-29 17:03:04 +00:00
|
|
|
}
|
2021-12-29 17:11:50 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
if (overall_cnt > 15) { //50sec
|
2021-12-29 17:11:50 +00:00
|
|
|
woomera_clear_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK);
|
2021-12-29 17:26:11 +00:00
|
|
|
woomera_set_flag(woomera, WFLAG_WAIT_FOR_ACK_TIMEOUT);
|
2021-12-29 17:03:04 +00:00
|
|
|
break;
|
|
|
|
}
|
2021-12-29 17:11:50 +00:00
|
|
|
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
if (!woomera_test_flag(&server.master_connection, WFLAG_RUNNING)) {
|
2021-12-29 17:11:50 +00:00
|
|
|
woomera_clear_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK);
|
2021-12-29 17:26:11 +00:00
|
|
|
woomera_set_flag(woomera, WFLAG_WAIT_FOR_ACK_TIMEOUT);
|
2021-12-29 17:11:50 +00:00
|
|
|
break;
|
|
|
|
}
|
2021-12-29 17:26:11 +00:00
|
|
|
|
|
|
|
if (woomera_test_flag(&server.master_connection, WFLAG_SYSTEM_RESET)){
|
|
|
|
break;
|
|
|
|
}
|
2021-12-29 17:11:50 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
usleep(50000);
|
2021-12-29 17:11:50 +00:00
|
|
|
sched_yield();
|
2021-12-29 17:03:04 +00:00
|
|
|
}
|
2021-12-29 17:14:12 +00:00
|
|
|
|
|
|
|
woomera_clear_flag(woomera, WFLAG_WAIT_FOR_STOPPED_ACK);
|
2021-12-29 17:03:04 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
if (woomera_test_flag(woomera, WFLAG_WAIT_FOR_ACK_TIMEOUT)) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, woomera->log,
|
2021-12-29 17:14:12 +00:00
|
|
|
"Wait TIMEDOUT on STOPPED ACK [%s] [id=%i]... \n",
|
|
|
|
woomera->interface,woomera->index_hold);
|
2021-12-29 17:11:50 +00:00
|
|
|
|
2021-12-29 17:14:12 +00:00
|
|
|
} else {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_8, woomera->log,
|
2021-12-29 17:14:12 +00:00
|
|
|
"Wait GOT STOPPED ACK [%s] [id=%i]... \n",
|
|
|
|
woomera->interface,woomera->index_hold);
|
2021-12-29 17:03:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************
|
|
|
|
* We must wait for WFLAG_WAIT_FOR_STOPPED_ACK here
|
|
|
|
* so that STOP_ACK can access the woomera
|
|
|
|
*****************************************************/
|
|
|
|
|
|
|
|
if (smg_validate_span_chan(span,chan) == 0) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, woomera->log,
|
2021-12-29 17:03:04 +00:00
|
|
|
"WOOMERA Clearing Processs Table ... \n",
|
|
|
|
woomera->interface);
|
|
|
|
pthread_mutex_lock(&server.process_lock);
|
2021-12-29 17:11:50 +00:00
|
|
|
if (server.process_table[span][chan].dev == woomera){
|
|
|
|
server.process_table[span][chan].dev = NULL;
|
|
|
|
memset(server.process_table[span][chan].session,0,SMG_SESSION_NAME_SZ);
|
2021-12-29 17:22:11 +00:00
|
|
|
memset(server.process_table[span][chan].digits,0,
|
|
|
|
sizeof(server.process_table[span][chan].digits));
|
|
|
|
server.process_table[span][chan].digits_len = 0;
|
2021-12-29 17:03:04 +00:00
|
|
|
}
|
|
|
|
pthread_mutex_unlock(&server.process_lock);
|
|
|
|
}
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
#if 0
|
|
|
|
//Used for testing
|
|
|
|
if (1) {
|
|
|
|
int chan = woomera->chan;
|
|
|
|
int span = woomera->span;
|
|
|
|
if (smg_validate_span_chan(span,chan) == 0) {
|
|
|
|
pthread_mutex_lock(&server.process_lock);
|
|
|
|
/* This is possible in case media thread dies on startup */
|
|
|
|
|
|
|
|
if (server.process_table[span][chan]){
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log,
|
2021-12-29 17:29:00 +00:00
|
|
|
"Sanity Span Chan Still in use: [s%dc%d] [%s] Index=%d ptr=%p\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
span+1, chan+1, woomera->interface, woomera->index, woomera);
|
|
|
|
//server.process_table[span][chan] = NULL;
|
|
|
|
}
|
|
|
|
pthread_mutex_unlock(&server.process_lock);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
usleep(3000000);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
/* Sanity Check */
|
|
|
|
if (woomera_test_flag(woomera, WFLAG_HANGUP_ACK)) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, woomera->log,
|
2021-12-29 16:59:00 +00:00
|
|
|
"Woomera MISSED HANGUP ACK: Retry HANGUP ACK\n");
|
|
|
|
goto woo_re_hangup;
|
|
|
|
}
|
|
|
|
if (woomera_test_flag(woomera, WFLAG_HANGUP_NACK_ACK)) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, woomera->log,
|
2021-12-29 16:59:00 +00:00
|
|
|
"Woomera MISSED HANGUP ACK: Retry HANGUP NACK ACK\n");
|
|
|
|
goto woo_re_hangup;
|
|
|
|
}
|
2021-12-29 17:26:11 +00:00
|
|
|
|
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
/* This is where we actually pull the index
|
|
|
|
* out of the tank. We had to keep the tank
|
|
|
|
* value until the end of the call. Tank is only
|
|
|
|
* used on outgoing calls. */
|
|
|
|
if (woomera->index_hold >= 1) {
|
2021-12-29 17:26:11 +00:00
|
|
|
if (woomera_test_flag(woomera, WFLAG_WAIT_FOR_ACK_TIMEOUT)) {
|
|
|
|
/* Replace real woomera interface with a dummy so
|
|
|
|
the tank is blocked. The real woomera interface will be
|
|
|
|
deallocated */
|
|
|
|
pull_from_holding_tank(woomera->index_hold,-1,-1);
|
|
|
|
|
|
|
|
if (check_tank_index(woomera->index_hold) != NULL){
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_PROD, woomera->log, "Woomera Thread: [%s] setup id %i blocked waiting for NACK or ACK\n",
|
2021-12-29 17:26:11 +00:00
|
|
|
woomera->interface ,woomera->index_hold);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
clear_from_holding_tank(woomera->index_hold, woomera);
|
|
|
|
|
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
woomera->index_hold=0;
|
|
|
|
}
|
2021-12-29 17:26:11 +00:00
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, woomera->log, "Woomera Thread Finished %u\n", (unsigned long) woomera->thread);
|
2021-12-29 16:59:00 +00:00
|
|
|
close_socket(&woomera->socket);
|
|
|
|
woomera->socket=-1;
|
|
|
|
|
|
|
|
/* delete queue */
|
|
|
|
while ((event_string = dequeue_event(woomera))) {
|
2021-12-29 17:15:08 +00:00
|
|
|
smg_free(event_string);
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (woomera_test_flag(woomera, WFLAG_LISTENING)) {
|
|
|
|
del_listener(woomera);
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, server.log, "WOOMERA session for [%s] stopped (ptr=%p)\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
woomera->interface,woomera);
|
|
|
|
|
|
|
|
pthread_mutex_destroy(&woomera->queue_lock);
|
|
|
|
pthread_mutex_destroy(&woomera->ms_lock);
|
2021-12-29 17:03:04 +00:00
|
|
|
pthread_mutex_destroy(&woomera->dtmf_lock);
|
2021-12-29 16:59:00 +00:00
|
|
|
pthread_mutex_destroy(&woomera->vlock);
|
|
|
|
pthread_mutex_destroy(&woomera->flags_lock);
|
|
|
|
woomera_set_raw(woomera, NULL);
|
|
|
|
woomera_set_interface(woomera, NULL);
|
|
|
|
|
|
|
|
woomera_message_clear(&wmsg);
|
|
|
|
|
2021-12-29 17:15:08 +00:00
|
|
|
smg_free(woomera);
|
2021-12-29 16:59:00 +00:00
|
|
|
pthread_mutex_lock(&server.thread_count_lock);
|
|
|
|
server.call_count--;
|
|
|
|
server.thread_count--;
|
|
|
|
pthread_mutex_unlock(&server.thread_count_lock);
|
|
|
|
|
|
|
|
pthread_exit(NULL);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int launch_woomera_thread(struct woomera_interface *woomera)
|
|
|
|
{
|
|
|
|
int result = 0;
|
|
|
|
pthread_attr_t attr;
|
|
|
|
|
|
|
|
result = pthread_attr_init(&attr);
|
|
|
|
//pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
|
|
|
|
//pthread_attr_setschedpolicy(&attr, SCHED_RR);
|
|
|
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
|
|
|
pthread_attr_setstacksize(&attr, MGD_STACK_SIZE);
|
|
|
|
|
|
|
|
woomera_set_flag(woomera, WFLAG_RUNNING);
|
|
|
|
result = pthread_create(&woomera->thread, &attr, woomera_thread_run, woomera);
|
|
|
|
if (result) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "%s: Error: Creating Woomera Thread! (%i) %s\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
__FUNCTION__,result,strerror(errno));
|
|
|
|
woomera_clear_flag(woomera, WFLAG_RUNNING);
|
|
|
|
}
|
|
|
|
pthread_attr_destroy(&attr);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int launch_monitor_thread(void)
|
|
|
|
{
|
|
|
|
pthread_attr_t attr;
|
|
|
|
int result = 0;
|
|
|
|
struct sched_param param;
|
|
|
|
|
|
|
|
param.sched_priority = 10;
|
|
|
|
result = pthread_attr_init(&attr);
|
|
|
|
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
|
|
|
|
pthread_attr_setschedpolicy(&attr, SCHED_RR);
|
|
|
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
|
|
|
pthread_attr_setstacksize(&attr, MGD_STACK_SIZE);
|
|
|
|
|
|
|
|
result = pthread_attr_setschedparam (&attr, ¶m);
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log,"%s: Old Priority =%i res=%i \n",__FUNCTION__,
|
2021-12-29 16:59:00 +00:00
|
|
|
param.sched_priority,result);
|
|
|
|
|
|
|
|
|
|
|
|
woomera_set_flag(&server.master_connection, WFLAG_MONITOR_RUNNING);
|
|
|
|
result = pthread_create(&server.monitor_thread, &attr, monitor_thread_run, NULL);
|
|
|
|
if (result) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "%s: Error: Creating Thread! %s\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
__FUNCTION__,strerror(errno));
|
|
|
|
woomera_clear_flag(&server.master_connection, WFLAG_MONITOR_RUNNING);
|
|
|
|
}
|
|
|
|
pthread_attr_destroy(&attr);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:03:04 +00:00
|
|
|
|
|
|
|
#ifdef WP_HPTDM_API
|
|
|
|
static void *hp_tdmapi_span_run(void *obj)
|
|
|
|
{
|
|
|
|
hp_tdm_api_span_t *span = obj;
|
|
|
|
int err;
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log,"Starting %s span!\n",span->ifname);
|
2021-12-29 17:03:04 +00:00
|
|
|
|
|
|
|
while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) &&
|
|
|
|
woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) {
|
|
|
|
|
|
|
|
if (!span->run_span) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
err = span->run_span(span);
|
|
|
|
if (err) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (span->close_span) {
|
|
|
|
span->close_span(span);
|
|
|
|
}
|
|
|
|
|
|
|
|
sleep(3);
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log,"Stopping %s span!\n",span->ifname);
|
2021-12-29 17:03:04 +00:00
|
|
|
|
|
|
|
pthread_exit(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int launch_hptdm_api_span_thread(int span)
|
|
|
|
{
|
|
|
|
pthread_attr_t attr;
|
|
|
|
int result = 0;
|
|
|
|
struct sched_param param;
|
|
|
|
|
|
|
|
param.sched_priority = 5;
|
|
|
|
result = pthread_attr_init(&attr);
|
|
|
|
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
|
|
|
|
pthread_attr_setschedpolicy(&attr, SCHED_RR);
|
|
|
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
|
|
|
pthread_attr_setstacksize(&attr, MGD_STACK_SIZE);
|
|
|
|
|
|
|
|
result = pthread_attr_setschedparam (&attr, ¶m);
|
|
|
|
|
|
|
|
result = pthread_create(&server.monitor_thread, &attr, hp_tdmapi_span_run, &hptdmspan[span]);
|
|
|
|
if (result) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "%s: Error: Creating Thread! %s\n",
|
2021-12-29 17:03:04 +00:00
|
|
|
__FUNCTION__,strerror(errno));
|
|
|
|
}
|
|
|
|
pthread_attr_destroy(&attr);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
static int configure_server(void)
|
|
|
|
{
|
|
|
|
struct woomera_config cfg;
|
|
|
|
char *var, *val;
|
|
|
|
int cnt = 0;
|
2021-12-29 17:29:00 +00:00
|
|
|
struct smg_tdm_ip_bridge *ip_bridge=NULL;
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:29:00 +00:00
|
|
|
|
2021-12-29 17:12:33 +00:00
|
|
|
server.dtmf_intr_ch = -1;
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
if (!woomera_open_file(&cfg, server.config_file)) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "open of %s failed\n", server.config_file);
|
2021-12-29 16:59:00 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2021-12-29 17:26:11 +00:00
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log, "\n======================= \n");
|
|
|
|
log_printf(SMG_LOG_ALL,server.log, "Server - Configuration \n");
|
|
|
|
log_printf(SMG_LOG_ALL,server.log, "======================= \n");
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
while (woomera_next_pair(&cfg, &var, &val)) {
|
|
|
|
if (!strcasecmp(var, "boost_local_ip")) {
|
2021-12-29 17:03:04 +00:00
|
|
|
strncpy(server.mcon.cfg.local_ip, val,
|
|
|
|
sizeof(server.mcon.cfg.local_ip) -1);
|
|
|
|
strncpy(server.mconp.cfg.local_ip, val,
|
|
|
|
sizeof(server.mconp.cfg.local_ip) -1);
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log, "Server - Boost Local IP: %s\n",val);
|
2021-12-29 17:26:11 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
cnt++;
|
|
|
|
} else if (!strcasecmp(var, "boost_local_port")) {
|
2021-12-29 17:03:04 +00:00
|
|
|
server.mcon.cfg.local_port = atoi(val);
|
|
|
|
server.mconp.cfg.local_port =
|
|
|
|
server.mcon.cfg.local_port+1;
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log, "Server - Boost Local Port: %i\n",server.mcon.cfg.local_port);
|
2021-12-29 16:59:00 +00:00
|
|
|
cnt++;
|
|
|
|
} else if (!strcasecmp(var, "boost_remote_ip")) {
|
2021-12-29 17:03:04 +00:00
|
|
|
strncpy(server.mcon.cfg.remote_ip, val,
|
|
|
|
sizeof(server.mcon.cfg.remote_ip) -1);
|
|
|
|
strncpy(server.mconp.cfg.remote_ip, val,
|
|
|
|
sizeof(server.mconp.cfg.remote_ip) -1);
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log, "Server - Boost Remote IP: %s\n",server.mcon.cfg.remote_ip);
|
2021-12-29 16:59:00 +00:00
|
|
|
cnt++;
|
|
|
|
} else if (!strcasecmp(var, "boost_remote_port")) {
|
2021-12-29 17:03:04 +00:00
|
|
|
server.mcon.cfg.remote_port = atoi(val);
|
|
|
|
server.mconp.cfg.remote_port =
|
|
|
|
server.mcon.cfg.remote_port+1;
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log, "Server - Boost Remote Port: %i\n",server.mcon.cfg.local_port);
|
2021-12-29 16:59:00 +00:00
|
|
|
cnt++;
|
|
|
|
} else if (!strcasecmp(var, "logfile_path")) {
|
|
|
|
if (!server.logfile_path) {
|
2021-12-29 17:15:08 +00:00
|
|
|
server.logfile_path = smg_strdup(val);
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
} else if (!strcasecmp(var, "woomera_port")) {
|
|
|
|
server.port = atoi(val);
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log, "Server - Woomera Port: %i\n",server.port);
|
2021-12-29 16:59:00 +00:00
|
|
|
} else if (!strcasecmp(var, "debug_level")) {
|
|
|
|
server.debug = atoi(val);
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log, "Server - Debug Level: %i\n",server.debug);
|
2021-12-29 16:59:00 +00:00
|
|
|
} else if (!strcasecmp(var, "out_tx_test")) {
|
|
|
|
server.out_tx_test = atoi(val);
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log, "Server - Tx Media Dbg: %s\n",server.out_tx_test?"On":"Off (Default)");
|
2021-12-29 16:59:00 +00:00
|
|
|
} else if (!strcasecmp(var, "loop_trace")) {
|
|
|
|
server.loop_trace = atoi(val);
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log, "Server - Media Loop Trace: %s\n",server.loop_trace?"On":"Off (Default)");
|
2021-12-29 16:59:00 +00:00
|
|
|
} else if (!strcasecmp(var, "rxgain")) {
|
|
|
|
server.rxgain = atoi(val);
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log, "Server - Rx Gain: %d\n",server.rxgain);
|
2021-12-29 16:59:00 +00:00
|
|
|
} else if (!strcasecmp(var, "txgain")) {
|
|
|
|
server.txgain = atoi(val);
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log, "Server - Tx Gain: %d\n",server.txgain);
|
2021-12-29 17:12:33 +00:00
|
|
|
} else if (!strcasecmp(var, "dtmf_on_duration")){
|
|
|
|
server.dtmf_on = atoi(val);
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log, "Server - DTMF ON Duration: %d ms\n",server.dtmf_on);
|
2021-12-29 17:12:33 +00:00
|
|
|
} else if (!strcasecmp(var, "dtmf_off_duration")){
|
|
|
|
server.dtmf_off = atoi(val);
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log, "Server - DTMF Off Duration: %d ms\n",server.dtmf_off);
|
2021-12-29 17:12:33 +00:00
|
|
|
} else if (!strcasecmp(var, "dtmf_inter_ch_duration")){
|
|
|
|
server.dtmf_intr_ch = atoi(val);
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log, "Server - DTMF Spacing: %d\n",server.dtmf_intr_ch);
|
2021-12-29 17:15:08 +00:00
|
|
|
} else if (!strcasecmp(var, "strip_cid_non_digits")){
|
|
|
|
server.strip_cid_non_digits = atoi(val);
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log, "Server - Strip non digits: %d\n",server.strip_cid_non_digits);
|
2021-12-29 16:59:00 +00:00
|
|
|
} else if (!strcasecmp(var, "max_calls")) {
|
|
|
|
int max = atoi(val);
|
|
|
|
if (max > 0) {
|
|
|
|
server.max_calls = max;
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log, "Server - Max Active Calls: %d\n",server.max_calls);
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
2021-12-29 17:14:12 +00:00
|
|
|
} else if (!strcasecmp(var, "autoacm")) {
|
|
|
|
int max = atoi(val);
|
|
|
|
if (max >= 0) {
|
|
|
|
autoacm=max;
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log, "Server - Auto ACM: %s\n",autoacm?"On":"Off (Default)");
|
2021-12-29 17:14:12 +00:00
|
|
|
}
|
2021-12-29 17:20:09 +00:00
|
|
|
} else if (!strcasecmp(var, "max_spans")) {
|
|
|
|
int max = atoi(val);
|
|
|
|
if (max > 0) {
|
|
|
|
max_spans = max;
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log, "Server - Max Spans: %d\n",max_spans);
|
2021-12-29 17:26:11 +00:00
|
|
|
}
|
|
|
|
} else if (!strcasecmp(var, "call_timeout")) {
|
|
|
|
int max = atoi(val);
|
|
|
|
if (max >= 0) {
|
|
|
|
server.call_timeout=max;
|
|
|
|
} else {
|
|
|
|
server.call_timeout=SMG_DEFAULT_CALL_TIMEOUT;
|
|
|
|
}
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log, "Server - Call Comp Timeout: %d s\n",server.call_timeout);
|
2021-12-29 17:26:11 +00:00
|
|
|
|
|
|
|
} else if (!strcasecmp(var, "base_media_port")) {
|
|
|
|
int base = atoi(val);
|
|
|
|
if (base >= 0) {
|
|
|
|
server.base_media_port = base;
|
|
|
|
server.next_media_port = base;
|
|
|
|
server.max_media_port = server.base_media_port + WOOMERA_MAX_MEDIA_PORTS;
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log, "Server - Base Media Port: %d\n",server.base_media_port);
|
2021-12-29 17:20:09 +00:00
|
|
|
}
|
2021-12-29 17:26:11 +00:00
|
|
|
|
|
|
|
} else if (!strcasecmp(var, "max_media_ports")) {
|
|
|
|
int max = atoi(val);
|
2021-12-29 17:29:00 +00:00
|
|
|
if (max >= 0) {
|
2021-12-29 17:26:11 +00:00
|
|
|
server.max_media_port = server.base_media_port+max;
|
2021-12-29 17:29:00 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log, "Server - Max Media Port: %d\n",server.max_media_port);
|
2021-12-29 17:26:11 +00:00
|
|
|
}
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
} else if (!strcasecmp(var, "media_ip")) {
|
|
|
|
strncpy(server.media_ip, val, sizeof(server.media_ip) -1);
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log, "Server - Media IP: %s\n",server.media_ip);
|
2021-12-29 17:29:00 +00:00
|
|
|
|
|
|
|
} else if (!strcasecmp(var, "bridge_tdm_ip")) {
|
|
|
|
int err=smg_get_ip_bridge_session(&ip_bridge);
|
|
|
|
if (err) {
|
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Error failed to get free ip bridge %i!\n",err);
|
|
|
|
} else {
|
|
|
|
log_printf(SMG_LOG_ALL,server.log, "\n======================= \n");
|
|
|
|
log_printf(SMG_LOG_ALL,server.log, "Bridge - Configuration \n");
|
|
|
|
log_printf(SMG_LOG_ALL,server.log, "======================= \n");
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if (!strcasecmp(var, "bridge_span")) {
|
|
|
|
int max = atoi(val);
|
|
|
|
if (max > 0 && max <= 32 && ip_bridge) {
|
|
|
|
ip_bridge->span=max;
|
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Bridge Span: %i\n",ip_bridge->span);
|
|
|
|
} else {
|
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Bridge Span: ERROR: Invalid Value %s\n",val);
|
|
|
|
}
|
|
|
|
} else if (!strcasecmp(var, "bridge_chan")) {
|
|
|
|
int max = atoi(val);
|
|
|
|
if (max > 0 && max < MAX_SMG_BRIDGE && ip_bridge) {
|
|
|
|
ip_bridge->chan=max;
|
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Bridge Chan: %i\n",ip_bridge->chan);
|
|
|
|
} else {
|
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Bridge Chan: ERROR: Invalid Value %s\n",val);
|
|
|
|
}
|
|
|
|
} else if (!strcasecmp(var, "bridge_local_ip")) {
|
|
|
|
if (ip_bridge) {
|
|
|
|
strncpy(ip_bridge->mcon.cfg.local_ip, val,
|
|
|
|
sizeof(ip_bridge->mcon.cfg.local_ip) -1);
|
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Bridge Local IP: %s\n",ip_bridge->mcon.cfg.local_ip);
|
|
|
|
}
|
|
|
|
} else if (!strcasecmp(var, "bridge_remote_ip")) {
|
|
|
|
if (ip_bridge) {
|
|
|
|
strncpy(ip_bridge->mcon.cfg.remote_ip, val,
|
|
|
|
sizeof(ip_bridge->mcon.cfg.remote_ip) -1);
|
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Bridge Remote IP: %s\n",ip_bridge->mcon.cfg.remote_ip);
|
|
|
|
}
|
|
|
|
} else if (!strcasecmp(var, "bridge_port")) {
|
|
|
|
int max = atoi(val);
|
|
|
|
if (max > 0 && ip_bridge) {
|
|
|
|
ip_bridge->mcon.cfg.local_port=max;
|
|
|
|
ip_bridge->mcon.cfg.remote_port=max;
|
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Bridge Port: %i\n",max);
|
|
|
|
}
|
|
|
|
} else if (!strcasecmp(var, "bridge_period")) {
|
|
|
|
int max = atoi(val);
|
|
|
|
if (max > 0 && ip_bridge) {
|
|
|
|
ip_bridge->period=max;
|
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Bridge Period: %ims\n",ip_bridge->period);
|
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
} else {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Invalid Option %s at line %d!\n", var, cfg.lineno);
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log, "======================= \n\n");
|
2021-12-29 17:26:11 +00:00
|
|
|
|
2021-12-29 17:12:33 +00:00
|
|
|
/* Post initialize */
|
|
|
|
if (server.dtmf_on == 0){
|
|
|
|
server.dtmf_on=SMG_DTMF_ON;
|
|
|
|
}
|
|
|
|
if (server.dtmf_off == 0) {
|
|
|
|
server.dtmf_off=SMG_DTMF_OFF;
|
|
|
|
}
|
|
|
|
if (server.dtmf_intr_ch == -1) {
|
2021-12-29 17:14:12 +00:00
|
|
|
server.dtmf_intr_ch = 0;
|
2021-12-29 17:12:33 +00:00
|
|
|
}
|
|
|
|
server.dtmf_size=(server.dtmf_on+server.dtmf_off)*10*2;
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL,server.log, "DTMF On=%i Off=%i IntrCh=%i Size=%i\n",
|
2021-12-29 17:12:33 +00:00
|
|
|
server.dtmf_on,server.dtmf_off,server.dtmf_intr_ch,server.dtmf_size);
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
woomera_close_file(&cfg);
|
|
|
|
return cnt == 4 ? 1 : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int main_thread(void)
|
|
|
|
{
|
|
|
|
|
|
|
|
struct sockaddr_in sock_addr, client_addr;
|
|
|
|
struct woomera_interface *new_woomera;
|
|
|
|
int client_sock = -1, pid = 0;
|
|
|
|
unsigned int len = 0;
|
|
|
|
FILE *tmp;
|
|
|
|
|
|
|
|
if ((server.master_connection.socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
|
2021-12-29 17:26:11 +00:00
|
|
|
fprintf(stderr,"%s:%d socket() failed %s\n",__FUNCTION__,__LINE__,strerror(errno));
|
|
|
|
return 1;
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
memset(&sock_addr, 0, sizeof(sock_addr)); /* Zero out structure */
|
|
|
|
sock_addr.sin_family = AF_INET; /* Internet address family */
|
|
|
|
sock_addr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */
|
|
|
|
sock_addr.sin_port = htons(server.port); /* Local port */
|
|
|
|
|
|
|
|
/* Bind to the local address */
|
|
|
|
if (bind(server.master_connection.socket, (struct sockaddr *) &sock_addr, sizeof(sock_addr)) < 0) {
|
2021-12-29 17:26:11 +00:00
|
|
|
fprintf(stderr,"%s:%d socket() bind %i failed %s\n",__FUNCTION__,__LINE__,server.port,strerror(errno));
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "bind(%d) failed\n", server.port);
|
2021-12-29 16:59:00 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Mark the socket so it will listen for incoming connections */
|
|
|
|
if (listen(server.master_connection.socket, MAXPENDING) < 0) {
|
2021-12-29 17:26:11 +00:00
|
|
|
fprintf(stderr,"%s:%d socket() listen failed %s\n",__FUNCTION__,__LINE__,strerror(errno));
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "listen() failed\n");
|
2021-12-29 17:26:11 +00:00
|
|
|
return 1;
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ((pid = get_pid_from_file(PIDFILE))) {
|
2021-12-29 17:26:11 +00:00
|
|
|
fprintf(stderr,"%s:%d get pid file failed %s\n",__FUNCTION__,__LINE__,strerror(errno));
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, stderr, "pid %d already exists.\n", pid);
|
2021-12-29 17:26:11 +00:00
|
|
|
exit(0);
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!(tmp = safe_fopen(PIDFILE, "w"))) {
|
2021-12-29 17:26:11 +00:00
|
|
|
fprintf(stderr,"%s:%d open pid file failed %s\n",__FUNCTION__,__LINE__,strerror(errno));
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, stderr, "Error creating pidfile %s\n", PIDFILE);
|
2021-12-29 17:26:11 +00:00
|
|
|
return 1;
|
2021-12-29 16:59:00 +00:00
|
|
|
} else {
|
2021-12-29 17:26:11 +00:00
|
|
|
fprintf(tmp, "%d", getpid());
|
|
|
|
fclose(tmp);
|
|
|
|
tmp = NULL;
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
no_nagle(server.master_connection.socket);
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
if (1) {
|
|
|
|
int span,chan;
|
|
|
|
call_signal_event_t event;
|
2021-12-29 17:03:04 +00:00
|
|
|
#if 0
|
|
|
|
span=1;
|
|
|
|
chan=30;
|
|
|
|
event.span=span;
|
|
|
|
event.chan=chan;
|
|
|
|
launch_woomera_loop_thread(&event);
|
|
|
|
#else
|
2021-12-29 16:59:00 +00:00
|
|
|
for (span=0;span<8;span++) {
|
|
|
|
for (chan=0;chan<31;chan++) {
|
|
|
|
event.span=span;
|
|
|
|
event.chan=chan;
|
|
|
|
launch_woomera_loop_thread(&event);
|
|
|
|
}
|
|
|
|
}
|
2021-12-29 17:03:04 +00:00
|
|
|
#endif
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
#endif
|
2021-12-29 17:03:04 +00:00
|
|
|
|
|
|
|
#ifdef WP_HPTDM_API
|
|
|
|
if (1) {
|
|
|
|
int span;
|
|
|
|
for (span=0;span<16;span++) {
|
|
|
|
hptdmspan[span] = sangoma_hptdm_api_span_init(span);
|
|
|
|
if (!hptdmspan[span]) {
|
|
|
|
break;
|
|
|
|
} else {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "HP TDM API Span: %d configured...\n",
|
2021-12-29 17:03:04 +00:00
|
|
|
span);
|
|
|
|
launch_hptdm_api_span_thread(span);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_PROD, server.log, "Main Process Started: Woomera Ready port: %d\n", server.port);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
while (woomera_test_flag(&server.master_connection, WFLAG_RUNNING) &&
|
|
|
|
woomera_test_flag(&server.master_connection, WFLAG_MONITOR_RUNNING)) {
|
|
|
|
|
|
|
|
/* Set the size of the in-out parameter */
|
|
|
|
len = sizeof(client_addr);
|
|
|
|
|
|
|
|
/* Wait for a client to connect */
|
|
|
|
if ((client_sock = accept(server.master_connection.socket, (struct sockaddr *) &client_addr, &len)) < 0) {
|
2021-12-29 17:26:11 +00:00
|
|
|
/* Check if we are supposed to stop */
|
|
|
|
if(!woomera_test_flag(&server.master_connection, WFLAG_RUNNING)) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "accept() stopped\n");
|
2021-12-29 17:26:11 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "accept() failed\n");
|
2021-12-29 16:59:00 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((new_woomera = new_woomera_interface(client_sock, &client_addr, len))) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_DEBUG_CALL, server.log, "Starting Thread for New Connection %s:%d Sock=%d\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
inet_ntoa(new_woomera->addr.sin_addr),
|
|
|
|
ntohs(new_woomera->addr.sin_port),
|
|
|
|
client_sock);
|
2021-12-29 17:22:11 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
pthread_mutex_lock(&server.thread_count_lock);
|
2021-12-29 16:59:00 +00:00
|
|
|
server.call_count++;
|
2021-12-29 17:26:11 +00:00
|
|
|
pthread_mutex_unlock(&server.thread_count_lock);
|
2021-12-29 17:22:11 +00:00
|
|
|
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
if (launch_woomera_thread(new_woomera)) {
|
2021-12-29 17:26:11 +00:00
|
|
|
socket_printf(new_woomera->socket,
|
2021-12-29 16:59:00 +00:00
|
|
|
"501 call was cancelled!%s",
|
|
|
|
WOOMERA_RECORD_SEPERATOR);
|
2021-12-29 17:26:11 +00:00
|
|
|
|
|
|
|
close_socket(&new_woomera->socket);
|
|
|
|
new_woomera->socket=-1;
|
|
|
|
smg_free(new_woomera);
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "ERROR: failed to launch woomera thread\n");
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
} else {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Critical ERROR: memory/socket error\n");
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_PROD, server.log, "Main Process End\n");
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int do_ignore(int sig)
|
2021-12-29 17:22:11 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
{
|
2021-12-29 17:22:11 +00:00
|
|
|
#ifdef SMG_DROP_SEQ
|
|
|
|
drop_seq=4;
|
|
|
|
#endif
|
2021-12-29 17:15:08 +00:00
|
|
|
sdla_memdbg_free(0);
|
|
|
|
return 0;
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int do_shut(int sig)
|
|
|
|
{
|
|
|
|
woomera_clear_flag(&server.master_connection, WFLAG_RUNNING);
|
|
|
|
close_socket(&server.master_connection.socket);
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_PROD, server.log, "Caught SIG %d, Closing Master Socket!\n", sig);
|
2021-12-29 16:59:00 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:12:33 +00:00
|
|
|
static int sangoma_tdm_init (int span)
|
2021-12-29 16:59:00 +00:00
|
|
|
{
|
|
|
|
#ifdef LIBSANGOMA_GET_HWCODING
|
|
|
|
wanpipe_tdm_api_t tdm_api;
|
2021-12-29 17:12:33 +00:00
|
|
|
int fd=sangoma_open_tdmapi_span(span);
|
2021-12-29 16:59:00 +00:00
|
|
|
if (fd < 0 ){
|
|
|
|
return -1;
|
|
|
|
} else {
|
|
|
|
server.hw_coding=sangoma_tdm_get_hw_coding(fd,&tdm_api);
|
|
|
|
close_socket(&fd);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
#error "libsangoma missing hwcoding feature: not up to date!"
|
|
|
|
#endif
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int woomera_startup(int argc, char **argv)
|
|
|
|
{
|
|
|
|
int x = 0, pid = 0, bg = 0;
|
2021-12-29 17:28:39 +00:00
|
|
|
int span_cnt, chan_cnt;
|
2021-12-29 16:59:00 +00:00
|
|
|
char *cfg=NULL, *debug=NULL, *arg=NULL;
|
|
|
|
|
|
|
|
while((arg = argv[x++])) {
|
|
|
|
|
|
|
|
if (!strcasecmp(arg, "-hup")) {
|
|
|
|
if (! (pid = get_pid_from_file(PIDFILE))) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, stderr, "Error reading pidfile %s\n", PIDFILE);
|
2021-12-29 16:59:00 +00:00
|
|
|
exit(1);
|
|
|
|
} else {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, stderr, "Killing PID %d\n", pid);
|
2021-12-29 16:59:00 +00:00
|
|
|
kill(pid, SIGHUP);
|
|
|
|
sleep(1);
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if (!strcasecmp(arg, "-term") || !strcasecmp(arg, "--term")) {
|
|
|
|
if (! (pid = get_pid_from_file(PIDFILE))) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, stderr, "Error reading pidfile %s\n", PIDFILE);
|
2021-12-29 16:59:00 +00:00
|
|
|
exit(1);
|
|
|
|
} else {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, stderr, "Killing PID %d\n", pid);
|
2021-12-29 16:59:00 +00:00
|
|
|
kill(pid, SIGTERM);
|
|
|
|
unlink(PIDFILE);
|
|
|
|
sleep(1);
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if (!strcasecmp(arg, "-version")) {
|
|
|
|
fprintf(stdout, "\nSangoma Media Gateway: Version %s\n\n", SMG_VERSION);
|
|
|
|
exit(0);
|
|
|
|
|
|
|
|
} else if (!strcasecmp(arg, "-help")) {
|
|
|
|
fprintf(stdout, "%s\n%s [-help] | [ -version] | [-hup] | [-wipe] | [[-bg] | [-debug <level>] | [-cfg <path>] | [-log <path>]]\n\n", WELCOME_TEXT, argv[0]);
|
|
|
|
exit(0);
|
|
|
|
} else if (!strcasecmp(arg, "-wipe")) {
|
|
|
|
unlink(PIDFILE);
|
|
|
|
} else if (!strcasecmp(arg, "-bg")) {
|
|
|
|
bg = 1;
|
|
|
|
|
|
|
|
} else if (!strcasecmp(arg, "-g")) {
|
|
|
|
coredump = 1;
|
|
|
|
|
|
|
|
} else if (!strcasecmp(arg, "-debug")) {
|
|
|
|
if (argv[x] && *(argv[x]) != '-') {
|
|
|
|
debug = argv[x++];
|
|
|
|
}
|
|
|
|
} else if (!strcasecmp(arg, "-cfg")) {
|
|
|
|
if (argv[x] && *(argv[x]) != '-') {
|
|
|
|
cfg = argv[x++];
|
|
|
|
}
|
|
|
|
} else if (!strcasecmp(arg, "-log")) {
|
|
|
|
if (argv[x] && *(argv[x]) != '-') {
|
2021-12-29 17:15:08 +00:00
|
|
|
server.logfile_path = smg_strdup(argv[x++]);
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
} else if (*arg == '-') {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, stderr, "Unknown Option %s\n", arg);
|
2021-12-29 16:59:00 +00:00
|
|
|
fprintf(stdout, "%s\n%s [-help] | [-hup] | [-wipe] | [[-bg] | [-debug <level>] | [-cfg <path>] | [-log <path>]]\n\n", WELCOME_TEXT, argv[0]);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:12:33 +00:00
|
|
|
if (1){
|
|
|
|
int spn;
|
|
|
|
for (spn=1;spn<=WOOMERA_MAX_SPAN;spn++) {
|
|
|
|
if (sangoma_tdm_init(spn) == 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (spn>WOOMERA_MAX_SPAN) {
|
|
|
|
printf("\nError: Failed to access a channel on spans 1-16\n");
|
|
|
|
printf(" Please start Wanpipe TDM API drivers\n");
|
2021-12-29 16:59:00 +00:00
|
|
|
return 0;
|
2021-12-29 17:12:33 +00:00
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (bg && (pid = fork())) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, stderr, "Backgrounding!\n");
|
2021-12-29 16:59:00 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:28:39 +00:00
|
|
|
for (span_cnt = 0; span_cnt < CORE_MAX_SPANS; span_cnt++) {
|
|
|
|
for (chan_cnt = 0; chan_cnt < CORE_MAX_CHAN_PER_SPAN; chan_cnt++) {
|
|
|
|
pthread_mutex_init(&server.process_table[span_cnt][chan_cnt].media_lock, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-29 17:12:33 +00:00
|
|
|
q931_cause_setup();
|
2021-12-29 17:26:11 +00:00
|
|
|
bearer_cap_setup();
|
|
|
|
uil1p_to_str_setup();
|
2021-12-29 17:12:33 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
server.port = 42420;
|
|
|
|
server.debug = 0;
|
|
|
|
strcpy(server.media_ip, "127.0.0.1");
|
2021-12-29 17:26:11 +00:00
|
|
|
server.base_media_port = WOOMERA_MIN_MEDIA_PORT;
|
|
|
|
server.max_media_port = WOOMERA_MAX_MEDIA_PORT;
|
|
|
|
server.next_media_port = server.base_media_port;
|
2021-12-29 16:59:00 +00:00
|
|
|
server.log = stdout;
|
|
|
|
server.master_connection.socket = -1;
|
|
|
|
server.master_connection.event_queue = NULL;
|
|
|
|
server.config_file = cfg ? cfg : "/etc/sangoma_mgd.conf";
|
|
|
|
pthread_mutex_init(&server.listen_lock, NULL);
|
|
|
|
pthread_mutex_init(&server.ht_lock, NULL);
|
|
|
|
pthread_mutex_init(&server.process_lock, NULL);
|
2021-12-29 17:22:11 +00:00
|
|
|
pthread_mutex_init(&server.digits_lock, NULL);
|
2021-12-29 16:59:00 +00:00
|
|
|
pthread_mutex_init(&server.media_udp_port_lock, NULL);
|
|
|
|
pthread_mutex_init(&server.thread_count_lock, NULL);
|
|
|
|
pthread_mutex_init(&server.master_connection.queue_lock, NULL);
|
|
|
|
pthread_mutex_init(&server.master_connection.flags_lock, NULL);
|
|
|
|
pthread_mutex_init(&server.mcon.lock, NULL);
|
|
|
|
server.master_connection.chan = -1;
|
|
|
|
server.master_connection.span = -1;
|
2021-12-29 17:26:11 +00:00
|
|
|
server.call_timeout=SMG_DEFAULT_CALL_TIMEOUT;
|
|
|
|
|
|
|
|
if (smg_log_init()) {
|
|
|
|
printf("Error: Logger Launch Failed\n");
|
|
|
|
fprintf(stderr, "Error: Logger Launch Failed\n");
|
|
|
|
return 0;
|
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
if (!configure_server()) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "configuration failed!\n");
|
2021-12-29 16:59:00 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef USE_SYSLOG
|
|
|
|
if (server.logfile_path) {
|
|
|
|
if (!(server.log = safe_fopen(server.logfile_path, "a"))) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, stderr, "Error setting logfile %s!\n", server.logfile_path);
|
2021-12-29 16:59:00 +00:00
|
|
|
server.log = stderr;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
if (debug) {
|
|
|
|
server.debug = atoi(debug);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (coredump) {
|
|
|
|
struct rlimit l;
|
|
|
|
memset(&l, 0, sizeof(l));
|
|
|
|
l.rlim_cur = RLIM_INFINITY;
|
|
|
|
l.rlim_max = RLIM_INFINITY;
|
|
|
|
if (setrlimit(RLIMIT_CORE, &l)) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, stderr, "Warning: Failed to disable core size limit: %s\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
strerror(errno));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef __LINUX__
|
|
|
|
if (geteuid() && coredump) {
|
|
|
|
if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, stderr, "Warning: Failed to disable core size limit for non-root: %s\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
strerror(errno));
|
2021-12-29 17:12:33 +00:00
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
(void) signal(SIGINT,(void *) do_shut);
|
|
|
|
(void) signal(SIGTERM,(void *) do_shut);
|
|
|
|
(void) signal(SIGPIPE,(void *) do_ignore);
|
|
|
|
(void) signal(SIGUSR1,(void *) do_ignore);
|
|
|
|
(void) signal(SIGHUP,(void *) do_shut);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
/* Wait for logger thread to start */
|
|
|
|
usleep(5000);
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
woomera_set_flag(&server.master_connection, WFLAG_RUNNING);
|
2021-12-29 17:29:00 +00:00
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
if (launch_monitor_thread()) {
|
|
|
|
woomera_clear_flag(&server.master_connection, WFLAG_RUNNING);
|
2021-12-29 17:29:00 +00:00
|
|
|
smg_log_cleanup();
|
|
|
|
return 0;
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fprintf(stderr, "%s", WELCOME_TEXT);
|
|
|
|
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, stderr, "Woomera STARTUP Complete. [AutoACM=%i SDigit=%i]\n",
|
2021-12-29 17:26:11 +00:00
|
|
|
autoacm,server.strip_cid_non_digits);
|
2021-12-29 16:59:00 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int woomera_shutdown(void)
|
|
|
|
{
|
|
|
|
char *event_string;
|
|
|
|
int told = 0, loops = 0;
|
2021-12-29 17:28:39 +00:00
|
|
|
int span_cnt, chan_cnt;
|
|
|
|
|
|
|
|
for (span_cnt = 0; span_cnt < CORE_MAX_SPANS; span_cnt++) {
|
|
|
|
for (chan_cnt = 0; chan_cnt < CORE_MAX_CHAN_PER_SPAN; chan_cnt++) {
|
|
|
|
pthread_mutex_destroy(&server.process_table[span_cnt][chan_cnt].media_lock);
|
|
|
|
}
|
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
close_socket(&server.master_connection.socket);
|
|
|
|
pthread_mutex_destroy(&server.listen_lock);
|
|
|
|
pthread_mutex_destroy(&server.ht_lock);
|
|
|
|
pthread_mutex_destroy(&server.process_lock);
|
2021-12-29 17:22:11 +00:00
|
|
|
pthread_mutex_destroy(&server.digits_lock);
|
2021-12-29 16:59:00 +00:00
|
|
|
pthread_mutex_destroy(&server.media_udp_port_lock);
|
|
|
|
pthread_mutex_destroy(&server.thread_count_lock);
|
|
|
|
pthread_mutex_destroy(&server.master_connection.queue_lock);
|
|
|
|
pthread_mutex_destroy(&server.master_connection.flags_lock);
|
|
|
|
pthread_mutex_destroy(&server.mcon.lock);
|
|
|
|
woomera_clear_flag(&server.master_connection, WFLAG_RUNNING);
|
|
|
|
|
|
|
|
|
|
|
|
if (server.logfile_path) {
|
2021-12-29 17:15:08 +00:00
|
|
|
smg_free(server.logfile_path);
|
2021-12-29 16:59:00 +00:00
|
|
|
server.logfile_path = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* delete queue */
|
|
|
|
while ((event_string = dequeue_event(&server.master_connection))) {
|
2021-12-29 17:15:08 +00:00
|
|
|
smg_free(event_string);
|
2021-12-29 17:26:11 +00:00
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
while(server.thread_count > 0) {
|
|
|
|
loops++;
|
|
|
|
|
|
|
|
if (loops % 1000 == 0) {
|
|
|
|
told = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (loops > 10000) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, server.log, "Red Alert! threads did not stop\n");
|
2021-12-29 16:59:00 +00:00
|
|
|
assert(server.thread_count == 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (told != server.thread_count) {
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_PROD, server.log, "Waiting For %d thread%s.\n",
|
2021-12-29 16:59:00 +00:00
|
|
|
server.thread_count, server.thread_count == 1 ? "" : "s");
|
|
|
|
told = server.thread_count;
|
|
|
|
}
|
|
|
|
ysleep(10000);
|
|
|
|
}
|
|
|
|
unlink(PIDFILE);
|
2021-12-29 17:27:14 +00:00
|
|
|
log_printf(SMG_LOG_ALL, stderr, "Woomera SHUTDOWN Complete.\n");
|
2021-12-29 17:26:11 +00:00
|
|
|
|
|
|
|
smg_log_cleanup();
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char *argv[])
|
|
|
|
{
|
|
|
|
int ret = 0;
|
2021-12-29 17:28:15 +00:00
|
|
|
|
|
|
|
memset(&server,0,sizeof(server));
|
|
|
|
memset(&woomera_dead_dev,0,sizeof(woomera_dead_dev));
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
mlockall(MCL_FUTURE);
|
2021-12-29 17:28:15 +00:00
|
|
|
memset(&server, 0, sizeof(server));
|
|
|
|
memset(&woomera_dead_dev, 0, sizeof(woomera_dead_dev));
|
2021-12-29 17:29:00 +00:00
|
|
|
memset(&g_smg_ip_bridge_idx,0, sizeof(g_smg_ip_bridge_idx));
|
|
|
|
|
2021-12-29 17:26:11 +00:00
|
|
|
ret=nice(-5);
|
|
|
|
|
2021-12-29 17:15:08 +00:00
|
|
|
sdla_memdbg_init();
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
server.hw_coding=0;
|
|
|
|
|
|
|
|
openlog (ps_progname ,LOG_PID, LOG_LOCAL2);
|
|
|
|
|
|
|
|
if (! (ret = woomera_startup(argc, argv))) {
|
2021-12-29 17:29:00 +00:00
|
|
|
exit(0);
|
2021-12-29 16:59:00 +00:00
|
|
|
}
|
2021-12-29 17:29:00 +00:00
|
|
|
|
|
|
|
ret = smg_ip_bridge_start();
|
|
|
|
if (ret == 0) {
|
|
|
|
ret = main_thread();
|
|
|
|
}
|
2021-12-29 16:59:00 +00:00
|
|
|
|
|
|
|
woomera_shutdown();
|
|
|
|
|
2021-12-29 17:29:00 +00:00
|
|
|
smg_ip_bridge_stop();
|
2021-12-29 17:15:08 +00:00
|
|
|
sdla_memdbg_free(1);
|
|
|
|
|
2021-12-29 16:59:00 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** EMACS **
|
|
|
|
* Local variables:
|
|
|
|
* mode: C
|
|
|
|
* c-basic-offset: 4
|
|
|
|
* End:
|
|
|
|
*/
|
|
|
|
|