/*!
\brief Test for the existance of a flag on an arbitary object
- \param obj the object to test
- \param flag the or'd list of flags to test
+ \command obj the object to test
+ \command flag the or'd list of flags to test
\return true value if the object has the flags defined
*/
#define zap_test_flag(obj, flag) ((obj)->flags & flag)
/*!
\brief Set a flag on an arbitrary object
- \param obj the object to set the flags on
- \param flag the or'd list of flags to set
+ \command obj the object to set the flags on
+ \command flag the or'd list of flags to set
*/
#define zap_set_flag(obj, flag) (obj)->flags |= (flag)
/*!
\brief Clear a flag on an arbitrary object while locked
- \param obj the object to test
- \param flag the or'd list of flags to clear
+ \command obj the object to test
+ \command flag the or'd list of flags to clear
*/
#define zap_clear_flag(obj, flag) (obj)->flags &= ~(flag)
/*!
\brief Copy flags from one arbitrary object to another
- \param dest the object to copy the flags to
- \param src the object to copy the flags from
- \param flags the flags to copy
+ \command dest the object to copy the flags to
+ \command src the object to copy the flags from
+ \command flags the flags to copy
*/
#define zap_copy_flags(dest, src, flags) (dest)->flags &= ~(flags); (dest)->flags |= ((src)->flags & (flags))
/*!
\brief Free a pointer and set it to NULL unless it already is NULL
- \param it the pointer
+ \command it the pointer
*/
#define zap_safe_free(it) if (it) {free(it);it=NULL;}
typedef enum {
ZAP_SUCCESS,
ZAP_FAIL,
- ZAP_MEMERR
+ ZAP_MEMERR,
+ ZAP_TIMEOUT
} zap_status_t;
typedef enum {
+ ZAP_NO_FLAGS = 0,
ZAP_READ = (1 << 0),
ZAP_WRITE = (1 << 1),
- ZAP_ERROR = (1 << 2),
- ZAP_EVENT = (1 << 3)
+ ZAP_ERROR = (1 << 2)
} zap_wait_flag_t;
typedef enum {
ZAP_CODEC_SLIN = 10
} zap_codec_t;
+typedef enum {
+ ZAP_COMMAND_SET_INTERVAL,
+ ZAP_COMMAND_GET_INTERVAL
+} zap_command_t;
+
typedef enum {
ZAP_SPAN_CONFIGURED = (1 << 0),
ZAP_SPAN_READY = (1 << 1)
#define ZINT_CONFIGURE_ARGS (struct zap_software_interface *zint)
#define ZINT_OPEN_ARGS (zap_channel_t *zchan)
#define ZINT_CLOSE_ARGS (zap_channel_t *zchan)
-#define ZINT_SET_CODEC_ARGS (zap_channel_t *zchan, zap_codec_t codec)
-#define ZINT_SET_INTERVAL_ARGS (zap_channel_t *zchan, unsigned ms)
-#define ZINT_WAIT_ARGS (zap_channel_t *zchan, zap_wait_flag_t flags, unsigned to)
+#define ZINT_COMMAND_ARGS (zap_channel_t *zchan, zap_command_t command, void *obj)
+#define ZINT_WAIT_ARGS (zap_channel_t *zchan, zap_wait_flag_t *flags, unsigned to)
#define ZINT_READ_ARGS (zap_channel_t *zchan, void *data, zap_size_t *datalen)
#define ZINT_WRITE_ARGS (zap_channel_t *zchan, void *data, zap_size_t *datalen)
typedef zap_status_t (*zint_configure_t) ZINT_CONFIGURE_ARGS ;
typedef zap_status_t (*zint_open_t) ZINT_OPEN_ARGS ;
typedef zap_status_t (*zint_close_t) ZINT_CLOSE_ARGS ;
-typedef zap_status_t (*zint_set_codec_t) ZINT_SET_CODEC_ARGS ;
-typedef zap_status_t (*zint_set_interval_t) ZINT_SET_INTERVAL_ARGS ;
+typedef zap_status_t (*zint_command_t) ZINT_COMMAND_ARGS ;
typedef zap_status_t (*zint_wait_t) ZINT_WAIT_ARGS ;
typedef zap_status_t (*zint_read_t) ZINT_READ_ARGS ;
typedef zap_status_t (*zint_write_t) ZINT_WRITE_ARGS ;
#define ZINT_CONFIGURE_FUNCTION(name) zap_status_t name ZINT_CONFIGURE_ARGS
#define ZINT_OPEN_FUNCTION(name) zap_status_t name ZINT_OPEN_ARGS
#define ZINT_CLOSE_FUNCTION(name) zap_status_t name ZINT_CLOSE_ARGS
-#define ZINT_SET_CODEC_FUNCTION(name) zap_status_t name ZINT_SET_CODEC_ARGS
-#define ZINT_SET_INTERVAL_FUNCTION(name) zap_status_t name ZINT_SET_INTERVAL_ARGS
+#define ZINT_COMMAND_FUNCTION(name) zap_status_t name ZINT_COMMAND_ARGS
#define ZINT_WAIT_FUNCTION(name) zap_status_t name ZINT_WAIT_ARGS
#define ZINT_READ_FUNCTION(name) zap_status_t name ZINT_READ_ARGS
#define ZINT_WRITE_FUNCTION(name) zap_status_t name ZINT_WRITE_ARGS
#define ZINT_CONFIGURE_MUZZLE assert(zint != NULL)
-#define ZINT_OPEN_MUZZLEE assert(zchan != NULL)
+#define ZINT_OPEN_MUZZLE assert(zchan != NULL)
#define ZINT_CLOSE_MUZZLE assert(zchan != NULL)
-#define ZINT_SET_CODEC_MUZZLE assert(zchan != NULL); assert(codec != 0)
-#define ZINT_SET_INTERVAL_MUZZLE assert(zchan != NULL); assert(ms != 0)
+#define ZINT_COMMAND_MUZZLE assert(zchan != NULL); assert(command != 0); assert(obj != NULL)
#define ZINT_WAIT_MUZZLE assert(zchan != NULL); assert(flags != 0); assert(to != 0)
#define ZINT_READ_MUZZLE assert(zchan != NULL); assert(data != NULL); assert(datalen != NULL)
#define ZINT_WRITE_MUZZLE assert(zchan != NULL); assert(data != NULL); assert(datalen != NULL)
zint_configure_t configure;
zint_open_t open;
zint_close_t close;
- zint_set_codec_t set_codec;
- zint_set_interval_t set_interval;
+ zint_command_t command;
zint_wait_t wait;
zint_read_t read;
zint_write_t write;
zap_status_t zap_channel_open(const char *name, unsigned span_id, unsigned chan_id, zap_channel_t **zchan);
zap_status_t zap_channel_close(zap_channel_t **zchan);
-zap_status_t zap_channel_set_codec(zap_channel_t *zchan, zap_codec_t codec);
-zap_status_t zap_channel_set_interval(zap_channel_t *zchan, unsigned ms);
-zap_status_t zap_channel_wait(zap_channel_t *zchan, zap_wait_flag_t flags, unsigned to);
+zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, void *obj);
+zap_status_t zap_channel_wait(zap_channel_t *zchan, zap_wait_flag_t *flags, unsigned to);
zap_status_t zap_channel_read(zap_channel_t *zchan, void *data, zap_size_t *datalen);
zap_status_t zap_channel_write(zap_channel_t *zchan, void *data, zap_size_t *datalen);
zap_status_t zap_global_init(void);
}
-zap_status_t zap_channel_set_codec(zap_channel_t *zchan, zap_codec_t codec)
-{
- assert(zchan != NULL);
- assert(zchan->zint != NULL);
-
- if (!zap_test_flag(zchan, ZAP_CHANNEL_OPEN)) {
- return ZAP_FAIL;
- }
-
- if (!zchan->zint->set_codec) {
- return ZAP_FAIL;
- }
-
- return zchan->zint->set_codec(zchan, codec);
-
-}
-
-zap_status_t zap_channel_set_interval(zap_channel_t *zchan, unsigned ms)
+zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, void *obj)
{
assert(zchan != NULL);
assert(zchan->zint != NULL);
return ZAP_FAIL;
}
- if (!zchan->zint->set_interval) {
+ if (!zchan->zint->command) {
return ZAP_FAIL;
}
- return zchan->zint->set_interval(zchan, ms);
+ return zchan->zint->command(zchan, command, obj);
}
-zap_status_t zap_channel_wait(zap_channel_t *zchan, zap_wait_flag_t flags, unsigned to)
+zap_status_t zap_channel_wait(zap_channel_t *zchan, zap_wait_flag_t *flags, unsigned to)
{
assert(zchan != NULL);
assert(zchan->zint != NULL);
assert(zchan != NULL);
assert(zchan->zint != NULL);
assert(zchan->zint != NULL);
-
+
if (!zap_test_flag(zchan, ZAP_CHANNEL_OPEN)) {
return ZAP_FAIL;
}
zap_log(ZAP_LOG_DEBUG, "span %d [%s]=[%s]\n", span->span_id, var, val);
if (!strcasecmp(var, "enabled")) {
- zap_log(ZAP_LOG_WARNING, "'enabled' param ignored when it's not the first param in a [span]\n");
+ zap_log(ZAP_LOG_WARNING, "'enabled' command ignored when it's not the first command in a [span]\n");
} else if (!strcasecmp(var, "b-channel")) {
configured += wp_configure_channel(&cfg, val, span, ZAP_CHAN_TYPE_B);
} else if (!strcasecmp(var, "d-channel")) {
static ZINT_OPEN_FUNCTION(wanpipe_open)
{
ZINT_OPEN_MUZZLE;
- return ZAP_FAIL;
+ return ZAP_SUCCESS;
}
static ZINT_CLOSE_FUNCTION(wanpipe_close)
{
ZINT_CLOSE_MUZZLE;
- return ZAP_FAIL;
+ return ZAP_SUCCESS;
}
-static ZINT_SET_CODEC_FUNCTION(wanpipe_set_codec)
+static ZINT_COMMAND_FUNCTION(wanpipe_command)
{
- ZINT_SET_CODEC_MUZZLE;
- return ZAP_FAIL;
-}
+ wanpipe_tdm_api_t tdm_api;
+ int err;
-static ZINT_SET_INTERVAL_FUNCTION(wanpipe_set_interval)
-{
- ZINT_SET_INTERVAL_MUZZLE;
- return ZAP_FAIL;
+ ZINT_COMMAND_MUZZLE;
+
+ memset(&tdm_api, 0, sizeof(tdm_api));
+
+ switch(command) {
+ case ZAP_COMMAND_GET_INTERVAL:
+ {
+ tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_USR_PERIOD;
+
+ if (!(err = sangoma_tdm_cmd_exec(zchan->sockfd, tdm_api))) {
+ *((int *)obj) = tdm_api.wp_tdm_cmd.usr_period;
+ }
+
+ }
+ break;
+ case ZAP_COMMAND_SET_INTERVAL:
+ {
+ tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_USR_PERIOD;
+ tdm_api.wp_tdm_cmd.usr_period = *((int *)obj);
+ err = sangoma_tdm_cmd_exec(zchan->sockfd, tdm_api);
+ }
+ break;
+ };
+
+ return err ? ZAP_FAIL : ZAP_SUCCESS;
}
static ZINT_WAIT_FUNCTION(wanpipe_wait)
{
+ fd_set read_fds, write_fds, error_fds, *r = NULL, *w = NULL, *e = NULL;
+ zap_wait_flag_t inflags = *flags;
+ int s;
+ struct timeval tv, *tvp = NULL;
+
ZINT_WAIT_MUZZLE;
- return ZAP_FAIL;
+
+ if (to) {
+ memset(&tv, 0, sizeof(tv));
+ tv.tv_sec = to / 1000;
+ tv.tv_usec = (to % 1000) * 1000;
+ tvp = &tv;
+ }
+
+ FD_ZERO(&read_fds);
+ FD_ZERO(&write_fds);
+ FD_ZERO(&error_fds);
+
+
+ if (inflags & ZAP_READ) {
+ r = &read_fds;
+ FD_SET(zchan->sockfd, r);
+ }
+
+ if (inflags & ZAP_WRITE) {
+ w = &write_fds;
+ FD_SET(zchan->sockfd, w);
+ }
+
+ if (inflags & ZAP_ERROR) {
+ e = &error_fds;
+ FD_SET(zchan->sockfd, e);
+ }
+
+ *flags = ZAP_NO_FLAGS;
+ s = select(zchan->sockfd + 1, r, w, e, tvp);
+
+ if (s < 0) {
+ return ZAP_FAIL;
+ }
+
+ if (s > 0) {
+ if (r && FD_ISSET(zchan->sockfd, r)) {
+ *flags |= ZAP_READ;
+ }
+
+ if (w && FD_ISSET(zchan->sockfd, w)) {
+ *flags |= ZAP_WRITE;
+ }
+
+ if (e && FD_ISSET(zchan->sockfd, e)) {
+ *flags |= ZAP_ERROR;
+ }
+ }
+
+ if (s == 0) {
+ return ZAP_TIMEOUT;
+ }
+
+}
+
+static ZINT_READ_FUNCTION(wanpipe_read_unix)
+{
+ int rx_len = 0;
+ struct msghdr msg;
+ struct iovec iov[2];
+ wp_tdm_api_rx_hdr_t hdrframe;
+
+ memset(&msg, 0, sizeof(struct msghdr));
+
+ iov[0].iov_len = sizeof(hdrframe);
+ iov[0].iov_base = &hdrframe;
+
+ iov[1].iov_len = *datalen;
+ iov[1].iov_base = data;
+
+ msg.msg_iovlen = 2;
+ msg.msg_iov = iov;
+
+ rx_len = read(zchan->sockfd, &msg, iov[1].iov_len + sizeof(hdrframe));
+
+ if (rx_len <= sizeof(hdrframe)) {
+ return ZAP_FAIL;
+ }
+
+ rx_len -= sizeof(hdrframe);
+ *datalen = rx_len;
+
+ 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;
+ struct msghdr msg;
+ struct iovec iov[2];
+ wp_tdm_api_rx_hdr_t hdrframe;
+
+ memset(&msg, 0, sizeof(struct msghdr));
+
+ iov[0].iov_len = sizeof(hdrframe);
+ iov[0].iov_base = &hdrframe;
+
+ iov[1].iov_len = *datalen;
+ iov[1].iov_base = data;
+
+ msg.msg_iovlen = 2;
+ msg.msg_iov = iov;
+
+ bsent = write(zchan->sockfd, &msg, iov[1].iov_len + sizeof(hdrframe));
+
+ if (bsent > 0){
+ bsent -= sizeof(wp_tdm_api_tx_hdr_t);
+ }
+
+}
+
static ZINT_WRITE_FUNCTION(wanpipe_write)
{
ZINT_WRITE_MUZZLE;
+
+#ifndef WIN32
+ return wanpipe_write_unix(zchan, data, datalen);
+#endif
+
return ZAP_FAIL;
}
wanpipe_interface.configure = wanpipe_configure;
wanpipe_interface.open = wanpipe_open;
wanpipe_interface.close = wanpipe_close;
- wanpipe_interface.set_codec = wanpipe_set_codec;
- wanpipe_interface.set_interval = wanpipe_set_interval;
+ wanpipe_interface.command = wanpipe_command;
wanpipe_interface.wait = wanpipe_wait;
wanpipe_interface.read = wanpipe_read;
wanpipe_interface.write = wanpipe_write;