some cross platform cleanup.
git-svn-id: http://svn.openzap.org/svn/openzap/trunk@40 a93c3328-9c30-0410-af19-c9cd2b2d52af
This commit is contained in:
parent
72609fa965
commit
6b55778560
|
@ -1,363 +1,432 @@
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* win_api_common.h Windows Sangoma API Code Library
|
* sangoma_tdm_api.h Sangoma API Code Library
|
||||||
*
|
*
|
||||||
* Author(s): David Rokhvarg <davidr@sangoma.com>
|
* Author(s): David Rokhvarg <davidr@sangoma.com>
|
||||||
*
|
*
|
||||||
* Copyright: (c) 1984-2006 Sangoma Technologies Inc.
|
* Copyright: (c) 1984-2006 Sangoma Technologies Inc.
|
||||||
*
|
*
|
||||||
* ============================================================================
|
* ============================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _WIN_API_COMMON_H
|
#ifndef _SANGOMA_TDM_API_H
|
||||||
#define _WIN_API_COMMON_H
|
#define _SANGOMA_TDM_API_H
|
||||||
|
|
||||||
|
#ifndef __WINDOWS__
|
||||||
|
#if defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32)
|
||||||
|
#define __WINDOWS__
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __WINDOWS__
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
/* disable warning for zero length array in a struct */
|
||||||
|
/* this will cause errors on c99 and ansi compliant compilers and will need to be fixed in the wanpipe header files */
|
||||||
|
#pragma warning(disable:4200 4201 4214)
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#define WP_INVALID_SOCKET INVALID_HANDLE_VALUE
|
||||||
|
#else
|
||||||
|
#define WP_INVALID_SOCKET -1
|
||||||
|
#include <stropts.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <wanpipe_defines.h>
|
||||||
|
#include <wanpipe_cfg.h>
|
||||||
|
#include <wanpipe_tdm_api.h>
|
||||||
|
#include <sdla_te1_pmc.h>
|
||||||
|
#ifdef __WINDOWS__
|
||||||
|
#include <sang_status_defines.h>
|
||||||
|
#include <sang_api.h>
|
||||||
|
#endif
|
||||||
|
#include <sdla_aft_te1.h>
|
||||||
|
|
||||||
|
#define FNAME_LEN 50
|
||||||
#define DEV_NAME_LEN 100
|
#define DEV_NAME_LEN 100
|
||||||
char device_name[DEV_NAME_LEN];
|
char device_name[DEV_NAME_LEN];
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __WINDOWS__
|
||||||
|
|
||||||
/* IOCTL management structures and variables*/
|
/* IOCTL management structures and variables*/
|
||||||
wan_udp_hdr_t wan_udp;
|
wan_udp_hdr_t wan_udp;
|
||||||
|
|
||||||
static wan_cmd_api_t api_cmd;
|
static wan_cmd_api_t api_cmd;
|
||||||
static api_tx_hdr_t *tx_hdr = (api_tx_hdr_t *)api_cmd.data;
|
static api_tx_hdr_t *tx_hdr = (api_tx_hdr_t *)api_cmd.data;
|
||||||
|
|
||||||
/* keeps the LAST (and single) event received */
|
/* keeps the LAST (and single) event received */
|
||||||
static wp_tdm_api_rx_hdr_t last_tdm_api_event_buffer;
|
static wp_tdm_api_rx_hdr_t last_tdm_api_event_buffer;
|
||||||
|
#endif
|
||||||
static
|
|
||||||
int
|
#ifdef __WINDOWS__
|
||||||
tdmv_api_ioctl(
|
static int tdmv_api_ioctl(sng_fd_t fd, wanpipe_tdm_api_cmd_t *tdm_api_cmd)
|
||||||
HANDLE fd,
|
{
|
||||||
wanpipe_tdm_api_cmd_t *tdm_api_cmd
|
DWORD ln;
|
||||||
)
|
unsigned char id = 0;
|
||||||
{
|
int err = 0;
|
||||||
DWORD ln;
|
|
||||||
unsigned char id = 0;
|
wan_udp.wan_udphdr_request_reply = 0x01;
|
||||||
int err = 0;
|
wan_udp.wan_udphdr_id = id;
|
||||||
|
wan_udp.wan_udphdr_return_code = WAN_UDP_TIMEOUT_CMD;
|
||||||
wan_udp.wan_udphdr_request_reply = 0x01;
|
|
||||||
wan_udp.wan_udphdr_id = id;
|
wan_udp.wan_udphdr_command = WAN_TDMV_API_IOCTL;
|
||||||
wan_udp.wan_udphdr_return_code = WAN_UDP_TIMEOUT_CMD;
|
wan_udp.wan_udphdr_data_len = sizeof(wanpipe_tdm_api_cmd_t);
|
||||||
|
|
||||||
wan_udp.wan_udphdr_command = WAN_TDMV_API_IOCTL;
|
//copy data from caller's buffer to driver's buffer
|
||||||
wan_udp.wan_udphdr_data_len = sizeof(wanpipe_tdm_api_cmd_t);
|
memcpy( wan_udp.wan_udphdr_data,
|
||||||
|
(void*)tdm_api_cmd,
|
||||||
//copy data from caller's buffer to driver's buffer
|
sizeof(wanpipe_tdm_api_cmd_t));
|
||||||
memcpy( wan_udp.wan_udphdr_data,
|
|
||||||
(void*)tdm_api_cmd,
|
if(DeviceIoControl(
|
||||||
sizeof(wanpipe_tdm_api_cmd_t));
|
fd,
|
||||||
|
IoctlManagementCommand,
|
||||||
if(DeviceIoControl(
|
(LPVOID)&wan_udp,
|
||||||
fd,
|
sizeof(wan_udp_hdr_t),
|
||||||
IoctlManagementCommand,
|
(LPVOID)&wan_udp,
|
||||||
(LPVOID)&wan_udp,
|
sizeof(wan_udp_hdr_t),
|
||||||
sizeof(wan_udp_hdr_t),
|
(LPDWORD)(&ln),
|
||||||
(LPVOID)&wan_udp,
|
(LPOVERLAPPED)NULL
|
||||||
sizeof(wan_udp_hdr_t),
|
) == FALSE){
|
||||||
(LPDWORD)(&ln),
|
//actual ioctl failed
|
||||||
(LPOVERLAPPED)NULL
|
err = 1;
|
||||||
) == FALSE){
|
return err;
|
||||||
//actual ioctl failed
|
}else{
|
||||||
err = 1;
|
err = 0;
|
||||||
return err;
|
}
|
||||||
}else{
|
|
||||||
err = 0;
|
if(wan_udp.wan_udphdr_return_code != WAN_CMD_OK){
|
||||||
}
|
//ioctl ok, but command failed
|
||||||
|
return 2;
|
||||||
if(wan_udp.wan_udphdr_return_code != WAN_CMD_OK){
|
}
|
||||||
//ioctl ok, but command failed
|
|
||||||
return 2;
|
//copy data from driver's buffer to caller's buffer
|
||||||
}
|
memcpy( (void*)tdm_api_cmd,
|
||||||
|
wan_udp.wan_udphdr_data,
|
||||||
//copy data from driver's buffer to caller's buffer
|
sizeof(wanpipe_tdm_api_cmd_t));
|
||||||
memcpy( (void*)tdm_api_cmd,
|
return 0;
|
||||||
wan_udp.wan_udphdr_data,
|
}
|
||||||
sizeof(wanpipe_tdm_api_cmd_t));
|
|
||||||
return 0;
|
#else
|
||||||
}
|
static int tdmv_api_ioctl(sng_fd_t fd, wanpipe_tdm_api_cmd_t *tdm_api_cmd)
|
||||||
|
{
|
||||||
static
|
return ioctl(fd, SIOC_WANPIPE_TDM_API, tdm_api_cmd);
|
||||||
int
|
}
|
||||||
wanpipe_api_ioctl(
|
#endif
|
||||||
HANDLE fd,
|
|
||||||
wan_cmd_api_t *api_cmd
|
static sng_fd_t tdmv_api_open_span_chan(int span, int chan)
|
||||||
)
|
{
|
||||||
{
|
char fname[FNAME_LEN];
|
||||||
DWORD ln;
|
#if defined(__WINDOWS__)
|
||||||
unsigned char id = 0;
|
|
||||||
int err = 0;
|
//NOTE: under Windows Interfaces are zero based but 'chan' is 1 based.
|
||||||
|
// Subtract 1 from 'chan'.
|
||||||
wan_udp.wan_udphdr_request_reply = 0x01;
|
_snprintf(fname , FNAME_LEN, "\\\\.\\WANPIPE%d_IF%d", span, chan - 1);
|
||||||
wan_udp.wan_udphdr_id = id;
|
|
||||||
wan_udp.wan_udphdr_return_code = WAN_UDP_TIMEOUT_CMD;
|
//prn(verbose, "Opening device: %s...\n", fname);
|
||||||
|
|
||||||
wan_udp.wan_udphdr_command = SIOC_WANPIPE_API;
|
return CreateFile( fname,
|
||||||
wan_udp.wan_udphdr_data_len = sizeof(wan_cmd_api_t);
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
//copy data from caller's buffer to driver's buffer
|
(LPSECURITY_ATTRIBUTES)NULL,
|
||||||
memcpy( wan_udp.wan_udphdr_data,
|
OPEN_EXISTING,
|
||||||
(void*)api_cmd,
|
FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH,
|
||||||
sizeof(wan_cmd_api_t));
|
(HANDLE)NULL
|
||||||
|
);
|
||||||
if(DeviceIoControl(
|
#else
|
||||||
fd,
|
int fd = WP_INVALID_SOCKET;
|
||||||
IoctlManagementCommand,
|
|
||||||
(LPVOID)&wan_udp,
|
sprintf(fname,"/dev/wptdm_s%dc%d",span,chan);
|
||||||
sizeof(wan_udp_hdr_t),
|
|
||||||
(LPVOID)&wan_udp,
|
fd = open(fname, O_RDWR);
|
||||||
sizeof(wan_udp_hdr_t),
|
|
||||||
(LPDWORD)(&ln),
|
if (fd < 0) {
|
||||||
(LPOVERLAPPED)NULL
|
fd = WP_INVALID_SOCKET;
|
||||||
) == FALSE){
|
}
|
||||||
err = 1;
|
|
||||||
return err;
|
return fd;
|
||||||
}else{
|
#endif
|
||||||
err = 0;
|
}
|
||||||
}
|
|
||||||
|
#ifdef __WINDOWS__
|
||||||
if(wan_udp.wan_udphdr_return_code != WAN_CMD_OK){
|
static int wanpipe_api_ioctl(sng_fd_t fd, wan_cmd_api_t *api_cmd)
|
||||||
return 2;
|
{
|
||||||
}
|
DWORD ln;
|
||||||
|
unsigned char id = 0;
|
||||||
//copy data from driver's buffer to caller's buffer
|
int err = 0;
|
||||||
memcpy( (void*)api_cmd,
|
|
||||||
wan_udp.wan_udphdr_data,
|
wan_udp.wan_udphdr_request_reply = 0x01;
|
||||||
sizeof(wan_cmd_api_t));
|
wan_udp.wan_udphdr_id = id;
|
||||||
return 0;
|
wan_udp.wan_udphdr_return_code = WAN_UDP_TIMEOUT_CMD;
|
||||||
}
|
|
||||||
|
wan_udp.wan_udphdr_command = SIOC_WANPIPE_API;
|
||||||
// Blocking read command. If used after DoApiPollCommand(),
|
wan_udp.wan_udphdr_data_len = sizeof(wan_cmd_api_t);
|
||||||
// it will return immediatly, without blocking.
|
|
||||||
static
|
//copy data from caller's buffer to driver's buffer
|
||||||
USHORT
|
memcpy( wan_udp.wan_udphdr_data,
|
||||||
DoReadCommand(
|
(void*)api_cmd,
|
||||||
HANDLE drv,
|
sizeof(wan_cmd_api_t));
|
||||||
RX_DATA_STRUCT * pRx
|
|
||||||
)
|
if(DeviceIoControl(
|
||||||
{
|
fd,
|
||||||
DWORD ln;
|
IoctlManagementCommand,
|
||||||
|
(LPVOID)&wan_udp,
|
||||||
if (DeviceIoControl(
|
sizeof(wan_udp_hdr_t),
|
||||||
drv,
|
(LPVOID)&wan_udp,
|
||||||
IoctlReadCommand,
|
sizeof(wan_udp_hdr_t),
|
||||||
(LPVOID)NULL,
|
(LPDWORD)(&ln),
|
||||||
0L,
|
(LPOVERLAPPED)NULL
|
||||||
(LPVOID)pRx,
|
) == FALSE){
|
||||||
sizeof(RX_DATA_STRUCT),
|
err = 1;
|
||||||
(LPDWORD)(&ln),
|
return err;
|
||||||
(LPOVERLAPPED)NULL
|
}else{
|
||||||
) == FALSE){
|
err = 0;
|
||||||
//check messages log
|
}
|
||||||
return 1;
|
|
||||||
}else{
|
if(wan_udp.wan_udphdr_return_code != WAN_CMD_OK){
|
||||||
return 0;
|
return 2;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
//copy data from driver's buffer to caller's buffer
|
||||||
// Blocking write command. If used after DoApiPollCommand(),
|
memcpy( (void*)api_cmd,
|
||||||
// it will return immediatly, without blocking.
|
wan_udp.wan_udphdr_data,
|
||||||
static
|
sizeof(wan_cmd_api_t));
|
||||||
UCHAR
|
return 0;
|
||||||
DoWriteCommand(
|
}
|
||||||
HANDLE drv,
|
|
||||||
TX_DATA_STRUCT * pTx
|
// Blocking read command. If used after DoApiPollCommand(),
|
||||||
)
|
// it will return immediatly, without blocking.
|
||||||
{
|
static
|
||||||
DWORD ln;
|
USHORT
|
||||||
|
DoReadCommand(
|
||||||
if(DeviceIoControl(
|
sng_fd_t drv,
|
||||||
drv,
|
RX_DATA_STRUCT * pRx
|
||||||
IoctlWriteCommand,
|
)
|
||||||
(LPVOID)pTx,
|
{
|
||||||
(ULONG)sizeof(TX_DATA_STRUCT),
|
DWORD ln;
|
||||||
(LPVOID)pTx,
|
|
||||||
sizeof(TX_DATA_STRUCT),
|
if (DeviceIoControl(
|
||||||
(LPDWORD)(&ln),
|
drv,
|
||||||
(LPOVERLAPPED)NULL
|
IoctlReadCommand,
|
||||||
) == FALSE){
|
(LPVOID)NULL,
|
||||||
return 1;
|
0L,
|
||||||
}else{
|
(LPVOID)pRx,
|
||||||
return 0;
|
sizeof(RX_DATA_STRUCT),
|
||||||
}
|
(LPDWORD)(&ln),
|
||||||
}
|
(LPOVERLAPPED)NULL
|
||||||
|
) == FALSE){
|
||||||
// Blocking API Poll command.
|
//check messages log
|
||||||
static
|
return 1;
|
||||||
USHORT
|
}else{
|
||||||
DoApiPollCommand(
|
return 0;
|
||||||
HANDLE drv,
|
}
|
||||||
API_POLL_STRUCT *api_poll_ptr
|
}
|
||||||
)
|
|
||||||
{
|
// Blocking write command. If used after DoApiPollCommand(),
|
||||||
DWORD ln;
|
// it will return immediatly, without blocking.
|
||||||
|
static
|
||||||
if (DeviceIoControl(
|
UCHAR
|
||||||
drv,
|
DoWriteCommand(
|
||||||
IoctlApiPoll,
|
sng_fd_t drv,
|
||||||
(LPVOID)NULL,
|
TX_DATA_STRUCT * pTx
|
||||||
0L,
|
)
|
||||||
(LPVOID)api_poll_ptr,
|
{
|
||||||
sizeof(API_POLL_STRUCT),
|
DWORD ln;
|
||||||
(LPDWORD)(&ln),
|
|
||||||
(LPOVERLAPPED)NULL
|
if(DeviceIoControl(
|
||||||
) == FALSE){
|
drv,
|
||||||
return 1;
|
IoctlWriteCommand,
|
||||||
}else{
|
(LPVOID)pTx,
|
||||||
return 0;
|
(ULONG)sizeof(TX_DATA_STRUCT),
|
||||||
}
|
(LPVOID)pTx,
|
||||||
}
|
sizeof(TX_DATA_STRUCT),
|
||||||
|
(LPDWORD)(&ln),
|
||||||
static
|
(LPOVERLAPPED)NULL
|
||||||
int
|
) == FALSE){
|
||||||
DoManagementCommand(
|
return 1;
|
||||||
HANDLE drv,
|
}else{
|
||||||
wan_udp_hdr_t* wan_udp
|
return 0;
|
||||||
)
|
}
|
||||||
{
|
}
|
||||||
DWORD ln;
|
|
||||||
static unsigned char id = 0;
|
// Blocking API Poll command.
|
||||||
|
static
|
||||||
wan_udp->wan_udphdr_request_reply = 0x01;
|
USHORT
|
||||||
wan_udp->wan_udphdr_id = id++;
|
DoApiPollCommand(
|
||||||
wan_udp->wan_udphdr_return_code = WAN_UDP_TIMEOUT_CMD;
|
sng_fd_t drv,
|
||||||
|
API_POLL_STRUCT *api_poll_ptr
|
||||||
if(DeviceIoControl(
|
)
|
||||||
drv,
|
{
|
||||||
IoctlManagementCommand,
|
DWORD ln;
|
||||||
(LPVOID)wan_udp,
|
|
||||||
sizeof(wan_udp_hdr_t),
|
if (DeviceIoControl(
|
||||||
(LPVOID)wan_udp,
|
drv,
|
||||||
sizeof(wan_udp_hdr_t),
|
IoctlApiPoll,
|
||||||
(LPDWORD)(&ln),
|
(LPVOID)NULL,
|
||||||
(LPOVERLAPPED)NULL
|
0L,
|
||||||
) == FALSE){
|
(LPVOID)api_poll_ptr,
|
||||||
return 1;
|
sizeof(API_POLL_STRUCT),
|
||||||
}else{
|
(LPDWORD)(&ln),
|
||||||
return 0;
|
(LPOVERLAPPED)NULL
|
||||||
}
|
) == FALSE){
|
||||||
}
|
return 1;
|
||||||
|
}else{
|
||||||
///////////////////////////////////////////////////////////////////////////
|
return 0;
|
||||||
//
|
}
|
||||||
//structures and definitions used for queueing data
|
}
|
||||||
//
|
|
||||||
typedef struct
|
static
|
||||||
{
|
int
|
||||||
void* previous;
|
DoManagementCommand(
|
||||||
TX_RX_DATA_STRUCT tx_rx_data;
|
sng_fd_t drv,
|
||||||
}api_queue_element_t;
|
wan_udp_hdr_t* wan_udp
|
||||||
|
)
|
||||||
#define API_Q_MUTEX_TIMEOUT 1000//1 second
|
{
|
||||||
#define API_Q_MAX_SIZE 100//optimal length. for short data may need longer queue
|
DWORD ln;
|
||||||
|
static unsigned char id = 0;
|
||||||
enum API_Q_STATUS{
|
|
||||||
API_Q_SUCCESS=0,
|
wan_udp->wan_udphdr_request_reply = 0x01;
|
||||||
API_Q_GEN_FAILURE,
|
wan_udp->wan_udphdr_id = id++;
|
||||||
API_Q_MEM_ALLOC_FAILURE,
|
wan_udp->wan_udphdr_return_code = WAN_UDP_TIMEOUT_CMD;
|
||||||
API_Q_FULL,
|
|
||||||
API_Q_EMPTY
|
if(DeviceIoControl(
|
||||||
};
|
drv,
|
||||||
|
IoctlManagementCommand,
|
||||||
typedef struct
|
(LPVOID)wan_udp,
|
||||||
{
|
sizeof(wan_udp_hdr_t),
|
||||||
//number of nodes in the list
|
(LPVOID)wan_udp,
|
||||||
USHORT size;
|
sizeof(wan_udp_hdr_t),
|
||||||
//insert at tail
|
(LPDWORD)(&ln),
|
||||||
api_queue_element_t * tail;
|
(LPOVERLAPPED)NULL
|
||||||
//remove from head
|
) == FALSE){
|
||||||
api_queue_element_t * head;
|
return 1;
|
||||||
//mutex for synchronizing access to the queue
|
}else{
|
||||||
HANDLE api_queue_mutex;
|
return 0;
|
||||||
}api_queue_t;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static __inline int api_enqueue( api_queue_t* api_queue,
|
///////////////////////////////////////////////////////////////////////////
|
||||||
unsigned char * buffer,
|
//
|
||||||
unsigned short length)
|
//structures and definitions used for queueing data
|
||||||
{
|
//
|
||||||
api_queue_element_t *element;
|
typedef struct
|
||||||
DWORD mresult;
|
{
|
||||||
|
void* previous;
|
||||||
mresult = WaitForSingleObject(api_queue->api_queue_mutex, API_Q_MUTEX_TIMEOUT);
|
TX_RX_DATA_STRUCT tx_rx_data;
|
||||||
if (mresult != WAIT_OBJECT_0) {
|
}api_queue_element_t;
|
||||||
return API_Q_GEN_FAILURE;
|
|
||||||
}
|
#define API_Q_MUTEX_TIMEOUT 1000//1 second
|
||||||
|
#define API_Q_MAX_SIZE 100//optimal length. for short data may need longer queue
|
||||||
if(api_queue->size == API_Q_MAX_SIZE){
|
|
||||||
ReleaseMutex(api_queue->api_queue_mutex);
|
enum API_Q_STATUS{
|
||||||
return API_Q_FULL;
|
API_Q_SUCCESS=0,
|
||||||
}
|
API_Q_GEN_FAILURE,
|
||||||
|
API_Q_MEM_ALLOC_FAILURE,
|
||||||
element = malloc(sizeof(api_queue_element_t));
|
API_Q_FULL,
|
||||||
if(element == NULL){
|
API_Q_EMPTY
|
||||||
ReleaseMutex(api_queue->api_queue_mutex);
|
};
|
||||||
return API_Q_MEM_ALLOC_FAILURE;
|
|
||||||
}
|
typedef struct
|
||||||
|
{
|
||||||
//now copy everything in to the element
|
//number of nodes in the list
|
||||||
memcpy(element->tx_rx_data.data, buffer, length);
|
USHORT size;
|
||||||
|
//insert at tail
|
||||||
element->tx_rx_data.api_header.data_length = length;
|
api_queue_element_t * tail;
|
||||||
element->tx_rx_data.api_header.operation_status = SANG_STATUS_TX_TIMEOUT;
|
//remove from head
|
||||||
|
api_queue_element_t * head;
|
||||||
//insert element at the tail of the queue
|
//mutex for synchronizing access to the queue
|
||||||
element->previous = NULL;
|
sng_fd_t api_queue_mutex;
|
||||||
|
}api_queue_t;
|
||||||
if(api_queue->size == 0){
|
|
||||||
//special case of a previously empty queue
|
|
||||||
api_queue->head = element;
|
static __inline int api_enqueue( api_queue_t* api_queue,
|
||||||
api_queue->tail = element;
|
unsigned char * buffer,
|
||||||
}else{
|
unsigned short length)
|
||||||
api_queue->tail->previous = element;
|
{
|
||||||
api_queue->tail = element;
|
api_queue_element_t *element;
|
||||||
}
|
DWORD mresult;
|
||||||
api_queue->size++;
|
|
||||||
ReleaseMutex(api_queue->api_queue_mutex);
|
mresult = WaitForSingleObject(api_queue->api_queue_mutex, API_Q_MUTEX_TIMEOUT);
|
||||||
return API_Q_SUCCESS;
|
if (mresult != WAIT_OBJECT_0) {
|
||||||
}
|
return API_Q_GEN_FAILURE;
|
||||||
|
}
|
||||||
static __inline int api_dequeue( api_queue_t* api_queue,
|
|
||||||
TX_RX_DATA_STRUCT* destination)
|
if(api_queue->size == API_Q_MAX_SIZE){
|
||||||
{
|
ReleaseMutex(api_queue->api_queue_mutex);
|
||||||
api_queue_element_t *element;
|
return API_Q_FULL;
|
||||||
DWORD mresult;
|
}
|
||||||
|
|
||||||
mresult = WaitForSingleObject(api_queue->api_queue_mutex, API_Q_MUTEX_TIMEOUT);
|
element = malloc(sizeof(api_queue_element_t));
|
||||||
if (mresult != WAIT_OBJECT_0) {
|
if(element == NULL){
|
||||||
return API_Q_GEN_FAILURE;
|
ReleaseMutex(api_queue->api_queue_mutex);
|
||||||
}
|
return API_Q_MEM_ALLOC_FAILURE;
|
||||||
|
}
|
||||||
if(api_queue->size == 0){
|
|
||||||
//tx queue is empty
|
//now copy everything in to the element
|
||||||
ReleaseMutex(api_queue->api_queue_mutex);
|
memcpy(element->tx_rx_data.data, buffer, length);
|
||||||
return API_Q_EMPTY;
|
|
||||||
}
|
element->tx_rx_data.api_header.data_length = length;
|
||||||
|
element->tx_rx_data.api_header.operation_status = SANG_STATUS_TX_TIMEOUT;
|
||||||
//remove from the head of the queue
|
|
||||||
element = api_queue->head;
|
//insert element at the tail of the queue
|
||||||
api_queue->head = element->previous;
|
element->previous = NULL;
|
||||||
|
|
||||||
//now copy everything in to the user buffer
|
if(api_queue->size == 0){
|
||||||
memcpy(destination, &element->tx_rx_data, sizeof(TX_DATA_STRUCT));
|
//special case of a previously empty queue
|
||||||
|
api_queue->head = element;
|
||||||
free(element);
|
api_queue->tail = element;
|
||||||
api_queue->size--;
|
}else{
|
||||||
if(api_queue->size == 0){
|
api_queue->tail->previous = element;
|
||||||
api_queue->head = NULL;
|
api_queue->tail = element;
|
||||||
api_queue->tail = NULL;
|
}
|
||||||
}
|
api_queue->size++;
|
||||||
ReleaseMutex(api_queue->api_queue_mutex);
|
ReleaseMutex(api_queue->api_queue_mutex);
|
||||||
return API_Q_SUCCESS;
|
return API_Q_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
//remove all elements from the queue
|
static __inline int api_dequeue( api_queue_t* api_queue,
|
||||||
static __inline void empty_api_queue(api_queue_t* api_queue)
|
TX_RX_DATA_STRUCT* destination)
|
||||||
{
|
{
|
||||||
TX_DATA_STRUCT tx_rx_data;
|
api_queue_element_t *element;
|
||||||
|
DWORD mresult;
|
||||||
while(api_dequeue(api_queue, &tx_rx_data) == 0){
|
|
||||||
;
|
mresult = WaitForSingleObject(api_queue->api_queue_mutex, API_Q_MUTEX_TIMEOUT);
|
||||||
}
|
if (mresult != WAIT_OBJECT_0) {
|
||||||
}
|
return API_Q_GEN_FAILURE;
|
||||||
|
}
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
#endif /* _WIN_API_COMMON_H */
|
if(api_queue->size == 0){
|
||||||
|
//tx queue is empty
|
||||||
|
ReleaseMutex(api_queue->api_queue_mutex);
|
||||||
|
return API_Q_EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
//remove from the head of the queue
|
||||||
|
element = api_queue->head;
|
||||||
|
api_queue->head = element->previous;
|
||||||
|
|
||||||
|
//now copy everything in to the user buffer
|
||||||
|
memcpy(destination, &element->tx_rx_data, sizeof(TX_DATA_STRUCT));
|
||||||
|
|
||||||
|
free(element);
|
||||||
|
api_queue->size--;
|
||||||
|
if(api_queue->size == 0){
|
||||||
|
api_queue->head = NULL;
|
||||||
|
api_queue->tail = NULL;
|
||||||
|
}
|
||||||
|
ReleaseMutex(api_queue->api_queue_mutex);
|
||||||
|
return API_Q_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
//remove all elements from the queue
|
||||||
|
static __inline void empty_api_queue(api_queue_t* api_queue)
|
||||||
|
{
|
||||||
|
TX_DATA_STRUCT tx_rx_data;
|
||||||
|
|
||||||
|
while(api_dequeue(api_queue, &tx_rx_data) == 0){
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _SANGOMA_TDM_API_H */
|
|
@ -36,37 +36,12 @@
|
||||||
#include "openzap.h"
|
#include "openzap.h"
|
||||||
#include "zap_wanpipe.h"
|
#include "zap_wanpipe.h"
|
||||||
|
|
||||||
#ifdef __WINDOWS__
|
#include <sangoma_tdm_api.h>
|
||||||
#ifdef _MSC_VER
|
|
||||||
/* disable warning for zero length array in a struct */
|
|
||||||
/* this will cause errors on c99 and ansi compliant compilers and will need to be fixed in the wanpipe header files */
|
|
||||||
#pragma warning(disable:4200 4201 4214)
|
|
||||||
#endif
|
|
||||||
#include <windows.h>
|
|
||||||
#define FNAME_LEN 50
|
|
||||||
#define WP_INVALID_SOCKET INVALID_HANDLE_VALUE
|
|
||||||
#else
|
|
||||||
#define WP_INVALID_SOCKET -1
|
|
||||||
#include <stropts.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <wanpipe_defines.h>
|
|
||||||
#include <wanpipe_cfg.h>
|
|
||||||
#include <wanpipe_tdm_api.h>
|
|
||||||
#include <sdla_te1_pmc.h>
|
|
||||||
#ifdef __WINDOWS__
|
|
||||||
#include <sang_status_defines.h>
|
|
||||||
#include <sang_api.h>
|
|
||||||
#endif
|
|
||||||
#include <sdla_aft_te1.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__WINDOWS__)
|
|
||||||
#include <zap_wanpipe_windows.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
unsigned codec_ms;
|
unsigned codec_ms;
|
||||||
|
@ -78,11 +53,7 @@ static zap_status_t wp_tdm_cmd_exec(zap_channel_t *zchan, wanpipe_tdm_api_t *tdm
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
#if defined(__WINDOWS__)
|
|
||||||
err = tdmv_api_ioctl(zchan->sockfd, &tdm_api->wp_tdm_cmd);
|
err = tdmv_api_ioctl(zchan->sockfd, &tdm_api->wp_tdm_cmd);
|
||||||
#else
|
|
||||||
err = ioctl(zchan->sockfd, SIOC_WANPIPE_TDM_API, &tdm_api->wp_tdm_cmd);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
snprintf(zchan->last_error, sizeof(zchan->last_error), "%s", strerror(errno));
|
snprintf(zchan->last_error, sizeof(zchan->last_error), "%s", strerror(errno));
|
||||||
|
@ -92,36 +63,6 @@ static zap_status_t wp_tdm_cmd_exec(zap_channel_t *zchan, wanpipe_tdm_api_t *tdm
|
||||||
return ZAP_SUCCESS;
|
return ZAP_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static zap_socket_t wp_open_device(int span, int chan)
|
|
||||||
{
|
|
||||||
char fname[256];
|
|
||||||
#if defined(__WINDOWS__)
|
|
||||||
|
|
||||||
_snprintf(fname , FNAME_LEN, "\\\\.\\WANPIPE%d_IF%d", span, chan - 1);
|
|
||||||
|
|
||||||
return CreateFile( fname,
|
|
||||||
GENERIC_READ | GENERIC_WRITE,
|
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
||||||
(LPSECURITY_ATTRIBUTES)NULL,
|
|
||||||
OPEN_EXISTING,
|
|
||||||
FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH,
|
|
||||||
(HANDLE)NULL
|
|
||||||
);
|
|
||||||
#else
|
|
||||||
int fd=-1;
|
|
||||||
|
|
||||||
sprintf(fname, "/dev/wptdm_s%dc%d", span, chan);
|
|
||||||
|
|
||||||
fd = open(fname, O_RDWR);
|
|
||||||
|
|
||||||
if (fd < 0) {
|
|
||||||
fd = WP_INVALID_SOCKET;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fd;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned wp_open_range(zap_span_t *span, unsigned spanno, unsigned start, unsigned end, zap_chan_type_t type)
|
static unsigned wp_open_range(zap_span_t *span, unsigned spanno, unsigned start, unsigned end, zap_chan_type_t type)
|
||||||
{
|
{
|
||||||
unsigned configured = 0, x;
|
unsigned configured = 0, x;
|
||||||
|
@ -130,7 +71,7 @@ static unsigned wp_open_range(zap_span_t *span, unsigned spanno, unsigned start,
|
||||||
zap_channel_t *chan;
|
zap_channel_t *chan;
|
||||||
zap_socket_t sockfd = WP_INVALID_SOCKET;
|
zap_socket_t sockfd = WP_INVALID_SOCKET;
|
||||||
|
|
||||||
sockfd = wp_open_device(spanno, x);
|
sockfd = tdmv_api_open_span_chan(spanno, x);
|
||||||
|
|
||||||
if (sockfd != WP_INVALID_SOCKET && zap_span_add_channel(span, sockfd, type, &chan) == ZAP_SUCCESS) {
|
if (sockfd != WP_INVALID_SOCKET && zap_span_add_channel(span, sockfd, type, &chan) == ZAP_SUCCESS) {
|
||||||
zap_log(ZAP_LOG_INFO, "configuring device s%dc%d as OpenZAP device %d:%d fd:%d\n", spanno, x, chan->span_id, chan->chan_id, sockfd);
|
zap_log(ZAP_LOG_INFO, "configuring device s%dc%d as OpenZAP device %d:%d fd:%d\n", spanno, x, chan->span_id, chan->chan_id, sockfd);
|
||||||
|
|
Loading…
Reference in New Issue