From 2511f8ff0e0e05aa8d57490116395749bcd4f948 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Fri, 18 May 2007 05:33:19 +0000 Subject: [PATCH] step towards building on windows again. git-svn-id: http://svn.openzap.org/svn/openzap/trunk@27 a93c3328-9c30-0410-af19-c9cd2b2d52af --- libs/openzap/openzap.vcproj | 40 +- libs/openzap/src/include/openzap.h | 20 +- .../openzap/src/include/zap_wanpipe_windows.h | 363 ++++++++++++++++++ libs/openzap/src/zap_wanpipe.c | 65 ++-- 4 files changed, 454 insertions(+), 34 deletions(-) create mode 100644 libs/openzap/src/include/zap_wanpipe_windows.h diff --git a/libs/openzap/openzap.vcproj b/libs/openzap/openzap.vcproj index 2cae0acfce..bdcaead122 100644 --- a/libs/openzap/openzap.vcproj +++ b/libs/openzap/openzap.vcproj @@ -20,7 +20,7 @@ OutputDirectory="$(SolutionDir)$(ConfigurationName)" IntermediateDirectory="$(ConfigurationName)" ConfigurationType="4" - CharacterSet="1" + CharacterSet="2" > + + + + + + + + + + + + + + diff --git a/libs/openzap/src/include/openzap.h b/libs/openzap/src/include/openzap.h index 5626df6adc..4ee1e3a6fe 100644 --- a/libs/openzap/src/include/openzap.h +++ b/libs/openzap/src/include/openzap.h @@ -36,6 +36,19 @@ #define _XOPEN_SOURCE 500 +#ifndef HAVE_STRINGS_H +#define HAVE_STRINGS_H 1 +#endif +#ifndef HAVE_SYS_SOCKET_H +#define HAVE_SYS_SOCKET_H 1 +#endif + +#ifndef __WINDOWS__ +#if defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32) +#define __WINDOWS__ +#endif +#endif + #ifdef _MSC_VER #if (_MSC_VER >= 1400) /* VC8+ */ #ifndef _CRT_SECURE_NO_DEPRECATE @@ -51,12 +64,17 @@ #ifndef snprintf #define snprintf _snprintf #endif +#undef HAVE_STRINGS_H +#undef HAVE_SYS_SOCKET_H +/* 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:4706) #endif #include #include #include -#ifndef _MSC_VER +#ifdef HAVE_STRINGS_H #include #endif #include diff --git a/libs/openzap/src/include/zap_wanpipe_windows.h b/libs/openzap/src/include/zap_wanpipe_windows.h new file mode 100644 index 0000000000..d5773da640 --- /dev/null +++ b/libs/openzap/src/include/zap_wanpipe_windows.h @@ -0,0 +1,363 @@ +/***************************************************************************** + * win_api_common.h Windows Sangoma API Code Library + * + * Author(s): David Rokhvarg + * + * Copyright: (c) 1984-2006 Sangoma Technologies Inc. + * + * ============================================================================ + */ + +#ifndef _WIN_API_COMMON_H +#define _WIN_API_COMMON_H + +#define DEV_NAME_LEN 100 +char device_name[DEV_NAME_LEN]; + +/* IOCTL management structures and variables*/ +wan_udp_hdr_t wan_udp; + +static wan_cmd_api_t api_cmd; +static api_tx_hdr_t *tx_hdr = (api_tx_hdr_t *)api_cmd.data; + +/* keeps the LAST (and single) event received */ +static wp_tdm_api_rx_hdr_t last_tdm_api_event_buffer; + +static +int +tdmv_api_ioctl( + HANDLE fd, + wanpipe_tdm_api_cmd_t *tdm_api_cmd + ) +{ + DWORD ln; + unsigned char id = 0; + int err = 0; + + wan_udp.wan_udphdr_request_reply = 0x01; + wan_udp.wan_udphdr_id = id; + wan_udp.wan_udphdr_return_code = WAN_UDP_TIMEOUT_CMD; + + wan_udp.wan_udphdr_command = WAN_TDMV_API_IOCTL; + wan_udp.wan_udphdr_data_len = sizeof(wanpipe_tdm_api_cmd_t); + + //copy data from caller's buffer to driver's buffer + memcpy( wan_udp.wan_udphdr_data, + (void*)tdm_api_cmd, + sizeof(wanpipe_tdm_api_cmd_t)); + + if(DeviceIoControl( + fd, + IoctlManagementCommand, + (LPVOID)&wan_udp, + sizeof(wan_udp_hdr_t), + (LPVOID)&wan_udp, + sizeof(wan_udp_hdr_t), + (LPDWORD)(&ln), + (LPOVERLAPPED)NULL + ) == FALSE){ + //actual ioctl failed + err = 1; + return err; + }else{ + err = 0; + } + + 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, + sizeof(wanpipe_tdm_api_cmd_t)); + return 0; +} + +static +int +wanpipe_api_ioctl( + HANDLE fd, + wan_cmd_api_t *api_cmd + ) +{ + DWORD ln; + unsigned char id = 0; + int err = 0; + + wan_udp.wan_udphdr_request_reply = 0x01; + wan_udp.wan_udphdr_id = id; + wan_udp.wan_udphdr_return_code = WAN_UDP_TIMEOUT_CMD; + + wan_udp.wan_udphdr_command = SIOC_WANPIPE_API; + wan_udp.wan_udphdr_data_len = sizeof(wan_cmd_api_t); + + //copy data from caller's buffer to driver's buffer + memcpy( wan_udp.wan_udphdr_data, + (void*)api_cmd, + sizeof(wan_cmd_api_t)); + + if(DeviceIoControl( + fd, + IoctlManagementCommand, + (LPVOID)&wan_udp, + sizeof(wan_udp_hdr_t), + (LPVOID)&wan_udp, + sizeof(wan_udp_hdr_t), + (LPDWORD)(&ln), + (LPOVERLAPPED)NULL + ) == FALSE){ + err = 1; + return err; + }else{ + err = 0; + } + + if(wan_udp.wan_udphdr_return_code != WAN_CMD_OK){ + return 2; + } + + //copy data from driver's buffer to caller's buffer + memcpy( (void*)api_cmd, + wan_udp.wan_udphdr_data, + sizeof(wan_cmd_api_t)); + return 0; +} + +// Blocking read command. If used after DoApiPollCommand(), +// it will return immediatly, without blocking. +static +USHORT +DoReadCommand( + HANDLE drv, + RX_DATA_STRUCT * pRx + ) +{ + DWORD ln; + + if (DeviceIoControl( + drv, + IoctlReadCommand, + (LPVOID)NULL, + 0L, + (LPVOID)pRx, + sizeof(RX_DATA_STRUCT), + (LPDWORD)(&ln), + (LPOVERLAPPED)NULL + ) == FALSE){ + //check messages log + return 1; + }else{ + return 0; + } +} + +// Blocking write command. If used after DoApiPollCommand(), +// it will return immediatly, without blocking. +static +UCHAR +DoWriteCommand( + HANDLE drv, + TX_DATA_STRUCT * pTx + ) +{ + DWORD ln; + + if(DeviceIoControl( + drv, + IoctlWriteCommand, + (LPVOID)pTx, + (ULONG)sizeof(TX_DATA_STRUCT), + (LPVOID)pTx, + sizeof(TX_DATA_STRUCT), + (LPDWORD)(&ln), + (LPOVERLAPPED)NULL + ) == FALSE){ + return 1; + }else{ + return 0; + } +} + +// Blocking API Poll command. +static +USHORT +DoApiPollCommand( + HANDLE drv, + API_POLL_STRUCT *api_poll_ptr + ) +{ + DWORD ln; + + if (DeviceIoControl( + drv, + IoctlApiPoll, + (LPVOID)NULL, + 0L, + (LPVOID)api_poll_ptr, + sizeof(API_POLL_STRUCT), + (LPDWORD)(&ln), + (LPOVERLAPPED)NULL + ) == FALSE){ + return 1; + }else{ + return 0; + } +} + +static +int +DoManagementCommand( + HANDLE drv, + wan_udp_hdr_t* wan_udp + ) +{ + DWORD ln; + static unsigned char id = 0; + + wan_udp->wan_udphdr_request_reply = 0x01; + wan_udp->wan_udphdr_id = id++; + wan_udp->wan_udphdr_return_code = WAN_UDP_TIMEOUT_CMD; + + if(DeviceIoControl( + drv, + IoctlManagementCommand, + (LPVOID)wan_udp, + sizeof(wan_udp_hdr_t), + (LPVOID)wan_udp, + sizeof(wan_udp_hdr_t), + (LPDWORD)(&ln), + (LPOVERLAPPED)NULL + ) == FALSE){ + return 1; + }else{ + return 0; + } +} + +/////////////////////////////////////////////////////////////////////////// +// +//structures and definitions used for queueing data +// +typedef struct +{ + void* previous; + TX_RX_DATA_STRUCT tx_rx_data; +}api_queue_element_t; + +#define API_Q_MUTEX_TIMEOUT 1000//1 second +#define API_Q_MAX_SIZE 100//optimal length. for short data may need longer queue + +enum API_Q_STATUS{ + API_Q_SUCCESS=0, + API_Q_GEN_FAILURE, + API_Q_MEM_ALLOC_FAILURE, + API_Q_FULL, + API_Q_EMPTY +}; + +typedef struct +{ + //number of nodes in the list + USHORT size; + //insert at tail + api_queue_element_t * tail; + //remove from head + api_queue_element_t * head; + //mutex for synchronizing access to the queue + HANDLE api_queue_mutex; +}api_queue_t; + + +static __inline int api_enqueue( api_queue_t* api_queue, + unsigned char * buffer, + unsigned short length) +{ + api_queue_element_t *element; + DWORD mresult; + + mresult = WaitForSingleObject(api_queue->api_queue_mutex, API_Q_MUTEX_TIMEOUT); + if (mresult != WAIT_OBJECT_0) { + return API_Q_GEN_FAILURE; + } + + if(api_queue->size == API_Q_MAX_SIZE){ + ReleaseMutex(api_queue->api_queue_mutex); + return API_Q_FULL; + } + + element = malloc(sizeof(api_queue_element_t)); + if(element == NULL){ + ReleaseMutex(api_queue->api_queue_mutex); + return API_Q_MEM_ALLOC_FAILURE; + } + + //now copy everything in to the element + memcpy(element->tx_rx_data.data, buffer, length); + + element->tx_rx_data.api_header.data_length = length; + element->tx_rx_data.api_header.operation_status = SANG_STATUS_TX_TIMEOUT; + + //insert element at the tail of the queue + element->previous = NULL; + + if(api_queue->size == 0){ + //special case of a previously empty queue + api_queue->head = element; + api_queue->tail = element; + }else{ + api_queue->tail->previous = element; + api_queue->tail = element; + } + api_queue->size++; + ReleaseMutex(api_queue->api_queue_mutex); + return API_Q_SUCCESS; +} + +static __inline int api_dequeue( api_queue_t* api_queue, + TX_RX_DATA_STRUCT* destination) +{ + api_queue_element_t *element; + DWORD mresult; + + mresult = WaitForSingleObject(api_queue->api_queue_mutex, API_Q_MUTEX_TIMEOUT); + if (mresult != WAIT_OBJECT_0) { + return API_Q_GEN_FAILURE; + } + + 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 /* _WIN_API_COMMON_H */ diff --git a/libs/openzap/src/zap_wanpipe.c b/libs/openzap/src/zap_wanpipe.c index 53ce0cc9d0..55c037d25a 100644 --- a/libs/openzap/src/zap_wanpipe.c +++ b/libs/openzap/src/zap_wanpipe.c @@ -33,12 +33,6 @@ #define WANPIPE_TDM_API 1 -#ifndef __WINDOWS__ -#if defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32) -#define __WINDOWS__ -#endif -#endif - #include "openzap.h" #include "zap_wanpipe.h" @@ -49,28 +43,30 @@ #pragma warning(disable:4200 4201 4214) #endif #include -#include -#include -#include -typedef unsigned __int16 u_int16_t; -typedef unsigned __int32 u_int32_t; +#define FNAME_LEN 50 +#define WP_INVALID_SOCKET INVALID_HANDLE_VALUE +#else +#define WP_INVALID_SOCKET -1 #endif #include #include #include +#include #ifdef __WINDOWS__ #include #include #endif -#include -#include -#include -#include -#include -#include #include + +#ifdef HAVE_SYS_SOCKET_H #include +#endif + +#if defined(__WINDOWS__) +#include +#endif + static zap_software_interface_t wanpipe_interface; @@ -96,6 +92,10 @@ static zap_socket_t wp_open_device(int span, int chan) fd = open(fname, O_RDWR); + if (fd < 0) { + fd = WP_INVALID_SOCKET; + } + return fd; #endif } @@ -106,11 +106,11 @@ static unsigned wp_open_range(zap_span_t *span, unsigned spanno, unsigned start, for(x = start; x < end; x++) { zap_channel_t *chan; - zap_socket_t sockfd = -1; + zap_socket_t sockfd = WP_INVALID_SOCKET; sockfd = wp_open_device(spanno, x); - if (sockfd > -1 && 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); configured++; } else { @@ -129,7 +129,6 @@ static unsigned wp_configure_channel(zap_config_t *cfg, const char *str, zap_spa int channo; int spanno; int top = 0; - int x; unsigned configured = 0; assert(str != NULL); @@ -380,6 +379,8 @@ static ZINT_WAIT_FUNCTION(wanpipe_wait) } +#ifndef __WINDOWS__ + static ZINT_READ_FUNCTION(wanpipe_read_unix) { int rx_len = 0; @@ -416,17 +417,6 @@ static ZINT_READ_FUNCTION(wanpipe_read_unix) return ZAP_SUCCESS; } -static ZINT_READ_FUNCTION(wanpipe_read) -{ - ZINT_READ_MUZZLE; - -#ifndef WIN32 - return wanpipe_read_unix(zchan, data, datalen); -#endif - - return ZAP_FAIL; -} - static ZINT_WRITE_FUNCTION(wanpipe_write_unix) { int bsent; @@ -455,6 +445,19 @@ static ZINT_WRITE_FUNCTION(wanpipe_write_unix) } +#endif + +static ZINT_READ_FUNCTION(wanpipe_read) +{ + ZINT_READ_MUZZLE; + +#ifndef WIN32 + return wanpipe_read_unix(zchan, data, datalen); +#endif + + return ZAP_FAIL; +} + static ZINT_WRITE_FUNCTION(wanpipe_write) { ZINT_WRITE_MUZZLE;