diff --git a/.git_info b/.git_info index ae77c6f..7b6c6d1 100644 --- a/.git_info +++ b/.git_info @@ -1,2 +1,2 @@ -wanpipe_linux: git ver a630c90 -wanpipe_common: git ver b7dfcf2 +wanpipe_linux: git ver 58560a0 +wanpipe_common: git ver 81099cc diff --git a/.router_version b/.router_version index bcd30d9..65942cd 100644 --- a/.router_version +++ b/.router_version @@ -1 +1 @@ -wanpipe-7.0.1 +wanpipe-7.0.2 diff --git a/ChangeLog b/ChangeLog index 315a406..c7d04b8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,23 @@ Copyright (c) 1995-2013 Sangoma Technologies Inc. For more info visit: http://wiki.sangoma.com ------------------------------------------------------------------------------ +* Fri May 10 2013 Nenad Corbic - 7.0.2 +================================================================== + +- Added sync error statistic in wanpipeomon Ta command + Sync error indicates clocking or synchronizatio errors + on T1/E1 lines. Provides added statistic to debug line, + slip errors on T1/E1. + +- Fixed DAHDI reconfiguration issues. + running dahdi_cfg multiple times will not bring down T1/E1 link + Added config option to change clocking from MASTER to NORMAL + from dahdi system.conf + +- New sample_data_tapping sample application for T116 and other + tapping boards. + + * Tue Mar 19 2013 Nenad Corbic - 7.0.1 ================================================================== diff --git a/Setup b/Setup index 39eb062..31e0e67 100755 --- a/Setup +++ b/Setup @@ -7338,7 +7338,7 @@ KERNEL_UNAME=`uname -r` PKG_NAME=wanpipe DISTR_NAME="WANPIPE" PROD=wanrouter -PROD_VER=7.0.1 +PROD_VER=7.0.2 PROD_HOME=`pwd` META_CONF=$PROD_HOME/$PROD.rc WAN_INTR_DIR=$PROD_HOME/interfaces diff --git a/api/libsangoma/examples/sample_data_tapping/ChannelizedBuffer.h b/api/libsangoma/examples/sample_data_tapping/ChannelizedBuffer.h deleted file mode 100644 index 5cc8618..0000000 --- a/api/libsangoma/examples/sample_data_tapping/ChannelizedBuffer.h +++ /dev/null @@ -1,37 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \file ChannelizedBuffer.h -/// \brief This file contains the definition of the ChannelizedBuffer class. This class provides -/// a set of dedicated buffers (1 survey, 8 data) for up to 32 timeslots of raw E1 or -/// T1 data. -/////////////////////////////////////////////////////////////////////////////////////////////// -#ifndef _CHANNELIZED_BUFFER_H -#define _CHANNELIZED_BUFFER_H - -#include - -typedef enum {UNSURVEYED_FRAMING=0, E1_FRAMING=32, T1_FRAMING=24} E1OrT1Framing; ///< Type of port (i.e., E1 or T1). This can also be used as the frame size - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \class ChannelizedBuffer -/// \brief This class provides a set of dedicated buffers (1 survey, 8 data) for up -/// to 32 timeslots of raw E1 or T1 data. It accepts data inserted from a L1 -/// source. The first data byte must be timeslot 0 for this routine to work -/// correctly. -/// \author Josh Markwordt -/// \date 07/22/2005 -/////////////////////////////////////////////////////////////////////////////////////////////// -class ChannelizedBuffer -{ -public: - explicit ChannelizedBuffer(const unsigned int buffer_size); ///< Constructor - ChannelizedBuffer(const ChannelizedBuffer &other); ///< Copy Constructor - ~ChannelizedBuffer(); ///< Destructor - void Reset(const bool clear_buffers); ///< Resets the buffers so that data will be inserted at the beginning - - void InsertAndChannelizeFramedData(unsigned char *p_source_buf, const unsigned int num_bytes_to_insert, const E1OrT1Framing frame_size) - { - - } -}; - -#endif //_CHANNELIZED_BUFFER_H diff --git a/api/libsangoma/examples/sample_data_tapping/Makefile b/api/libsangoma/examples/sample_data_tapping/Makefile index 8ad438f..591e34a 100755 --- a/api/libsangoma/examples/sample_data_tapping/Makefile +++ b/api/libsangoma/examples/sample_data_tapping/Makefile @@ -10,27 +10,32 @@ OS_TYPE = __LINUX__ DEBUG = 2 -LINK_ARGS= -lcurses -lpthread +LINK_ARGS= -lcurses -lpthread -LSangoma/Code/Sangoma -lSangoma # Tools options. -CFLAGS = -Wall -g -O0 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ -CFLAGS += -I. -I/usr/include/wanpipe -I/usr/include -CFLAGS += $(EXTRA_FLAGS) -D__LINUX__ -CFLAGS += -D_REENTRANT -D_GNU_SOURCE +CFLAGS = -Wall -g -O0 -D$(OS_TYPE) -D_DEBUG_=$(DEBUG) -D_GNUC_ +CFLAGS += -I. -ISangoma/Code -ISangoma/Code/Sangoma -I../../ -I../../../../patches/kdrivers/include -I../../wanec -I../../../../patches/kdrivers/wanec -I../../../../patches/kdrivers/wanec/oct6100_api/include +CFLAGS += -I/usr/include/wanpipe +CFLAGS += $(EXTRA_FLAGS) -D__LINUX__ -DLINUX +CFLAGS += -D_REENTRANT -D_GNU_SOURCE CXX=g++ TARGETS=sample_data_tapping -LIBS= driver_configurator.cpp PortBuffer.cpp SangomaCard.cpp SangomaPort.cpp sangoma_interface.cpp - +LIBS= ####### RULES ################################################################ + #make -C Sangoma/Code/Sangoma -all: $(TARGETS) +all: pre_build $(TARGETS) @echo "Ok." +pre_build: + make -f Makefile.Linux -C Sangoma/Code/Sangoma + sample_data_tapping: sample_data_tapping.cpp $(LIBS) $(LIBS_STEL) $(LIBS_TONE) - $(CXX) $(CFLAGS) -o $@ $^ $(LINK_ARGS) -lsangoma -lstelephony -lm + $(CXX) $(CFLAGS) -o $@ $^ $(LINK_ARGS) clean: rm -f $(TARGETS) + make -f Makefile.Linux -C Sangoma/Code/Sangoma clean diff --git a/api/libsangoma/examples/sample_data_tapping/PortBuffer.cpp b/api/libsangoma/examples/sample_data_tapping/PortBuffer.cpp deleted file mode 100644 index cd6f649..0000000 --- a/api/libsangoma/examples/sample_data_tapping/PortBuffer.cpp +++ /dev/null @@ -1,102 +0,0 @@ - -#include "PortBuffer.h" - -#define ERR_PORT_BUFFER printf("Error:%s():line:%d: ", __FUNCTION__, __LINE__);printf - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \class PortBuffer -/// \brief Structure containing a buffer for the port to read from or write to. The -/// size of buffer is indicated so that it can be allocated dynamically -/// \author David Rokhvarg (davidr@sangoma.com) -/// \date 11/13/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -PortBuffer::PortBuffer(unsigned int size) -{ - BufferSize = size; - Buffer = (unsigned char*)malloc(size); - - memset(&ApiHeader, 0x00, sizeof(ApiHeader)); -} - -PortBuffer::~PortBuffer() -{ - free(Buffer); -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn PortBuffer::PortBuffer() -/// \brief Returns pointer to Buffer. -/// \return pointer to Buffer. -/// \author David Rokhvarg (davidr@sangoma.com) -/// \date 11/15/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -unsigned char *PortBuffer::GetPortBuffer() -{ - return Buffer; -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn PortBuffer::PortBuffer() -/// \brief Returns the total Buffer size. -/// \return Buffer size. -/// \author David Rokhvarg (davidr@sangoma.com) -/// \date 11/15/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -unsigned int PortBuffer::GetPortBufferSize() -{ - return BufferSize; -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn PortBuffer::GetUserDataBuffer() -/// \brief Returns pointer to buffer containng user data. -/// When data is recieved, this buffer will hold rx data. -/// When data is transmitted, this buffer should contain tx data before Write() is called. -/// \return pointer to buffer containing user data. -/// \author David Rokhvarg (davidr@sangoma.com) -/// \date 11/15/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -unsigned char *PortBuffer::GetUserDataBuffer() -{ - return GetPortBuffer(); -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn PortBuffer::GetMaximumUserDataBufferSize() -/// \brief Returns maximum size of user data buffer. This is the maximum length of user data -/// which can be transmitted/received in one buffer. -/// \return maximum size of user data buffer. -/// \author David Rokhvarg (davidr@sangoma.com) -/// \date 11/15/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -unsigned int PortBuffer::GetMaximumUserDataBufferSize() -{ - return GetPortBufferSize(); -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn PortBuffer::GetUserDataLength() -/// \brief Returns current length of user data at DataBuffer. -/// When data is recieved, GetUserDataLength() will return length of rx data. -/// \return current length of user data at DataBuffer.. -/// \author David Rokhvarg (davidr@sangoma.com) -/// \date 11/15/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -unsigned int PortBuffer::GetUserDataLength() -{ - return ApiHeader.data_length; -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn PortBuffer::SetUserDataLength() -/// \brief Set length of user data at DataBuffer. -/// When data is transmitted, SetUserDataLength() will indicate to Sangoma API how many -/// should be transmitted. -/// \return there is no return value. -/// \author David Rokhvarg (davidr@sangoma.com) -/// \date 11/15/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -void PortBuffer::SetUserDataLength(unsigned int user_data_length) -{ - ApiHeader.data_length = user_data_length; -} diff --git a/api/libsangoma/examples/sample_data_tapping/PortBuffer.h b/api/libsangoma/examples/sample_data_tapping/PortBuffer.h deleted file mode 100644 index 2010119..0000000 --- a/api/libsangoma/examples/sample_data_tapping/PortBuffer.h +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef _PORT_BUFFER_H -#define _PORT_BUFFER_H - -#include "sangoma_interface.h" - -#include -#include - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \class PortBuffer -/// \brief Structure containing a buffer for the port to read from or write to. The -/// size of buffer is indicated so that it can be allocated dynamically -/// \author David Rokhvarg (davidr@sangoma.com) -/// \date 11/13/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -class PortBuffer { - unsigned char *Buffer; ///< Pointer to dynamically allocated buffer of BufferSize size. - unsigned int BufferSize; ///< The size of the unsigned char buffer that was allocated at Buffer. - - wp_api_hdr_t ApiHeader; ///< Will store the size of the Rx/Tx DATA at DataBuffer coming To/From User. - -public: - PortBuffer(unsigned int size); - ~PortBuffer(void); - - /////////////////////////////////////////////////////////////////////////////////////////////// - /// \fn PortBuffer::PortBuffer() - /// \brief Returns pointer to Buffer. - /// \return pointer to Buffer. - /// \author David Rokhvarg (davidr@sangoma.com) - /// \date 11/15/2007 - /////////////////////////////////////////////////////////////////////////////////////////////// - unsigned char *GetPortBuffer(); - - /////////////////////////////////////////////////////////////////////////////////////////////// - /// \fn PortBuffer::GetPortBufferSize() - /// \brief Returns the total Buffer size. - /// \return Buffer size. - /// \author David Rokhvarg (davidr@sangoma.com) - /// \date 11/15/2007 - /////////////////////////////////////////////////////////////////////////////////////////////// - unsigned int GetPortBufferSize(); - - /////////////////////////////////////////////////////////////////////////////////////////////// - /// \fn PortBuffer::GetUserDataBuffer() - /// \brief Returns pointer to buffer containng user data. - /// When data is recieved, this buffer will hold rx data. - /// When data is transmitted, this buffer should contain tx data before Write() is called. - /// \return pointer to buffer containing user data. - /// \author David Rokhvarg (davidr@sangoma.com) - /// \date 11/15/2007 - /////////////////////////////////////////////////////////////////////////////////////////////// - unsigned char *GetUserDataBuffer(); - - /////////////////////////////////////////////////////////////////////////////////////////////// - /// \fn PortBuffer::GetUserDataLength() - /// \brief Returns current length of user data at UserDataBuffer. - /// When data is recieved, GetUserDataLength() will return length of rx data. - /// \return current length of user data at UserDataBuffer.. - /// \author David Rokhvarg (davidr@sangoma.com) - /// \date 11/15/2007 - /////////////////////////////////////////////////////////////////////////////////////////////// - unsigned int GetUserDataLength(); - - /////////////////////////////////////////////////////////////////////////////////////////////// - /// \fn PortBuffer::SetUserDataLength() - /// \brief Set lenght of user data at UserDataBuffer. - /// When data is transmitted, SetUserDataLength() will indicate to Sangoma API how many - /// should be transmitted. - /// \return there is no return value. - /// \author David Rokhvarg (davidr@sangoma.com) - /// \date 11/15/2007 - /////////////////////////////////////////////////////////////////////////////////////////////// - void SetUserDataLength(unsigned int user_data_length); - - /////////////////////////////////////////////////////////////////////////////////////////////// - /// \fn PortBuffer::GetMaximumUserDataBufferSize() - /// \brief Returns maximum size of user data buffer. This is the maximum length of user data - /// which can be transmitted/received in one buffer. - /// \return maximum size of user data buffer. - /// \author David Rokhvarg (davidr@sangoma.com) - /// \date 11/15/2007 - /////////////////////////////////////////////////////////////////////////////////////////////// - unsigned int GetMaximumUserDataBufferSize(); -}; - -#endif //_PORT_BUFFER_H diff --git a/api/libsangoma/examples/sample_data_tapping/SangomaCard.cpp b/api/libsangoma/examples/sample_data_tapping/SangomaCard.cpp deleted file mode 100644 index b2fe007..0000000 --- a/api/libsangoma/examples/sample_data_tapping/SangomaCard.cpp +++ /dev/null @@ -1,397 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \file SangomaCard.cpp -/// \brief This file contains the implementation of the SangomaCard class -/////////////////////////////////////////////////////////////////////////////////////////////// -#if defined(__WINDOWS__) -# ifndef _DEBUG -# pragma optimize("2gt",on) // Windows specific (MS_SPECIFIC), enables optimization in Release mode -# endif -#endif - -#include "SangomaCard.h" -#include - -using namespace Sangoma; - -#include "driver_configurator.h" - - -#define DBG_CARD if(0)printf -#define INFO_CARD if(0)printf -#define FUNC_TRACE() DBG_CARD("%s(): Line: %u\n", __FUNCTION__, __LINE__) -//This macro is for Error reporting and should NOT be disabled. -#define ERR_CARD printf("Error:%s():line:%d: ", __FUNCTION__, __LINE__);printf - -//these arrays is initialized by GetNumberOfCardsInstalled() -static wanpipe_instance_info_t a104_wanpipe_info_array[MAX_CARDS]; -static wanpipe_instance_info_t a108_wanpipe_info_array[MAX_CARDS]; -static wanpipe_instance_info_t a116_wanpipe_info_array[MAX_CARDS]; -static wanpipe_instance_info_t t116_wanpipe_info_array[MAX_CARDS]; - - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn unsigned int GetNumberOfCardsInstalled(const CardModel model) -/// \brief Returns the number of Sangoma cards of the model provided for this system. It is -/// possible for there to be a mixture of A104 and A108, and so the number of each can -/// be requested by changing the CardModel provided. -/// \param model CardModel for which we want to retrieve the number of cards installed -/// \return unsigned int number of cards of the CardModel provided -/// \author J. Markwordt -/// \date 10/08/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -unsigned int GetNumberOfCardsInstalled(const CardModel model) -{ - unsigned int number_of_card_model = 0; - driver_configurator *drv_cfg_obj; - - /// Perform operations to get the number of Sangoma cards of the model provided in the system - drv_cfg_obj = new driver_configurator(); - switch(model) - { - case A104: - number_of_card_model = drv_cfg_obj->scan_for_sangoma_cards(a104_wanpipe_info_array, A104_ADPTR_4TE1); - break; - - case A108: - number_of_card_model = drv_cfg_obj->scan_for_sangoma_cards(a108_wanpipe_info_array, A108_ADPTR_8TE1); - break; - - case A116: - number_of_card_model = drv_cfg_obj->scan_for_sangoma_cards(a116_wanpipe_info_array, A116_ADPTR_16TE1); - break; - - case T116: - number_of_card_model = drv_cfg_obj->scan_for_sangoma_cards(t116_wanpipe_info_array, AFT_ADPTR_T116); - break; - - default: - number_of_card_model = 0; - break; - } - - delete drv_cfg_obj; - return number_of_card_model; -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn SangomaCard::SangomaCard(const unsigned int card_number, const CardModel model, -/// const BufferSettings & ReceiveBufferSettings, const BufferSettings & TransmitBufferSettings) -/// \brief Constructor -/// \param card_number const unsigned int of the number of this card (zero indexed) -/// \param model const CardModel of the type of Sangoma card this object is to -/// represent (A104 or A108) -/// \param ReceiveBufferSettings BufferSettings to configure the host memory buffers -/// for receive operations on this port (set NumberOfBuffersPerPort -/// to 0 to disable receiving data on this port) -/// \param TransmitBufferSettings BufferSettings to configure the host memory buffers -/// for transmit operations on this port (set NumberOfBuffersPerPort -/// to 0 to disable transmitting data on this port) -/// \author J. Markwordt -/// \date 10/04/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -SangomaCard::SangomaCard(const unsigned int card_number, const CardModel model, - const BufferSettings & ReceiveBufferSettings, const BufferSettings & TransmitBufferSettings) -: CardNumber(card_number), -Model(model), // Set the card model to that provided -NumberOfPorts(NUMBER_OF_A104_PORTS), // Initialize to A104, but will be reset in the body of the constructor -Ports(), -LastError(NO_ERROR_OCCURRED) -{ - FUNC_TRACE(); - wanpipe_instance_info_t *wanpipe_instance_info; - - switch (model) { - case A104: - wanpipe_instance_info = a104_wanpipe_info_array; - break; - case A108: - wanpipe_instance_info = a108_wanpipe_info_array; - break; - case A116: - wanpipe_instance_info = a116_wanpipe_info_array; - break; - case T116: - wanpipe_instance_info = t116_wanpipe_info_array; - break; - } - - if(MAX_CARDS <= card_number){ - ERR_CARD("%s(): invalid 'card_number' %u!!\n", __FUNCTION__, card_number); - return; - } - - // The number of ports was initialized above for the A104, - // so only change it if A108 was the model that was actually provided. - if (A108 == model) { - NumberOfPorts = NUMBER_OF_A108_PORTS; - } - if (A116 == model) { - NumberOfPorts = NUMBER_OF_A116_PORTS; - } - if (T116 == model) { - NumberOfPorts = NUMBER_OF_T116_PORTS; - } - - DBG_CARD("%s(): wanpipe_instance_info: 0x%p\n", __FUNCTION__, wanpipe_instance_info); - - // Create the number of ports required for this card's - // model type and add them to the Ports vector. - for (unsigned int port = 0; port < NumberOfPorts; port++) { - - Ports.push_back(new SangomaPort(wanpipe_instance_info[CardNumber].wanpipe_number, port, - ReceiveBufferSettings, TransmitBufferSettings)); - } -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn SangomaCard::~SangomaCard() -/// \brief Destructor -/// \author J. Markwordt -/// \date 10/04/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -SangomaCard::~SangomaCard() -{ - // Delete the all of the ports created for this card's - // model type and then clear the Ports vector - for (unsigned int port = 0; port < NumberOfPorts; ++port) { - delete Ports.at(port); - } - Ports.clear(); -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn unsigned int SangomaCard::GetCardNumber() const -/// \brief Returns the card number of this Sangoma card (zero indexed) -/// \return unsigned int card number of this card -/// \author J. Markwordt -/// \date 10/04/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -unsigned int SangomaCard::GetCardNumber() const -{ - return CardNumber; -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn CardModel SangomaCard::GetModel() const -/// \brief Returns the model of Sangoma card that this object represents (A104 or A108) -/// \return CardModel of this SangomaCard -/// \author J. Markwordt -/// \date 10/04/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -CardModel SangomaCard::GetModel() const -{ - return Model; -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn unsigned int SangomaCard::GetNumberOfPorts() const -/// \brief Returns the number of ports in this card -/// \return unsigned int number of ports in this card -/// \author J. Markwordt -/// \date 10/04/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -unsigned int SangomaCard::GetNumberOfPorts() const -{ - return NumberOfPorts; -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn SangomaCard::GetPort(const unsigned int port_number) -/// \brief Returns a pointer to the port requested -/// \return SangomaPort* to the port requested -/// \author J. Markwordt -/// \date 10/04/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -SangomaPort* SangomaCard::GetPort(const unsigned int port_number) -{ - // Check to make make sure the port_number requested is valid - bool valid_port_number = (NumberOfPorts > port_number); - if (!valid_port_number) { - std::ostringstream error_msg; - error_msg << "ERROR: SangomaCard::GetPort() called on invalid port number " << port_number << "."; - LastError = error_msg.str(); - return NULL; - } - - // Port number is valid, so indicate that no error occured on this operation - LastError = NO_ERROR_OCCURRED; - - // If valid, return the pointer to the SangomaPort at that position - return Ports.at(port_number); -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn SangomaCard::GetCardDriverVersion() -/// \brief Returns the card's driver version number. Sangoma has given the card a driver and -/// the port what Sangoma refers to as a "Hardware Abstraction Driver", and although -/// these two should have the same version number IF INSTALLED PROPERLY, they are in -/// fact two separate drivers. -/// -/// This function is to retrieve the driver associated with the card as a whole and -/// can be used to verify that it matches the version number of the ports' hardware -/// abstraction drivers. -/// \return DriverVersion structure containing the driver version information for this card -/// \author J. Markwordt -/// \date 10/04/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -DriverVersion SangomaCard::GetCardDriverVersion() -{ - DriverVersion card_driver_version; - - /// Perform low level calls to retrieve the driver version from the card - SangomaPort *p_port = GetPort(0); - if(p_port != NULL){ - card_driver_version.Major = p_port->GetDriverVersion().Major; - card_driver_version.Build = p_port->GetDriverVersion().Build; - card_driver_version.Minor = p_port->GetDriverVersion().Minor; - card_driver_version.Revision = p_port->GetDriverVersion().Revision; - DBG_CARD("%s(): card_driver_version: %i.%i.%i.%i\n", __FUNCTION__, card_driver_version.Major, - card_driver_version.Minor, card_driver_version.Build, card_driver_version.Revision); - } - return card_driver_version; -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn SangomaCard::GetSerialNumber() const -/// \brief Returns the card's serial number -/// \return std::string containing the card's serial number -/// \author J. Markwordt -/// \date 10/04/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -std::string SangomaCard::GetSerialNumber() const -{ - std::string serial_number; - /// \todo Perform low level calls to retrieve the serial number for the card - //DAVIDR: there is no way to know card serial number. - return serial_number; -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn SangomaCard::GetFirmwareVersion() const -/// \brief Returns the card's firmware version -/// \return std::string containing the card's firmware version -/// \author J. Markwordt -/// \date 10/04/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -std::string SangomaCard::GetFirmwareVersion() const -{ - std::string firmware_version; - wanpipe_instance_info_t *WanpipeInstanceInfo = NULL; - - /// Perform low level calls to retrieve the firmware version number for the card - switch(GetModel()) - { - case A104: - WanpipeInstanceInfo = a104_wanpipe_info_array; - break; - case A108: - WanpipeInstanceInfo = a108_wanpipe_info_array; - break; - case A116: - WanpipeInstanceInfo = a116_wanpipe_info_array; - break; - case T116: - WanpipeInstanceInfo = t116_wanpipe_info_array; - break; - } - - firmware_version = "0000"; - if(WanpipeInstanceInfo){ - sprintf((char*)firmware_version.c_str(), "%X", - WanpipeInstanceInfo[GetCardNumber()].hardware_info.firmware_version); - DBG_CARD("%s(): card firmware version: %s\n", __FUNCTION__, firmware_version.c_str()); - } - return firmware_version; -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn SangomaCard::GetCardPciBus() const -/// \brief Returns the number of the PCI bus that the card is located in -/// \return unsigned int number of the PCI bus that the card is located in -/// \author J. Markwordt -/// \date 10/04/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -unsigned int SangomaCard::GetCardPciBus() const -{ - unsigned int pci_bus_number = 0; - wanpipe_instance_info_t *WanpipeInstanceInfo = NULL; - - /// Perform low level calls to retrieve the number of the PCI bus that the card is located in - switch(GetModel()) - { - case A104: - WanpipeInstanceInfo = a104_wanpipe_info_array; - break; - case A108: - WanpipeInstanceInfo = a108_wanpipe_info_array; - break; - case A116: - WanpipeInstanceInfo = a116_wanpipe_info_array; - break; - case T116: - WanpipeInstanceInfo = t116_wanpipe_info_array; - break; - } - - if(WanpipeInstanceInfo){ - pci_bus_number = WanpipeInstanceInfo[GetCardNumber()].hardware_info.pci_bus_number; - DBG_CARD("%s(): card pci_bus_number: %i\n", __FUNCTION__, pci_bus_number); - } - return pci_bus_number; -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn SangomaCard::GetCardPciSlot() const -/// \brief Returns the number of the PCI slot that the card is located in -/// \return unsigned int number of the PCI slot that the card is located in -/// \author J. Markwordt -/// \date 10/10/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -unsigned int SangomaCard::GetCardPciSlot() const -{ - unsigned int pci_bus_slot = 0; - wanpipe_instance_info_t *WanpipeInstanceInfo = NULL; - - /// Perform low level calls to retrieve the number of the PCI slot that the card is located in - switch(GetModel()) - { - case A104: - WanpipeInstanceInfo = a104_wanpipe_info_array; - break; - case A108: - WanpipeInstanceInfo = a108_wanpipe_info_array; - break; - case A116: - WanpipeInstanceInfo = a116_wanpipe_info_array; - break; - case T116: - WanpipeInstanceInfo = t116_wanpipe_info_array; - break; - } - - if(WanpipeInstanceInfo){ - pci_bus_slot = WanpipeInstanceInfo[GetCardNumber()].hardware_info.pci_slot_number; - DBG_CARD("%s(): card pci_bus_slot: %i\n", __FUNCTION__, pci_bus_slot); - } - return pci_bus_slot; -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn SangomaCard::GetLastError() const -/// \brief Returns a description of the last error that occurred -/// \return Returns a description of the last error that occurred (NO_ERROR_OCCURRED if the last command was successful) -/// \author J. Markwordt -/// \date 10/17/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -std::string SangomaCard::GetLastError() const -{ - return LastError; -} - - -#if defined(__WINDOWS__) -# ifndef _DEBUG -# pragma optimize("2gt",off)// Windows specific (MS_SPECIFIC), disables optimization in Release mode -# endif -#endif - diff --git a/api/libsangoma/examples/sample_data_tapping/SangomaCard.h b/api/libsangoma/examples/sample_data_tapping/SangomaCard.h deleted file mode 100644 index 692fb33..0000000 --- a/api/libsangoma/examples/sample_data_tapping/SangomaCard.h +++ /dev/null @@ -1,144 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \mainpage Sangoma API Design Document -/// -/// \section overview Overview -/// -/// The Sangoma API defines several C++ classes that provide an interface to perform commands -/// on the Sangoma A104 and A108 E1/T1 cards. Each physical PCI card is represented by a -/// \link Sangoma::SangomaCard \endlink object which contains the appropriate number of \link Sangoma::SangomaPort \endlink -/// objects to encapsulate their behaviour. -/// -/// The Sangoma API will transfer data read from the physical port to host memory using Direct -/// Memory Access (DMA), filling a series of buffers and then raising an event to alert calling -/// programs that data is available to be read. By eliminating polling for data, this will -/// improve efficiency. -/// -/// \subsection card_object SangomaCard -/// A SangomaCard object represents a physical Sangoma A104 or A108 PCI E1/T1 card containing -/// 4 or 8 E1/T1 ports respectively. The relationship between SangomaCard and SangomaPorts can -/// be seen below for the Sangoma A104: -/// -/// \image html SangomaA104Overview.jpg -/// -/// and for the Sangoma A108: -/// -/// \image html SangomaA108Overview.jpg -/// -/// Any behaviour which occurs at the card level and access to the SangomaPort objects (which do -/// most of the actual work) are controlled through this class. -/// -/// \subsection port_object SangomaPort -/// A SangomaPort represents a physical E1/T1 port and encapsulates the ability to set the -/// configuration of the port, read, write and retrieve hardware alarms and statistics. Note -/// that since multiple E1/T1 lines are multiplexed into a single physical port on the Sangoma -/// A108, there will be two SangomaPort objects for each physical port of the A108 (as seen in the -/// figure above). -/// -/// SangomaPorts can be accessed through SangomaCard::GetPort() and then manipulated directly. -/// -/// \subsection port_buffers SangomaPort Buffers -/// Each SangomaPort contains software buffers to store data read from the physical card. -/// Buffers are allocated as multiples of 8188 bytes (8188 bytes is the size of the Sangoma -/// card’s hardware buffer. The software buffers use the same size to simplify the processing.). -/// Therefore the size of a single buffer will be set by the BufferMultiplierFactor, such that the -/// size of a buffer is 8188 * BufferMultiplierFactor bytes. SangomaPorts can have multiple buffers. -/// The number of buffers is controlled by NumberOfBuffersPerPort. -/// -/// When a buffer becomes full the ReadDataAvailable event is signaled to indicate data is -/// available for retrieval. Note that a full buffer does not necessarily use the fully -/// allocated size. It always contains full E1 (32 bytes) or T1 (24 bytes) frames. Therefore -/// a small portion at the end of each buffer may be left unused. -/// -/// The diagram below provides an example of the buffers contained in a SangomaPort. -/// -/// \image html SangomaPortBuffers.jpg -/// -/// To store data the SangomaPort will cycle through its buffers in a circular fashion so that when the -/// current buffer becomes full data can be stored in the next buffer while the previous one -/// is waiting to be read. The diagram below shows how the buffers will be used within the -/// SangomaPort. -/// -/// \image html SangomaPortBuffersCycle.jpg -/////////////////////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \file SangomaCard.h -/// \brief This file contains the declaration of the SangomaCard class -/////////////////////////////////////////////////////////////////////////////////////////////// -#ifndef _SANGOMA_CARD_H -#define _SANGOMA_CARD_H - -#include -#include -#include "SangomaPort.h" - -const unsigned int NUMBER_OF_A104_PORTS = 4; ///< The number of ports in a Sangoma A104 card -const unsigned int NUMBER_OF_A108_PORTS = 8; ///< The number of ports in a Sangoma A108 card -const unsigned int NUMBER_OF_A116_PORTS = 8; ///< The number of ports in a Sangoma A108 card -const unsigned int NUMBER_OF_T116_PORTS = 16; ///< The number of ports in a Sangoma T116 card - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \enum CardModel -/// \brief Enumeration indicating the model of Sangoma card that this SangomaCard is -/////////////////////////////////////////////////////////////////////////////////////////////// -enum CardModel { - A104, ///< Indicates the Sangoma A104 card model - A108, ///< Indicates the Sangoma A108 card model - A116, ///< Indicates the Sangoma A108 card model - T116 -}; - -unsigned int GetNumberOfCardsInstalled(const CardModel model); ///< Checks for the number of cards of the model type provided are installed - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \namespace Sangoma -/// \brief The Sangoma namespace is used to wrap all Sangoma classes to identify them as a -/// package and to allow simple names for structures, constants, enums and other -/// identifiers without having to worry about creating naming conflicts with other -/// packages. -/////////////////////////////////////////////////////////////////////////////////////////////// -namespace Sangoma { - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \class SangomaCard -/// \brief This class encapsulates the functionality of a physical Sangoma card (models A104 -/// or A108). -/// \author J. Markwordt -/// \date 10/03/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -class SangomaCard { -public: - explicit SangomaCard(const unsigned int card_number, const CardModel model, - const BufferSettings & ReceiveBufferSettings, - const BufferSettings & TransmitBufferSettings); ///< Constructor - ~SangomaCard(); ///< Destructor - - unsigned int GetCardNumber() const; ///< Returns the card number of this Sangoma card - CardModel GetModel() const; ///< Returns the model of Sangoma card that this object represents (A104 or A108) - unsigned int GetNumberOfPorts() const; ///< Returns the number of ports in this card - SangomaPort* GetPort(const unsigned int port_number); ///< Returns a pointer to the port requested - - DriverVersion GetCardDriverVersion(); ///< Returns the card's driver version number - std::string GetSerialNumber() const; ///< Returns the card's serial number - std::string GetFirmwareVersion() const; ///< Returns the card's firmware version - unsigned int GetCardPciBus() const; ///< Returns the number of the PCI bus that the card is located in - unsigned int GetCardPciSlot() const; ///< Returns the number of the PCI bus that the card is located in - - std::string GetLastError() const; ///< Returns string description of the last error that occured for this card - -private: - // Copy constructor and assigment operator are made private - // and left unimplemented to ensure that the SangomaCard object cannot be copied - SangomaCard(const SangomaCard& port); ///< Copy Constructor (do not implement) - SangomaCard& operator=(const SangomaCard& rhs); ///< Assignment Operator (do not implement) - - unsigned int CardNumber; ///< Number of this card in the system (zero indexed) - CardModel Model; ///< The model of Sangoma card that this object represents (A104 or A108) - unsigned int NumberOfPorts; ///< The number of SangomaPorts found in this card - std::vector Ports; ///< Vector of the SangomaPorts contained in this card - std::string LastError; ///< String description of the last error that occurred (should be set if an error occurs in any SangomaCard member functions, or empty if successful) -}; - -}// namespace Sangoma - -#endif //_SANGOMA_CARD_H diff --git a/api/libsangoma/examples/sample_data_tapping/SangomaPort.cpp b/api/libsangoma/examples/sample_data_tapping/SangomaPort.cpp deleted file mode 100644 index 1bc2aa6..0000000 --- a/api/libsangoma/examples/sample_data_tapping/SangomaPort.cpp +++ /dev/null @@ -1,1289 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \file SangomaPort.cpp -/// \brief This file contains the implementation of the SangomaPort class -/////////////////////////////////////////////////////////////////////////////////////////////// - -#if defined(__WINDOWS__) -# ifndef _DEBUG -# pragma optimize("2gt",on) // Windows specific (MS_SPECIFIC), enables optimization in Release mode -# endif -#endif - -#include -#include -#include "SangomaPort.h" -#include "driver_configurator.h" - -#define DBG_PORT if(0)printf -#define INFO_PORT if(0)printf -//This macro is for Error reporting and should NOT be disabled. -#define ERR_PORT printf("Error:%s():line:%d: ", __FUNCTION__, __LINE__);printf - -#define DBG_OPEN if(0)printf -#define PORT_FUNC() if(0)printf("%s(): Line: %u\n", __FUNCTION__, __LINE__) - -extern void print_data_buffer(unsigned char *buffer, int buffer_length); - -using namespace Sangoma; - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn Configuration::Configuration() -/// \brief Constructor (for the Configuration structure) -/// \author J. Markwordt -/// \date 10/04/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -Configuration::Configuration() -: e1Ort1(E1), - Framing(E1_CAS_CRC4_ON), - lineCoding(OFF), - HighImpedanceMode(true), - TxTristateMode(false) -{ -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn Statistics::Statistics() -/// \brief Constructor (for the Statistics structure) -/// \author J. Markwordt -/// \date 10/04/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -Statistics::Statistics() -: TimeLastOpened(0), - TimeLastClosed(0), - TimeLastFoundSync(0), - TimeLastLostSync(0), - OpenCount(0), - CloseCount(0), - FoundSyncCount(0), - LostSyncCount(0), - BytesReceived(0), - BytesSent(0) -{ -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn Alarms::Alarms() -/// \brief Constructor (for the Alarms structure) -/// \author J. Markwordt -/// \date 10/19/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -Alarms::Alarms() -: LossOfSignal(false), - ReceiveLossOfSignal(false), - AlternateLossOfSignalStatus(false), - OutOfFrame(false), - Red(false), - AlarmIndicationSignal(false), - LossOfSignalingMultiframe(false), - LossOfCrcMultiframe(false), - OutOfOfflineFrame(false), - ReceiveLossOfSignalV(false), - Yellow(false) -{ -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn DriverVersion::DriverVersion() -/// \brief Constructor (for the DriverVersion structure) -/// \author J. Markwordt -/// \date 10/19/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -DriverVersion::DriverVersion() -: Major(0), - Minor(0), - Build(0), - Revision(0) -{ -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn PortEvent::PortEvent() -/// \brief Constructor (for the PortEvent structure) -/// \author J. Markwordt -/// \date 10/18/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -PortEvent::PortEvent() -: EventType(Unsignalled), - EventHandle(NULL) -{ -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn SangomaPort::SangomaPort(const unsigned int card_number, const unsigned int port_number, -/// const PortEvent & event, const BufferSettings & ReceiveBufferSettings, -/// const BufferSettings & TransmitBufferSettings) -/// \brief Constructor -/// -/// Sets the size and number of the port's buffers for transmit and recieve (see the -/// BufferSettings structure for more details). Receive or transmit can be disabled, -/// allowing more resources to be devoted to the other direction by setting the -/// NumberOfBuffersPerPort for their respective BufferSettings structures. -/// \param card_number unsigned int number of the SangomaCard that this port is part of -/// (zero indexed) -/// \param port_number unsigned int number of the port that this object represents -/// (this is relative to the card and zero indexed, so the first -/// port of both card 1 and 2 will be 0) -/// \param event PortEvent structure to signal port events with (contains HANDLE -/// to signal the event with and EventType to set indicating the type of event) -/// \param ReceiveBufferSettings BufferSettings to configure the host memory buffers -/// for receive operations on this port (set NumberOfBuffersPerPort -/// to 0 to disable receiving data on this port) -/// \param TransmitBufferSettings BufferSettings to configure the host memory buffers -/// for transmit operations on this port (set NumberOfBuffersPerPort -/// to 0 to disable transmitting data on this port) -/// \author J. Markwordt -/// \date 10/04/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -SangomaPort::SangomaPort(const unsigned int card_number, const unsigned int port_number, - const BufferSettings & ReceiveBufferSettings, - const BufferSettings & TransmitBufferSettings) -: CardNumber(card_number), - PortNumber(port_number), - IsOpen(false), - CurrentConfiguration(), - PortStatistics() -{ - PORT_FUNC(); - - LastError = NO_ERROR_OCCURRED; - - DBG_PORT("%s(): card_number: %u, port_number: %u\n", __FUNCTION__, card_number, port_number); - - InitializeCriticalSection(&cs_CriticalSection); - - SangomaInterface = new sangoma_interface(CardNumber, PortNumber); - DBG_PORT("SangomaInterface: 0x%p\n", SangomaInterface); - - this->ReceiveBufferSettings = ReceiveBufferSettings; - this->TransmitBufferSettings = TransmitBufferSettings; - - // Calculate the size of a host memory buffer by multiplying the maximum buffer size as defined - // by the Sangoma API by a multiplier (buffer_multiplier_factor) for both the receive and transmit buffers - ReceiveBuffer = new PortBuffer(sizeof(RX_DATA_STRUCT) * ReceiveBufferSettings.BufferMultiplierFactor); - TransmitBuffer = new PortBuffer(sizeof(TX_DATA_STRUCT) * TransmitBufferSettings.BufferMultiplierFactor); - - pTxFile = NULL; -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn SangomaPort::~SangomaPort() -/// \brief Destructor -/// \author J. Markwordt -/// \date 10/04/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -SangomaPort::~SangomaPort() -{ - PORT_FUNC(); - //EnterPortCriticalSection(); - //LeavePortCriticalSection(); - //PORT_FUNC(); - - // If the has not been properly closed, close it - if (IsOpen) { - Close(); - } - - // Deallocate Rx/Tx Port buffers - delete ReceiveBuffer; - delete TransmitBuffer; - - if(SangomaInterface != NULL){ - delete SangomaInterface; - SangomaInterface = NULL; - } - - if (pTxFile) { - fclose( pTxFile ); - } - - PORT_FUNC(); -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn SangomaPort::~SangomaPort(const Configuration & config) -/// \brief Implementation of Sangoma's low level API call to set port configuration - T1/E1. -/// \author David Rokhvarg -/// \date 11/08/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -int SangomaPort::SetPortConfiguration(const Configuration & config) -{ - int return_code; - sdla_fe_cfg_t sdla_fe_cfg; - buffer_settings_t buffer_settings; - std::ostringstream error_msg; - - driver_configurator *p_drv_cfg_obj = new driver_configurator(); - if(p_drv_cfg_obj->init(CardNumber, SangomaInterface->get_mapped_port_number())){ - error_msg << "ERROR: " << __FUNCTION__ << "(): failed to initialize Sangoma Driver Configuration object"; - LastError = error_msg.str(); - delete p_drv_cfg_obj; - return 1; - } - - memset(&sdla_fe_cfg, 0x00, sizeof(sdla_fe_cfg_t)); - switch(config.e1Ort1) - { - case T1: - FE_LBO(&sdla_fe_cfg) = WAN_T1_LBO_0_DB;//important to set to a valid value for both T1 and E1!! - FE_MEDIA(&sdla_fe_cfg) = WAN_MEDIA_T1; - switch(config.lineCoding) - { - case OFF: - FE_LCODE(&sdla_fe_cfg) = WAN_LCODE_AMI; - break; - case ON: - FE_LCODE(&sdla_fe_cfg) = WAN_LCODE_B8ZS; - break; - default: - error_msg << "ERROR: " << __FUNCTION__ << "(): T1 invalid lineCoding " << config.lineCoding; - LastError = error_msg.str(); - delete p_drv_cfg_obj; - return 1; - } - - switch(config.Framing) - { - case T1_EXTENDED_SUPERFRAME: - FE_FRAME(&sdla_fe_cfg) = WAN_FR_ESF; - break; - case T1_SUPERFRAME: - FE_FRAME(&sdla_fe_cfg) = WAN_FR_D4; - break; - default: - error_msg << "ERROR: " << __FUNCTION__ << "(): T1: invalid Framing " << config.Framing; - LastError = error_msg.str(); - delete p_drv_cfg_obj; - return 1; - } - - FE_SIG_MODE(&sdla_fe_cfg) = WAN_TE1_SIG_CCS; - FE_LBO(&sdla_fe_cfg) = WAN_T1_LBO_0_DB; - //320*24=7680 - TxMtu = 7680; - break; - - case E1: - FE_LBO(&sdla_fe_cfg) = WAN_E1_120;//important to set to a valid value for both T1 and E1!! - FE_MEDIA(&sdla_fe_cfg) = WAN_MEDIA_E1; - switch(config.lineCoding) - { - case OFF: - FE_LCODE(&sdla_fe_cfg) = WAN_LCODE_AMI; - break; - case ON: - FE_LCODE(&sdla_fe_cfg) = WAN_LCODE_HDB3; - break; - default: - error_msg << "ERROR: " << __FUNCTION__ << "(): E1 invalid lineCoding " << config.lineCoding; - LastError = error_msg.str(); - delete p_drv_cfg_obj; - return 1; - } - - //FE_FRAME(&sdla_fe_cfg) = WAN_FR_CRC4; - switch(config.Framing) - { - case E1_CAS_CRC4_ON: - FE_FRAME(&sdla_fe_cfg) = WAN_FR_CRC4; - FE_SIG_MODE(&sdla_fe_cfg) = WAN_TE1_SIG_CAS; - //240*31=7440 - TxMtu = 7440; - break; - case E1_CAS_CRC4_OFF: - FE_FRAME(&sdla_fe_cfg) = WAN_FR_NCRC4; - FE_SIG_MODE(&sdla_fe_cfg) = WAN_TE1_SIG_CAS; - //240*31=7440 - TxMtu = 7440; - break; - case E1_CCS_CRC4_ON: - FE_FRAME(&sdla_fe_cfg) = WAN_FR_CRC4; - FE_SIG_MODE(&sdla_fe_cfg) = WAN_TE1_SIG_CCS; - //240*31=7440 - TxMtu = 7440; - break; - case E1_CCS_CRC4_OFF: - FE_FRAME(&sdla_fe_cfg) = WAN_FR_NCRC4; - FE_SIG_MODE(&sdla_fe_cfg) = WAN_TE1_SIG_CCS; - //240*31=7440 - TxMtu = 7440; - break; - - case E1_CAS_UNFRAMED: - FE_FRAME(&sdla_fe_cfg) = WAN_FR_UNFRAMED; - FE_SIG_MODE(&sdla_fe_cfg) = WAN_TE1_SIG_CAS; - //240*32=7680 - TxMtu = 7680; - break; - case E1_CCS_UNFRAMED: - FE_FRAME(&sdla_fe_cfg) = WAN_FR_UNFRAMED; - FE_SIG_MODE(&sdla_fe_cfg) = WAN_TE1_SIG_CCS; - //240*32=7680 - TxMtu = 7680; - break; - - default: - error_msg << "ERROR: " << __FUNCTION__ << "(): E1: invalid Framing " << config.Framing; - LastError = error_msg.str(); - delete p_drv_cfg_obj; - return 1; - } - break; - - default: - error_msg << "ERROR: " << __FUNCTION__ << "(): Invalid configuration! Not T1 or E1."; - LastError = error_msg.str(); - delete p_drv_cfg_obj; - return 1; - }//switch(config.e1Ort1) - - //FE_REFCLK(&sdla_fe_cfg) = 0; //optional - - /////////////////////////////////////////////////////////////////////////////// - //DAVIDR: for "TAPPING" set clock to WAN_NORMAL_CLK - //FE_CLK(&sdla_fe_cfg) = WAN_NORMAL_CLK; - //DAVIDR: for "PLAYBACK/RECORD" set clock to WAN_NORMAL_CLK or WAN_MASTER_CLK, - // depending on how the other side is configured! - - if (config.Master) { - FE_CLK(&sdla_fe_cfg) = WAN_MASTER_CLK; - } else { - FE_CLK(&sdla_fe_cfg) = WAN_NORMAL_CLK; - } - /////////////////////////////////////////////////////////////////////////////// - - //DAVIDR: High Impedance can be used only with external filters installed!! - FE_HIMPEDANCE_MODE(&sdla_fe_cfg) = (config.HighImpedanceMode == true ? WANOPT_YES:WANOPT_NO); - FE_RX_SLEVEL(&sdla_fe_cfg) = config.MaxCableLoss; - FE_TXTRISTATE(&sdla_fe_cfg) = (config.TxTristateMode == true ? WANOPT_YES:WANOPT_NO); - - /////////////////////////////////////////////////////////////////////////////// - //The same buffer settings will be used in both directions - Tx and Rx. - buffer_settings.buffer_multiplier_factor = ReceiveBufferSettings.BufferMultiplierFactor; - buffer_settings.number_of_buffers_per_api_interface = ReceiveBufferSettings.NumberOfBuffersPerPort; - - return_code = p_drv_cfg_obj->set_t1_e1_configuration(&sdla_fe_cfg, &buffer_settings); - - delete p_drv_cfg_obj; - return return_code; -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn SangomaPort::Open(const Configuration & config) -/// \brief Opens this port, setting its current configuration to the one provided -/// \author J. Markwordt -/// \date 10/05/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -bool SangomaPort::Open(const Configuration & config) -{ - LastError = NO_ERROR_OCCURRED; // Reset so if the function is successful GetLastError() will return NO_ERROR_OCCURRED - - EnterPortCriticalSection(); - - PORT_FUNC(); - DBG_OPEN("%s(): CardNumber: %u, PortNumber: %u (mapped port: %u)\n", __FUNCTION__, - CardNumber, PortNumber, SangomaInterface->get_mapped_port_number()); - - DBG_PORT("%s, Framing: %u, lineCoding: %u, HighImpedanceMode: %u\n", - (config.e1Ort1 == T1 ? "T1" : - (config.e1Ort1 == E1 ? "E1" : "Error: Not T1 or E1")), - config.Framing, - config.lineCoding, - config.HighImpedanceMode); - - // If the port is already opened, return false, it must be Closed first before it can be reopened - if (IsOpen) { - PORT_FUNC(); - std::ostringstream error_msg; - error_msg << "ERROR: SangomaPort::Open() failed to open, port " << GetPortNumber() << " is already opened."; - error_msg << "SangomaPort::Close() must be called before attempting to reopen."; - LastError = error_msg.str(); - - // Return false to indicate the open failed, but do not change - // IsOpen since port is currently open in a valid configuration - LeavePortCriticalSection(); - return false; - } - - // Apply configuration to the port after checking that the configuration is valid. - if(SetPortConfiguration(config)){ - PORT_FUNC(); - - std::ostringstream error_msg; - error_msg << "ERROR: SangomaPort::SetPortConfiguration() failed for port " << GetPortNumber() << "."; - LastError = error_msg.str(); - - Event.EventHandle = NULL; - ERR_PORT("SetPortConfiguration() failed! (CardNumber: %u, PortNumber: %u (mapped port: %u))\n", - CardNumber, PortNumber, SangomaInterface->get_mapped_port_number()); - //axit(1); - LeavePortCriticalSection(); - return false; - } - - // Perform any operations necessary to open the port with the new configuration and prepare to receive data - if(SangomaInterface->init()){ - PORT_FUNC(); - - std::ostringstream error_msg; - error_msg << "ERROR: SangomaPort: SangomaInterface->init() failed for port " << GetPortNumber() << "."; - LastError = error_msg.str(); - - Event.EventHandle = NULL; - ERR_PORT("SangomaInterface->init() failed! (CardNumber: %u, PortNumber: %u (mapped port: %u))\n", - CardNumber, PortNumber, SangomaInterface->get_mapped_port_number()); - //exit(1); - LeavePortCriticalSection(); - return false; - } - - if(SangomaInterface->set_buffer_multiplier(&wp_api, ReceiveBufferSettings.BufferMultiplierFactor)){ - PORT_FUNC(); - - std::ostringstream error_msg; - error_msg << "ERROR: SangomaPort: SangomaInterface->set_buffer_multiplier() failed for port " << GetPortNumber() << "."; - LastError = error_msg.str(); - - Event.EventHandle = NULL; - ERR_PORT("SangomaInterface->set_buffer_multiplier() failed! (CardNumber: %u, PortNumber: %u (mapped port: %u))\n", - CardNumber, PortNumber, SangomaInterface->get_mapped_port_number()); - //exit(1); - LeavePortCriticalSection(); - return false; - } - - Event.EventHandle = SangomaInterface->get_wait_object_reference(); - - // Store the time that this successful Open() occurred, both for statistics - // purposes and so that we can calculate time elapsed since opening for - // determining whether we have acheived syncronization - time(&PortStatistics.TimeLastOpened); - - DBG_PORT("%s(): PortStatistics.TimeLastOpened:%u (ptr: 0x%p)\n", - __FUNCTION__, (uint32_t)PortStatistics.TimeLastOpened, &PortStatistics.TimeLastOpened); - - IsOpen = true; - - PORT_FUNC(); - // Save the current configuration since it was successfully applied to the port - CurrentConfiguration = config; - - LeavePortCriticalSection(); - // Unless the port was successfully opened, IsOpen will still be false - return IsOpen; -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn SangomaPort::Close() -/// \brief Closes this port -/// \return true if the port was successfully closed, false if -/// \author J. Markwordt -/// \date 10/05/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -bool SangomaPort::Close() -{ - EnterPortCriticalSection(); - PORT_FUNC(); - - LastError = NO_ERROR_OCCURRED; // Reset so if the function is successful GetLastError() will return NO_ERROR_OCCURRED - - DBG_OPEN("%s(): CardNumber: %u, PortNumber: %u (mapped port: %u)\n", __FUNCTION__, - CardNumber, PortNumber, SangomaInterface->get_mapped_port_number()); - - // If the port is not currently opened just return true, there is nothing to do - if (!IsOpen) { - LeavePortCriticalSection(); - return true; // this is not an error, there is just nothing to do, already closed - } - - IsOpen = false; - - /////////////////////////////////////////////////////////////////////////////////////// - // Signal the wait object BEFORE deleting it so anyone who is waiting will not use it anymore - //sangoma_wait_obj_signal(SangomaInterface->get_wait_object_reference()); - /////////////////////////////////////////////////////////////////////////////////////// - - // Perform actions to close and cleanup the port - bool close_successful = false; - if(SangomaInterface->cleanup() == 0){ - close_successful = true; - }else{ - ERR_PORT("CardNumber: %u, PortNumber: %u (mapped port: %u): failed the cleanup()!!\n", - CardNumber, PortNumber, SangomaInterface->get_mapped_port_number()); - } - - if (close_successful) { - // Store the time that this successful Close() occurred for statistical purposes - time(&PortStatistics.TimeLastClosed); - LeavePortCriticalSection(); - return true; - } - - LeavePortCriticalSection(); - return false; -} - -bool SangomaPort::GetIsOpen() -{ - bool boolTmpIsOpen; - - if(TryEnterPortCriticalSection()){ - //Do NOT wait! We only want to check, not actually wait for another thread to complete its work. - return false; - } - - boolTmpIsOpen = IsOpen; - LeavePortCriticalSection(); - - return boolTmpIsOpen; -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn efficient_32bit_byte_copy(unsigned char **p_destination_buf, unsigned char **p_source_buf, unsigned int num_bytes_to_copy){ -/// \brief Copies data bytes from one byte buffer to another. This routine is optimized -/// for 32 bit processors. This routine does not handle detection of overrunning -/// the buffer boundaries. That responsibility is left to the calling routine. -/// -/// \param **p_destination_buf : Address of a pointer to the destination byte buffer -/// \param **p_source_buf : Address of a pointer to the source byte buffer. -/// \param num_bytes_to_copy : Number of bytes to copy from the source buffer to the -/// destination buffer. -/// \author Andrew Park -/// \date 07/18/2005 -/////////////////////////////////////////////////////////////////////////////////////////////// -const unsigned int BITMASK_FOR_LEAST_SIGNIFICANT_TWO_BITS = 0x3; -void efficient_32bit_byte_copy(unsigned char **p_destination_buf, unsigned char **p_source_buf, unsigned int num_bytes_to_copy){ - // We do not need to do a NULL check here, because the function that calls this checks. NOTE: since this is a public - // function, there does still exist the possibility that NULL arrays may be passed in, but I didn't want to mess with - // the efficiency here if at all possible - - //Transfer bytes in chunks of 32 bit words - int num_words = static_cast(num_bytes_to_copy >> 2); //divide by 4 to get the integral # words - unsigned int *p_destination_buf_32bit = reinterpret_cast(*p_destination_buf); - unsigned int *p_source_buf_32bit = reinterpret_cast(*p_source_buf); - unsigned int i=0; - for(i=0;i<(unsigned int)num_words;i++){ - *p_destination_buf_32bit++ = *p_source_buf_32bit++; - } - //Convert pointers back from 32 bit to byte pointers - *p_destination_buf = reinterpret_cast(p_destination_buf_32bit); - *p_source_buf = reinterpret_cast(p_source_buf_32bit); - - //Transfer remaining bytes individually - unsigned int remaining_bytes = static_cast(num_bytes_to_copy & BITMASK_FOR_LEAST_SIGNIFICANT_TWO_BITS); - for(i=0;iread_data(&rxhdr, ReceiveBuffer->GetPortBuffer(), ReceiveBuffer->GetPortBufferSize())) - { - std::ostringstream error_msg; - error_msg << "ERROR: read_data() failed! Port: " << GetPortNumber() << " error description: DeviceIoControl() failed\n"; - LastError = error_msg.str(); - LeavePortCriticalSection(); - return ERROR_DEVICE_IOCTL; - } - break; - case POLLPRI: - if(SangomaInterface->read_event(&wp_api)) - { - std::ostringstream error_msg; - error_msg << "ERROR: read_event() failed! Port: " << GetPortNumber() << " error description: DeviceIoControl() failed\n"; - LastError = error_msg.str(); - LeavePortCriticalSection(); - return ERROR_DEVICE_IOCTL; - } - break; - case POLLOUT: - return_code = TransmitBufferAvailable; - break; - default: - std::ostringstream error_msg; - error_msg << "ERROR: SangomaPort::Read(unsigned int out_flags) for port " << GetPortNumber() << " invalid 'out_flags'=" << out_flags << "\n"; - ERR_PORT("Port %u: SangomaPort::Read() invalid out_flags=0x%X!\n", GetPortNumber(), out_flags); - LastError = error_msg.str(); - LeavePortCriticalSection(); - return ERROR_INVALID_READ_REQUEST; - }//switch() - - if (POLLIN == out_flags) - { - switch (rxhdr.operation_status) - { - case SANG_STATUS_RX_DATA_AVAILABLE: - return_code = ReadDataAvailable; - ReceiveBuffer->SetUserDataLength(rxhdr.data_length); - break; - default: - ERR_PORT("Port %u: Rx Error: Operation Status: %s (%d)\n", GetPortNumber(), - SDLA_DECODE_SANG_STATUS(rxhdr.operation_status), rxhdr.operation_status); - return_code = ERROR_NO_DATA_AVILABLE; - break; - } - } - - if (POLLPRI == out_flags) - { - wp_api_event_t *wp_tdm_api_event = &wp_api.wp_cmd.event; - - switch (wp_api.wp_cmd.result) - { - case SANG_STATUS_SUCCESS: - - switch(wp_tdm_api_event->wp_tdm_api_event_type) - { - case WP_TDMAPI_EVENT_LINK_STATUS: - if(wp_tdm_api_event->wp_tdm_api_event_link_status == WAN_EVENT_LINK_STATUS_CONNECTED){ - return_code = LineConnected; - }else{ - return_code = LineDisconnected; - } - break; - case WP_TDMAPI_EVENT_ALARM: - if(wp_tdm_api_event->wp_tdm_api_event_alarm == 0){ - return_code = LineConnected; - }else{ - return_code = LineDisconnected; - } - break; - default: - //FIXME: Remove this - ERR_PORT("Port %u INVALID EVENT Type 0x%X\n",GetPortNumber(),wp_tdm_api_event->wp_tdm_api_event_type); - exit(1); - } - break; - - default: - - if (rxhdr.operation_status == SANG_STATUS_RX_DATA_AVAILABLE) { - return_code = ReadDataAvailable; - } else { - ERR_PORT("Port %u: Event Error: Operation Status: %s (%d)\n", GetPortNumber(), - SDLA_DECODE_SANG_STATUS(rxhdr.operation_status), rxhdr.operation_status); - return_code = ERROR_NO_DATA_AVILABLE; - } - //FIXME: Remove this - ERR_PORT("Port %u INVALID EVENT\n",GetPortNumber()); - exit(1); - break; - } - } - - if(return_code == ReadDataAvailable){ - PortStatistics.BytesReceived += ReceiveBuffer->GetUserDataLength(); - } - - LeavePortCriticalSection(); - return return_code; -} - - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn SangomaPort::Write(unsigned char* p_source_buffer, const int bytes_to_write) -/// \brief Writes the specified number of bytes from the source buffer to the port -/// \param p_source_buffer Pointer to an array of unsigned chars used as the source of the -/// data to write. Assumes that it contains at least bytes_to_write -/// number of bytes. -/// \param bytes_to_write the number of bytes to write to the port -/// \return Zero if successful (all bytes are written) or one of the following error codes: -/// ERROR_NO_DATA_WRITTEN - no data was able to be written on the port -/// ERROR_INVALID_SOURCE_BUFFER - a NULL source buffer was provided so nothing was written -/// ERROR_PORT_NOT_OPEN - Write attempted before the port had been opened -/// \author J. Markwordt -/// \date 10/15/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -int SangomaPort::Write(unsigned char* p_source_buffer, const unsigned int bytes_to_write) -{ - EnterPortCriticalSection(); - //PORT_FUNC(); - - // The port must have been successfully opened with a valid configuration before a write can be performed - if (!IsOpen) { - std::ostringstream error_msg; - error_msg << "ERROR: SangomaPort::Write(unsigned char*, int) attempted when port " << GetPortNumber() << " had not been opened yet."; - LastError = error_msg.str(); - LeavePortCriticalSection(); - return ERROR_PORT_NOT_OPEN; - } - - // Check to make sure the source is valid before attempting to access it - bool invalid_source_buffer = (NULL == p_source_buffer); - if (invalid_source_buffer) { - std::ostringstream error_msg; - error_msg << "ERROR: SangomaPort::Write(unsigned char*, int) attempted with invalid source buffer on port " << GetPortNumber() << "."; - LastError = error_msg.str(); - LeavePortCriticalSection(); - return ERROR_INVALID_SOURCE_BUFFER; - } - - // Perform Sangoma API functions to write data to the port. - if(bytes_to_write > TransmitBuffer->GetPortBufferSize()){ - std::ostringstream error_msg; - error_msg << "ERROR: SangomaPort::Write(unsigned char*, int) attempted with Tx data length exceeding maximum " << GetPortNumber() << "."; - LastError = error_msg.str(); - LeavePortCriticalSection(); - return ERROR_INVALID_TX_DATA_LENGTH; - } - - TransmitBuffer->SetUserDataLength(bytes_to_write); - // - //If src and dst buffers are the same, there is no need to copy the data because - //it is already there. This is the case for TxFile (see code in WriteChunkOfTxFile()). - // - if (TransmitBuffer->GetUserDataBuffer() != p_source_buffer) { - memcpy(TransmitBuffer->GetUserDataBuffer(), p_source_buffer, bytes_to_write); - } - - int number_of_bytes_written = 0; - - memset(&txhdr, 0x00, sizeof(txhdr)); - -#if 0 - if (GetPortNumber() == 0) { - print_data_buffer((unsigned char*)TransmitBuffer->GetUserDataBuffer(), TransmitBuffer->GetUserDataLength()); - } -#endif - - if(SangomaInterface->transmit(&txhdr, TransmitBuffer->GetUserDataBuffer(), TransmitBuffer->GetUserDataLength())){ - std::ostringstream error_msg; - error_msg << "ERROR: SangomaPort::" << __FUNCTION__ << "() failed! Port: " << GetPortNumber() << " error description: DeviceIoControl() failed"; - LastError = error_msg.str(); - LeavePortCriticalSection(); - return ERROR_DEVICE_IOCTL; - } - - std::ostringstream error_msg; - - switch(txhdr.operation_status) - { - case SANG_STATUS_SUCCESS: - PortStatistics.BytesSent += bytes_to_write; - number_of_bytes_written = bytes_to_write; - break; - case SANG_STATUS_TX_TIMEOUT: - error_msg << "ERROR: SangomaPort::" << __FUNCTION__ << "() failed! Port: " << GetPortNumber() << " error description: TX_TIMEOUT"; - break; - case SANG_STATUS_TX_DATA_TOO_LONG: - error_msg << "ERROR: SangomaPort::" << __FUNCTION__ << "() failed! Port: " << GetPortNumber() << " error description: TX_DATA_TOO_LONG"; - break; - case SANG_STATUS_TX_DATA_TOO_SHORT: - error_msg << "ERROR: SangomaPort::" << __FUNCTION__ << "() failed! Port: " << GetPortNumber() << " error description: TX_DATA_TOO_SHORT"; - break; - case SANG_STATUS_LINE_DISCONNECTED: - error_msg << "ERROR: SangomaPort::" << __FUNCTION__ << "() failed! Port: " << GetPortNumber() << " error description: PORT_OUT_OF_SYNC"; - break; - default: - break; - }//switch() - - bool no_data_written = (0 == number_of_bytes_written); - if (no_data_written) { - LastError = error_msg.str(); - LeavePortCriticalSection(); - return ERROR_NO_DATA_WRITTEN; - } - - LeavePortCriticalSection(); - return 0;// ALL bytes were written -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn SangomaPort::GetSynchronizationStatus() -/// \brief Closes this port -/// \return true if the port was successfully closed, false if -/// \author J. Markwordt -/// \date 10/05/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -SynchronizationStatus SangomaPort::GetSynchronizationStatus() -{ - EnterPortCriticalSection(); - PORT_FUNC(); - - // If the port is not currently open with a valid configuration - // the port cannot be in sync, simply return not in sync. - if (!IsOpen) { - PORT_FUNC(); - LeavePortCriticalSection(); - return PORT_NOT_IN_SYNC; - } - - // Else we need to know if enough time has elapsed to be able to reliably - // check for alarms. If ALARM_WAIT_TIME_MS has not passed, the Sangoma card - // will always return no alarms, giving a false positive that we have found - // synchronization, when in fact we have not. - time_t CurrentTime; - time(&CurrentTime); - - DBG_PORT("%s(): CurrentTime:%u, PortStatistics.TimeLastOpened:%u (ptr: 0x%p)\n", - __FUNCTION__, (uint32_t)CurrentTime, (uint32_t)PortStatistics.TimeLastOpened, &PortStatistics.TimeLastOpened); - -#if 0 - time_t t_time_diff = CurrentTime - PortStatistics.TimeLastOpened; - DBG_PORT("%s(): t_time_diff: %d\n", __FUNCTION__, t_time_diff); - //translate time differemce into milliseconds - t_time_diff *= 1000; - bool ready_to_check_for_alarms = (t_time_diff >= ALARM_WAIT_TIME_MS); -#else - double t_time_diff = difftime(CurrentTime, PortStatistics.TimeLastOpened); - DBG_PORT("%s(): t_time_diff: %f\n", __FUNCTION__, t_time_diff); - bool ready_to_check_for_alarms = (t_time_diff >= ALARM_WAIT_TIME_MS / 1000 / 2 /* allow to poll after 1/2 of maximum wait time (approximately 16 seconds) */); -#endif - - DBG_PORT("%s(): ready_to_check_for_alarms: %d\n", __FUNCTION__, ready_to_check_for_alarms); - - if (ready_to_check_for_alarms) { - // Check to see if there are alarms present. We aren't interested in - // what individual ports are present or saving them, just see if any - // are present. - char alarms_present = SangomaInterface->alarms_present(); - if (alarms_present) { - sync_cnt=0; - if (t_time_diff >= ALARM_WAIT_TIME_MS / 1000) { - // Set the LastError string to indicate that - std::ostringstream error_msg; - error_msg << "ERROR: SangomaPort::GetSynchronizationStatus() detected alarms present on port " << GetPortNumber() << " with the current configuration. Closing the port."; - LastError = error_msg.str(); - - LeavePortCriticalSection(); - - // DAVIDR: reached maximum wait time. - // The *caller* will decide what to do with the port: to close it or not. - return PORT_NOT_IN_SYNC; - } else { - // DAVIDR: the maximum wait time was not reached yet, keep waiting for sync. - LeavePortCriticalSection(); - return PORT_WAITING_FOR_SYNC; - } - } else { - PortStatistics.TimeLastFoundSync = CurrentTime; - sync_cnt++; - LeavePortCriticalSection(); - return PORT_IN_SYNC; - } - - }else{ - PORT_FUNC(); - } - - LeavePortCriticalSection(); - return PORT_WAITING_FOR_SYNC; -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn SangomaPort::GetPortNumber() const -/// \brief Returns this port's number (zero indexed, relative to the card) -/// \return This port's number (zero indexed, relative to the card) -/// \author J. Markwordt -/// \date 10/15/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -unsigned int SangomaPort::GetPortNumber() const -{ - return PortNumber; -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn SangomaPort::GetUnmappedPortNumber() -/// \brief Returns this port's number UNMAPPED (Without G3 port mapping). Use for debugging only. -/// \return This port's UNMAPPED number (zero indexed, relative to the card) -/// \author David Rokhvarg (davidr@sangoma.com) -/// \date 1/10/2008 -/////////////////////////////////////////////////////////////////////////////////////////////// -unsigned int SangomaPort::GetUnmappedPortNumber() -{ - unsigned int unmapped_port = 0; - EnterPortCriticalSection(); - if(SangomaInterface != NULL){ - unmapped_port = SangomaInterface->get_mapped_port_number(); - } - LeavePortCriticalSection(); - return unmapped_port; -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn SangomaPort::GetConfiguration() const -/// \brief Returns the current configuration of the port -/// \return Current Configuration structure for the port -/// \author J. Markwordt -/// \date 10/15/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -Configuration SangomaPort::GetConfiguration() const -{ - PORT_FUNC(); - return CurrentConfiguration; -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn SangomaPort::GetEvent() const -/// \brief Return the PortEvent associated with this port -/// \return PortEvent structure for events associated with this port -/// \author J. Markwordt -/// \date 10/18/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -PortEvent SangomaPort::GetEvent() const -{ - return Event; -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn SangomaPort::GetDriverVersion() const -/// \brief Returns this port's hardware abstraction driver version number. -/// -/// Sangoma has given the card a driver and the port what Sangoma refers to as a "Hardware -/// Abstraction Driver", and although these two should have the same version number if -/// installed properly, they are in fact two separate drivers. -/// -/// This function is to retrieve the driver associated with the port's hardware abstraction -/// driver and can be used to verify that it matches the version number of the card as a whole. -/// \return DriverVersion containing the version of the software abstraction driver associated -/// with this port. -/// \author J. Markwordt -/// \date 10/17/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -DriverVersion SangomaPort::GetDriverVersion() /* DAVIDR: removed 'const' to get rid of compiler errors */ -{ - DriverVersion software_abstraction_driver_version; - wan_driver_version_t drv_version; - - if(SangomaInterface->get_api_driver_version(&drv_version)){ - std::ostringstream error_msg; - error_msg << "ERROR: SangomaPort::%s()" << __FUNCTION__ << " failed! Port: " << GetPortNumber(); - LastError = error_msg.str(); - } - - //translate low level version structure into high level version structure - software_abstraction_driver_version.Major = drv_version.major; - software_abstraction_driver_version.Minor = drv_version.minor; - software_abstraction_driver_version.Build = drv_version.minor1; - software_abstraction_driver_version.Revision = drv_version.minor2; - - return software_abstraction_driver_version; -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn SangomaPort::GetStatistics() -/// \brief Get the statistics for this port. -/// -/// The reason this function is not declared constant is that the Statistics strucure -/// that is returned contains both statisics that are maintained in software by this -/// class, and statistics that are maintained in hardware on the port. We do not want -/// to continuously poll to keep these statistics up to date, so when requested, we will -/// issue low level commands to fill in these statistics. -/// \return Statistics structure containing information related to this port -/// \author J. Markwordt -/// \date 10/17/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -Statistics SangomaPort::GetStatistics() -{ - /// Perform low level calls to retrieve the net_device_stats_t structure and update - /// PortStatistics with the statistics we are interested in. For example, - /// net_device_stats_t.rx_bytes maps to Statistics.BytesReceived. Statistics maintained - /// by the SangomaPort class (such as TimeLastOpened, TimeLastFoundSync, etc.) will be - /// returned as is. - wanpipe_chan_stats_t stats; - - EnterPortCriticalSection(); - if (IsOpen) - { - SangomaInterface->operational_stats(&stats); - //translate low level statistics structure into high level statistics structure - PortStatistics.BytesReceived = stats.rx_bytes; - PortStatistics.BytesSent = stats.tx_bytes; - PortStatistics.Errors = stats.errors; - } - LeavePortCriticalSection(); - return PortStatistics; -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn SangomaPort::ClearStatistics() -/// \brief Clear the statistics for this port -/// \author J. Markwordt -/// \date 10/17/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -void SangomaPort::ClearStatistics() -{ - /// \todo Reset the PortStatistics member to default values - - /// Issue low level command to clear the statistics maintained on the port - EnterPortCriticalSection(); - if (IsOpen) - { - SangomaInterface->flush_operational_stats(); - } - LeavePortCriticalSection(); -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn SangomaPort::FlushBuffers() -/// \brief Clear the statistics for this port -/// \author J. Markwordt -/// \date 10/17/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -void SangomaPort::FlushBuffers() -{ - /// \todo Reset the PortStatistics member to default values - - /// Issue low level command to clear the statistics maintained on the port - EnterPortCriticalSection(); - if (IsOpen) - { - SangomaInterface->flush_buffers(); - } - LeavePortCriticalSection(); -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn SangomaPort::GetAlarms() const -/// \brief Retrieves the alarms from the hardware for this port -/// \return Alarms structure containing indications of the current alarms -/// \author J. Markwordt -/// \date 10/17/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -Alarms SangomaPort::GetAlarms() -{ - Alarms alarms(FALSE); - unsigned long u_alarms = 1; - unsigned char adapter_type; - - EnterPortCriticalSection(); - if (IsOpen) - { - adapter_type = SangomaInterface->get_adapter_type(); - SangomaInterface->read_te1_56k_stat(&u_alarms); - /// translate low level alarms structure into high level alarms structure - if (adapter_type == WAN_MEDIA_T1 || adapter_type == WAN_MEDIA_E1){ - if(!strcmp(WAN_TE_LOS_ALARM(u_alarms), ON_STR)){ - alarms.LossOfSignal = TRUE; - } - if(!strcmp(WAN_TE_ALOS_ALARM(u_alarms), ON_STR)){ - alarms.AlternateLossOfSignalStatus = TRUE; - } - if(!strcmp(WAN_TE_RED_ALARM(u_alarms), ON_STR)){ - alarms.Red = TRUE; - } - if(!strcmp(WAN_TE_AIS_ALARM(u_alarms), ON_STR)){ - alarms.AlarmIndicationSignal = TRUE; - } - if(!strcmp(WAN_TE_OOF_ALARM(u_alarms), ON_STR)){ - alarms.OutOfFrame = TRUE; - } - if (adapter_type == WAN_MEDIA_T1){ - if(!strcmp(WAN_TE_YEL_ALARM(u_alarms), ON_STR)){ - alarms.Yellow = TRUE; - } - } - - if(!strcmp(WAN_TE_OOSMF_ALARM(u_alarms), ON_STR)){ - alarms.LossOfSignalingMultiframe = TRUE; - } - if(!strcmp(WAN_TE_OOCMF_ALARM(u_alarms), ON_STR)){ - alarms.LossOfCrcMultiframe = TRUE; - } - if(!strcmp(WAN_TE_OOOF_ALARM(u_alarms), ON_STR)){ - alarms.OutOfOfflineFrame = TRUE; - } - if(!strcmp(WAN_TE_RAI_ALARM(u_alarms), ON_STR)){ - alarms.ReceiveLossOfSignalV = TRUE; - } - } - } - LeavePortCriticalSection(); - return alarms; -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn SangomaPort::GetLastError() const -/// \brief Returns a description of the last error that occurred -/// \return Returns a description of the last error that occurred (NO_ERROR_OCCURRED if the last command was successful) -/// \author J. Markwordt -/// \date 10/17/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -std::string SangomaPort::GetLastError() const -{ - return LastError; -} - -//////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn SangomaPort::GetRxDataBuffer() -/// \brief Returns a pointer to received data. -/// \return Returns a pointer to received data after a successful Read() -/// \author David Rokhvarg (davidr@sangoma.com) -/// \date 1/10/2008 -/////////////////////////////////////////////////////////////////////////////////////////////// -unsigned char *SangomaPort::GetRxDataBuffer() -{ - return ReceiveBuffer->GetUserDataBuffer(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn SangomaPort::GetRxDataLength() -/// \brief Returns length of received data. -/// \return Returns length of received data after a successful Read(). -/// \author David Rokhvarg (davidr@sangoma.com) -/// \date 1/10/2008 -/////////////////////////////////////////////////////////////////////////////////////////////// -unsigned int SangomaPort::GetRxDataLength() -{ - return ReceiveBuffer->GetUserDataLength(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn SangomaPort::EnterPortCriticalSection() -/// \brief Enter a SangomaPort operation in thread-safe manner. -/// \return No return value. -/// \author David Rokhvarg (davidr@sangoma.com) -/// \date 1/10/2008 -/////////////////////////////////////////////////////////////////////////////////////////////// -void SangomaPort::EnterPortCriticalSection() -{ - EnterCriticalSection(&cs_CriticalSection); -} - -//////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn SangomaPort::LeavePortCriticalSection() -/// \brief Leave a SangomaPort operation in thread-safe manner. -/// \return No return value. -/// \author David Rokhvarg (davidr@sangoma.com) -/// \date 1/10/2008 -/////////////////////////////////////////////////////////////////////////////////////////////// -void SangomaPort::LeavePortCriticalSection() -{ - LeaveCriticalSection(&cs_CriticalSection); -} - - -//////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn SangomaPort::TryEnterPortCriticalSection() -/// \brief Try to enter a SangomaPort operation in thread-safe manner. -/// \return 1 - the mutex already taken, return without waiting 0 - the mutex was free -/// \author David Rokhvarg (davidr@sangoma.com) -/// \date 6/2/2010 -/////////////////////////////////////////////////////////////////////////////////////////////// -int SangomaPort::TryEnterPortCriticalSection() -{ - if (! TryEnterCriticalSection(&cs_CriticalSection) ) - { - //If another thread already owns the critical section, the return value of TryEnterCriticalSection() is zero. - return 1; - } - return 0; -} - -int SangomaPort::SetAndOpenTxFile(char *szTxFileName) -{ - pTxFile = fopen(szTxFileName, "rb" ); - if( pTxFile == NULL){ - ERR_PORT("Can't open file: [%s]\n", szTxFileName); - return 1; - } - - return 0; -} - -int SangomaPort::WriteChunkOfTxFile() -{ - unsigned char *user_tx_buffer = NULL; - - if (!pTxFile) { - ERR_PORT("TxFile is NOT open!\n"); - return 1; - } - - user_tx_buffer = this->TransmitBuffer->GetUserDataBuffer(); - - //Initialize the buffer to 0xFF, so when End-of-File is reached, - //the padding up-to-end of tx buffer is automatic. - memset( user_tx_buffer, 0xFF, this->TransmitBuffer->GetUserDataLength() ); - - if (feof( pTxFile )) { - //End-of-File reached. Re-wind the file to zero. - fseek( pTxFile, 0, SEEK_SET ); - } - - //Read tx data from the file. - fread( user_tx_buffer, 1, TxMtu, pTxFile ); - - return this->Write(user_tx_buffer, TxMtu); -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn SangomaPort::LineLoopbackEnable() -/// \brief Enable line loopback for testing. All transmitted data will be also received -// locally. Requires the Port to be in Master clock mode. -/// \return 0 - success, non-zero - error -/// \author David Rokhvarg -/// \date 01/27/2011 -/////////////////////////////////////////////////////////////////////////////////////////////// -int SangomaPort::LineLoopbackEnable() -{ - int rc = SangomaInterface->loopback_command(WAN_TE1_DDLB_MODE, WAN_TE1_LB_ENABLE, ENABLE_ALL_CHANNELS); - - if (rc) { - ERR_PORT("Port %u: %s() failed! rc: %d\n", GetPortNumber(), __FUNCTION__, rc); - } - - return rc; -} - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn SangomaPort::LineLoopbackDisable() -/// \brief Disable line loopback which was enabled by SangomaPort::LineLoopbackEnable() -/// \return 0 - success, non-zero - error -/// \author David Rokhvarg -/// \date 01/27/2011 -/////////////////////////////////////////////////////////////////////////////////////////////// -int SangomaPort::LineLoopbackDisable() -{ - int rc = SangomaInterface->loopback_command(WAN_TE1_DDLB_MODE, WAN_TE1_LB_DISABLE, ENABLE_ALL_CHANNELS); - - if (rc) { - ERR_PORT("Port %u: %s() failed! rc: %d\n", GetPortNumber(), __FUNCTION__, rc); - } - - return rc; - -} - -#if defined(__WINDOWS__) -# ifndef _DEBUG -# pragma optimize("2gt",off)// Windows specific (MS_SPECIFIC), disables optimization in Release mode -# endif -#endif - diff --git a/api/libsangoma/examples/sample_data_tapping/SangomaPort.h b/api/libsangoma/examples/sample_data_tapping/SangomaPort.h deleted file mode 100644 index bac3cd8..0000000 --- a/api/libsangoma/examples/sample_data_tapping/SangomaPort.h +++ /dev/null @@ -1,384 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \file SangomaPort.h -/// \brief This file contains the declaration of the SangomaPort class -/////////////////////////////////////////////////////////////////////////////////////////////// -#ifndef _SANGOMA_PORT_H -#define _SANGOMA_PORT_H - -#include -#include "ChannelizedBuffer.h" - -#include "sangoma_interface.h" - -#include "PortBuffer.h" - -namespace Sangoma { - -// Read/Write error codes -const int ERROR_NO_DATA_AVILABLE = -1; ///< Error code indicating that a SangomaPort::Read was attempted when no data was available (indicates a possible abuse of the API by polling for data instead of waiting for the DataAvailableEvent) -const int ERROR_INVALID_DESTINATION_BUFFER = -2; ///< Error code indicating that the destination buffer provided to SangomaPort::Read was NULL -const int ERROR_INVALID_SOURCE_BUFFER = -3; ///< Error code indicating that the source buffer provided to SangomaPort::Write was NULL -const int ERROR_NO_DATA_WRITTEN = -4; ///< Error code indicating that the SangomaPort::Write command failed -const int ERROR_PORT_NOT_OPEN = -5; ///< Error code indicating that the Read or Write command failed because the port has not been opened. Call SangomaPort::Open() successfully before attempting to Read or Write. -const int ERROR_INVALID_DESTINATION_BUFFER_TOO_SMALL = -6; ///< Error code indicating that the destination buffer provided to SangomaPort::Read was to small to contain a full buffer's worth of data (configuration error) -const int ERROR_INVALID_READ_REQUEST = -7; ///< Error code indicating that the input to SangomaPort::Read was invalid -/// \todo Add more detailed read/write failure codes as available from the API (more detail is better) -const int ERROR_DEVICE_IOCTL = -8; ///< Error code indicating that DeviceIoControl() for API Device Driver failed. Check '\System32\drivers\wanpipelog.txt' messages log for detailes. -const int ERROR_INVALID_TX_DATA_LENGTH = -8; ///< Error code indicating that SangomaPort::Write failed because user data was too long. - - -const std::string NO_ERROR_OCCURRED = ""; ///< String indicating that no error occurred on the last operation (returned by GetLastError() when the last operation was successful) -const unsigned int MAX_SANGOMA_BUFFER_SIZE = 8188; ///< Maximum Sangoma buffer size in bytes -const unsigned int ALARM_WAIT_TIME_MS = 30000; ///< The number of milliseconds that the Sangoma API must wait in order to be able to reliably report the absense of alarms. - /// If GetAlarms() is called before this amount of time has elapsed after setting a configuration, the card will always - /// report no alarms, giving a false positive that we have found synchronization. - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \enum E1OrT1 -/// \brief Enumeration indicating whether a port is in E1 or T1 mode -/////////////////////////////////////////////////////////////////////////////////////////////// -enum E1OrT1 { - E1=32, ///< Indicates that the port is configured as an E1 port - T1=24 ///< Indicates that the port is configured as a T1 port -}; - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \enum FramingType -/// \brief Enumeration indicating the framing type and signaling of the port -/////////////////////////////////////////////////////////////////////////////////////////////// - -enum FramingType { - //DAVIDR: i added the UNFRAMED E1 types - E1_CCS_UNFRAMED, ///< Indicates that Common Channel Signalling (CCS) with Unframed E1, all 32 timeslots available for the E1 port - E1_CAS_UNFRAMED, ///< Indicates that Channel Associated Signaling (CAS) with Unframed E1, all 32 timeslots available for the E1 port - - E1_CAS_CRC4_ON, ///< Indicates that Channel Associated Signaling (CAS) with CRC4 is the framing type for the E1 port - E1_CAS_CRC4_OFF, ///< Indicates that Channel Associated Signaling (CAS) with no CRC4 is the framing type for the E1 port - E1_CCS_CRC4_ON, ///< Indicates that Common Channel Signalling (CCS) with CRC4 is the framing type for the E1 port - E1_CCS_CRC4_OFF, ///< Indicates that Common Channel Signalling (CCS) with no CRC4 is the framing type for the E1 port - - T1_EXTENDED_SUPERFRAME, ///< Indicates that Extended Superframe (ESF, also called D5 framing) is the framing type for the T1 port - T1_SUPERFRAME ///< Indicates that Superframe (also called D4 or D3/D4 framing) is the framing type for the T1 port -}; - -#define DECODE_FRAMING(framing)\ - (framing == E1_CCS_UNFRAMED)? "E1_CCS_UNFRAMED" : \ - (framing == E1_CAS_UNFRAMED)? "E1_CAS_UNFRAMED" : \ - (framing == E1_CAS_CRC4_ON) ? "E1_CAS_CRC4_ON" : \ - (framing == E1_CAS_CRC4_OFF)? "E1_CAS_CRC4_OFF" : \ - (framing == E1_CCS_CRC4_ON) ? "E1_CCS_CRC4_ON" : \ - (framing == E1_CCS_CRC4_OFF)? "E1_CCS_CRC4_OFF" : \ - (framing == T1_EXTENDED_SUPERFRAME) ? "T1_EXTENDED_SUPERFRAME" : \ - (framing == T1_SUPERFRAME) ? "T1_SUPERFRAME" : "???" - -#define DECODE_CARD_TYPE(type) \ - (type == A104)? "A104" : \ - (type == A108)? "A108" : \ - (type == A116)? "A116" : \ - (type == T116)? "T116" : "Invalid Card" - - -//DAVIDR: On E1 line Sangoma card provides access to timeslot 0 ONLY if Framing is "Unframed E1". - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \enum LineCoding -/// \brief Enumeration indicating whether line coding is on or off for the port -/////////////////////////////////////////////////////////////////////////////////////////////// -enum LineCoding { - OFF, ///< Indicates that line coding is off (meaning set to the default AMI value) - ON ///< Indicates that line coding is on (meaning B8ZS for T1, and HDB3 for E1) -}; - -/********************************************************** -DAVIDR: Receiver Sensitivity (Max Cable Loss Allowed) (dB) -The user will have the following option to choose: -1. HI IMPEDANCE mode: -30 dB -22.5 dB -17.5 dB -12 dB - -Depending on selection, use the following values: -300 -225 -175 -120 - -2. NORMAL mode: -12 dB -18 dB -30 dB -36 dB (for T1) -43 dB (for E1) - -Depending on selection, use the following values: -120 -180 -300 -360 -430 -**********************************************************/ -enum MAX_CABLE_LOSS{ - MCLV_43_0dB=430, - MCLV_36_0dB=360, - MCLV_30_0dB=300, - MCLV_22_5dB=225, - MCLV_18_0dB=180, - MCLV_17_5dB=175, - MCLV_12_0dB=120 -}; - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \struct Configuration -/// \brief Structure containing all settings necessary to configure a Sangoma port -/////////////////////////////////////////////////////////////////////////////////////////////// -struct Configuration { - E1OrT1 e1Ort1; ///< Configures the port as either E1 or T1 - FramingType Framing; ///< Framing type and signalling of the E1/T1 port - LineCoding lineCoding; ///< Indicates whether line coding is ON or OFF - bool HighImpedanceMode; ///< true to indicate High Impedance mode is to be enabled, false to disable it - MAX_CABLE_LOSS MaxCableLoss; ///< If High Impedance is true, indicates value of external resistor. - bool TxTristateMode; ///< If true, indicates transmitter is disabled on T1/E1 level. - bool Master; ///< If true, configure for master clock - Configuration(); ///< Constructor -}; - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \struct Statistics -/// \brief Structure containing all statistics related to a Sangoma port -/////////////////////////////////////////////////////////////////////////////////////////////// -struct Statistics { - // The following time values are to be calculated using the time() function found in time.h. This - // is standard ANSI C and returns the current time as the number of seconds elapsed since midnight - // on January 1, 1970. Operations involving elapsed time can then be done by subtracting from - // current time (or some other instant) and converting to hours, minutes and seconds - // The function struct tm * localtime(const time_t * timer); will convert the time to a tm structure - // that is broken into date and time fields - - // Statistics maintained in software by the SangomaPort class - time_t TimeLastOpened; ///< System time of the last time this port was opened - time_t TimeLastClosed; ///< System time of the last time this port was closed - time_t TimeLastFoundSync; ///< System time of the last time this port found sync with a valid configuration - time_t TimeLastLostSync; ///< System time of the last time this port lost sync when already in sync - - unsigned int OpenCount; ///< Count of the number of times the port was opened (i.e. number of times SangomaPort::Open() returned successfully) - unsigned int CloseCount; ///< Count of the number of times the port was closed (i.e. number of times SangomaPort::Close() returned successfully) - unsigned int FoundSyncCount; ///< Count of the number of times synchronization was found on the port (i.e. number of times sync was found when the port was opened) - unsigned int LostSyncCount; ///< Count of the number of times synchronization was lost on the port (i.e. number of times the LineDisconnected event was raised, since both indicate a loss of sync on the line) - - // Statistics maintained in hardware, a command will have to be sent to the port to retrieve this data - unsigned int BytesReceived; ///< Number of bytes received on this port - unsigned int BytesSent; ///< Number of bytes transmitted from this port - unsigned int Errors; ///< Number of bytes transmitted from this port - - Statistics(); ///< Constructor -}; - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \struct Alarms -/// \brief Structure containing a series off boolean flags to indicate the presence of Sangoma -/// hardware alarms. If true, indicates that the given alarm is present, if false indicates -/// that the alarm is not present. -/////////////////////////////////////////////////////////////////////////////////////////////// -struct Alarms { - bool LossOfSignal; ///< Indicates that the Loss of Signal (ALOSV) alarm is present if true - bool ReceiveLossOfSignal; ///< Indicates that the Receive Loss of Signal (LOS) alarm is present if true - bool AlternateLossOfSignalStatus; ///< Indicates that the Alternate loss of Signal Status (ALTLOS) alarm is present if true - bool OutOfFrame; ///< Indicates that the Out of Frame (OOF) alarm is present if true - bool Red; ///< Indicates that the Telco Red Alarm condition (RED) is present if true - bool AlarmIndicationSignal; ///< Indicates that the Alarm Indication Signal (AIS) is present if true - bool LossOfSignalingMultiframe; ///< Indicates that the Loss of Signaling Multiframe (OOSMFV) alarm is present if true - bool LossOfCrcMultiframe; ///< Indicates that the Loss of CRC Multiframe (OOCMFV) alarm is present if true - bool OutOfOfflineFrame; ///< Indicates that the Out of Off-Line Frame (OOOFV) alarm is present if true - bool ReceiveLossOfSignalV; ///< Indicates that the Receive Loss of Signal (RAIV) alarm is present if true - bool Yellow; ///< Indicates that the Receive Telco Yellow Alarm (YEL) is present if true - - Alarms(); ///< Constructor - Alarms(bool value) ///< Constructor - { - LossOfSignal = value; - ReceiveLossOfSignal = value; - AlternateLossOfSignalStatus = value; - OutOfFrame = value; - Red = value; - AlarmIndicationSignal = value; - LossOfSignalingMultiframe = value; - LossOfCrcMultiframe = value; - OutOfOfflineFrame = value; - ReceiveLossOfSignalV = value; - Yellow = value; - } -}; - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \struct DriverVersion -/// \brief Structure containing the driver version number -/////////////////////////////////////////////////////////////////////////////////////////////// -struct DriverVersion { - unsigned int Major; ///< The major version number of the driver (i.e. the 1 in 1.2.3.4) - unsigned int Minor; ///< The minor version number of the driver (i.e. the 2 in 1.2.3.4) - unsigned int Build; ///< The build version number of the driver (i.e. the 3 in 1.2.3.4) - unsigned int Revision; ///< The revision version number of the driver (i.e. the 4 in 1.2.3.4) - - DriverVersion(); ///< Constructor -}; - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \enum SynchronizationStatus -/// \brief Enumeration indicating the synchronization status of the port -/////////////////////////////////////////////////////////////////////////////////////////////// -enum SynchronizationStatus { - PORT_NOT_IN_SYNC, ///< Indicates that an Open() was attempted on the port and the configuration has proved to be incompatible with the data provided on that port - PORT_WAITING_FOR_SYNC, ///< Indicates that an Open() was attempted on the port and not enough time has elapsed to be able to reliably tell whether the configuration is correct - PORT_IN_SYNC ///< Indicates that an Open() was attempted on the port and the configuration matched the data provided, the port is in sync -}; - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \enum PortEventType -/// \brief Enumeration indicating the type of event that that triggered a call to the PortEventHandler -/////////////////////////////////////////////////////////////////////////////////////////////// -enum PortEventType { - Unsignalled, ///< Default value, indicates that the event has not been signalled (should not be seen in actual events that are triggered) - ReadDataAvailable, ///< Indicates that the read buffer is full (SangomaPort::Read() can be called to service the buffer) - LineConnected, ///< Indicates that a port that was unoccupied has had an E1/T1 line plugged in - LineDisconnected, ///< Indicates that a port that had an E1/T1 line plugged in has had the line disconnected - TransmitBufferAvailable ///< Indicated that a port has at least one free Transmit buffer. -}; - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \struct PortEvent -/// \brief Structure representing an event that occurred on a port within the card -/////////////////////////////////////////////////////////////////////////////////////////////// -struct PortEvent { - PortEventType EventType; ///< Status code indicating the type of event that occured - sangoma_wait_obj_t *EventHandle; ///< Handle to the Sangoma waitable object - - PortEvent(); ///< Constructor -}; - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \struct BufferSettings -/// \brief Structure containing settings for configuring the host memory buffers assigned to a -/// Sangoma port. Data is transferred to host memory via DMA, and an event is set to indicate -/// that the buffers are full and read to be read, so it is inportant to configure the host -/// memory buffers to the needs of your application. Sangoma defines a MRU/MTU of 8188 bytes -/// (the maximum size of an HDLC frame) and assigns buffers of this size to a port (although -/// data is always read or written in even frames of 8184 bytes for T1 and 8160 for E1 -/// (32 timeslots). -/// -/// The size of the buffers will be configurable in multiples of this 8188 bytes enforced -/// by hardware, such that 8188 * BufferMultiplierFactor = BufferSize (i.e. a BufferMultiplierFactor -/// of 4 will result in BufferSize = 4 * 8188 = 32752 byes). -/// -/// Multiple buffers are assigned for transmit and receiving to queue a certain amount of -/// data. These are configured by setting NumberOfBuffersPerPort. If you intend to only -/// use a SangomaPort for either receive or transmit, the NumberOfBuffersPerPort for that -/// set of buffers can be set to 0 (SangomaPort also has special constructors which are -/// for receive-only or transmit-only ports). -/////////////////////////////////////////////////////////////////////////////////////////////// -struct BufferSettings { - unsigned int BufferMultiplierFactor; ///< Number to multiply the MAX_SANGOMA_BUFFER_SIZE by in order to get the size of the buffers allocated in host memory - unsigned int NumberOfBuffersPerPort; ///< Number of buffers in host memory that will be dedicated to with receiving or transmitting data on this port -}; - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \class SangomaPort -/// \brief This class encapsulates the functionality of a physical Sangoma port found on the -/// A104 and A108 card models. -/// \author J. Markwordt -/// \date 10/03/2007 -/////////////////////////////////////////////////////////////////////////////////////////////// -class SangomaPort { -public: - SangomaPort(const unsigned int card_number, const unsigned int port_number, - const BufferSettings & ReceiveBufferSettings, - const BufferSettings & TransmitBufferSettings); ///< Constructor - - ~SangomaPort(); ///< Destructor - - bool Open(const Configuration & config); ///< Opens this port, setting its current configuration to the one provided - bool Close(); ///< Closes this port - - int Read(unsigned int out_flags); ///< Reads Rx data or an Event and places them in the ReceiveBuffer. - ///< Returns reason for wait object being signaled - - unsigned char *GetRxDataBuffer(); ///< Returns a pointer to received data. - unsigned int GetRxDataLength(); ///< Returns length of received data. - - int Write(unsigned char* p_source_buffer, const unsigned int bytes_to_write); ///< Writes the specified number of bytes from the source buffer to the port - SynchronizationStatus GetSynchronizationStatus(); ///< Returns the status of port synchronization - - //SynchronizationStatus SyncStatus; ///< Stores current status of port synchronization indicated by Connected/Disconnected events - - unsigned int GetPortNumber() const; ///< Returns this port's number - Configuration GetConfiguration() const; ///< Returns the current configuration of the port - PortEvent GetEvent() const; ///< Return the PortEvent associated with this port - bool GetIsOpen(); ///< Return true if this port is currently open, false otherwise - - DriverVersion GetDriverVersion(); ///< Returns this port's driver version number - Statistics GetStatistics(); ///< Get the statistics for this port - void ClearStatistics(); ///< Clear the statistics for this port - void FlushBuffers(); ///< Clear the statistics for this port - - Alarms GetAlarms(); ///< Retrieves the alarms from the hardware for this port - - std::string GetLastError() const; ///< Returns a description of the last error that occurred (NO_ERROR_OCCURRED if the last command was successful) - - PortBuffer *ReceiveBuffer; ///< Buffers allocated to receive data for this port - PortBuffer *TransmitBuffer; ///< Buffers allocated to transmit data for this port - - unsigned int GetUnmappedPortNumber(); - - int SetAndOpenTxFile(char *szTxFileName); ///< Open a file which will be continuesly transmitted - - int WriteChunkOfTxFile(); ///< Transmit a chunk of the TxFile - - int LineLoopbackEnable(); ///< Enable line loopback for testing. All transmitted data will be also received locally. Requires the Port to be in Master clock mode. - int LineLoopbackDisable(); ///< Disable line loopback which was enabled by SangomaPort::LineLoopbackEnable() - - unsigned int rx_discard_counter; ///< Number of rx buffers to discard after LineConnected event (the buffers may contain idle data). - unsigned int rx_cnt; ///< Number of rx buffers to discard after LineConnected event (the buffers may contain idle data). - unsigned int sync_cnt; ///< Number of rx buffers to discard after LineConnected event (the buffers may contain idle data). - unsigned int rx_len; ///< Number of rx buffers to discard after LineConnected event (the buffers may contain idle data). - -private: - // Copy constructor and assigment operator are made private - // and left unimplemented to ensure that the SangomaPort object cannot be copied - SangomaPort(const SangomaPort& port); - SangomaPort& operator=(const SangomaPort& rhs); - - unsigned int CardNumber; ///< The number of the SangomaCard that this port is associated with (zero-indexed) - unsigned int PortNumber; ///< The number assigned to this port (zero-indexed) - PortEvent Event; ///< Event used to trigger port events with - bool IsOpen; ///< true if this port is currently open, false otherwise - Configuration CurrentConfiguration; ///< The current configuration of this port - Statistics PortStatistics; ///< Statistics related to this port (made member because some are maintained by the class, some are maintained by the hardware) - - std::string LastError; ///< String description of the last error that occurred (should be set if an error occurs in any SangomaPort member functions, or NO_ERROR_OCCURRED if successful) - - BufferSettings ReceiveBufferSettings, TransmitBufferSettings; - - sangoma_interface *SangomaInterface; - - CRITICAL_SECTION cs_CriticalSection; - void EnterPortCriticalSection(); - void LeavePortCriticalSection(); - int TryEnterPortCriticalSection(); - int SetPortConfiguration(const Configuration & config); - - /*! API header for rx data */ - wp_api_hdr_t rxhdr; - - /*! API header for tx data */ - wp_api_hdr_t txhdr; - - /*! API command structure used to execute API commands. This command structure is used with libsangoma library */ - wanpipe_api_t wp_api; - - FILE *pTxFile; - int TxMtu; -}; - -}// namespace Sangoma - -#endif //_SANGOMA_PORT_H diff --git a/api/libsangoma/examples/sample_data_tapping/driver_configurator.cpp b/api/libsangoma/examples/sample_data_tapping/driver_configurator.cpp deleted file mode 100644 index 0c71ce4..0000000 --- a/api/libsangoma/examples/sample_data_tapping/driver_configurator.cpp +++ /dev/null @@ -1,427 +0,0 @@ -////////////////////////////////////////////////////////////////////// -// driver_configurator.cpp: implementation of the driver_configurator class. -// -// Author : David Rokhvarg -////////////////////////////////////////////////////////////////////// - -#include "driver_configurator.h" - -#define DBG_CFG if(0)printf -#define _DBG_CFG if(0)printf - -#define INFO_CFG if(0)printf -#define _INFO_CFG if(0)printf - -#define ERR_CFG printf("Error:%s():line:%d: ", __FUNCTION__, __LINE__);printf -#define _ERR_CFG if(1)printf - - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - -driver_configurator::driver_configurator() -{ - DBG_CFG("%s()\n", __FUNCTION__); - - wp_handle = INVALID_HANDLE_VALUE; -} - -driver_configurator::~driver_configurator() -{ - DBG_CFG("%s()\n", __FUNCTION__); - - cleanup(); -} - -void driver_configurator::cleanup() -{ - DBG_CFG("%s()\n", __FUNCTION__); - - if(wp_handle != INVALID_HANDLE_VALUE){ - sangoma_close(&wp_handle); - wp_handle = INVALID_HANDLE_VALUE; - } -} - -//GET current configuraion of the API driver -int driver_configurator::get_configuration(port_cfg_t *out_port_cfg) -{ - DBG_CFG("%s()\n", __FUNCTION__); - - int err = sangoma_driver_port_get_config(wp_handle, out_port_cfg, wp_number); - if (err) { - return 1; - } - - return 0; -} - -//SET new configuration of the API driver -int driver_configurator::set_configuration(port_cfg_t *port_cfg) -{ - port_management_struct_t port_mgmnt; - int err; - - DBG_CFG("%s()\n", __FUNCTION__); - - //////////////////////////////////////////////////////////////////////////////////// - memset(&port_mgmnt, 0x00, sizeof(port_mgmnt)); - port_mgmnt.operation_status = SANG_STATUS_GENERAL_ERROR; - - err = sangoma_driver_port_stop(wp_handle, &port_mgmnt, wp_number); - if (err) { - ERR_CFG("%s: failed to stop Port for re-configuration!\n", wanpipe_name_str); - return 1; - } - - switch(port_mgmnt.operation_status) - { - case SANG_STATUS_SUCCESS: - case SANG_STATUS_CAN_NOT_STOP_DEVICE_WHEN_ALREADY_STOPPED: - //OK - break; - default: - ERR_CFG("%s: %s(): return code: %s\n", wanpipe_name_str, - __FUNCTION__, SDLA_DECODE_SANG_STATUS(port_mgmnt.operation_status)); - return 1; - } - - //////////////////////////////////////////////////////////////////////////////////// - err = sangoma_driver_port_set_config(wp_handle, port_cfg, wp_number); - if (err) { - ERR_CFG("%s: failed to set Port configuration!\n", wanpipe_name_str); - return 1; - } - - DBG_CFG("%s(): return code: %s (%d)\n", __FUNCTION__, - SDLA_DECODE_SANG_STATUS(port_cfg->operation_status), port_cfg->operation_status); - switch(port_cfg->operation_status) - { - case SANG_STATUS_DEVICE_BUSY: - ERR_CFG("Error: open handles exist for '%s_IF\?\?' interfaces!\n", wanpipe_name_str); - return port_cfg->operation_status; - case SANG_STATUS_SUCCESS: - //OK - break; - default: - //error - return 1; - } - - //////////////////////////////////////////////////////////////////////////////////// - memset(&port_mgmnt, 0x00, sizeof(port_mgmnt)); - port_mgmnt.operation_status = SANG_STATUS_GENERAL_ERROR; - - err=sangoma_driver_port_start(wp_handle, &port_mgmnt, wp_number); - if(err || port_mgmnt.operation_status){ - ERR_CFG("%s: failed to start Port after re-configuration!\n", wanpipe_name_str); - return 1; - } - - return 0; -} - - -int driver_configurator::init(unsigned int wanpipe_number, unsigned int port_number) -{ - DBG_CFG("%s():\n", __FUNCTION__); - - //this the MAPPED port number - wp_number = wanpipe_number + port_number + 1; - - wp_snprintf(wanpipe_name_str, sizeof(wanpipe_name_str), "wanpipe%d", wp_number); - DBG_CFG("%s\n", wanpipe_name_str); - - wp_handle = sangoma_open_driver_ctrl(wp_number); - - if(wp_handle == INVALID_HANDLE_VALUE){ -// ERR_CFG("Error: failed to open %s!!\n", wanpipe_name_str); - return 1; - } - - return 0; -} - -int driver_configurator::print_port_cfg_structure(port_cfg_t *port_cfg) -{ - wandev_conf_t *wandev_conf = &port_cfg->wandev_conf; - sdla_fe_cfg_t *sdla_fe_cfg = &wandev_conf->fe_cfg; - wanif_conf_t *wanif_conf = &port_cfg->if_cfg[0]; - - DBG_CFG("%s()\n", __FUNCTION__); - - _INFO_CFG("\n================================================\n"); - - INFO_CFG("Card Type\t: %s(%d)\n", SDLA_DECODE_CARDTYPE(wandev_conf->card_type), - wandev_conf->card_type);/* Sangoma Card type - S514, S518 or AFT.*/ - - INFO_CFG("Number of TimeSlot Groups: %d\n", port_cfg->num_of_ifs); - - INFO_CFG("MTU\t\t: %d\n", wandev_conf->mtu); - - print_sdla_fe_cfg_t_structure(sdla_fe_cfg); - - for(unsigned int i = 0; i < port_cfg->num_of_ifs; i++){ - _INFO_CFG("\n************************************************\n"); - _INFO_CFG("Configration of Group Number %d:\n", i); - print_wanif_conf_t_structure(&wanif_conf[i]); - } - return 0; -} - -int driver_configurator::print_sdla_fe_cfg_t_structure(sdla_fe_cfg_t *sdla_fe_cfg) -{ - _INFO_CFG("\n################################################\n"); - INFO_CFG("MEDIA\t\t: %s\n", MEDIA_DECODE(sdla_fe_cfg)); - if(FE_MEDIA(sdla_fe_cfg) == WAN_MEDIA_T1 || FE_MEDIA(sdla_fe_cfg) == WAN_MEDIA_E1){ - INFO_CFG("Line CODE\t: %s\n", LCODE_DECODE(sdla_fe_cfg)); - INFO_CFG("Framing\t\t: %s\n", FRAME_DECODE(sdla_fe_cfg)); - INFO_CFG("Clock Mode\t: %s\n", TECLK_DECODE(sdla_fe_cfg)); - INFO_CFG("Clock Reference port: %d (0 - not used)\n", FE_REFCLK(sdla_fe_cfg)); - INFO_CFG("Signalling Insertion Mode: %s\n", TE1SIG_DECODE(sdla_fe_cfg)); - - INFO_CFG("High Impedance Mode: %s\n", - (FE_HIMPEDANCE_MODE(sdla_fe_cfg) == WANOPT_YES ? "Yes":"No")); - INFO_CFG("FE_RX_SLEVEL: %d\n", FE_RX_SLEVEL(sdla_fe_cfg)); - }//if() - INFO_CFG("TDMV LAW\t: %s\n", (FE_TDMV_LAW(sdla_fe_cfg) == WAN_TDMV_MULAW ?"MuLaw":"ALaw")); - - switch(FE_MEDIA(sdla_fe_cfg)) - { - case WAN_MEDIA_T1: - INFO_CFG("LBO\t\t: %s\n", LBO_DECODE(sdla_fe_cfg)); - break; - case WAN_MEDIA_E1: - break; - default: - break; - } - return 0; -} - -int driver_configurator::print_wanif_conf_t_structure(wanif_conf_t *wanif_conf) -{ - INFO_CFG("Operation Mode\t: %s\n", wanif_conf->usedby); - INFO_CFG("Timeslot BitMap\t: 0x%08X\n", wanif_conf->active_ch); - INFO_CFG("Line Mode\t: %s\n", - (wanif_conf->hdlc_streaming == WANOPT_YES ? "HDLC":"BitStream")); - INFO_CFG("MTU\\MRU\t\t: %d\n", wanif_conf->mtu); - - return 0; -} - -int driver_configurator::get_hardware_info(hardware_info_t *hardware_info) -{ - DBG_CFG("%s()\n", __FUNCTION__); - - port_management_struct_t port_management; - - int err=sangoma_driver_get_hw_info(wp_handle,&port_management, wp_number); - - if (err) { - ERR_CFG("Error: failed to get hw info for wanpipe%d!\n", wp_number); - return 1; - } - - memcpy(hardware_info,port_management.data,sizeof(hardware_info_t)); - - return 0; -} - - -int driver_configurator::get_driver_version(wan_driver_version_t *version) -{ - DBG_CFG("%s()\n", __FUNCTION__); - - port_management_struct_t port_management; - - int err = sangoma_driver_get_version(wp_handle, &port_management, wp_number); - - if (err) { - ERR_CFG("Error: failed to get Driver Version from wanpipe%d!\n", wp_number); - return 1; - } - - memcpy(version, port_management.data, sizeof(*version)); - - return 0; -} - - -int driver_configurator::push_a_card_into_wanpipe_info_array( - wanpipe_instance_info_t *wanpipe_info_array, - hardware_info_t *new_hw_info) -{ - unsigned int card_ind; - hardware_info_t *tmp_hw_info; - - //check this card is not in the array already - for(card_ind = 0; card_ind < MAX_CARDS; card_ind++){ - tmp_hw_info = &wanpipe_info_array[card_ind].hardware_info; - - if( (new_hw_info->pci_bus_number == tmp_hw_info->pci_bus_number) && - (new_hw_info->pci_slot_number == tmp_hw_info->pci_slot_number)){ - //already in array. not an error. - DBG_CFG("already in array.\n"); - return 1; - } - } - - //find an empty slot in the array and place the new card there - for(card_ind = 0; card_ind < MAX_CARDS; card_ind++){ - tmp_hw_info = &wanpipe_info_array[card_ind].hardware_info; - if(tmp_hw_info->card_model == -1){ - //found an empty slot in array - memcpy(tmp_hw_info, new_hw_info, sizeof(hardware_info_t)); - return 0; - } - } - - //too many cards in the computer. - INFO_CFG("Warning: number of cards in the computer is greater than the maximum of %d.\n", - MAX_CARDS); - return 2; -} - -// -//Scan all running wanpipes, check which ones are on the same card, -//figure out how many physical cards installed. -// -//Returns: -1 - if error. -// number of cards, starting from zero. -int driver_configurator::scan_for_sangoma_cards(wanpipe_instance_info_t *wanpipe_info_array, int card_model) -{ - int card_counter = 0, wp_ind; - hardware_info_t hardware_info; - - //initialize hardware information array. - memset(wanpipe_info_array, -1, sizeof(wanpipe_instance_info_t)*MAX_CARDS); - - DBG_CFG("%s(): wanpipe_info_array: 0x%p\n", __FUNCTION__, wanpipe_info_array); - - for(wp_ind = 0; wp_ind < (MAX_CARDS * MAX_PORTS_PER_CARD); wp_ind++){ - if(init(wp_ind, 0)){ - continue; - } - if(get_hardware_info(&hardware_info)){ - //Port was opened but could not read hw info - dont add the port to the list - //and also consider there are no more ports, so exit the loop. - break; - } - - DBG_CFG("card_model : %s (0x%08X)\n", - SDLA_ADPTR_NAME(hardware_info.card_model), hardware_info.card_model); - DBG_CFG("firmware_version\t: 0x%02X\n", hardware_info.firmware_version); - DBG_CFG("pci_bus_number\t\t: %d\n", hardware_info.pci_bus_number); - DBG_CFG("pci_slot_number\t\t: %d\n", hardware_info.pci_slot_number); - - if(card_model == hardware_info.card_model){ - if(push_a_card_into_wanpipe_info_array(wanpipe_info_array, &hardware_info) == 0){ - //At this point we know: 1. WANPIPE number, for example WANPIPE1. - // 2. Card type, for example A104. - //It allows to figure out Device Name of each port on the card. - //For example: for A104 it will be WANPIPE1, WANPIPE2, WANPIPE3, WANPIPE4 - wanpipe_info_array[card_counter].wanpipe_number = wp_ind; - DBG_CFG("%s(): wp_ind: %u\n", __FUNCTION__, wp_ind); - card_counter++; - } - }else{ - DBG_CFG("Found a Card but Card Model is different from what was searched for.\n"); - } - - //it is important to Close each port which was opened during the scan. - cleanup(); - }//for() - - return card_counter; -} - -//function to switch between T1 and E1 -int driver_configurator::set_t1_e1_configuration(sdla_fe_cfg_t *in_sdla_fe_cfg, buffer_settings_t *buffer_settings) -{ - wandev_conf_t *wandev_conf = &port_cfg.wandev_conf; - sdla_fe_cfg_t *sdla_fe_cfg = &wandev_conf->fe_cfg; - wan_tdmv_conf_t *tdmv_cfg = &wandev_conf->tdmv_conf; - wanif_conf_t *wanif_cfg = &port_cfg.if_cfg[0]; - hardware_info_t tmp_hardware_info; - - DBG_CFG("%s()\n", __FUNCTION__); - - memset(&port_cfg, 0x00, sizeof(port_cfg_t)); - - get_hardware_info(&tmp_hardware_info); - - //copy T1/E1 configuration into the Driver configuration structure. - memcpy(sdla_fe_cfg, in_sdla_fe_cfg, sizeof(sdla_fe_cfg_t)); - - port_cfg.buffer_settings.buffer_multiplier_factor = buffer_settings->buffer_multiplier_factor; - port_cfg.buffer_settings.number_of_buffers_per_api_interface = buffer_settings->number_of_buffers_per_api_interface; - - wandev_conf->fe_cfg.cfg.te_cfg.active_ch = 0xFFFFFFFF;//a constant - - port_cfg.num_of_ifs = 1;//1 Group always - - /////////////////////////////////////////////////////////////////////////////// - wandev_conf->config_id = WANCONFIG_AFT_TE1; - wandev_conf->magic = ROUTER_MAGIC; - - wandev_conf->mtu = 2048; - - DBG_CFG("%s(): slot: %d, bus: %d, port_number:%d\n", __FUNCTION__, - tmp_hardware_info.pci_slot_number, tmp_hardware_info.pci_bus_number, - tmp_hardware_info.port_number); - - wandev_conf->PCI_slot_no = tmp_hardware_info.pci_slot_number; - wandev_conf->pci_bus_no = tmp_hardware_info.pci_bus_number; - wandev_conf->card_type = WANOPT_AFT; //m_DeviceInfoData.card_model; - - wanif_cfg->hdlc_streaming = WANOPT_NO;//BitStream - wanif_cfg->magic = ROUTER_MAGIC; - - sprintf(wanif_cfg->usedby, SDLA_DECODE_USEDBY_FIELD(TDM_SPAN_VOICE_API));//TDM_SPAN_VOICE_API - span mode supported by libsangoma.dll. - wanif_cfg->u.aft.idle_flag=0xFF; - - sprintf(wanif_cfg->name, "w%dg1", wp_number); - /////////////////////////////////////////////////////////////////////////////// - - port_cfg.port_no = FE_LINENO(sdla_fe_cfg) = tmp_hardware_info.port_number; - - // - //Set MTU/MRU per-TIMESLOT - the API driver will multiply this value by the - //number of timeslots this interface is using - t1:24, e1:31 or 32. - //The 'buffer_multiplier_factor' value will control how many of these - //buffers will be received on each RX indication. - // - if(FE_MEDIA(sdla_fe_cfg) == WAN_MEDIA_T1){ - //320*24=7680 - wanif_cfg->mtu = wanif_cfg->u.aft.mtu = wanif_cfg->u.aft.mru = 320; - } else { - //240*31=7440, 240*32=7680 - wanif_cfg->mtu = wanif_cfg->u.aft.mtu = wanif_cfg->u.aft.mru = 240; - } - - if(FE_MEDIA(sdla_fe_cfg) == WAN_MEDIA_T1){ - //T1, 1 Group of 24 Timeslots. - wanif_cfg->active_ch = 0xFFFFFF; - - FE_TDMV_LAW(sdla_fe_cfg) = WAN_TDMV_MULAW; - - }else if(FE_MEDIA(sdla_fe_cfg) == WAN_MEDIA_E1){ - //E1, 1 Group of 31 or 32 Timeslots. - //API driver will automatically adjust timeslot bitmap for "framed" e1 - wanif_cfg->active_ch = 0xFFFFFFFF; - - FE_TDMV_LAW(sdla_fe_cfg) = WAN_TDMV_ALAW; - FE_LBO(sdla_fe_cfg) = WAN_T1_LBO_NONE;//important to set to a valid value!! - }else{ - ERR_CFG("%s(): Error: invalid Media Type %d!\n", __FUNCTION__, sdla_fe_cfg->media); - return 1; - } - - tdmv_cfg->span_no = (unsigned char)wp_number; - - print_port_cfg_structure(&port_cfg); - - return set_configuration(&port_cfg); -} diff --git a/api/libsangoma/examples/sample_data_tapping/driver_configurator.h b/api/libsangoma/examples/sample_data_tapping/driver_configurator.h deleted file mode 100644 index 3a0aa9d..0000000 --- a/api/libsangoma/examples/sample_data_tapping/driver_configurator.h +++ /dev/null @@ -1,86 +0,0 @@ -////////////////////////////////////////////////////////////////////// -// driver_configurator.h: interface for the driver_configurator class. -// -// Author : David Rokhvarg -////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_DRIVER_CONFIGURATOR_H__115A6EC1_518C_45E9_AA55_148A8D999B61__INCLUDED_) -#define AFX_DRIVER_CONFIGURATOR_H__115A6EC1_518C_45E9_AA55_148A8D999B61__INCLUDED_ - -#if defined(__WINDOWS__) -# include -# include -#elif defined(__LINUX__) -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -#else -# error Unsupported OS -#endif - -#include -#include //for offsetof() - -#include "libsangoma.h" -#include "wanpipe_api.h" - -#define MAX_CARDS 16 -#define MAX_PORTS_PER_CARD 16 - -class driver_configurator -{ -public: - driver_configurator(); - virtual ~driver_configurator(); - - int get_hardware_info(hardware_info_t *hardware_info); - - int get_driver_version(wan_driver_version_t *version); - - int set_t1_e1_configuration(sdla_fe_cfg_t *sdla_fe_cfg, buffer_settings_t *buffer_settings); - - int init(unsigned int wanpipe_number, unsigned int port_number); - - //GET current configuraion of the API driver - int get_configuration(port_cfg_t *port_cfg); - - //SET new configuration of the API driver - int set_configuration(port_cfg_t *port_cfg); - - //Function to print contents of 'port_cfg_t' structure. - int print_port_cfg_structure(port_cfg_t *port_cfg); - - int print_sdla_fe_cfg_t_structure(sdla_fe_cfg_t *sdla_fe_cfg); - int print_wanif_conf_t_structure(wanif_conf_t *wanif_conf); - - int scan_for_sangoma_cards(wanpipe_instance_info_t *wanpipe_info_array, int card_model); - -private: - - port_cfg_t port_cfg; - unsigned int wp_number; - char wanpipe_name_str[WAN_DRVNAME_SZ*2]; - sng_fd_t wp_handle; - - //reverse actions of init() - void cleanup(); - - int push_a_card_into_wanpipe_info_array(wanpipe_instance_info_t *wanpipe_info_array, hardware_info_t *new_hw_info); -}; - -#endif // !defined(AFX_DRIVER_CONFIGURATOR_H__115A6EC1_518C_45E9_AA55_148A8D999B61__INCLUDED_) - diff --git a/api/libsangoma/examples/sample_data_tapping/sample_data_tapping.cpp b/api/libsangoma/examples/sample_data_tapping/sample_data_tapping.cpp index 57a1c06..9eaa848 100644 --- a/api/libsangoma/examples/sample_data_tapping/sample_data_tapping.cpp +++ b/api/libsangoma/examples/sample_data_tapping/sample_data_tapping.cpp @@ -1,12 +1,13 @@ - - -// sample_data_tapping.cpp : Defines the entry point for the console application. -// - -#include -#include "SangomaCard.h" - -#ifndef __WINDOWS__ + + +// sample_data_tapping.cpp : Defines the entry point for the console application. +// + +#include +#include +#include "Sangoma/SangomaCard.h" + +#ifndef __WINDOWS__ # include # include # include @@ -15,864 +16,888 @@ int _kbhit(void); #endif - -using namespace Sangoma; - -/* 64 is maximum number of handles in windows - This code will start another thread for - maximum capacity of 128 handles */ -#define MAX_HANDLES 64 - -const int VALID_NUM_OF_ARGS = 2; ///< The valid number of arguements expected by the program -const std::string A104_MODEL = "A104"; ///< Command line string used to indicate to check the system for Sangoma A104 cards -const std::string A108_MODEL = "A108"; ///< Command line string used to indicate to check the system for Sangoma A108 cards -const std::string A116_MODEL = "A116"; ///< Command line string used to indicate to check the system for Sangoma A116 cards -const std::string T116_MODEL = "T116"; ///< Command line string used to indicate to check the system for Sangoma A116 cards -bool gRunning = false; ///< Flag which is true if the sample program is currently monitoring the cards, false otherwise - -std::vector sangoma_cards; //stores all the cards in the system -std::vector sangoma_ports; //stores ALL the ports in the system -std::vector sangoma_ports_bank2; //stores ALL the ports in the system -std::vector next_framing_type_index; //for each port store the index of the next framing type to open the port with - -#define DBG_MAIN if(0)printf -#define INFO_MAIN if(1)printf -#define WRN_MAIN if(1)printf -#define ERR_MAIN printf("Error: %s():line:%d: ", __FUNCTION__, __LINE__);printf - -#define FUNC_MAIN() if(1)printf("%s():line:%d\n", __FUNCTION__, __LINE__) - -//SETUP FOR DETERMING PORT CONFIGURATION -const unsigned int NUMBER_OF_E1_FRAME_TYPES = 6; -const unsigned int NUMBER_OF_T1_FRAME_TYPES = 2; -const FramingType E1_TYPES[NUMBER_OF_E1_FRAME_TYPES] = {E1_CCS_CRC4_ON, E1_CCS_CRC4_OFF, E1_CAS_CRC4_ON, E1_CAS_CRC4_OFF, E1_CCS_UNFRAMED, E1_CAS_UNFRAMED}; -const FramingType T1_TYPES[NUMBER_OF_T1_FRAME_TYPES] = {T1_EXTENDED_SUPERFRAME, T1_SUPERFRAME}; - -static int iForcedLineType = -1;//< When greater than zero, will disable "Line Discovery" and configure for Line Type specified on command line. -static char szTxFileName[1024]; //< Full path to a file for transmission. -static int iLocalLoopback = 0; //< When non-zero, will enable Local Loopback at T1/E1 level -static int iSilent = 0; -static int iTimeout = 0; -static char rx2tx = 0; //< When non-zero, all Rx data will be transmitted at the time of reception. -static unsigned int total_number_of_ports=0; - - -#define sng_getch() do { if (!iSilent) _getch(); } while(0) - -char* wp_get_time_stamp() -{ - static char formatted_time_stamp[400]; - -#if defined(__WINDOWS__) - SYSTEMTIME timestamp; - GetLocalTime(×tamp); - wp_snprintf(formatted_time_stamp, sizeof(formatted_time_stamp), "Y:%d/M:%d/D:%d. H:%d/M:%d/S:%d/MS:%u", - timestamp.wYear, - timestamp.wMonth, - timestamp.wDay, - timestamp.wHour, - timestamp.wMinute, - timestamp.wSecond, - timestamp.wMilliseconds); -#else - struct timeval timestamp; - gettimeofday(×tamp, NULL); - - wp_snprintf(formatted_time_stamp, sizeof(formatted_time_stamp), "Sec:%u Ms:%u", - (uint32_t)timestamp.tv_sec, (uint32_t)(timestamp.tv_usec / 1000)); -#endif - return formatted_time_stamp; -} - -void print_data_buffer(unsigned char *buffer, int buffer_length) -{ - printf("Data length: %u\n", buffer_length); - - for(int ln = 0; ln < buffer_length; ln++){ - if((ln % 20 == 0)){ - if(ln){ - printf("\n"); - } - printf("%04d ", ln/20);//print offset - } - printf("%02X ", buffer[ln]); - } - printf("\n"); -} - -void print_to_debugger(void *pszFormat, ...) -{ - char str[512]; - va_list vaArg; - - va_start (vaArg, pszFormat); - _vsnprintf((char*)str, sizeof(str), (char *)pszFormat, vaArg); - va_end (vaArg); - -#if defined(__WINDOWS__) - OutputDebugString(str); -#else - printf("%s\n",str); -#endif - -} - -static int parse_command_line_args( - int argc, char* argv[], - CardModel *model, - unsigned int *number_of_ports_per_card, - Configuration & configuration, - BufferSettings & buffer_settings) -{ - int i; -#define USAGE_STR \ -"\n\ -Usage: sample_data_tapping CardModel [LineType] [h MaxCableLossOption]\n\ -\n\ -Options:\n\ - CardModel [a104 | a108 | a116]\n\ - LineType T1 or E1\n\ - MaxCableLossOption 430, 360, 300, 225, 180, 175, 120\n\ - tx_tristate this option will disable transmitter\n\ - bm Buffer Multiplier - between 1 and 7 (including)\n\ - -tx_file Will continuesly transmit when Line becomes synchronized.\n\ - Must be used in conjuction with one of \"Line Type\" options because\n\ - Line Tapping Device will discover the line type.\n\ - -local_loopback Enable \"Local Line Looopback\" at T1/E1 level. Must be used only for Master clock.\n\ - -e1_cas_crc4 Disable \"Line Discovery\" and configure for E1_CAS_CRC4_ON\n\ - -e1_cas_no_crc Disable \"Line Discovery\" and configure for E1_CAS_CRC4_OFF\n\ - -e1_ccs_crc4 Disable \"Line Discovery\" and configure for E1_CCS_CRC4_ON\n\ - -e1_ccs_no_crc Disable \"Line Discovery\" and configure for E1_CCS_CRC4_OFF\n\ - -e1_cas_unframed Disable \"Line Discovery\" and configure for E1_CAS_UNFRAMED\n\ - -e1_ccs_unframed Disable \"Line Discovery\" and configure for E1_CCS_UNFRAMED\n\ - -t1_esf Disable \"Line Discovery\" and configure for T1_EXTENDED_SUPERFRAME\n\ - -t1_sf Disable \"Line Discovery\" and configure for T1_SUPERFRAME\n\ - -rx2tx If used, all Rx data will be transmitted back to the transmitter.\n\ - -silent No user interaction.\n\ - -timeout No user interaction.\n\ -\n\ -Example 1: sample_data_tapping a108 e1\n\ -Example 2: sample_data_tapping a108 t1\n\ -Example 3: sample_data_tapping a108 e1 h 320\n\ -Example 4: sample_data_tapping a108 e1 h 320 tx_tristate\n\ -Example 4: sample_data_tapping a108 -e1_cas_crc4 -tx_file c:\\tmp\\test_file.pcm -local_loopback\n" - - *number_of_ports_per_card = 0; - szTxFileName[0] = '\0'; - - for(i = 0; i < argc; i++){ - - if(wp_strncasecmp(argv[i], "?", strlen(argv[i])) == 0 || wp_strncasecmp(argv[i], "/?", strlen(argv[i])) == 0){ - printf(USAGE_STR); - return 1; - }else if(wp_strncasecmp(argv[i], "T1", strlen(argv[i])) == 0){ - configuration.e1Ort1 = T1; - }else if(wp_strncasecmp(argv[i], "E1", strlen(argv[i])) == 0){ - configuration.e1Ort1 = E1; - }else if(wp_strncasecmp(argv[i], "a104", strlen(argv[i])) == 0){ - *model = A104; - *number_of_ports_per_card = NUMBER_OF_A104_PORTS; - }else if(wp_strncasecmp(argv[i], "a108", strlen(argv[i])) == 0){ - *model = A108; - *number_of_ports_per_card = NUMBER_OF_A108_PORTS; - }else if(wp_strncasecmp(argv[i], "a116", strlen(argv[i])) == 0){ - *model = A116; - *number_of_ports_per_card = NUMBER_OF_A116_PORTS; - }else if(wp_strncasecmp(argv[i], "t116", strlen(argv[i])) == 0){ - *model = T116; - *number_of_ports_per_card = 16; - }else if(wp_strncasecmp(argv[i], "h", strlen(argv[i])) == 0){ - if (i+1 > argc-1){ - ERR_MAIN("No Valid 'Max Cable Loss' value was provided!\n"); - printf(USAGE_STR); - return 1; - } - switch(atoi(argv[i+1])) - { - case MCLV_43_0dB: - case MCLV_36_0dB: - case MCLV_30_0dB: - case MCLV_22_5dB: - case MCLV_18_0dB: - case MCLV_17_5dB: - case MCLV_12_0dB: - configuration.HighImpedanceMode = true; - configuration.MaxCableLoss = (MAX_CABLE_LOSS)atoi(argv[i+1]); - break; - default: - configuration.HighImpedanceMode = false; - configuration.MaxCableLoss = MCLV_12_0dB; - } - }else if(wp_strncasecmp(argv[i], "tx_tristate", strlen(argv[i])) == 0){ - configuration.TxTristateMode = true; - - }else if(wp_strncasecmp(argv[i], "bm", strlen(argv[i])) == 0){ - if (i+1 > argc-1){ - ERR_MAIN("No Valid 'Buffer Multiplier' value was provided!\n"); - printf(USAGE_STR); - return 1; - } - buffer_settings.BufferMultiplierFactor = atoi(argv[i+1]); - if( buffer_settings.BufferMultiplierFactor < MIN_BUFFER_MULTIPLIER_FACTOR || - buffer_settings.BufferMultiplierFactor > MAX_BUFFER_MULTIPLIER_FACTOR){ - ERR_MAIN("The 'Buffer Multiplier' value of %d is invalid! Minimum is: %d, maximum is: %d! Setting to %d.\n", - buffer_settings.BufferMultiplierFactor, - MIN_BUFFER_MULTIPLIER_FACTOR, MAX_BUFFER_MULTIPLIER_FACTOR, - MIN_BUFFER_MULTIPLIER_FACTOR); - buffer_settings.BufferMultiplierFactor = MIN_BUFFER_MULTIPLIER_FACTOR; - printf(USAGE_STR); - return 1; - }else{ - INFO_MAIN("User's 'Buffer Multiplier' value is: %d.\n", buffer_settings.BufferMultiplierFactor); - } - - }else if(wp_strncasecmp(argv[i], "-tx_file", strlen(argv[i])) == 0){ - if (i + 1 > argc - 1) { +#include "libsangoma.h" + +using namespace Sangoma; + +/* 64 is maximum number of handles in windows + This code will start another thread for + maximum capacity of 128 handles */ +#define MAX_HANDLES 64 + +const int VALID_NUM_OF_ARGS = 2; ///< The valid number of arguements expected by the program +const std::string A104_MODEL = "A104"; ///< Command line string used to indicate to check the system for Sangoma A104 cards +const std::string A108_MODEL = "A108"; ///< Command line string used to indicate to check the system for Sangoma A108 cards +const std::string A116_MODEL = "A116"; ///< Command line string used to indicate to check the system for Sangoma A116 cards +const std::string T116_MODEL = "T116"; ///< Command line string used to indicate to check the system for Sangoma A116 cards +bool gRunning = false; ///< Flag which is true if the sample program is currently monitoring the cards, false otherwise + +std::vector sangoma_cards; //stores all the cards in the system +std::vector sangoma_ports; //stores ALL the ports in the system +std::vector sangoma_ports_bank2; //stores ALL the ports in the system + +#define DBG_MAIN if(0)printf +#define INFO_MAIN if(1)printf +#define WRN_MAIN if(1)printf +#define ERR_MAIN printf("Error: %s():line:%d: ", __FUNCTION__, __LINE__);printf + +#define FUNC_MAIN() if(1)printf("%s():line:%d\n", __FUNCTION__, __LINE__) + +//SETUP FOR DETERMING PORT CONFIGURATION +const unsigned int NUMBER_OF_E1_FRAME_TYPES = 2; +const unsigned int NUMBER_OF_T1_FRAME_TYPES = 2; +const FramingType E1_TYPES[NUMBER_OF_E1_FRAME_TYPES] = {E1_CCS_CRC4_ON, E1_CCS_CRC4_OFF}; +const FramingType T1_TYPES[NUMBER_OF_T1_FRAME_TYPES] = {T1_EXTENDED_SUPERFRAME, T1_SUPERFRAME}; + +static int iForcedLineType = -1;//< When greater than zero, will disable "Line Discovery" and configure for Line Type specified on command line. +static char szTxFileName[1024]; //< Full path to a file for transmission. +static int iLocalLoopback = 0; //< When non-zero, will enable Local Loopback at T1/E1 level +static int iSilent = 0; +static int iTimeout = 0; +static char rx2tx = 0; //< When non-zero, all Rx data will be transmitted at the time of reception. +static unsigned int total_number_of_ports=0; + + +#define sng_getch() do { if (!iSilent) _getch(); } while(0) + +char* wp_get_time_stamp() +{ + static char formatted_time_stamp[400]; + +#if defined(__WINDOWS__) + SYSTEMTIME timestamp; + GetLocalTime(×tamp); + wp_snprintf(formatted_time_stamp, sizeof(formatted_time_stamp), "Y:%d/M:%d/D:%d. H:%d/M:%d/S:%d/MS:%u", + timestamp.wYear, + timestamp.wMonth, + timestamp.wDay, + timestamp.wHour, + timestamp.wMinute, + timestamp.wSecond, + timestamp.wMilliseconds); +#else + struct timeval timestamp; + gettimeofday(×tamp, NULL); + + wp_snprintf(formatted_time_stamp, sizeof(formatted_time_stamp), "Sec:%u Ms:%u", + (uint32_t)timestamp.tv_sec, (uint32_t)(timestamp.tv_usec / 1000)); +#endif + return formatted_time_stamp; +} + +void print_data_buffer(unsigned char *buffer, int buffer_length) +{ + printf("Data length: %u\n", buffer_length); + + for(int ln = 0; ln < buffer_length; ln++){ + if((ln % 20 == 0)){ + if(ln){ + printf("\n"); + } + printf("%04d ", ln/20);//print offset + } + printf("%02X ", buffer[ln]); + } + printf("\n"); +} + +void print_to_debugger(void *pszFormat, ...) +{ + char str[512]; + va_list vaArg; + + va_start (vaArg, pszFormat); + _vsnprintf((char*)str, sizeof(str), (char *)pszFormat, vaArg); + va_end (vaArg); + +#if defined(__WINDOWS__) + OutputDebugString(str); +#else + printf("%s\n",str); +#endif + +} + +static int parse_command_line_args( + int argc, char* argv[], + CardModel *model, + unsigned int *number_of_ports_per_card, + Configuration & configuration, + BufferSettings & buffer_settings) +{ + int i; +#define USAGE_STR \ +"\n\ +Usage: sample_data_tapping CardModel [LineType] [h MaxCableLossOption]\n\ +\n\ +Options:\n\ + CardModel [a104 | a108 | a116]\n\ + LineType T1 or E1\n\ + MaxCableLossOption 430, 360, 300, 225, 180, 175, 120\n\ + tx_tristate this option will disable transmitter\n\ + bm Buffer Multiplier - between 1 and 7 (including)\n\ + -tx_file Will continuesly transmit when Line becomes synchronized.\n\ + Must be used in conjuction with one of \"Line Type\" options because\n\ + Line Tapping Device will discover the line type.\n\ + -local_loopback Enable \"Local Line Looopback\" at T1/E1 level. Must be used only for Master clock.\n\ + -e1_cas_crc4 Disable \"Line Discovery\" and configure for E1_CAS_CRC4_ON\n\ + -e1_cas_no_crc Disable \"Line Discovery\" and configure for E1_CAS_CRC4_OFF\n\ + -e1_ccs_crc4 Disable \"Line Discovery\" and configure for E1_CCS_CRC4_ON\n\ + -e1_ccs_no_crc Disable \"Line Discovery\" and configure for E1_CCS_CRC4_OFF\n\ + -e1_cas_unframed Disable \"Line Discovery\" and configure for E1_CAS_UNFRAMED\n\ + -e1_ccs_unframed Disable \"Line Discovery\" and configure for E1_CCS_UNFRAMED\n\ + -t1_esf Disable \"Line Discovery\" and configure for T1_EXTENDED_SUPERFRAME\n\ + -t1_sf Disable \"Line Discovery\" and configure for T1_SUPERFRAME\n\ + -rx2tx If used, all Rx data will be transmitted back to the transmitter.\n\ + -silent No user interaction.\n\ + -timeout No user interaction.\n\ +\n\ +Example 1: sample_data_tapping a108 e1\n\ +Example 2: sample_data_tapping a108 t1\n\ +Example 3: sample_data_tapping a108 e1 h 320\n\ +Example 4: sample_data_tapping a108 e1 h 320 tx_tristate\n\ +Example 4: sample_data_tapping a108 -e1_cas_crc4 -tx_file c:\\tmp\\test_file.pcm -local_loopback\n" + + *number_of_ports_per_card = 0; + szTxFileName[0] = '\0'; + + for(i = 0; i < argc; i++){ + + if(wp_strncasecmp(argv[i], "?", strlen(argv[i])) == 0 || wp_strncasecmp(argv[i], "/?", strlen(argv[i])) == 0){ + printf(USAGE_STR); + return 1; + }else if(wp_strncasecmp(argv[i], "T1", strlen(argv[i])) == 0){ + configuration.E1OrT1 = T1; + }else if(wp_strncasecmp(argv[i], "E1", strlen(argv[i])) == 0){ + configuration.E1OrT1 = E1; + }else if(wp_strncasecmp(argv[i], "a104", strlen(argv[i])) == 0){ + *model = A104; + *number_of_ports_per_card = NUMBER_OF_A104_PORTS; + }else if(wp_strncasecmp(argv[i], "a108", strlen(argv[i])) == 0){ + *model = A108; + *number_of_ports_per_card = NUMBER_OF_A108_PORTS; + }else if(wp_strncasecmp(argv[i], "a116", strlen(argv[i])) == 0){ + *model = A116; + *number_of_ports_per_card = NUMBER_OF_A116_PORTS; + }else if(wp_strncasecmp(argv[i], "t116", strlen(argv[i])) == 0){ + *model = T116; + *number_of_ports_per_card = 16; + }else if(wp_strncasecmp(argv[i], "h", strlen(argv[i])) == 0){ + if (i+1 > argc-1){ + ERR_MAIN("No Valid 'Max Cable Loss' value was provided!\n"); + printf(USAGE_STR); + return 1; + } + switch(atoi(argv[i+1])) + { + case MCLV_43_0dB: + case MCLV_36_0dB: + case MCLV_30_0dB: + case MCLV_22_5dB: + case MCLV_18_0dB: + case MCLV_17_5dB: + case MCLV_12_0dB: + configuration.HighImpedanceMode = true; + configuration.MaxCableLoss = (MAX_CABLE_LOSS)atoi(argv[i+1]); + break; + default: + configuration.HighImpedanceMode = false; + configuration.MaxCableLoss = MCLV_12_0dB; + } + }else if(wp_strncasecmp(argv[i], "tx_tristate", strlen(argv[i])) == 0){ + configuration.TxTristateMode = true; + + }else if(wp_strncasecmp(argv[i], "bm", strlen(argv[i])) == 0){ + if (i+1 > argc-1){ + ERR_MAIN("No Valid 'Buffer Multiplier' value was provided!\n"); + printf(USAGE_STR); + return 1; + } + buffer_settings.BufferMultiplierFactor = atoi(argv[i+1]); + if( buffer_settings.BufferMultiplierFactor < BufferSettings::MINIMUM_BUFFER_MULTIPLIER_FACTOR || + buffer_settings.BufferMultiplierFactor > BufferSettings::MAXIMUM_BUFFER_MULTIPLIER_FACTOR){ + ERR_MAIN("The 'Buffer Multiplier' value of %d is invalid! Minimum is: %d, maximum is: %d! Setting to %d.\n", + buffer_settings.BufferMultiplierFactor, + BufferSettings::MINIMUM_BUFFER_MULTIPLIER_FACTOR, BufferSettings::MAXIMUM_BUFFER_MULTIPLIER_FACTOR, + BufferSettings::MINIMUM_BUFFER_MULTIPLIER_FACTOR); + buffer_settings.BufferMultiplierFactor = BufferSettings::MINIMUM_BUFFER_MULTIPLIER_FACTOR; + printf(USAGE_STR); + return 1; + }else{ + INFO_MAIN("User's 'Buffer Multiplier' value is: %d.\n", buffer_settings.BufferMultiplierFactor); + } + + }else if(wp_strncasecmp(argv[i], "-tx_file", strlen(argv[i])) == 0){ + if (i + 1 > argc - 1) { INFO_MAIN("No TxFileName provided!\n"); printf(USAGE_STR); return 1; } wp_snprintf(szTxFileName, sizeof(szTxFileName), "%s", argv[i + 1]); INFO_MAIN("Setting szTxFileName to '%s'.\n", szTxFileName); - - }else if(wp_strncasecmp(argv[i], "-local_loopback", strlen(argv[i])) == 0){ + + }else if(wp_strncasecmp(argv[i], "-local_loopback", strlen(argv[i])) == 0){ INFO_MAIN("Enabling Local Loopback at T1/E1 level.\n"); - iLocalLoopback = 1; - configuration.Master=1; - }else if(wp_strncasecmp(argv[i], "-silent", strlen(argv[i])) == 0){ - iSilent = 1; - }else if(wp_strncasecmp(argv[i], "-timeout", strlen(argv[i])) == 0){ - if (i+1 > argc-1){ - ERR_MAIN("Invalid 'Timeout' value was provided!\n"); - printf(USAGE_STR); - return 1; - } - iTimeout = atoi(argv[i+1]); + iLocalLoopback = 1; + configuration.Master=1; + }else if(wp_strncasecmp(argv[i], "-silent", strlen(argv[i])) == 0){ + iSilent = 1; + }else if(wp_strncasecmp(argv[i], "-timeout", strlen(argv[i])) == 0){ + if (i+1 > argc-1){ + ERR_MAIN("Invalid 'Timeout' value was provided!\n"); + printf(USAGE_STR); + return 1; + } + iTimeout = atoi(argv[i+1]); }else if(wp_strncasecmp(argv[i], "-rx2tx", strlen(argv[i])) == 0){ INFO_MAIN("Enabling Rx-to-Tx for Rx data.\n"); rx2tx = 1; - }else if(wp_strncasecmp(argv[i], "-e1_cas_crc4", strlen(argv[i])) == 0){ - iForcedLineType = E1_CAS_CRC4_ON; - configuration.e1Ort1 = E1; - }else if(wp_strncasecmp(argv[i], "-e1_cas_no_crc", strlen(argv[i])) == 0){ - iForcedLineType = E1_CAS_CRC4_OFF; - configuration.e1Ort1 = E1; - }else if(wp_strncasecmp(argv[i], "-e1_ccs_crc4", strlen(argv[i])) == 0){ - iForcedLineType = E1_CCS_CRC4_ON; - configuration.e1Ort1 = E1; - }else if(wp_strncasecmp(argv[i], "-e1_ccs_no_crc", strlen(argv[i])) == 0){ - iForcedLineType = E1_CCS_CRC4_OFF; - configuration.e1Ort1 = E1; - }else if(wp_strncasecmp(argv[i], "-e1_cas_unframed", strlen(argv[i])) == 0){ - iForcedLineType = E1_CAS_UNFRAMED; - configuration.e1Ort1 = E1; - }else if(wp_strncasecmp(argv[i], "-e1_ccs_unframed", strlen(argv[i])) == 0){ - iForcedLineType = E1_CCS_UNFRAMED; - configuration.e1Ort1 = E1; - }else if(wp_strncasecmp(argv[i], "-t1_esf", strlen(argv[i])) == 0){ - iForcedLineType = T1_EXTENDED_SUPERFRAME; - configuration.e1Ort1 = T1; - }else if(wp_strncasecmp(argv[i], "-t1_sf", strlen(argv[i])) == 0){ - iForcedLineType = T1_SUPERFRAME; - configuration.e1Ort1 = T1; - } - }//for() - - if(*number_of_ports_per_card == 0){ - printf(USAGE_STR); - return 1; - } - - if (szTxFileName[0] != '\0' && iForcedLineType == -1) { - ERR_MAIN("\"Line Type\" must be provided for -tx_file option!\n"); - printf(USAGE_STR); - return 1; - } - - INFO_MAIN("\nCommand Line parsing summary:\n"); - - if (iForcedLineType != -1) { - configuration.Framing = (FramingType)iForcedLineType; - } - - if (szTxFileName[0] != '\0') { - //user wants to transmit a file - no need for Line Discovery - INFO_MAIN("CardModel: %s, Forced Line Type: %s, TxFileName: '%s'\n\n", - DECODE_CARD_TYPE(*model), DECODE_FRAMING(configuration.Framing), szTxFileName); - - } else { - //user wants to tap a line - first must run Line Discovery - INFO_MAIN("CardModel: %s, Line Type: %s, HighImpedance: %s, MaxCableLoss: %u, TxTristateMode: %s\n\n", - DECODE_CARD_TYPE(*model), (configuration.e1Ort1 == T1 ? "T1":"E1"), - (configuration.HighImpedanceMode == true ? "On":"Off"), configuration.MaxCableLoss, - (configuration.TxTristateMode == true ? "On":"Off")); - } - INFO_MAIN("Press key to continue.\n"); - sng_getch(); - - return 0; -} - - -/////////////////////////////////////////////////////////////////////////////////////////////// -/// \fn PortEventHandler(SangomaPort* p_port, unsigned int out_flags) -/// \brief This function handles Data and Events raised by the Sangoma classes. -/// \param p_port Pointer to the SangomaPort object that issued this event -/// \param out_flags BitMap containing information about Data/Events raised by Sangoma Classes -/// \return true if the event was successfully handled, false if an error occured -/// \author Josh Markwordt/David Rokhvarg -/// \date 5/31/2010 -/////////////////////////////////////////////////////////////////////////////////////////////// -bool PortEventHandler(SangomaPort* p_port, unsigned int out_flags) -{ - Alarms sangoma_alarms; -#if 0 - static int print_flag = 1; -#endif - - //CHECK IF WE WERE PASSED A VALID PORT - bool invalid_port = (NULL == p_port); - if (invalid_port) { - std::cerr << "ERROR: PortEvent created on invalid port." << std::endl; - return false; - } - - if(p_port->GetIsOpen() == false){ - /* Some other port's event got signalled. Don't try to Read() on a closed port. */ - return true; - } - - //READ FROM THE PORT THAT GENERATED THE EVENT (THIS READ NEEDS TO BE THREAD SAFE) - //Regardless of the reason for the event always call Read(). This will either gives us the data or return - //reason the event was triggered (e.g. PORT_IN_SYNC, PORT_OUT_OF_SYNC). - int read_result = p_port->Read(out_flags); - - //PROCESS THE EVENT. - //Also check if the read was successful, if not then we need to determine what the problem was. - //DBG_MAIN("Port %u: ", p_port->GetPortNumber()); - switch(read_result) - { - case ReadDataAvailable: - DBG_MAIN("ReadDataAvailable\n"); -#if 0 - //As an example of how to access Rx data, print the Rx data: - if (p_port->GetPortNumber() == 0) { - print_data_buffer(p_port->GetRxDataBuffer(), p_port->GetRxDataLength()); - } -#endif -#if 0 - if (print_flag) { - print_flag = 0; - printf("rx len: %d\n", p_port->GetRxDataLength()); - } -#endif - p_port->rx_len=p_port->GetRxDataLength(); - - //As an example of how to transmit data, call Write() whith Rx data as input. - p_port->rx_discard_counter++; + }else if(wp_strncasecmp(argv[i], "-e1_cas_crc4", strlen(argv[i])) == 0){ + iForcedLineType = E1_CAS_CRC4_ON; + configuration.E1OrT1 = E1; + }else if(wp_strncasecmp(argv[i], "-e1_cas_no_crc", strlen(argv[i])) == 0){ + iForcedLineType = E1_CAS_CRC4_OFF; + configuration.E1OrT1 = E1; + }else if(wp_strncasecmp(argv[i], "-e1_ccs_crc4", strlen(argv[i])) == 0){ + iForcedLineType = E1_CCS_CRC4_ON; + configuration.E1OrT1 = E1; + }else if(wp_strncasecmp(argv[i], "-e1_ccs_no_crc", strlen(argv[i])) == 0){ + iForcedLineType = E1_CCS_CRC4_OFF; + configuration.E1OrT1 = E1; + }else if(wp_strncasecmp(argv[i], "-e1_cas_unframed", strlen(argv[i])) == 0){ + iForcedLineType = E1_CAS_UNFRAMED; + configuration.E1OrT1 = E1; + }else if(wp_strncasecmp(argv[i], "-e1_ccs_unframed", strlen(argv[i])) == 0){ + iForcedLineType = E1_CCS_UNFRAMED; + configuration.E1OrT1 = E1; + }else if(wp_strncasecmp(argv[i], "-t1_esf", strlen(argv[i])) == 0){ + iForcedLineType = T1_EXTENDED_SUPERFRAME; + configuration.E1OrT1 = T1; + }else if(wp_strncasecmp(argv[i], "-t1_sf", strlen(argv[i])) == 0){ + iForcedLineType = T1_SUPERFRAME; + configuration.E1OrT1 = T1; + } + }//for() + + if(*number_of_ports_per_card == 0){ + printf(USAGE_STR); + return 1; + } + + if (szTxFileName[0] != '\0' && iForcedLineType == -1) { + ERR_MAIN("\"Line Type\" must be provided for -tx_file option!\n"); + printf(USAGE_STR); + return 1; + } + + INFO_MAIN("\nCommand Line parsing summary:\n"); + + if (iForcedLineType != -1) { + configuration.Framing = (FramingType)iForcedLineType; + } + + if (szTxFileName[0] != '\0') { + //user wants to transmit a file - no need for Line Discovery + INFO_MAIN("CardModel: %s, Forced Line Type: %s, TxFileName: '%s'\n\n", + DECODE_CARD_TYPE(*model), DECODE_FRAMING(configuration.Framing), szTxFileName); + + } else { + //user wants to tap a line - first must run Line Discovery + INFO_MAIN("CardModel: %s, Line Type: %s, HighImpedance: %s, MaxCableLoss: %u, TxTristateMode: %s\n\n", + DECODE_CARD_TYPE(*model), (configuration.E1OrT1 == T1 ? "T1":"E1"), + (configuration.HighImpedanceMode == true ? "On":"Off"), configuration.MaxCableLoss, + (configuration.TxTristateMode == true ? "On":"Off")); + } + INFO_MAIN("Press key to continue.\n"); + sng_getch(); + + return 0; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// \fn PortEventHandler(SangomaPort* p_port, unsigned int out_flags) +/// \brief This function handles Data and Events raised by the Sangoma classes. +/// \param p_port Pointer to the SangomaPort object that issued this event +/// \param out_flags BitMap containing information about Data/Events raised by Sangoma Classes +/// \return true if the event was successfully handled, false if an error occured +/// \author Josh Markwordt/David Rokhvarg +/// \date 5/31/2010 +/////////////////////////////////////////////////////////////////////////////////////////////// +bool PortEventHandler(SangomaPort* p_port, unsigned int out_flags) +{ + Alarms sangoma_alarms; +#if 0 + static int print_flag = 1; +#endif + + //CHECK IF WE WERE PASSED A VALID PORT + bool invalid_port = (NULL == p_port); + if (invalid_port) { + std::cerr << "ERROR: PortEvent created on invalid port." << std::endl; + return false; + } + + if(p_port->GetIsOpen() == false){ + /* Some other port's event got signalled. Don't try to Read() on a closed port. */ + return true; + } + + //READ FROM THE PORT THAT GENERATED THE EVENT (THIS READ NEEDS TO BE THREAD SAFE) + //Regardless of the reason for the event always call Read(). This will either gives us the data or return + //reason the event was triggered (e.g. PORT_IN_SYNC, PORT_OUT_OF_SYNC). + int read_result = p_port->Read(out_flags); + + //PROCESS THE EVENT. + //Also check if the read was successful, if not then we need to determine what the problem was. + //DBG_MAIN("Port %u: ", p_port->GetPortNumber()); + switch(read_result) + { + case ReadDataAvailable: + DBG_MAIN("ReadDataAvailable\n"); + p_port->RxCount++; +#if 0 + //As an example of how to access Rx data, print the Rx data: + if (p_port->GetPortNumber() == 0) { + print_data_buffer(p_port->GetRxDataBuffer(), p_port->GetRxDataLength()); + } +#endif +#if 0 + if (print_flag) { + print_flag = 0; + printf("rx len: %d\n", p_port->GetRxDataLength()); + } +#endif + p_port->RxLength=p_port->GetRxDataLength(); + + //As an example of how to transmit data, call Write() whith Rx data as input. + p_port->RxDiscardCounter++; if (rx2tx) { //To avoid blocking receiver when waiting for transmitter, //discard 1-st hundred rx buffers before starting rx2tx //(it will clear the Tx queue before we start transmitting). - if (1 || p_port->rx_discard_counter > 100) { + if (1 || p_port->RxDiscardCounter > 100) { p_port->Write(p_port->GetRxDataBuffer(), p_port->GetRxDataLength()); - if (p_port->rx_discard_counter == 1) { - p_port->ClearStatistics(); - } + if (p_port->RxDiscardCounter == 1) { + p_port->ClearStatistics(); + } } } - break; - case LineConnected: - //DBG_MAIN("LineConnected\n"); - /// \todo Handle the line connected event - //DAVIDR: port is open, line connected --> start handling incoming data. - p_port->rx_discard_counter = 0; - p_port->ClearStatistics(); - p_port->FlushBuffers(); - break; - case LineDisconnected: - //DBG_MAIN("LineDisconnected\n"); - //DAVIDR: the line got disconnected. If Alarams are of any interest, read them here. - //May put a message for the user "cable disconnected". - // - sangoma_alarms = p_port->GetAlarms(); - /// \todo Handle the line disconnected event - //DAVIDR Note: Some lines go up/down frequently and closing the port and starting Line type discovery - //may cause a lot of unwanted load on the CPU. The best thing to do is to keep the port open - //and wait for the LineConnected event, because the line type is already known and in the - //real world it is not changing often. If the LineConnected event not received within - //some timeout, it may make sense to close the port and start the Line type discovery. - break; - case ERROR_NO_DATA_AVILABLE: - //FIXME: This condition may occur only during Line Discovery. Since no data can be received from - //a disconnected port, this should be treated as a Warning, not an Error. Still, should be debugged in the future. - //For now, ignore the warning. - std::cout << "Port: " << p_port->GetPortNumber() << ": Warning: The event triggered but no data is available\n" << std::endl; - break; - case ERROR_INVALID_DESTINATION_BUFFER: - std::cerr << "Port: " << p_port->GetPortNumber() << ": Error: Unable to read because provided buffer was invalid\n" << std::endl; - break; - case ERROR_INVALID_DESTINATION_BUFFER_TOO_SMALL: - std::cerr << "Port: " << p_port->GetPortNumber() << ": Error: Unable to read because provided buffer was too small to hold the data.\n" << std::endl; - break; - case ERROR_PORT_NOT_OPEN: - std::cerr << "Port: " << p_port->GetPortNumber() << ": Error: The port is not Open.\n" << std::endl; - break; - case ERROR_DEVICE_IOCTL: - std::cout << p_port->GetLastError(); - break; - case TransmitBufferAvailable: - p_port->WriteChunkOfTxFile(); - break; - default: - std::cerr << "Port: " << p_port->GetPortNumber() << ": Unknown Error reported by Read()\n" << std::endl; - break; - } // switch(read_result) - - return true; -} -#if defined(__WINDOWS__) -DWORD SangomaThreadFunc(void *p_param) -#else -void* SangomaThreadFunc(void *p_param) -#endif -{ - int iResult; - DBG_MAIN("\n%s() - start\n", __FUNCTION__); - - //CAST TO THE OBJECT THAT WAS PASSED IN - std::vector* p_ports = static_cast*>(p_param); - std::vector::iterator iter; - - SangomaPort *p_port; - - //DETERMINE THE EVENT HANDLES FOR ALL THE PORTS IN ALL OF THE CARDS - //these handles will be passed to WaitForMultipleObjects so that we know when to read - unsigned int total_number_of_ports_in_system = static_cast( p_ports->size() ); - unsigned int port_index, number_of_open_ports = 0; - //SETUP VARIABLES FOR PROCESSING THE EVENT - DWORD PORT_READ_TIMEOUT = 3000; //arbitrarily set, doesn't matter b/c we don't do anything on a time out - - sangoma_wait_obj* port_event_handles[MAX_HANDLES]; - unsigned int port_input_flags[MAX_HANDLES]; - unsigned int port_output_flags[MAX_HANDLES]; - SangomaPort* sangoma_open_ports[MAX_HANDLES]; //stores Open ports only - - if (total_number_of_ports_in_system > MAX_HANDLES) { - fprintf(stderr,"Error Total number of ports %i > Max Hanldes %i\n",total_number_of_ports_in_system,MAX_HANDLES); - exit(1); - } - - DBG_MAIN("%s():total_number_of_ports_in_system: %d\n", __FUNCTION__, total_number_of_ports_in_system); - - //START PROCESSING IN THE THREAD - while(gRunning) - { - //DavidR: Ports are getting Open and Closed during Line type Discovery, only - //the Open ports will have a valid Event which can be waited on. - //Go through the list of Open ports and populate the array of Sangoma Waitable objects. - number_of_open_ports = 0; - memset(port_event_handles, 0x00, sizeof(port_event_handles)); - memset(port_input_flags, 0x00, sizeof(port_input_flags)); - memset(port_output_flags, 0x00, sizeof(port_output_flags)); - memset(sangoma_open_ports, 0x00, sizeof(sangoma_open_ports)); - - - for (iter = p_ports->begin(); iter != p_ports->end(); ++iter) { - p_port = *iter; - - if (p_port->GetIsOpen() == true && - p_port->GetEvent().EventHandle && - p_port->GetEvent().EventHandle != (void*)INVALID_HANDLE_VALUE) - { - port_event_handles[number_of_open_ports] = p_port->GetEvent().EventHandle; - DBG_MAIN("Port %i Handle %p\n",p_port->GetPortNumber(),p_port->GetEvent().EventHandle); - - if (szTxFileName[0] == '\0') { - //rx and line state - port_input_flags[number_of_open_ports] = (POLLIN | POLLPRI); - } else { - //tx and line state - port_input_flags[number_of_open_ports] = (POLLOUT | POLLPRI); - } - - sangoma_open_ports[number_of_open_ports] = p_port; - - number_of_open_ports++; - } - } - - if(!number_of_open_ports){ - WRN_MAIN("%s(): no open ports!\n", __FUNCTION__); - sangoma_msleep(1000); - continue; - } - - DBG_MAIN("%s(): number_of_open_ports: %d\n", __FUNCTION__, number_of_open_ports); - - //WAIT FOR AN EVENT FROM THE PORT - //We are signalled anytime there is an event. This could be for a line connection, - //a line disconnection, or if there is data available. - - iResult = sangoma_waitfor_many(port_event_handles, - port_input_flags, - port_output_flags, - number_of_open_ports, - PORT_READ_TIMEOUT /* Wait timeout, in milliseconds. Or SANGOMA_INFINITE_API_POLL_WAIT. */ - ); - - if (iResult == SANG_STATUS_APIPOLL_TIMEOUT) { - WRN_MAIN("%s(): Timeout\n", __FUNCTION__); - continue; - } - - if (iResult != SANG_STATUS_SUCCESS) { - WRN_MAIN("sangoma_waitfor_many: iResult: %s (%d)\n", SDLA_DECODE_SANG_STATUS(iResult), iResult); - //FIXME Do not Assert in production - exit(1); - break; - } - - //DavidR: go through the array of OUT flags and do the work for those which are set. - for(port_index = 0; port_index < number_of_open_ports; ++port_index) - { - /* a wait object was signaled */ - if( port_output_flags[port_index] & POLLIN || - port_output_flags[port_index] & POLLPRI || - port_output_flags[port_index] & POLLOUT ) { - - // Retreive the signaled port from the list of open ports - p_port = sangoma_open_ports[port_index]; - if(p_port == NULL){ - std::cout << "ERROR: invalid port index: " << port_index << std::endl; - exit(1); - continue; - } - - // Call PortEventHandler() for each bit in port_output_flags[port_index] - if (port_output_flags[port_index] & POLLIN) - { // handle Rx Data - if (PortEventHandler(p_port, POLLIN) == false) - { // Call the event handler to take the appropriate actions - std::cout << "ERROR: Rx Data on port " << port_index << " could not be handled properly." << std::endl; - } - } - - if (port_output_flags[port_index] & POLLPRI) - { //handle an Event - if (PortEventHandler(p_port, POLLPRI) == false) - { // Call the event handler to take the appropriate actions - std::cout << "ERROR: An Event on port " << port_index << " could not be handled properly." << std::endl; - } - } - - if (port_output_flags[port_index] & POLLOUT) - { //handle an Event - if (PortEventHandler(p_port, POLLOUT) == false) - { // Call the event handler to take the appropriate actions - std::cout << "ERROR: An Event on port " << port_index << " could not be handled properly." << std::endl; - } - } - - } - - if( port_output_flags[port_index] & (~port_input_flags[port_index]) ){ - WRN_MAIN("\nUnexpected port_output_flags[%d]: 0x%X\n\n", port_index, port_output_flags[port_index]); - iResult = SANG_STATUS_IO_ERROR; - - //FIXME Don't assert in production - exit(1); - } - }//for() - - } // while(gRunning) - - DBG_MAIN( "\n%s() - end\n", __FUNCTION__); - -#if defined(__WINDOWS__) - return 0; -#else - pthread_exit(NULL); - return NULL; -#endif -} - -const char *decode_port_sync_status(SynchronizationStatus & status) -{ - switch( status ) - { - case PORT_IN_SYNC: - return "PORT_IN_SYNC"; - case PORT_NOT_IN_SYNC: - return "PORT_NOT_IN_SYNC"; - case PORT_WAITING_FOR_SYNC: - return "PORT_WAITING_FOR_SYNC"; - } - return "Unknown sync status"; -} - -void load_driver_modules() -{ -#if defined(__WINDOWS__) - //driver loaded by PnP system - do nothing here -#else - //run "hwprobe" - if driver not loaded yet this command will load the driver - system("wanrouter hwprobe"); -#endif -} - -void clear_screen() -{ -#if defined(__WINDOWS__) - system("cls"); -#else - system("clear"); -#endif -} - -void print_cfg_stats(void *p_param) -{ - std::vector* p_ports = static_cast*>(p_param); - - INFO_MAIN("\n"); - //print port statistics/status - for(unsigned int port_index = 0; port_index < p_ports->size(); ++port_index) - { - SangomaPort* p_port = p_ports->at(port_index); //make a copy of the pointer to make it easier to work with - SynchronizationStatus status = p_port->GetSynchronizationStatus(); //retrieve the synchronization status. DAVIDR: requires context switch to kernel-mode, should not be called too often. - - if (p_port->sync_cnt == 1) { - p_port->GetStatistics(); - } - - Statistics stats = p_port->GetStatistics(); //Get the statistics for this port - - INFO_MAIN("Port:%02d(unmapped:%02d):%20s,\tRx Count: %8u\tTx Count: %8u\tErrors: %8u\tRx Len: %i\n", - p_port->GetPortNumber(), p_port->GetUnmappedPortNumber(), - decode_port_sync_status(status), - stats.BytesReceived, stats.BytesSent,stats.Errors,p_port->rx_len); - } - -} - -void print_io_stats(void *p_param) -{ - //print Line Type of Ports in Sync - std::vector* p_ports = static_cast*>(p_param); - - INFO_MAIN("\n"); - for(unsigned int port_index = 0; port_index < p_ports->size(); ++port_index) - { - SangomaPort* p_port = p_ports->at(port_index); //make a copy of the pointer to make it easier to work with - SynchronizationStatus status = p_port->GetSynchronizationStatus(); //retrieve the synchronization status. DAVIDR: requires context switch to kernel-mode, should not be called too often. - Configuration cfg = p_port->GetConfiguration(); - - INFO_MAIN("Port %d: %20s,\tLineType: %s,\tFraming: %s\n", - p_port->GetPortNumber(), - decode_port_sync_status(status), - (cfg.e1Ort1 == E1 ? "E1" : "T1"), - DECODE_FRAMING(cfg.Framing)); - } -} - -int main_loop_per_port_bank(void *p_param, Configuration & configuration) -{ - std::vector* p_ports = static_cast*>(p_param); - - //DETERMINE EACH PORTS CONFIGURATION - for(unsigned int port_index = 0; port_index < p_ports->size(); ++port_index) - { - //RETRIEVE THE SYNCHRONIZATION STATUS - SangomaPort* p_port = p_ports->at(port_index); //make a copy of the pointer to make it easier to work with - SynchronizationStatus status = p_port->GetSynchronizationStatus(); //retrieve the synchronization status. DAVIDR: requires context switch to kernel-mode, should not be called too often. - - DBG_MAIN("Port %d: %s\n", port_index, decode_port_sync_status(status)); - //BASED ON THE STATUS DETERMINE WHAT TO DO - switch( status ) - { - case PORT_IN_SYNC: - //do nothing here, Read() will be performed in their separate threads - break; - case PORT_NOT_IN_SYNC: - if (iForcedLineType != -1) - { //user specified the Line Type - do not attempt to run Line Discovery. - if (p_port->GetIsOpen() == false) { - configuration.lineCoding = ON; - p_port->Open(configuration);//open the port with FORCED configuration, only a single time. - - if (szTxFileName[0] != '\0') { - if (p_port->SetAndOpenTxFile(szTxFileName)) { - ERR_MAIN("Failed to open file: %s\n", szTxFileName); - exit(1); - } - } - - ////////////////////////////////////////// - //apply user-specfied settings to the port - ////////////////////////////////////////// - if (iLocalLoopback) { - p_port->LineLoopbackEnable(); - } - } - } else { - //determine the next configuration to try - unsigned int next_frame_type = next_framing_type_index.at(port_index); //retrieve the next frame type to try - if(configuration.e1Ort1 == T1){ - next_framing_type_index.at(port_index) = (next_frame_type + 1) % NUMBER_OF_T1_FRAME_TYPES; //move the stored index to the frame type to try next time - configuration.Framing = T1_TYPES[next_frame_type]; - configuration.lineCoding = ON; - }else{ - next_framing_type_index.at(port_index) = (next_frame_type + 1) % NUMBER_OF_E1_FRAME_TYPES; //move the stored index to the frame type to try next time - configuration.Framing = E1_TYPES[next_frame_type]; - configuration.lineCoding = ON; - } - - p_port->Close(); //close the port - p_port->Open(configuration); //re-open the port with the new configuration - } - break; - case PORT_WAITING_FOR_SYNC: - //do nothing because we are waiting on a configuration to find sync - break; - default: - //error, unknown synchronization status - break; - } // switch( status ) - } // for(unsigned int port_index = 0; port_index < ports.size(); ++port_index) - - return 0; -} - -int main_program_loop(void * p_param, void *p_param2, Configuration & configuration) -{ - //CAST TO THE OBJECT THAT WAS PASSED IN - int timeout=0; - std::vector* p_ports = static_cast*>(p_param); - std::vector* p_ports_bank2 = static_cast*>(p_param2); - - std::cerr << "Errout Test \n" << std::endl; - - //CONTINUOUSLY TRY TO DETERMINE THE PORTS CONFIGURATION - //if the port is in-sync nothing happens but while the port is out of sync - //we cycle through the framing types to try and find the correct one. - while( gRunning ) - { - - main_loop_per_port_bank(p_ports, configuration); - main_loop_per_port_bank(p_ports_bank2, configuration); - - clear_screen(); - - - INFO_MAIN("\nTime: %s \n", wp_get_time_stamp()); - - print_cfg_stats(&sangoma_ports); //print statistics for all ports - print_cfg_stats(&sangoma_ports_bank2); //print statistics for all ports -#if 0 - print_io_stats(&sangoma_ports); //print statistics for all ports - print_io_stats(&sangoma_ports_bank2); //print statistics for all ports -#endif - - -// std::cout << "To refresh the screen press " << std::endl; - - if (!iTimeout) { - - std::cout << "To exit, press or " << std::endl; - - sangoma_msleep(2000); //sleep 2 seconds between each iteration to avoid busy loop! - - if( _kbhit() ) { - switch(tolower(_getch())) - { - case 'x': - case 'q': - gRunning = false; - break; - default: - std::cout << "Warning: Invalid command!" << std::endl; - break; - } - } - } else { - sangoma_msleep(1000); - timeout++; - if (timeout >= iTimeout) { - break; - } - } - - } // while( gRunning ) - - std::cout << "Exiting Main Loop ... " << std::endl; - - sangoma_msleep(2000); //Sleep 2 seconds before exiting to make sure the other thread exits - - return 0; -} - -int G3TI_CreateThread(void *sangoma_ports_ptr) -{ -#if defined(__WINDOWS__) - DWORD SangomaThreadId; - HANDLE hSangomaThread; - - //step 1 - create the single worker thread - hSangomaThread = CreateThread( - NULL, /* no security attributes */ - 0, /* use default stack size */ - (LPTHREAD_START_ROUTINE)SangomaThreadFunc, /* thread function */ - sangoma_ports_ptr, /* argument to thread function */ - 0, /* use default creation flags */ - &SangomaThreadId /* returns the thread identifier */ - ); - - if(hSangomaThread == NULL){ - ERR_MAIN( "Failed to create Sangoma thread!!\n"); - return 1; - } - -#if 0 - //step 2 - set process priority to above normal - if (!SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS)) { - WRN_MAIN( "Failed to set Process priority!!\n"); - } - - //step 3 - set thread priority to real-time - if(SetThreadPriority(hSangomaThread, THREAD_PRIORITY_TIME_CRITICAL) == FALSE){ - WRN_MAIN( "Failed to set Thread priority!!\n"); - } -#endif - - //success - return 0; - -#elif defined(__LINUX__) -# define CTHREAD_STACK_SIZE 1024 * 240 - pthread_t dwThreadId; - pthread_attr_t attr; - int result = -1; - void *pParam = sangoma_ports_ptr; - - 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, CTHREAD_STACK_SIZE); - - result = pthread_create(&dwThreadId, &attr, SangomaThreadFunc, pParam); - pthread_attr_destroy(&attr); - if (result) { - return 1; - } - - return 0; -#else -# error Unsupported OS -#endif -} - -#ifndef __WINDOWS__ + break; + case LineConnected: + //DBG_MAIN("LineConnected\n"); + /// \todo Handle the line connected event + //DAVIDR: port is open, line connected --> start handling incoming data. + p_port->RxDiscardCounter = 0; + p_port->ClearStatistics(); + p_port->FlushBuffers(); + break; + case LineDisconnected: + //DBG_MAIN("LineDisconnected\n"); + //DAVIDR: the line got disconnected. If Alarams are of any interest, read them here. + //May put a message for the user "cable disconnected". + // + sangoma_alarms = p_port->GetAlarms(); + /// \todo Handle the line disconnected event + //DAVIDR Note: Some lines go up/down frequently and closing the port and starting Line type discovery + //may cause a lot of unwanted load on the CPU. The best thing to do is to keep the port open + //and wait for the LineConnected event, because the line type is already known and in the + //real world it is not changing often. If the LineConnected event not received within + //some timeout, it may make sense to close the port and start the Line type discovery. + break; + case ERROR_NO_DATA_AVAILABLE: + //FIXME: This condition may occur only during Line Discovery. Since no data can be received from + //a disconnected port, this should be treated as a Warning, not an Error. Still, should be debugged in the future. + //For now, ignore the warning. + std::cout << "Port: " << p_port->GetPortNumber() << ": Warning: The event triggered but no data is available\n" << std::endl; + break; + case ERROR_INVALID_DESTINATION_BUFFER: + std::cerr << "Port: " << p_port->GetPortNumber() << ": Error: Unable to read because provided buffer was invalid\n" << std::endl; + break; + case ERROR_INVALID_DESTINATION_BUFFER_TOO_SMALL: + std::cerr << "Port: " << p_port->GetPortNumber() << ": Error: Unable to read because provided buffer was too small to hold the data.\n" << std::endl; + break; + case ERROR_PORT_NOT_OPEN: + std::cerr << "Port: " << p_port->GetPortNumber() << ": Error: The port is not Open.\n" << std::endl; + break; + case ERROR_DEVICE_IOCTL: + std::cout << p_port->GetLastError(); + break; + case TransmitBufferAvailable: + p_port->WriteChunkOfTxFile(); + break; + default: + std::cerr << "Port: " << p_port->GetPortNumber() << ": Unknown Error reported by Read()\n" << std::endl; + break; + } // switch(read_result) + + return true; +} +#if defined(__WINDOWS__) +DWORD SangomaThreadFunc(void *p_param) +#else +void* SangomaThreadFunc(void *p_param) +#endif +{ + int iResult; + DBG_MAIN("\n%s() - start\n", __FUNCTION__); + + //CAST TO THE OBJECT THAT WAS PASSED IN + std::vector* p_ports = static_cast*>(p_param); + std::vector::iterator iter; + + SangomaPort *p_port; + + //DETERMINE THE EVENT HANDLES FOR ALL THE PORTS IN ALL OF THE CARDS + //these handles will be passed to WaitForMultipleObjects so that we know when to read + unsigned int total_number_of_ports_in_system = static_cast( p_ports->size() ); + unsigned int port_index, number_of_open_ports = 0; + //SETUP VARIABLES FOR PROCESSING THE EVENT + DWORD PORT_READ_TIMEOUT = 3000; //arbitrarily set, doesn't matter b/c we don't do anything on a time out + + sangoma_wait_obj* port_event_handles[MAX_HANDLES]; + unsigned int port_input_flags[MAX_HANDLES]; + unsigned int port_output_flags[MAX_HANDLES]; + SangomaPort* sangoma_open_ports[MAX_HANDLES]; //stores Open ports only + + if (total_number_of_ports_in_system > MAX_HANDLES) { + fprintf(stderr,"Error Total number of ports %i > Max Hanldes %i\n",total_number_of_ports_in_system,MAX_HANDLES); + exit(1); + } + + DBG_MAIN("%s():total_number_of_ports_in_system: %d\n", __FUNCTION__, total_number_of_ports_in_system); + + //START PROCESSING IN THE THREAD + while(gRunning) + { + //DavidR: Ports are getting Open and Closed during Line type Discovery, only + //the Open ports will have a valid Event which can be waited on. + //Go through the list of Open ports and populate the array of Sangoma Waitable objects. + number_of_open_ports = 0; + memset(port_event_handles, 0x00, sizeof(port_event_handles)); + memset(port_input_flags, 0x00, sizeof(port_input_flags)); + memset(port_output_flags, 0x00, sizeof(port_output_flags)); + memset(sangoma_open_ports, 0x00, sizeof(sangoma_open_ports)); + + + for (iter = p_ports->begin(); iter != p_ports->end(); ++iter) { + p_port = *iter; + + if (p_port->GetIsOpen() == true && + p_port->GetEvent().EventHandle && + p_port->GetEvent().EventHandle != (void*)INVALID_HANDLE_VALUE) + { + port_event_handles[number_of_open_ports] = p_port->GetEvent().EventHandle; + DBG_MAIN("Port %i Handle %p\n",p_port->GetPortNumber(),p_port->GetEvent().EventHandle); + + if (szTxFileName[0] == '\0') { + //rx and line state + port_input_flags[number_of_open_ports] = (POLLIN | POLLPRI); + } else { + //tx and line state + port_input_flags[number_of_open_ports] = (POLLOUT | POLLPRI); + } + + sangoma_open_ports[number_of_open_ports] = p_port; + + number_of_open_ports++; + } + } + + if(!number_of_open_ports){ + WRN_MAIN("%s(): no open ports!\n", __FUNCTION__); + sangoma_msleep(1000); + continue; + } + + DBG_MAIN("%s(): number_of_open_ports: %d\n", __FUNCTION__, number_of_open_ports); + + //WAIT FOR AN EVENT FROM THE PORT + //We are signalled anytime there is an event. This could be for a line connection, + //a line disconnection, or if there is data available. + + iResult = sangoma_waitfor_many(port_event_handles, + port_input_flags, + port_output_flags, + number_of_open_ports, + PORT_READ_TIMEOUT /* Wait timeout, in milliseconds. Or SANGOMA_INFINITE_API_POLL_WAIT. */ + ); + + if (iResult == SANG_STATUS_APIPOLL_TIMEOUT) { + WRN_MAIN("%s(): Timeout\n", __FUNCTION__); + continue; + } + + if (iResult != SANG_STATUS_SUCCESS) { + WRN_MAIN("sangoma_waitfor_many: iResult: %s (%d)\n", SDLA_DECODE_SANG_STATUS(iResult), iResult); + //FIXME Do not Assert in production + exit(1); + break; + } + + //DavidR: go through the array of OUT flags and do the work for those which are set. + for(port_index = 0; port_index < number_of_open_ports; ++port_index) + { + /* a wait object was signaled */ + if( port_output_flags[port_index] & POLLIN || + port_output_flags[port_index] & POLLPRI || + port_output_flags[port_index] & POLLOUT ) { + + // Retreive the signaled port from the list of open ports + p_port = sangoma_open_ports[port_index]; + if(p_port == NULL){ + std::cout << "ERROR: invalid port index: " << port_index << std::endl; + exit(1); + continue; + } + + // Call PortEventHandler() for each bit in port_output_flags[port_index] + if (port_output_flags[port_index] & POLLIN) + { // handle Rx Data + if (PortEventHandler(p_port, POLLIN) == false) + { // Call the event handler to take the appropriate actions + std::cout << "ERROR: Rx Data on port " << port_index << " could not be handled properly." << std::endl; + } + } + + if (port_output_flags[port_index] & POLLPRI) + { //handle an Event + if (PortEventHandler(p_port, POLLPRI) == false) + { // Call the event handler to take the appropriate actions + std::cout << "ERROR: An Event on port " << port_index << " could not be handled properly." << std::endl; + } + } + + if (port_output_flags[port_index] & POLLOUT) + { //handle an Event + if (PortEventHandler(p_port, POLLOUT) == false) + { // Call the event handler to take the appropriate actions + std::cout << "ERROR: An Event on port " << port_index << " could not be handled properly." << std::endl; + } + } + + } + + if( port_output_flags[port_index] & (~port_input_flags[port_index]) ){ + WRN_MAIN("\nUnexpected port_output_flags[%d]: 0x%X\n\n", port_index, port_output_flags[port_index]); + iResult = SANG_STATUS_IO_ERROR; + } + }//for() + + } // while(gRunning) + + DBG_MAIN( "\n%s() - end\n", __FUNCTION__); + +#if defined(__WINDOWS__) + return 0; +#else + pthread_exit(NULL); + return NULL; +#endif +} + +void load_driver_modules() +{ +#if defined(__WINDOWS__) + //driver loaded by PnP system - do nothing here +#else + //run "hwprobe" - if driver not loaded yet this command will load the driver + system("wanrouter hwprobe"); +#endif +} + +void clear_screen() +{ +#if defined(__WINDOWS__) + system("cls"); +#else + system("clear"); +#endif +} + +void print_cfg_stats(void *p_param) +{ + std::vector* p_ports = static_cast*>(p_param); + + INFO_MAIN("\n"); + //print port statistics/status + for(unsigned int port_index = 0; port_index < p_ports->size(); ++port_index) + { + SangomaPort* p_port = p_ports->at(port_index); //make a copy of the pointer to make it easier to work with + bool synchronization_achieved = p_port->GetSynchronizationStatus(); //retrieve the synchronization status. DAVIDR: requires context switch to kernel-mode, should not be called too often. + + if (p_port->SyncCount == 1) { + p_port->GetStatistics(); + } + + Statistics stats = p_port->GetStatistics(); //Get the statistics for this port + + float receiver_level_db; + bool receiver_level_retrieved = p_port->GetReceiverLevelInDb(receiver_level_db); + INFO_MAIN("Port:%02d(unmapped:%02d):%20s,\tRx Count: %8u\tTx Count: %8u\tErrors: %8u\tRx Len: %i\t", + p_port->GetPortNumber(), p_port->GetUnmappedPortNumber(), + (synchronization_achieved ? "synchronized" : "not synchronized"), + stats.BytesReceived, stats.BytesSent,stats.Errors,p_port->RxLength); + + if(receiver_level_retrieved) + { + printf("Receiver level: %.1fdB\n", receiver_level_db); + } + else + { + printf("Receiver level: ERROR (Could not retrieve receiver level)\n"); + } + } + +} + +void print_io_stats(void *p_param) +{ + //print Line Type of Ports in Sync + std::vector* p_ports = static_cast*>(p_param); + + INFO_MAIN("\n"); + for(unsigned int port_index = 0; port_index < p_ports->size(); ++port_index) + { + SangomaPort* p_port = p_ports->at(port_index); //make a copy of the pointer to make it easier to work with + bool synchronization_achieved = p_port->GetSynchronizationStatus(); //retrieve the synchronization status. DAVIDR: requires context switch to kernel-mode, should not be called too often. + Configuration cfg; + bool configuration_obtained = p_port->GetConfiguration(cfg); + + INFO_MAIN("Port %d: %20s,\tLineType: %s,\tFraming: %s\n", + p_port->GetPortNumber(), + (synchronization_achieved ? "synchronized" : "not synchronized"), + (cfg.E1OrT1 == E1 ? "E1" : "T1"), + configuration_obtained ? (DECODE_FRAMING(cfg.Framing)) : "could not obtain configuration"); + } +} + +int main_loop_per_port_bank(void *p_param, Configuration & configuration) +{ + std::vector* p_ports = static_cast*>(p_param); + + //DETERMINE EACH PORTS CONFIGURATION + for(unsigned int port_index = 0; port_index < p_ports->size(); ++port_index) + { + // CHECK WHETHER THE PORT HAS BEEN PREVIOUSLY OPENED. + SangomaPort* p_port = p_ports->at(port_index); //make a copy of the pointer to make it easier to work with + time_t port_open_time = p_port->GetStatistics().TimeLastOpened; + bool portWasPreviouslyOpened = (port_open_time != 0); + if(portWasPreviouslyOpened) + { + // Check how long it has been since opening the port. + time_t current_time; + time(¤t_time); + double seconds_since_opening_port = difftime(current_time, port_open_time); + const double SECONDS_REQUIRED_FOR_PORT_SYNCHRONIZATION = 22.0; + bool port_has_been_open_long_enough_for_synchronization = (seconds_since_opening_port > SECONDS_REQUIRED_FOR_PORT_SYNCHRONIZATION); + if(!port_has_been_open_long_enough_for_synchronization) + { + // Allow this port to continue attempting synchronization. Move on to the next port. + continue; + } + } + + //RETRIEVE THE SYNCHRONIZATION STATUS + bool synchronization_achieved = p_port->GetSynchronizationStatus(); //retrieve the synchronization status. DAVIDR: requires context switch to kernel-mode, should not be called too often. + + DBG_MAIN("Port %d: %s\n", port_index, (synchronization_achieved ? "synchronized" : "not synchronized")); + //BASED ON THE STATUS DETERMINE WHAT TO DO + + if (synchronization_achieved) { + if (!p_port->RxCount) { + time_t current_time; + time(¤t_time); + if (p_port->rx_pkt_timeout == 0) { + time(&p_port->rx_pkt_timeout); + } else { + double rx_timeout_in_sec = difftime(current_time, p_port->rx_pkt_timeout); + if (rx_timeout_in_sec > 5) { + synchronization_achieved=0; + printf("Error: Connected by no RX - going out of sync"); + } + } + } else { + p_port->rx_pkt_timeout=0; + } + } + + if(!synchronization_achieved) + { + p_port->rx_pkt_timeout=0; + p_port->RxCount=0; + if (iForcedLineType != -1) + { //user specified the Line Type - do not attempt to run Line Discovery. + if (p_port->GetIsOpen() == false) { + configuration.LineCoding = ON; + p_port->Open(configuration);//open the port with FORCED configuration, only a single time. + + if (szTxFileName[0] != '\0') { + if (p_port->SetAndOpenTxFile(szTxFileName)) { + ERR_MAIN("Failed to open file: %s\n", szTxFileName); + exit(1); + } + } + + ////////////////////////////////////////// + //apply user-specfied settings to the port + ////////////////////////////////////////// + if (iLocalLoopback) { + p_port->LineLoopbackEnable(); + } + } + } else { + //determine the next configuration to try + unsigned int next_frame_type = p_port->next_framing_type; //retrieve the next frame type to try + if(configuration.E1OrT1 == T1){ + p_port->next_framing_type = (next_frame_type + 1) % NUMBER_OF_T1_FRAME_TYPES; //move the stored index to the frame type to try next time + configuration.Framing = T1_TYPES[next_frame_type]; + configuration.LineCoding = ON; + }else{ + p_port->next_framing_type = (next_frame_type + 1) % NUMBER_OF_E1_FRAME_TYPES; //move the stored index to the frame type to try next time + configuration.Framing = E1_TYPES[next_frame_type]; + configuration.LineCoding = ON; + } + + p_port->Close(); //close the port + p_port->Open(configuration); //re-open the port with the new configuration + } + } + } // for(unsigned int port_index = 0; port_index < ports.size(); ++port_index) + + return 0; +} + +int main_program_loop(void * p_param, void *p_param2, Configuration & configuration) +{ + //CAST TO THE OBJECT THAT WAS PASSED IN + int timeout=0; + std::vector* p_ports = static_cast*>(p_param); + std::vector* p_ports_bank2 = static_cast*>(p_param2); + + std::cerr << "Errout Test \n" << std::endl; + + //CONTINUOUSLY TRY TO DETERMINE THE PORTS CONFIGURATION + //if the port is in-sync nothing happens but while the port is out of sync + //we cycle through the framing types to try and find the correct one. + while( gRunning ) + { + + main_loop_per_port_bank(p_ports, configuration); + main_loop_per_port_bank(p_ports_bank2, configuration); + + clear_screen(); + + + INFO_MAIN("\nTime: %s \n", wp_get_time_stamp()); + + print_cfg_stats(&sangoma_ports); //print statistics for all ports + print_cfg_stats(&sangoma_ports_bank2); //print statistics for all ports +#if 0 + print_io_stats(&sangoma_ports); //print statistics for all ports + print_io_stats(&sangoma_ports_bank2); //print statistics for all ports +#endif + + +// std::cout << "To refresh the screen press " << std::endl; + + if (!iTimeout) { + + std::cout << "To exit, press or " << std::endl; + + sangoma_msleep(2000); //sleep 2 seconds between each iteration to avoid busy loop! + + if( _kbhit() ) { + switch(tolower(_getch())) + { + case 'x': + case 'q': + gRunning = false; + break; + default: + std::cout << "Warning: Invalid command!" << std::endl; + break; + } + } + } else { + sangoma_msleep(1000); + timeout++; + if (timeout >= iTimeout) { + break; + } + } + + } // while( gRunning ) + + std::cout << "Exiting Main Loop ... " << std::endl; + + sangoma_msleep(2000); //Sleep 2 seconds before exiting to make sure the other thread exits + + return 0; +} + +int G3TI_CreateThread(void *sangoma_ports_ptr) +{ +#if defined(__WINDOWS__) + DWORD SangomaThreadId; + HANDLE hSangomaThread; + + //step 1 - create the single worker thread + hSangomaThread = CreateThread( + NULL, /* no security attributes */ + 0, /* use default stack size */ + (LPTHREAD_START_ROUTINE)SangomaThreadFunc, /* thread function */ + sangoma_ports_ptr, /* argument to thread function */ + 0, /* use default creation flags */ + &SangomaThreadId /* returns the thread identifier */ + ); + + if(hSangomaThread == NULL){ + ERR_MAIN( "Failed to create Sangoma thread!!\n"); + return 1; + } + +#if 0 + //step 2 - set process priority to above normal + if (!SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS)) { + WRN_MAIN( "Failed to set Process priority!!\n"); + } + + //step 3 - set thread priority to real-time + if(SetThreadPriority(hSangomaThread, THREAD_PRIORITY_TIME_CRITICAL) == FALSE){ + WRN_MAIN( "Failed to set Thread priority!!\n"); + } +#endif + + //success + return 0; + +#elif defined(__LINUX__) +# define CTHREAD_STACK_SIZE 1024 * 240 + pthread_t dwThreadId; + pthread_attr_t attr; + int result = -1; + void *pParam = sangoma_ports_ptr; + + 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, CTHREAD_STACK_SIZE); + + result = pthread_create(&dwThreadId, &attr, SangomaThreadFunc, pParam); + pthread_attr_destroy(&attr); + if (result) { + return 1; + } + + return 0; +#else +# error Unsupported OS +#endif +} + +#ifndef __WINDOWS__ int _kbhit(void) { @@ -900,113 +925,117 @@ int _kbhit(void) return 0; } -#endif - - -int __cdecl main(int argc, char* argv[]) -{ - unsigned int number_of_cards; - struct BufferSettings buffer_settings; - - //create the configuration - Configuration configuration; - - std::cout << "Application compiled on " << __DATE__ " " << __TIME__ << std::endl; - - // PROCESS THE SUPPLIED INPUT - // Parse the command line arguements to retreive the card model to check for. At this - // time, we only expect to use either A104 or A108 or A116s in the system, but not a mixture of the - // two. - CardModel model; - unsigned int number_of_ports_per_card = 0; - //default line type is T1 - configuration.e1Ort1 = T1; - configuration.HighImpedanceMode = false; - configuration.MaxCableLoss = MCLV_12_0dB;//default value for both Hi Impedance and Normal mode - configuration.TxTristateMode = false; - configuration.Master=0; - - - buffer_settings.BufferMultiplierFactor = MIN_BUFFER_MULTIPLIER_FACTOR;// go to higher mulitiplier only if CPU usage is high - //buffer_settings.BufferMultiplierFactor = 7;// go to higher mulitiplier only if CPU usage is high - buffer_settings.NumberOfBuffersPerPort = MIN_NUMBER_OF_BUFFERS_PER_API_INTERFACE; - - if(parse_command_line_args(argc, argv, &model, &number_of_ports_per_card, configuration, buffer_settings)){ - return 1; - } - - std::cout << "Press key to continue." << std::endl; - sng_getch(); - - load_driver_modules(); - - std::cout << "Search for '" << (DECODE_CARD_TYPE(model)) << "' Sangoma card." << std::endl; - - number_of_cards = GetNumberOfCardsInstalled(model); - INFO_MAIN("Found %d %s card(s).\n", number_of_cards, DECODE_CARD_TYPE(model)); - - if(number_of_cards < 1){ - ERR_MAIN("No %s Sangoma cards running. Exiting...\n", DECODE_CARD_TYPE(model)); - return 1; - } - - for (unsigned int card_number = 0; card_number < number_of_cards; card_number++) - { - SangomaCard* p_card = new SangomaCard(card_number, model, buffer_settings, buffer_settings); - sangoma_cards.push_back(p_card); - - INFO_MAIN("\nCard Driver version: %i.%i.%i.%i, Firmware version: %s, PCI Slot: %i, PCI Bus: %i\n", - p_card->GetCardDriverVersion().Major, p_card->GetCardDriverVersion().Minor, - p_card->GetCardDriverVersion().Build, p_card->GetCardDriverVersion().Revision, - p_card->GetFirmwareVersion().c_str(), p_card->GetCardPciBus(), p_card->GetCardPciSlot()); - - //Add this cards ports to the vector containing all the system's ports - unsigned int number_of_ports = p_card->GetNumberOfPorts(); - for(unsigned int port_index = 0; port_index < number_of_ports; ++port_index) - { - total_number_of_ports++; - if (total_number_of_ports > MAX_HANDLES) { - sangoma_ports_bank2.push_back(p_card->GetPort(port_index) ); - } else { - sangoma_ports.push_back(p_card->GetPort(port_index) ); - } - next_framing_type_index.push_back(0); //Start with the first framing type, this indexes T1/E1_TYPES to find - //the frame type to use. - } - } // for (unsigned int card_number = 0; card_number < number_of_cards; card_number++) - - std::cout << "Press key to continue." << std::endl; - sng_getch(); - - gRunning = true; - if (G3TI_CreateThread(&sangoma_ports)) - { - ERR_MAIN("Failed to create receiver thread!\n"); - return 1; - } - - if (sangoma_ports_bank2.size() > 0) { - if (G3TI_CreateThread(&sangoma_ports_bank2)) - { - ERR_MAIN("Failed to create receiver thread!\n"); - return 1; - } - } - - main_program_loop(&sangoma_ports, &sangoma_ports_bank2, configuration); - - gRunning = false; - - - //DELETE ALL THE SANGOMA CARDS - for(unsigned int card_index = 0; card_index < sangoma_cards.size(); ++card_index) - { - delete sangoma_cards.at(card_index); - } - - - INFO_MAIN("\n%s: Done.\n", argv[0]); - return 0; -} - - +#endif + + +int __cdecl main(int argc, char* argv[]) +{ + unsigned int number_of_cards; + struct BufferSettings buffer_settings; + + //create the configuration + Configuration configuration; + + std::cout << "Application compiled on " << __DATE__ " " << __TIME__ << std::endl; + + // PROCESS THE SUPPLIED INPUT + // Parse the command line arguements to retreive the card model to check for. At this + // time, we only expect to use either A104 or A108 or A116s in the system, but not a mixture of the + // two. + CardModel model; + unsigned int number_of_ports_per_card = 0; + //default line type is T1 + configuration.E1OrT1 = T1; + configuration.HighImpedanceMode = false; + configuration.MaxCableLoss = MCLV_12_0dB;//default value for both Hi Impedance and Normal mode + configuration.TxTristateMode = false; + configuration.Master=0; + + + buffer_settings.BufferMultiplierFactor = BufferSettings::MINIMUM_BUFFER_MULTIPLIER_FACTOR;// go to higher mulitiplier only if CPU usage is high + //buffer_settings.BufferMultiplierFactor = 7;// go to higher mulitiplier only if CPU usage is high + buffer_settings.NumberOfBuffersPerPort = BufferSettings::MINIMUM_NUMBER_OF_BUFFERS_PER_API_INTERFACE; + + if(parse_command_line_args(argc, argv, &model, &number_of_ports_per_card, configuration, buffer_settings)){ + return 1; + } + + std::cout << "Press key to continue." << std::endl; + sng_getch(); + + load_driver_modules(); + + std::cout << "Search for '" << (DECODE_CARD_TYPE(model)) << "' Sangoma card." << std::endl; + + number_of_cards = GetNumberOfCardsInstalled(model); + INFO_MAIN("Found %d %s card(s).\n", number_of_cards, DECODE_CARD_TYPE(model)); + + if(number_of_cards < 1){ + ERR_MAIN("No %s Sangoma cards running. Exiting...\n", DECODE_CARD_TYPE(model)); + return 1; + } + + for (unsigned int card_number = 0; card_number < number_of_cards; card_number++) + { + SangomaCard* p_card = new SangomaCard(card_number, model, buffer_settings, buffer_settings); + sangoma_cards.push_back(p_card); + + INFO_MAIN("\nCard Driver version: %i.%i.%i.%i, Firmware version: %s, PCI Slot: %i, PCI Bus: %i\n", + p_card->GetCardDriverVersion().Major, p_card->GetCardDriverVersion().Minor, + p_card->GetCardDriverVersion().Build, p_card->GetCardDriverVersion().Revision, + p_card->GetFirmwareVersion().c_str(), p_card->GetCardPciBus(), p_card->GetCardPciSlot()); + + //Add this cards ports to the vector containing all the system's ports + unsigned int number_of_ports = p_card->GetNumberOfPorts(); + for(unsigned int port_index = 0; port_index < number_of_ports; ++port_index) + { + total_number_of_ports++; +#if 0 + /* NC Debug code */ + if (total_number_of_ports > 8) { + break; + } +#endif + if (total_number_of_ports > MAX_HANDLES) { + sangoma_ports_bank2.push_back(p_card->GetPort(port_index) ); + } else { + sangoma_ports.push_back(p_card->GetPort(port_index) ); + } + } + } // for (unsigned int card_number = 0; card_number < number_of_cards; card_number++) + + std::cout << "Press key to continue." << std::endl; + sng_getch(); + + gRunning = true; + if (G3TI_CreateThread(&sangoma_ports)) + { + ERR_MAIN("Failed to create receiver thread!\n"); + return 1; + } + + if (sangoma_ports_bank2.size() > 0) { + if (G3TI_CreateThread(&sangoma_ports_bank2)) + { + ERR_MAIN("Failed to create receiver thread!\n"); + return 1; + } + } + + main_program_loop(&sangoma_ports, &sangoma_ports_bank2, configuration); + + gRunning = false; + + + //DELETE ALL THE SANGOMA CARDS + for(unsigned int card_index = 0; card_index < sangoma_cards.size(); ++card_index) + { + delete sangoma_cards.at(card_index); + } + + + INFO_MAIN("\n%s: Done.\n", argv[0]); + return 0; +} + + diff --git a/api/libsangoma/examples/sample_data_tapping/sangoma_interface.cpp b/api/libsangoma/examples/sample_data_tapping/sangoma_interface.cpp deleted file mode 100644 index 1fe461a..0000000 --- a/api/libsangoma/examples/sample_data_tapping/sangoma_interface.cpp +++ /dev/null @@ -1,840 +0,0 @@ -////////////////////////////////////////////////////////////////////// -// sangoma_interface.cpp: interface for Sangoma API driver. -// -// Author : David Rokhvarg -////////////////////////////////////////////////////////////////////// - -#include "sangoma_interface.h" -#include "driver_configurator.h" - -#define DBG_IFACE if(0)printf -#define INFO_IFACE if(0)printf -#define ERR_IFACE printf("Error: %s(): line:%d :", __FUNCTION__, __LINE__);printf -#define WRN_IFACE printf("Warning: %s(): line:%d :", __FUNCTION__, __LINE__);printf - -#define DBG_PORT_NUM if(0)printf -#define IFACE_FUNC() if(0)printf("%s():line:%d\n", __FUNCTION__, __LINE__) - - -#define DO_COMMAND(wan_udp) DoManagementCommand(sangoma_dev, &wan_udp); - -sangoma_interface::sangoma_interface(int wanpipe_num, int interface_num) -{ - DBG_IFACE("%s()\n", __FUNCTION__); - - wanpipe_number = wanpipe_num; - interface_number = interface_num; - - DBG_PORT_NUM("%s(): (1) wanpipe_number: %i, interface_number: %i\n", - __FUNCTION__, wanpipe_number, interface_number); - - memset(interface_name, 0x00, DEV_NAME_LEN); - memset(&drv_version, 0x00, sizeof(drv_version)); - - ////////////////////////////////////////////////////////////////// - driver_configurator drv_cfg; - hardware_info_t hardware_info; - card_model = A104_ADPTR_4TE1;//default - if(drv_cfg.init(wanpipe_number, 0) == 0){ - if(drv_cfg.get_hardware_info(&hardware_info) == 0){ - DBG_IFACE("card_model : %s (0x%08X)\n", - SDLA_ADPTR_NAME(hardware_info.card_model), hardware_info.card_model); - DBG_IFACE("firmware_version\t: 0x%02X\n", hardware_info.firmware_version); - DBG_IFACE("pci_bus_number\t\t: %d\n", hardware_info.pci_bus_number); - DBG_IFACE("pci_slot_number\t\t: %d\n", hardware_info.pci_slot_number); - - card_model = hardware_info.card_model; - } - } else { - ERR_IFACE("Failed to get Card Model!\n"); - exit(1); - } - - //G3 requred port numbers on A108 to be different from what Sangoma API provides. - //Physical Port 0: Ports 0 and 1 (not 0 and 4) - //Physical Port 1: Ports 2 and 3 (not 1 and 5) - //Physical Port 2: Ports 4 and 5 (not 2 and 6) - //Physical Port 3: Ports 6 and 7 (not 3 and 7) - if(card_model == A108_ADPTR_8TE1){ - DBG_PORT_NUM("%s(): card_model == A108_ADPTR_8TE1\n", __FUNCTION__); - //correct the interface_number for A108 accoringly - switch(interface_num) - { - case 0: - interface_number = 0; - break; - case 1: - interface_number = 4; - break; - case 2: - interface_number = 1; - break; - case 3: - interface_number = 5; - break; - case 4: - interface_number = 2; - break; - case 5: - interface_number = 6; - break; - case 6: - interface_number = 3; - break; - case 7: - interface_number = 7; - break; - } - } - - DBG_PORT_NUM("%s(): (2) wanpipe_number: %i, MAPPED interface_number: %i\n", - __FUNCTION__, wanpipe_number, interface_number); - - //Form the MAPPED Interface Name from Wanpipe Number and Interface Index (i.e. wanpipe1_if1). - wp_snprintf(interface_name, DEV_NAME_LEN, "\\\\.\\WANPIPE%d_IF%d", - wanpipe_number + 1 + interface_number, 1); - DBG_PORT_NUM( "Using Device Name: %s\n", interface_name); - - ////////////////////////////////////////////////////////////////// - if(drv_cfg.get_driver_version(&drv_version)){ - ERR_IFACE("Failed to get Driver Version!\n"); - exit(1); - } - - check_api_driver_version(); - - ////////////////////////////////////////////////////////////////// - sangoma_dev = INVALID_HANDLE_VALUE; - - sng_wait_obj = NULL; - - ////////////////////////////////////////////////////////////////// - //receive stuff - rx_frames_count = 0; - rx_bytes_count = 0; - //for counting frames with CRC/Abort errors - bad_rx_frames_count = 0; - - ////////////////////////////////////////////////////////////////// - //transmit stuff - tx_bytes_count = 0; - tx_frames_count = 0; - tx_test_byte = 0; - - ////////////////////////////////////////////////////////////////// - //IOCTL management structures and variables - protocol_cb_size = sizeof(wan_mgmt_t)+sizeof(wan_cmd_t)+1; - wan_protocol = 0; - adapter_type = 0; -} - -sangoma_interface::~sangoma_interface() -{ - DBG_IFACE("%s()\n", __FUNCTION__); - cleanup(); -} - -HANDLE sangoma_interface::open_first_interface_of_a_mapped_port() -{ - sng_fd_t hTmp; - int span, chan; - - span = get_mapped_span_number();//wanpipe_number + 1 + interface_number; - chan = 1;/* wanpipe1_if1... */ - - DBG_IFACE("%s(): opening Span: %d, Chan: %d\n", __FUNCTION__, span, chan); - - hTmp = sangoma_open_api_span_chan(span, chan); - - if(hTmp == INVALID_HANDLE_VALUE){ - DBG_IFACE("%s(): failed to open Span: %d, Chan: %d!\n", __FUNCTION__, span, chan); - } - - return hTmp; -} - -int sangoma_interface::init() -{ - DBG_IFACE("%s()\n", __FUNCTION__); - DBG_IFACE("interface_name: %s, wanpipe_number:%d, interface_number:%d\n", interface_name, wanpipe_number, interface_number); - -#if defined(__LINUX__) - //under Linux must wait for interfaces to be available for opening - sangoma_interface_wait_up(get_mapped_span_number(), 1/*chan*/, 2/* 2 second timeout */); -#endif - - //////////////////////////////////////////////////////////////////////////// - //open handle for reading and writing data, for events reception and other commands - sangoma_dev = open_first_interface_of_a_mapped_port(); - if (sangoma_dev == INVALID_HANDLE_VALUE){ - ERR_IFACE( "Unable to open %s for Rx/Tx!\n", interface_name); - return 1; - } - - DBG_IFACE("Span %i - creatig an object\n",get_mapped_span_number()); - - if(SANG_ERROR(sangoma_wait_obj_create(&sng_wait_obj, sangoma_dev, SANGOMA_DEVICE_WAIT_OBJ_SIG))){ - ERR_IFACE("Failed to create 'Tx/Rx/Event WAIT_OBJECT' for %s\n", interface_name); - return 1; - } - - //////////////////////////////////////////////////////////////////////////// - //get current protocol - if(GetWANConfig() == WAN_FALSE){ - ERR_IFACE( "Failed to get current protocol!\n"); - goto init_error; - } - - //////////////////////////////////////////////////////////////////////////// - //get Front End Type (T1/E1/Analog...) - if (get_fe_type(&adapter_type) == WAN_FALSE){ - ERR_IFACE( "Failed to get Front End Type!\n"); - goto init_error; - } - - //////////////////////////////////////////////////////////////////////////// -#if 0 - //For Debugging only print the interface configuration. - if_cfg_t wanif_conf_struct; - - if(get_interface_configuration(&wanif_conf_struct)){ - ERR_IFACE( "Failed to get Interface Configuration!\n"); - return 1; - } -#endif - return 0; - -init_error: - - if(sng_wait_obj){ - sangoma_wait_obj_delete(&sng_wait_obj); - sng_wait_obj = NULL; - } - - return 1; - -} - -// -//cleanup() - reverse everything what was done in init(). -// -//It is very important to close ALL open -//handles, because the API will continue -//receive data until the LAST handel is closed. -int sangoma_interface::cleanup() -{ - DBG_IFACE("%s()\n", __FUNCTION__); - - if(sng_wait_obj){ - sangoma_wait_obj_delete(&sng_wait_obj); - sng_wait_obj = NULL; - } - - if(sangoma_dev != INVALID_HANDLE_VALUE){ - DBG_IFACE( "Closing Rx/Tx fd.\n"); - sangoma_close(&sangoma_dev); - sangoma_dev = INVALID_HANDLE_VALUE; - } - - return 0; -} - -int sangoma_interface::GetWANConfig( void ) -{ - int err = WAN_TRUE; - - /* Get Protocol type */ - wan_udp.wan_udphdr_command = WAN_GET_PROTOCOL; - wan_udp.wan_udphdr_data_len = 0; - - DO_COMMAND(wan_udp); - if (wan_udp.wan_udphdr_return_code){ - ERR_IFACE( "Error: Command WAN_GET_PROTOCOL failed! return code: 0x%X", - wan_udp.wan_udphdr_return_code); - return WAN_FALSE; - } - - wan_protocol = wan_udp.wan_udphdr_data[0]; - - DBG_IFACE( "Device %s running protocol: %s\n", - interface_name, DECODE_PROT(wan_protocol)); - - return err; -} - -int sangoma_interface::get_fe_type(unsigned char* adapter_type) -{ - int err = WAN_TRUE; - - /* Read Adapter Type */ - wan_udp.wan_udphdr_command = WAN_GET_MEDIA_TYPE; - wan_udp.wan_udphdr_data[0] = WAN_MEDIA_NONE; - wan_udp.wan_udphdr_data_len = 0; - - DO_COMMAND(wan_udp); - if(wan_udp.wan_udphdr_return_code){ - ERR_IFACE( "Error: Command WAN_GET_MEDIA_TYPE failed! return code: 0x%X", - wan_udp.wan_udphdr_return_code); - return WAN_FALSE; - } - - *adapter_type = get_wan_udphdr_data_byte(0); - - DBG_IFACE( "Front End Type: "); - switch(*adapter_type) - { - case WAN_MEDIA_NONE: - DBG_IFACE( "Serial"); - break; - - case WAN_MEDIA_T1: - DBG_IFACE( "T1"); - break; - - case WAN_MEDIA_E1: - DBG_IFACE( "E1"); - break; - - case WAN_MEDIA_56K: - DBG_IFACE( "56K"); - break; - - case WAN_MEDIA_FXOFXS: - DBG_IFACE( "Aanalog"); - break; - - default: - DBG_IFACE( "Unknown"); - err = WAN_FALSE; - } - DBG_IFACE( "\n"); - - return err; -} - -//return POINTER to data at offset 'off' -unsigned char* sangoma_interface::get_wan_udphdr_data_ptr(unsigned char off) -{ - unsigned char *p_data = (unsigned char*)&wan_udp.wan_udphdr_data[0]; - p_data += off; - return p_data; -} - -unsigned char sangoma_interface::set_wan_udphdr_data_byte(unsigned char off, unsigned char data) -{ - unsigned char *p_data = (unsigned char*)&wan_udp.wan_udphdr_data[0]; - p_data[off] = data; - return 0; -} - -//return DATA at offset 'off' -unsigned char sangoma_interface::get_wan_udphdr_data_byte(unsigned char off) -{ - unsigned char *p_data = (unsigned char*)&wan_udp.wan_udphdr_data[0]; - return p_data[off]; -} - -int sangoma_interface::read_te1_56k_stat(unsigned long *p_alarms) -{ - unsigned char* data = NULL; - unsigned long alarms = 0x00; - sdla_te_pmon_t* pmon = NULL; - - DBG_IFACE("%s()\n", __FUNCTION__); - - memset(&wan_udp, 0x00, sizeof(wan_udp)); - - switch(adapter_type) - { - case WAN_MEDIA_T1: - case WAN_MEDIA_E1: - case WAN_MEDIA_56K: - ;//do nothing - break; - - default: - ERR_IFACE( "Command invalid for Adapter Type %d.\n", adapter_type); - return 1; - } - - /* Read T1/E1/56K alarms and T1/E1 performance monitoring counters */ - wan_udp.wan_udphdr_command = WAN_FE_GET_STAT; - wan_udp.wan_udphdr_data_len = 0; - - DO_COMMAND(wan_udp); - if (wan_udp.wan_udphdr_return_code != 0){ - ERR_IFACE( "Failed to read T1/E1/56K statistics.\n"); - return 1; - } - - data = get_wan_udphdr_data_ptr(0); - - *p_alarms = alarms = *(unsigned long*)data; - if (adapter_type == WAN_MEDIA_T1 || adapter_type == WAN_MEDIA_E1){ - DBG_IFACE( "***** %s: %s Alarms *****\n\n", - interface_name, (adapter_type == WAN_MEDIA_T1) ? "T1" : "E1"); - DBG_IFACE( "ALOS:\t%s\t| LOS:\t%s\n", - WAN_TE_ALOS_ALARM(alarms), - WAN_TE_LOS_ALARM(alarms)); - DBG_IFACE( "RED:\t%s\t| AIS:\t%s\n", - WAN_TE_RED_ALARM(alarms), - WAN_TE_AIS_ALARM(alarms)); - if (adapter_type == WAN_MEDIA_T1){ - DBG_IFACE( "YEL:\t%s\t| OOF:\t%s\n", - WAN_TE_YEL_ALARM(alarms), - WAN_TE_OOF_ALARM(alarms)); - }else{ - DBG_IFACE( "OOF:\t%s\n", - WAN_TE_OOF_ALARM(alarms)); - } - }else{ - DBG_IFACE( "***** %s: 56K CSU/DSU Alarms *****\n\n\n", interface_name); - DBG_IFACE( "In Service:\t\t%s\tData mode idle:\t\t%s\n", - INS_ALARM_56K(alarms), - DMI_ALARM_56K(alarms)); - - DBG_IFACE( "Zero supp. code:\t%s\tCtrl mode idle:\t\t%s\n", - ZCS_ALARM_56K(alarms), - CMI_ALARM_56K(alarms)); - - DBG_IFACE( "Out of service code:\t%s\tOut of frame code:\t%s\n", - OOS_ALARM_56K(alarms), - OOF_ALARM_56K(alarms)); - - DBG_IFACE( "Valid DSU NL loopback:\t%s\tUnsigned mux code:\t%s\n", - DLP_ALARM_56K(alarms), - UMC_ALARM_56K(alarms)); - - DBG_IFACE( "Rx loss of signal:\t%s\t\n", - RLOS_ALARM_56K(alarms)); - } - - pmon = (sdla_te_pmon_t*)&data[sizeof(unsigned long)]; -/* -//FIXME: - DBG_IFACE( "\n\n***** %s: %s Performance Monitoring Counters *****\n\n", - interface_name, (adapter_type == WAN_MEDIA_T1) ? "T1" : "E1"); - DBG_IFACE( "Framing Bit Error:\t%ld\tLine Code Violation:\t%ld\n", - pmon->frm_bit_error, - pmon->lcv); - if (adapter_type == WAN_MEDIA_T1){ - DBG_IFACE( "Out of Frame Errors:\t%ld\tBit Errors:\t\t%ld\n", - pmon->oof_errors, - pmon->bit_errors); - }else{ - DBG_IFACE( "Far End Block Errors:\t%ld\tCRC Errors:\t%ld\n", - pmon->far_end_blk_errors, - pmon->crc_errors); - } -*/ - return 0; -} - -char sangoma_interface::alarms_present() -{ - unsigned long alarms; - unsigned char is_alarm_set = 0; - wanpipe_api_t wp_api; - - SANGOMA_INIT_TDM_API_CMD(wp_api); - - DBG_IFACE("%s()\n", __FUNCTION__); - -#define DBG_ALARMS if(0)printf - - if(read_te1_56k_stat(&alarms)){ - return 1; - } - - if (adapter_type == WAN_MEDIA_T1 || adapter_type == WAN_MEDIA_E1){ - DBG_IFACE( "***** %s: %s Alarms *****\n\n", - interface_name, (adapter_type == WAN_MEDIA_T1) ? "T1" : "E1"); - - if(!strcmp(WAN_TE_ALOS_ALARM(alarms), ON_STR)){ - DBG_ALARMS("ALOS\n"); - is_alarm_set = 1; - } - - if(!strcmp(WAN_TE_LOS_ALARM(alarms), ON_STR)){ - DBG_ALARMS("LOS\n"); - is_alarm_set = 1; - } - - if(!strcmp(WAN_TE_RED_ALARM(alarms), ON_STR)){ - DBG_ALARMS("RED\n"); - is_alarm_set = 1; - } - - if(!strcmp(WAN_TE_AIS_ALARM(alarms), ON_STR)){ - DBG_ALARMS("AIS\n"); - is_alarm_set = 1; - } - - if (adapter_type == WAN_MEDIA_T1){ - if(!strcmp(WAN_TE_YEL_ALARM(alarms), ON_STR)){ - DBG_ALARMS("\n"); - is_alarm_set = 1; - } - - if(!strcmp(WAN_TE_OOF_ALARM(alarms), ON_STR)){ - DBG_ALARMS("\n"); - is_alarm_set = 1; - } - }else{ - if(!strcmp(WAN_TE_OOF_ALARM(alarms), ON_STR)){ - DBG_ALARMS("\n"); - is_alarm_set = 1; - } - } - } - - unsigned char fe_status = FE_DISCONNECTED; - - if (is_alarm_set == 1) { - //An alarm may be set, but the Front End code in the driver has - //better idea if it should be ignored. Check FE status, and if, - //it is "Connected", ignore the alarm. - sangoma_get_fe_status(sangoma_dev, &wp_api, &fe_status); - - if (fe_status == FE_CONNECTED) { - is_alarm_set = 0; - } - } - - DBG_ALARMS("is_alarm_set: %d\n", is_alarm_set); - - return is_alarm_set; -} - -int sangoma_interface::loopback_command(u_int8_t type, u_int8_t mode, u_int32_t chan_map) -{ - sdla_fe_lbmode_t *lb; - int err = 0, cnt = 0; - - lb = (sdla_fe_lbmode_t*)get_wan_udphdr_data_ptr(0); - memset(lb, 0, sizeof(sdla_fe_lbmode_t)); - lb->cmd = WAN_FE_LBMODE_CMD_SET; - lb->type = type; - lb->mode = mode; - lb->chan_map = chan_map; - -lb_poll_again: - wan_udp.wan_udphdr_command = WAN_FE_LB_MODE; - wan_udp.wan_udphdr_data_len = sizeof(sdla_fe_lbmode_t); - wan_udp.wan_udphdr_return_code = 0xaa; - - DO_COMMAND(wan_udp); - - if (wan_udp.wan_udphdr_return_code){ - err = 1; - return err; - } - if (lb->rc == WAN_FE_LBMODE_RC_PENDING){ - - if (!cnt) printf("Please wait ..");fflush(stdout); - if (cnt++ < 10){ - printf(".");fflush(stdout); - Sleep(100); - lb->cmd = WAN_FE_LBMODE_CMD_POLL; - lb->rc = 0x00; - goto lb_poll_again; - } - err = 2; - goto loopback_command_exit; - }else if (lb->rc != WAN_FE_LBMODE_RC_SUCCESS){ - err = 3; - } - if (cnt) printf("\n"); - -loopback_command_exit: - return err; -} - -void sangoma_interface::set_lb_modes(unsigned char type, unsigned char mode) -{ - DBG_IFACE("%s()\n", __FUNCTION__); - switch(adapter_type) - { - case WAN_MEDIA_T1: - case WAN_MEDIA_E1: - case WAN_MEDIA_56K: - ;//do nothing - break; - default: - ERR_IFACE( "Command invalid for Adapter Type %d.\n", adapter_type); - return; - } - - if(loopback_command(type, mode, ENABLE_ALL_CHANNELS)){ - ERR_IFACE("Error: Loop Back command failed!\n"); - return; - } - - if (adapter_type == WAN_MEDIA_T1 || adapter_type == WAN_MEDIA_E1){ - DBG_IFACE("%s %s mode ... %s!\n", - WAN_TE1_LB_ACTION_DECODE(mode), - WAN_TE1_LB_MODE_DECODE(type), - (!wan_udp.wan_udphdr_return_code)?"Done":"Failed"); - }else if (adapter_type == WAN_MEDIA_DS3 || adapter_type == WAN_MEDIA_E3){ - DBG_IFACE("%s %s mode ... %s!\n", - WAN_TE3_LB_ACTION_DECODE(mode), - WAN_TE3_LB_TYPE_DECODE(type), - (!wan_udp.wan_udphdr_return_code)?"Done":"Failed"); - }else{ - DBG_IFACE("%s %s mode ... %s (default)!\n", - WAN_TE1_LB_ACTION_DECODE(mode), - WAN_TE1_LB_MODE_DECODE(type), - (!wan_udp.wan_udphdr_return_code)?"Done":"Failed"); - } - return; -} - -void sangoma_interface::operational_stats(wanpipe_chan_stats_t *stats) -{ - wanpipe_api_t wp_api; - - SANGOMA_INIT_TDM_API_CMD(wp_api); - - int err = sangoma_get_stats(sangoma_dev, &wp_api, stats); - if (err || wp_api.wp_cmd.result != SANG_STATUS_SUCCESS) { - ERR_IFACE("sangoma_get_stats() failed! err: %d (0x%X), result:%d!\n", - err, err, wp_api.wp_cmd.result); - return; - } - - DBG_IFACE( "**** OPERATIONAL_STATS ****\n"); - - DBG_IFACE( "\ttx_dropped\t: %u\n", stats->tx_dropped); - DBG_IFACE( "\ttx_packets\t: %u\n", stats->tx_packets); - DBG_IFACE( "\ttx_bytes\t: %u\n", stats->tx_bytes); - DBG_IFACE( "\n"); - - //receive stats - DBG_IFACE( "\trx_packets\t: %u\n", stats->rx_packets); - DBG_IFACE( "\trx_bytes\t: %u\n", stats->rx_bytes); - - DBG_IFACE( "\trx_errors\t: %u\n", stats->rx_errors); - DBG_IFACE( "\trx_frame_errors\t: %u\n", stats->rx_frame_errors); - - DBG_IFACE( "\trx_packets_discarded_rx_q_full\t: %u\n", - stats->rx_dropped); - DBG_IFACE( "\n"); - - //hardware level stats - //AFT card - DBG_IFACE( "\trx_fifo_errors\t: %u\n", stats->rx_fifo_errors); - DBG_IFACE( "\ttx_fifo_errors\t: %u\n", stats->tx_fifo_errors); - - //BitStream mode only - counter of data blocks transmitted automatically, - //because no User Data was available. Transmit underrun counter from user - //point of view. - DBG_IFACE( "\ttx_idle_data\t: %u\n", stats->tx_idle_packets); -} - -void sangoma_interface::flush_operational_stats (void) -{ - wanpipe_api_t wp_api; - - SANGOMA_INIT_TDM_API_CMD(wp_api); - int err = sangoma_flush_stats(sangoma_dev, &wp_api); - if (err || wp_api.wp_cmd.result != SANG_STATUS_SUCCESS) { - ERR_IFACE("sangoma_flush_stats() failed! err: %d (0x%X), result:%d!\n", - err, err, wp_api.wp_cmd.result); - return; - } - - DBG_IFACE( "Command FLUSH_OPERATIONAL_STATS was successful.\n"); -} - -void sangoma_interface::flush_buffers (void) -{ - wanpipe_api_t wp_api; - - SANGOMA_INIT_TDM_API_CMD(wp_api); - int err = sangoma_flush_bufs(sangoma_dev, &wp_api); - if (err || wp_api.wp_cmd.result != SANG_STATUS_SUCCESS) { - ERR_IFACE("sangoma_flush_buffers() failed! err: %d (0x%X), result:%d!\n", - err, err, wp_api.wp_cmd.result); - return; - } - - DBG_IFACE( "Command sangoma_flush_bufs was successful.\n"); -} - -int sangoma_interface::get_interface_configuration(if_cfg_t *wanif_conf_ptr) -{ - wan_udp.wan_udphdr_command = WANPIPEMON_READ_CONFIGURATION; - wan_udp.wan_udphdr_data_len = sizeof(if_cfg_t); - - memset(wanif_conf_ptr, 0x00, sizeof(if_cfg_t)); - - DO_COMMAND(wan_udp); - if(wan_udp.wan_udphdr_return_code){ - ERR_IFACE( "Error: command READ_CONFIGURATION failed!\n"); - return 1; - } - memcpy(wanif_conf_ptr, get_wan_udphdr_data_ptr(0), sizeof(if_cfg_t)); - - DBG_IFACE( "**** READ_CONFIGURATION ****\n"); - DBG_IFACE( "Operational Mode\t: %s (%d)\n", SDLA_DECODE_USEDBY_FIELD(wanif_conf_ptr->usedby), wanif_conf_ptr->usedby); - DBG_IFACE( "Configued Active Channels \t: 0x%08X\n", wanif_conf_ptr->active_ch); - DBG_IFACE( "Echo Canceller Channels\t\t: 0x%08X\n", wanif_conf_ptr->ec_active_ch); - DBG_IFACE( "User Specified Channels during Port Config\t: 0x%08X\n", wanif_conf_ptr->cfg_active_ch); - DBG_IFACE( "Interface Number\t: %u\n", wanif_conf_ptr->interface_number); - DBG_IFACE( "Media type\t\t: %u\n", wanif_conf_ptr->media); - DBG_IFACE( "Line Mode\t\t: %s\n", wanif_conf_ptr->line_mode); - DBG_IFACE( "****************************\n"); - -#if 1 - // Audio Codec can be read for Voice interface. - // For Data interface this setting is ignored by the API. - wanpipe_api_t wp_api; - SANGOMA_INIT_TDM_API_CMD(wp_api); - sangoma_get_hw_coding(sangoma_dev, &wp_api); - if (wp_api.wp_cmd.result == SANG_STATUS_SUCCESS) { - DBG_IFACE("Audio Codec: %s\n", - WP_CODEC_FORMAT_DECODE(wp_api.wp_cmd.hw_tdm_coding)); - } -#endif - - return 0; -} - -int sangoma_interface::get_api_driver_version (PDRIVER_VERSION p_drv_version) -{ - memcpy(p_drv_version, &drv_version, sizeof(DRIVER_VERSION)); - - DBG_IFACE("\nAPI version\t: %d,%d,%d,%d\n", - p_drv_version->major, p_drv_version->minor, p_drv_version->minor1, p_drv_version->minor2); - DBG_IFACE("\n"); - return 0; -} - -int sangoma_interface::check_api_driver_version( ) -{ - DBG_IFACE("\nAPI version\t: %d,%d,%d,%d\n", - drv_version.major, drv_version.minor, drv_version.minor1, drv_version.minor2); - - // verify that Driver Version is the same as Header files used to compile this application - if(drv_version.major != WANPIPE_VERSION_MAJOR){ - ERR_IFACE("Error: drv_version.major (%d) != WANPIPE_VERSION_MAJOR (%d)\n", - drv_version.major, WANPIPE_VERSION_MAJOR); - exit(1); - } - - if(drv_version.minor != WANPIPE_VERSION_MINOR){ - ERR_IFACE("Error: drv_version.minor (%d) != WANPIPE_VERSION_MINOR (%d)\n", - drv_version.minor, WANPIPE_VERSION_MINOR); - exit(1); - } - - if(drv_version.minor1 != WANPIPE_VERSION_MINOR1){ - ERR_IFACE("Error: drv_version.minor1 (%d) != WANPIPE_VERSION_MINOR1 (%d)\n", - drv_version.minor1, WANPIPE_VERSION_MINOR1); - exit(1); - } - - unsigned int compiled_minor_version = WANPIPE_VERSION_MINOR2; - // This is a PATCH number - allow it to be greater or equal because binary - // compatibility is guaranteed - if(drv_version.minor2 < compiled_minor_version){ - ERR_IFACE("Error: drv_version.minor2 (%d) != WANPIPE_VERSION_MINOR2 (%d)\n", - drv_version.minor2, WANPIPE_VERSION_MINOR2); - exit(1); - } - - return 0; -} - -int sangoma_interface::DoManagementCommand(sng_fd_t fd, wan_udp_hdr_t* wan_udp) -{ - return sangoma_mgmt_cmd(fd, wan_udp); -} - -sangoma_wait_obj_t* sangoma_interface::get_wait_object_reference() -{ - return sng_wait_obj; -} - -unsigned char sangoma_interface::get_adapter_type() -{ - return adapter_type; -} - -//Returns Port Number mapped specifically for G3 use for a CARD. -unsigned int sangoma_interface::get_mapped_port_number() -{ - return interface_number; -} - -//Returns Span Number - global for the APPLICATION -unsigned int sangoma_interface::get_mapped_span_number() -{ - return wanpipe_number + 1 + get_mapped_port_number(); -} - -int sangoma_interface::transmit(wp_api_hdr_t* txhdr, void *pTx, UINT buffer_length) -{ - txhdr->operation_status = SANG_STATUS_GENERAL_ERROR; - txhdr->data_length = buffer_length; - - if(sangoma_writemsg(sangoma_dev, txhdr, sizeof(*txhdr), pTx, buffer_length, 0) < 0){ - //error - ERR_IFACE("sangoma_writemsg() failed!\n"); - return SANG_STATUS_IO_ERROR; - } - - switch(txhdr->operation_status) - { - case SANG_STATUS_SUCCESS: - //OK - break; - default: - //Error! Non-zero return code indicates Error to G3TI application. - ERR_IFACE("Return code: %s (%d) on transmission!\n", - SDLA_DECODE_SANG_STATUS(txhdr->operation_status), txhdr->operation_status); - break; - }//switch() - - return txhdr->operation_status; -} - -int sangoma_interface::read_data(wp_api_hdr_t* rxhdr, void *pRx, UINT buffer_length) -{ - int return_code; - - memset(rxhdr, 0x00, sizeof(*rxhdr)); - - rxhdr->operation_status = SANG_STATUS_GENERAL_ERROR; - - //Non-blocking read data. - return_code = sangoma_readmsg(sangoma_dev, rxhdr, sizeof(*rxhdr), pRx, buffer_length, 0); - - if(return_code <= 0){ - - if (SANG_STATUS_NO_DATA_AVAILABLE == rxhdr->operation_status) { - // no data is NOT an error at THIS level - return 0; - } else { - //Error! Non-zero return code indicates Error to G3TI application. - return 1; - } - } - - return 0; -} - -int sangoma_interface::read_event(wanpipe_api_t* wp_api) -{ - SANGOMA_INIT_TDM_API_CMD(*wp_api); - - //Non-blocking read Event. - return sangoma_read_event(sangoma_dev, wp_api); -} - -int sangoma_interface::set_buffer_multiplier(wanpipe_api_t* wp_api, int buffer_multiplier) -{ - SANGOMA_INIT_TDM_API_CMD(*wp_api); - - return sangoma_tdm_set_buffer_multiplier(sangoma_dev, wp_api, buffer_multiplier); -} diff --git a/api/libsangoma/examples/sample_data_tapping/sangoma_interface.h b/api/libsangoma/examples/sample_data_tapping/sangoma_interface.h deleted file mode 100644 index 19489a0..0000000 --- a/api/libsangoma/examples/sample_data_tapping/sangoma_interface.h +++ /dev/null @@ -1,167 +0,0 @@ -////////////////////////////////////////////////////////////////////// -// sangoma_interface.h: interface for Sangoma API driver. -// -// Author : David Rokhvarg -////////////////////////////////////////////////////////////////////// - -#ifndef SANGOMA_INTERFACE_H -#define SANGOMA_INTERFACE_H - -#if defined(__WINDOWS__) -# include -# include -#elif defined(__LINUX__) -/* Include headers */ -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -#else -# error Unsupported OS -#endif - -#include -#include //for offsetof() - -#include "libsangoma.h" -#include "wanpipe_api.h" - -/** - *@author David Rokhvarg - */ -struct func_protocol { - int protocol_id; - unsigned char prot_name[10]; - unsigned char mbox_offset; -}; - -#define DECODE_PROT(prot)((prot==WANCONFIG_FR)?"Frame Relay": \ - (prot==WANCONFIG_MFR)?"Frame Relay": \ - (prot==WANCONFIG_PPP)?"PPP Point-to-Point": \ - (prot==WANCONFIG_CHDLC)?"Cisco HDLC": \ - (prot==WANCONFIG_X25)?"X25": \ - (prot==WANCONFIG_ADSL)?"ADSL: Eth,IP,PPP/ATM": \ - (prot==WANCONFIG_ATM)?"ATM": \ - (prot==WANCONFIG_AFT)?"AFT T1/E1": \ - (prot==WANCONFIG_AFT_TE1)?"AFT T1/E1": \ - (prot==WANCONFIG_AFT_ANALOG)?"AFT Analog": \ - "Unknown") - -#define DEV_NAME_LEN 100 - -#define ON_STR "ON" -#define OFF_STR "OFF" - -#define MAX_INTERFACES_PER_PORT 32 - -class sangoma_interface { - - ////////////////////////////////////////////////////////////////// - /*! Sangoma IO device descriptor */ - sng_fd_t sangoma_dev; - - /*! wait object for an IO device */ - sangoma_wait_obj_t *sng_wait_obj; - - ////////////////////////////////////////////////////////////////// - //receive stuff - ULONG rx_frames_count; - ULONG rx_bytes_count; - //for counting frames with CRC/Abort errors - ULONG bad_rx_frames_count; - - ////////////////////////////////////////////////////////////////// - //transmit stuff - ULONG tx_bytes_count; - ULONG tx_frames_count; - UCHAR tx_test_byte; - - ////////////////////////////////////////////////////////////////// - //IOCTL management structures and variables - wan_udp_hdr_t wan_udp; - int protocol_cb_size; - int wan_protocol; - unsigned char adapter_type; - unsigned int card_model; - - int GetWANConfig( void ); - int get_interface_configuration(if_cfg_t *wanif_conf_ptr); - - //return DATA at offset 'off' - unsigned char get_wan_udphdr_data_byte(unsigned char off); - //return POINTER to data at offset 'off' - unsigned char *get_wan_udphdr_data_ptr(unsigned char off); - unsigned char set_wan_udphdr_data_byte(unsigned char off, unsigned char data); - - int get_fe_type(unsigned char* adapter_type); - int check_api_driver_version(); - - int wanpipe_api_ioctl(wan_cmd_api_t *api_cmd); - - - UCHAR DoWriteCommand(sng_fd_t drv, TX_DATA_STRUCT * pTx, UINT buffer_length); - UCHAR DoSetIdleTxBufferCommand(sng_fd_t drv, TX_DATA_STRUCT *pTx); - int DoManagementCommand(sng_fd_t fd, wan_udp_hdr_t* wan_udp); - - ////////////////////////////////////////////////////////////////// - wan_driver_version_t drv_version; - - char interface_name[DEV_NAME_LEN]; //used only for debugging - if_cfg_t wanif_conf_struct; //used only for debugging - - int wanpipe_number, interface_number; - - //In Legacy Mode 1-st interface is zero-based (i.g. wanpipe1_if0). - //In Regular Mode 1-st interface is one-based (i.g. wanpipe1_if1). - //The Setup installs in Regular Mode. - HANDLE open_first_interface_of_a_mapped_port(); - -public: - - sangoma_interface(int wanpipe_number, int interface_number); - ~sangoma_interface(); - - int init(); - int cleanup(); - - int read_te1_56k_stat(unsigned long *p_alarms); - char alarms_present(); - void set_lb_modes(unsigned char type, unsigned char mode); - int loopback_command(u_int8_t type, u_int8_t mode, u_int32_t chan_map); - - void operational_stats (wanpipe_chan_stats_t *stats); - void flush_operational_stats (void); - void flush_buffers (void); - - sangoma_wait_obj_t* get_wait_object_reference(); - unsigned char get_adapter_type(); - - //Returns Port Number mapped specifically for G3 use. - unsigned int get_mapped_port_number(); - - unsigned int get_mapped_span_number(); - - int get_api_driver_version (PDRIVER_VERSION p_drv_version); - - int set_buffer_multiplier(wanpipe_api_t* wp_api, int buffer_multiplier); - - int transmit (wp_api_hdr_t* hdr, void *pTx, UINT buffer_length); - int read_data(wp_api_hdr_t* hdr, void *pRx, UINT buffer_length); - int read_event(wanpipe_api_t* wp_api); -}; - -#endif//#define SANGOMA_INTERFACE_H - diff --git a/api/libsangoma/libsangoma.h b/api/libsangoma/libsangoma.h index e9a3329..87fc42f 100644 --- a/api/libsangoma/libsangoma.h +++ b/api/libsangoma/libsangoma.h @@ -2270,6 +2270,7 @@ sangoma_status_t _LIBSNG_CALL sangoma_hwec_get_global_chip_statistics(sng_fd_t f sangoma_status_t _LIBSNG_CALL sangoma_hwec_get_chip_image_info(sng_fd_t fd, int *hwec_api_return_code, wanec_chip_image_t *wanec_chip_image, int verbose); +#ifdef WP_API_FEATURE_LIBSNG_HWEC_DTMF_REMOVAL /*! \fn sangoma_status_t _LIBSNG_CALL sangoma_hwec_set_hwdtmf_removal(sng_fd_t fd, unsigned int fe_chan, int *hwec_api_return_code, int enable) @@ -2292,6 +2293,7 @@ sangoma_status_t _LIBSNG_CALL sangoma_hwec_get_chip_image_info(sng_fd_t fd, sangoma_status_t _LIBSNG_CALL sangoma_hwec_set_hwdtmf_removal(sng_fd_t fd, unsigned int fe_chan, int *hwec_api_return_code, int enable, int verbose); #endif /* WP_API_FEATURE_LIBSNG_HWEC */ +#endif diff --git a/deb_control/wanpipe.deb b/deb_control/wanpipe.deb index f00e792..4ab2611 100644 --- a/deb_control/wanpipe.deb +++ b/deb_control/wanpipe.deb @@ -1,5 +1,5 @@ Package: wanpipe -Version: 7.0.1-0 +Version: 7.0.2-0 Section: networking Priority: optional Architecture: all diff --git a/patches/kdrivers/include/sdla_te1.h b/patches/kdrivers/include/sdla_te1.h index ea9f0f9..3ef54a5 100644 --- a/patches/kdrivers/include/sdla_te1.h +++ b/patches/kdrivers/include/sdla_te1.h @@ -475,8 +475,15 @@ typedef struct { u_int16_t feb_diff; u_int32_t fer_errors; /* Framing bit errors (T1) */ u_int16_t fer_diff; + u_int32_t sync_errors; } sdla_te_pmon_t; +#define WAN_PMON_SYNC_ERROR(card) do { \ + sdla_te_pmon_t *pmon; \ + pmon = &card->fe.fe_stats.te_pmon; \ + pmon->sync_errors++; \ + } while (0); + #define WAN_TE_RXLEVEL_LEN 20 typedef struct { u_int16_t mask; diff --git a/patches/kdrivers/include/wanpipe_version.h b/patches/kdrivers/include/wanpipe_version.h index 85ffc32..eb8aa41 100644 --- a/patches/kdrivers/include/wanpipe_version.h +++ b/patches/kdrivers/include/wanpipe_version.h @@ -10,14 +10,14 @@ #define WANPIPE_COMPANY "Sangoma Technologies Inc" /********** LINUX **********/ -#define WANPIPE_VERSION "7.0.1" +#define WANPIPE_VERSION "7.0.2" #define WANPIPE_SUB_VERSION "0" #define WANPIPE_LITE_VERSION "1.1.1" #if defined(__LINUX__) #define WANPIPE_VERSION_MAJOR 7 #define WANPIPE_VERSION_MINOR 0 -#define WANPIPE_VERSION_MINOR1 1 +#define WANPIPE_VERSION_MINOR1 2 #define WANPIPE_VERSION_MINOR2 0 #endif diff --git a/patches/kdrivers/src/net/aft_core.c b/patches/kdrivers/src/net/aft_core.c index af4fd1d..50b44f9 100644 --- a/patches/kdrivers/src/net/aft_core.c +++ b/patches/kdrivers/src/net/aft_core.c @@ -6961,8 +6961,9 @@ static void t116_error_counter_check(sdla_t *card) } if (wan_test_and_clear_bit(AFT_LCFG_T116_FE_RX_SYNC, &dump)){ - err++; + WAN_PMON_SYNC_ERROR(card); DEBUG_ERROR("%s: Error: T116 Lost Sync\n",card->devname); + err++; } if (err) { @@ -7714,6 +7715,7 @@ global_irq_skip: card->u.aft.lcfg_reg=lcfg_reg; disable_data_error_intr(card,LINK_DOWN); + WAN_PMON_SYNC_ERROR(card); if (!wan_test_bit(AFT_FE_RESTART,&card->u.aft.port_task_cmd)) { DEBUG_ERROR("%s: Warning: Front End Lost Synchronization (sync_cnt=%i,c=%i,f=%i)\n", diff --git a/patches/kdrivers/src/net/sdla_8te1.c b/patches/kdrivers/src/net/sdla_8te1.c index c747281..6e7a54b 100644 --- a/patches/kdrivers/src/net/sdla_8te1.c +++ b/patches/kdrivers/src/net/sdla_8te1.c @@ -1984,8 +1984,6 @@ static int sdla_ds_te1_unconfig(void* pfe) DEBUG_EVENT("%s: %s Front End unconfigation!\n", fe->name, FE_MEDIA_DECODE(fe)); - sdla_ds_te1_set_alarms(fe,WAN_TE_BIT_ALARM_AIS); - /* FIXME: Alex to disable interrupts here */ sdla_ds_te1_disable_irq(fe); @@ -4784,8 +4782,18 @@ static int sdla_ds_te1_pmon(sdla_fe_t *fe, int action) WAN_TE_BIT_PMON_CRC4 | WAN_TE_BIT_PMON_FAS | WAN_TE_BIT_PMON_FEB; - pmon->crc4_diff = pmon2; - pmon->crc4_errors = pmon->crc4_errors + pmon2; + if (fe->fe_chip_id == DEVICE_ID_DS26519) { + if (WAN_FE_FRAME(fe) == WAN_FR_CRC4){ + pmon->crc4_diff = pmon2; + pmon->crc4_errors = pmon->crc4_errors + pmon2; + } else { + pmon->crc4_diff = 0; + pmon->crc4_errors = 0; + } + } else { + pmon->crc4_diff = pmon2; + pmon->crc4_errors = pmon->crc4_errors + pmon2; + } pmon->fas_diff = pmon3; pmon->fas_errors = pmon->fas_errors + pmon3; pmon->feb_diff = pmon4; diff --git a/patches/kdrivers/src/net/sdla_tdmv.c b/patches/kdrivers/src/net/sdla_tdmv.c index 4bf1bb1..e63f05f 100644 --- a/patches/kdrivers/src/net/sdla_tdmv.c +++ b/patches/kdrivers/src/net/sdla_tdmv.c @@ -1690,6 +1690,7 @@ static int wp_tdmv_spanconfig(struct zt_span *span, struct zt_lineconfig *lc) sdla_t *card = NULL; int err = 0; wan_smp_flag_t smp_flags; + int need_reconfig=0; WAN_ASSERT2(span == NULL, -ENODEV); @@ -1697,8 +1698,20 @@ static int wp_tdmv_spanconfig(struct zt_span *span, struct zt_lineconfig *lc) WAN_ASSERT2(wp == NULL, -ENODEV); card = (sdla_t*)wp->card; - DEBUG_EVENT("%s: DAHDI Configuring span device..\n", wp->devname); + DEBUG_EVENT("%s: DAHDI Configuring device [name=%s, span=%i, sync=%i, lcfg=0x%X,]\n", + wp->devname,lc->name, lc->span,lc->sync,lc->lineconfig); + if (lc->sync == 0) { + if (WAN_TE1_CLK(&card->fe) != WAN_MASTER_CLK) { + WAN_TE1_CLK(&card->fe) = WAN_MASTER_CLK; + need_reconfig=1; + } + } else { + if (WAN_TE1_CLK(&card->fe) != WAN_NORMAL_CLK) { + WAN_TE1_CLK(&card->fe) = WAN_NORMAL_CLK; + need_reconfig=1; + } + } if (!wp->ise1) { if (lc->lineconfig & ZT_CONFIG_B8ZS) { @@ -1725,7 +1738,10 @@ static int wp_tdmv_spanconfig(struct zt_span *span, struct zt_lineconfig *lc) return -EINVAL; } - WAN_TE1_LBO(&card->fe) = lc->lbo+WAN_T1_0_133; + if (WAN_TE1_LBO(&card->fe) != (lc->lbo+WAN_T1_0_133)) { + WAN_TE1_LBO(&card->fe) = lc->lbo+WAN_T1_0_133; + need_reconfig=1; + } } else { if (lc->lineconfig & ZT_CONFIG_HDB3){ @@ -1743,35 +1759,52 @@ static int wp_tdmv_spanconfig(struct zt_span *span, struct zt_lineconfig *lc) wp->frame = WAN_FR_CRC4; } - card->fe.fe_cfg.cfg.te_cfg.sig_mode = WAN_TE1_SIG_CAS; if (lc->lineconfig & ZT_CONFIG_CCS) { span->lineconfig |= ZT_CONFIG_CCS; - card->fe.fe_cfg.cfg.te_cfg.sig_mode = WAN_TE1_SIG_CCS; + + if (card->fe.fe_cfg.cfg.te_cfg.sig_mode != WAN_TE1_SIG_CCS) { + card->fe.fe_cfg.cfg.te_cfg.sig_mode = WAN_TE1_SIG_CCS; + need_reconfig=1; + } + } else { + if (card->fe.fe_cfg.cfg.te_cfg.sig_mode != WAN_TE1_SIG_CAS) { + need_reconfig=1; + card->fe.fe_cfg.cfg.te_cfg.sig_mode = WAN_TE1_SIG_CAS; + } } WAN_TE1_LBO(&card->fe) = WAN_E1_120; } - - WAN_FE_LCODE(&card->fe) = wp->lcode; - WAN_FE_FRAME(&card->fe) = wp->frame; - - if (card->wandev.fe_iface.config && - card->wandev.fe_iface.unconfig && - card->wandev.fe_iface.reconfig) { + if (WAN_FE_LCODE(&card->fe) != wp->lcode || + WAN_FE_FRAME(&card->fe) != wp->frame) { - card->hw_iface.hw_lock(card->hw,&smp_flags); - card->wandev.fe_iface.unconfig(&card->fe); - card->hw_iface.hw_unlock(card->hw,&smp_flags); + WAN_FE_LCODE(&card->fe) = wp->lcode; + WAN_FE_FRAME(&card->fe) = wp->frame; + need_reconfig=1; + } - card->wandev.fe_iface.post_unconfig(&card->fe); - card->hw_iface.hw_lock(card->hw,&smp_flags); - card->wandev.fe_iface.config(&card->fe); - card->wandev.fe_iface.reconfig(&card->fe); - card->hw_iface.hw_unlock(card->hw,&smp_flags); + if (need_reconfig) { + if (card->wandev.fe_iface.config && + card->wandev.fe_iface.unconfig && + card->wandev.fe_iface.reconfig) { - card->wandev.fe_iface.post_init(&card->fe); + card->hw_iface.hw_lock(card->hw,&smp_flags); + card->wandev.fe_iface.unconfig(&card->fe); + card->hw_iface.hw_unlock(card->hw,&smp_flags); + + card->wandev.fe_iface.post_unconfig(&card->fe); + + card->hw_iface.hw_lock(card->hw,&smp_flags); + card->wandev.fe_iface.config(&card->fe); + card->wandev.fe_iface.reconfig(&card->fe); + card->hw_iface.hw_unlock(card->hw,&smp_flags); + + card->wandev.fe_iface.post_init(&card->fe); + } + } else { + DEBUG_EVENT("%s: Wanpipe front end skipped, no changes in config\n", wp->devname); } span->txlevel = 0; diff --git a/rpmspec/wanpipe-mod.rpmspec b/rpmspec/wanpipe-mod.rpmspec index 0929c97..1a24c81 100644 --- a/rpmspec/wanpipe-mod.rpmspec +++ b/rpmspec/wanpipe-mod.rpmspec @@ -1,6 +1,6 @@ %define WANPIPE_VER wanpipe-modules %define name %{WANPIPE_VER} -%define version 7.0.1 +%define version 7.0.2 %define release 0 %define serial 1 %define MODULES_DIR /lib/modules @@ -59,6 +59,23 @@ fi %changelog +* Fri May 10 2013 Nenad Corbic - 7.0.2 +================================================================== + +- Added sync error statistic in wanpipeomon Ta command + Sync error indicates clocking or synchronizatio errors + on T1/E1 lines. Provides added statistic to debug line, + slip errors on T1/E1. + +- Fixed DAHDI reconfiguration issues. + running dahdi_cfg multiple times will not bring down T1/E1 link + Added config option to change clocking from MASTER to NORMAL + from dahdi system.conf + +- New sample_data_tapping sample application for T116 and other + tapping boards. + + * Tue Mar 19 2013 Nenad Corbic - 7.0.1 ================================================================== diff --git a/rpmspec/wanpipe-util.rpmspec b/rpmspec/wanpipe-util.rpmspec index 6390f50..57df3f7 100644 --- a/rpmspec/wanpipe-util.rpmspec +++ b/rpmspec/wanpipe-util.rpmspec @@ -1,6 +1,6 @@ %define WANPIPE_VER wanpipe-util %define name %{WANPIPE_VER} -%define version 7.0.1 +%define version 7.0.2 %define release 0 %define serial 1 %define UTILS_DIR /usr/sbin @@ -229,6 +229,23 @@ chmod 755 /usr/local/sbin/setup-sangoma %changelog +* Fri May 10 2013 Nenad Corbic - 7.0.2 +================================================================== + +- Added sync error statistic in wanpipeomon Ta command + Sync error indicates clocking or synchronizatio errors + on T1/E1 lines. Provides added statistic to debug line, + slip errors on T1/E1. + +- Fixed DAHDI reconfiguration issues. + running dahdi_cfg multiple times will not bring down T1/E1 link + Added config option to change clocking from MASTER to NORMAL + from dahdi system.conf + +- New sample_data_tapping sample application for T116 and other + tapping boards. + + * Tue Mar 19 2013 Nenad Corbic - 7.0.1 ================================================================== diff --git a/rpmspec/wanpipe.rpmspec b/rpmspec/wanpipe.rpmspec index 3a67171..ee4cf87 100644 --- a/rpmspec/wanpipe.rpmspec +++ b/rpmspec/wanpipe.rpmspec @@ -1,7 +1,7 @@ %define KERNEL_VERSION %{?kern_ver} %define WANPIPE_VER wanpipe %define name %{WANPIPE_VER} -%define version 7.0.1 +%define version 7.0.2 %define release 0 %define serial 1 %define UTILS_DIR /usr/sbin @@ -246,6 +246,23 @@ chmod 755 /usr/local/sbin/setup-sangoma %changelog +* Fri May 10 2013 Nenad Corbic - 7.0.2 +================================================================== + +- Added sync error statistic in wanpipeomon Ta command + Sync error indicates clocking or synchronizatio errors + on T1/E1 lines. Provides added statistic to debug line, + slip errors on T1/E1. + +- Fixed DAHDI reconfiguration issues. + running dahdi_cfg multiple times will not bring down T1/E1 link + Added config option to change clocking from MASTER to NORMAL + from dahdi system.conf + +- New sample_data_tapping sample application for T116 and other + tapping boards. + + * Tue Mar 19 2013 Nenad Corbic - 7.0.1 ================================================================== diff --git a/samples/wanrouter b/samples/wanrouter index 0230589..e3523bb 100644 --- a/samples/wanrouter +++ b/samples/wanrouter @@ -2231,7 +2231,7 @@ init_global_params() { if [ $OSYSTEM = "Linux" ]; then - ROUTER_VERSION=7.0.1 + ROUTER_VERSION=7.0.2 IFCONFIG_LIST=ifconfig MODULE_STAT=lsmod WAN_DRIVERS="wanpipe" diff --git a/util/wancfg_zaptel/A10x.pm b/util/wancfg_zaptel/A10x.pm index 6337e19..f69a6c6 100755 --- a/util/wancfg_zaptel/A10x.pm +++ b/util/wancfg_zaptel/A10x.pm @@ -443,6 +443,11 @@ sub gen_wanpipe_conf{ $wp_file =~ s/RXSLEVEL/$rx_slevel/g; $wp_file =~ s/FELBO/$fe_lbo/g; + if ($fe_lcode eq "AMI" && $fe_frame eq "D4" ){ + print "Setting DCHAN $dchan to zero\n"; + $dchan=0; + } + if($self->is_data_api eq '0') { $wp_file =~ s/TDMVDCHAN/0/g; $hw_dtmf="NO"; diff --git a/util/wanpipemon/fe_lib.c b/util/wanpipemon/fe_lib.c index b2b1177..8a6bd1b 100644 --- a/util/wanpipemon/fe_lib.c +++ b/util/wanpipemon/fe_lib.c @@ -1277,6 +1277,8 @@ void read_te1_56k_stat(unsigned char force) printf("FAS Errors\t\t: %d\n", pmon->fas_errors); } + printf("Sync Errors\t\t: %d\n", + pmon->sync_errors); } if (femedia.media == WAN_MEDIA_DS3 || femedia.media == WAN_MEDIA_E3){ diff --git a/wanpipe.spec b/wanpipe.spec index 951352e..39d5b44 100644 --- a/wanpipe.spec +++ b/wanpipe.spec @@ -25,7 +25,7 @@ # %define NAME wanpipe -%define VERSION 7.0.1 +%define VERSION 7.0.2 %define RELEASE 0 %define KVERSION %{?kernel} %define KSRC %{?ksrc} @@ -259,6 +259,23 @@ fi %changelog +* Fri May 10 2013 Nenad Corbic - 7.0.2 +================================================================== + +- Added sync error statistic in wanpipeomon Ta command + Sync error indicates clocking or synchronizatio errors + on T1/E1 lines. Provides added statistic to debug line, + slip errors on T1/E1. + +- Fixed DAHDI reconfiguration issues. + running dahdi_cfg multiple times will not bring down T1/E1 link + Added config option to change clocking from MASTER to NORMAL + from dahdi system.conf + +- New sample_data_tapping sample application for T116 and other + tapping boards. + + * Tue Mar 19 2013 Nenad Corbic - 7.0.1 ==================================================================