ZAP_ANALOG_START_KEWL,
ZAP_ANALOG_START_LOOP,
ZAP_ANALOG_START_GROUND,
- ZAP_ANALOG_START_INVALID
+ ZAP_ANALOG_START_NA
} zap_analog_start_type_t;
-#define START_TYPE_STRINGS "KEWL", "LOOP", "GROUND", "INVALID"
+#define START_TYPE_STRINGS "KEWL", "LOOP", "GROUND", "NA"
ZAP_STR2ENUM_P(zap_str2zap_analog_start_type, zap_analog_start_type2str, zap_analog_start_type_t)
typedef enum {
ZAP_OOB_FLASH,
ZAP_OOB_RING_START,
ZAP_OOB_RING_STOP,
+ ZAP_OOB_NOOP,
ZAP_OOB_INVALID
} zap_oob_event_t;
-#define OOB_STRINGS "DTMF", "ONHOOK", "OFFHOOK", "WINK", "FLASH", "RING_START", "RING_STOP", "INVALID"
+#define OOB_STRINGS "DTMF", "ONHOOK", "OFFHOOK", "WINK", "FLASH", "RING_START", "RING_STOP", "NOOP", "INVALID"
ZAP_STR2ENUM_P(zap_str2zap_oob_event, zap_oob_event2str, zap_oob_event_t)
typedef enum {
typedef enum {
ZAP_CHANNEL_STATE_DOWN,
- ZAP_CHANNEL_STATE_UP,
ZAP_CHANNEL_STATE_HANGUP,
ZAP_CHANNEL_STATE_HOLD,
ZAP_CHANNEL_STATE_DIALTONE,
ZAP_CHANNEL_STATE_RING,
ZAP_CHANNEL_STATE_BUSY,
ZAP_CHANNEL_STATE_ATTN,
- ZAP_CHANNEL_STATE_IDLE,
ZAP_CHANNEL_STATE_GENRING,
ZAP_CHANNEL_STATE_DIALING,
ZAP_CHANNEL_STATE_GET_CALLERID,
ZAP_CHANNEL_STATE_RESTART,
ZAP_CHANNEL_STATE_PROGRESS_MEDIA,
ZAP_CHANNEL_STATE_PROGRESS,
+ ZAP_CHANNEL_STATE_IDLE,
+ ZAP_CHANNEL_STATE_UP,
ZAP_CHANNEL_STATE_INVALID
} zap_channel_state_t;
-#define CHANNEL_STATE_STRINGS "DOWN", "UP", "HANGUP", "HOLD", "DIALTONE", "COLLECT", \
- "RING", "BUSY", "ATTN", "IDLE", "GENRING", "DIALING", "GET_CALLERID", "CALLWAITING", \
- "TERMINATING", "RESTART", "PROGRESS_MEDIA", "PROGRESS", "INVALID"
+#define CHANNEL_STATE_STRINGS "DOWN", "HANGUP", "HOLD", "DIALTONE", "COLLECT", \
+ "RING", "BUSY", "ATTN", "GENRING", "DIALING", "GET_CALLERID", "CALLWAITING", \
+ "TERMINATING", "RESTART", "PROGRESS_MEDIA", "PROGRESS", "IDLE", "UP", "INVALID"
ZAP_STR2ENUM_P(zap_str2zap_channel_state, zap_channel_state2str, zap_channel_state_t)
typedef enum {
ZAP_STR2ENUM(zap_str2zap_trunk_type, zap_trunk_type2str, zap_trunk_type_t, TRUNK_TYPE_NAMES, ZAP_TRUNK_NONE)
ZAP_ENUM_NAMES(START_TYPE_NAMES, START_TYPE_STRINGS)
-ZAP_STR2ENUM(zap_str2zap_analog_start_type, zap_analog_start_type2str, zap_analog_start_type_t, START_TYPE_NAMES, ZAP_ANALOG_START_INVALID)
+ZAP_STR2ENUM(zap_str2zap_analog_start_type, zap_analog_start_type2str, zap_analog_start_type_t, START_TYPE_NAMES, ZAP_ANALOG_START_NA)
ZAP_ENUM_NAMES(SIGNAL_NAMES, SIGNAL_STRINGS)
ZAP_STR2ENUM(zap_str2zap_signal_event, zap_signal_event2str, zap_signal_event_t, SIGNAL_NAMES, ZAP_SIGEVENT_INVALID)
char name[80] = "";
char number[25] = "";
zap_io_interface_t *zio = NULL;
+ zap_analog_start_type_t tmp;
if (!zap_config_open_file(&cfg, cfg_name)) {
return ZAP_FAIL;
} else {
zap_copy_string(number, val, sizeof(number));
}
- } else if (!strncasecmp(var, "fxo-channel", 11)) {
+ } else if (!strcasecmp(var, "analog-start-type")) {
+ if (span->trunk_type == ZAP_TRUNK_FXS || span->trunk_type == ZAP_TRUNK_FXO) {
+ if ((tmp = zap_str2zap_analog_start_type(val)) != ZAP_ANALOG_START_NA) {
+ span->start_type = tmp;
+ zap_log(ZAP_LOG_DEBUG, "changing start type to '%s'\n", zap_analog_start_type2str(span->start_type));
+ }
+ } else {
+ zap_log(ZAP_LOG_ERROR, "This option is only valid on analog trunks!\n");
+ }
+ } else if (!strcasecmp(var, "fxo-channel")) {
if (span->trunk_type == ZAP_TRUNK_NONE) {
- char *stype = var + 11;
- zap_analog_start_type_t tmp, start_type = ZAP_ANALOG_START_KEWL;
-
span->trunk_type = ZAP_TRUNK_FXO;
- if (stype) {
- while(*stype == '-') stype++;
- if ((tmp = zap_str2zap_analog_start_type(stype)) != ZAP_ANALOG_START_INVALID) {
- start_type = tmp;
- }
-
- }
-
- span->start_type = start_type;
- zap_log(ZAP_LOG_DEBUG, "setting trunk type to '%s' (%s)\n", zap_trunk_type2str(span->trunk_type),
- zap_analog_start_type2str(start_type));
+ zap_log(ZAP_LOG_DEBUG, "setting trunk type to '%s' start(%s)\n", zap_trunk_type2str(span->trunk_type),
+ zap_analog_start_type2str(span->start_type));
}
if (span->trunk_type == ZAP_TRUNK_FXO) {
configured += zio->configure_span(span, val, ZAP_CHAN_TYPE_FXO, name, number);
}
} else if (!strcasecmp(var, "fxs-channel")) {
if (span->trunk_type == ZAP_TRUNK_NONE) {
- char *stype = var + 11;
- zap_analog_start_type_t tmp, start_type = ZAP_ANALOG_START_KEWL;
-
- span->trunk_type = ZAP_TRUNK_FXS;
- if (stype) {
- while(*stype == '-') stype++;
- if ((tmp = zap_str2zap_analog_start_type(stype)) != ZAP_ANALOG_START_INVALID) {
- start_type = tmp;
- }
-
- }
-
- span->start_type = start_type;
- zap_log(ZAP_LOG_DEBUG, "setting trunk type to '%s' (%s)\n", zap_trunk_type2str(span->trunk_type),
- zap_analog_start_type2str(start_type));
+ span->trunk_type = ZAP_TRUNK_FXS;
+ zap_log(ZAP_LOG_DEBUG, "setting trunk type to '%s' start(%s)\n", zap_trunk_type2str(span->trunk_type),
+ zap_analog_start_type2str(span->start_type));
}
if (span->trunk_type == ZAP_TRUNK_FXS) {
configured += zio->configure_span(span, val, ZAP_CHAN_TYPE_FXS, name, number);
#include <sys/socket.h>
#include <wanpipe_tdm_api_iface.h>
+typedef enum {
+ WP_RINGING = (1 << 0)
+} wp_flag_t;
+
static struct {
uint32_t codec_ms;
uint32_t wink_ms;
uint32_t flash_ms;
+ uint32_t ring_on_ms;
+ uint32_t ring_off_ms;
} wp_globals;
/* a bunch of this stuff should go into the wanpipe_tdm_api_iface.h */
if (type == ZAP_CHAN_TYPE_FXS || type == ZAP_CHAN_TYPE_FXO) {
wanpipe_tdm_api_t tdm_api;
+#if 1
+ if (type == ZAP_CHAN_TYPE_FXO) {
+ tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT;
+ tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_TXSIG_ONHOOK;
+ tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE;
+ wp_tdm_cmd_exec(chan, &tdm_api);
+ }
+#endif
+
tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT;
tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_RING_DETECT;
tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE;
wp_tdm_cmd_exec(chan, &tdm_api);
-
+#if 1
tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT;
tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_RING_TRIP_DETECT;
tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE;
wp_tdm_cmd_exec(chan, &tdm_api);
-
+#endif
tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT;
tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_RXHOOK;
tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE;
wp_tdm_cmd_exec(chan, &tdm_api);
+
+
tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_HW_CODING;
wp_tdm_cmd_exec(chan, &tdm_api);
if (tdm_api.wp_tdm_cmd.hw_tdm_coding) {
switch(command) {
case ZAP_COMMAND_OFFHOOK:
{
- tdm_api.wp_tdm_cmd.cmd=SIOC_WP_TDM_SET_EVENT;
- tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_TXSIG_OFFHOOK;
+ tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT;
+ tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type = zchan->span->start_type == ZAP_ANALOG_START_KEWL ?
+ WP_TDMAPI_EVENT_TXSIG_START : WP_TDMAPI_EVENT_TXSIG_KEWL;
tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE;
if ((err = wp_tdm_cmd_exec(zchan, &tdm_api))) {
snprintf(zchan->last_error, sizeof(zchan->last_error), "OFFHOOK Failed");
break;
case ZAP_COMMAND_ONHOOK:
{
- tdm_api.wp_tdm_cmd.cmd=SIOC_WP_TDM_SET_EVENT;
- tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_TXSIG_OFFHOOK;
- tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_mode=WP_TDMAPI_EVENT_DISABLE;
+ tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT;
+ tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_TXSIG_ONHOOK;
+ tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE;
if ((err = wp_tdm_cmd_exec(zchan, &tdm_api))) {
snprintf(zchan->last_error, sizeof(zchan->last_error), "ONHOOK Failed");
return ZAP_FAIL;
break;
case ZAP_COMMAND_GENERATE_RING_ON:
{
- tdm_api.wp_tdm_cmd.cmd=SIOC_WP_TDM_SET_EVENT;
+ tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT;
tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_RING;
tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE;
if ((err = wp_tdm_cmd_exec(zchan, &tdm_api))) {
return ZAP_FAIL;
}
zap_set_flag_locked(zchan, ZAP_CHANNEL_RINGING);
+ zap_set_pflag_locked(zchan, WP_RINGING);
+ zchan->ring_time = zap_current_time_in_ms() + wp_globals.ring_on_ms;
}
break;
case ZAP_COMMAND_GENERATE_RING_OFF:
{
- tdm_api.wp_tdm_cmd.cmd=SIOC_WP_TDM_SET_EVENT;
+ tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT;
tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_RING;
- tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_mode=WP_TDMAPI_EVENT_ENABLE;
+ tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_DISABLE;
if ((err = wp_tdm_cmd_exec(zchan, &tdm_api))) {
snprintf(zchan->last_error, sizeof(zchan->last_error), "Ring-off Failed");
return ZAP_FAIL;
int r;
for(i = 1; i <= span->chan_count; i++) {
+ zap_channel_t *zchan = &span->channels[i];
memset(&pfds[j], 0, sizeof(pfds[j]));
pfds[j].fd = span->channels[i].sockfd;
pfds[j].events = POLLPRI;
- if (zap_test_flag((&span->channels[i]), ZAP_CHANNEL_WINK) || zap_test_flag((&span->channels[i]), ZAP_CHANNEL_FLASH)) {
- l++;
+
+ /* The driver probably should be able to do this wink/flash/ringing by itself this is sort of a hack to make it work! */
+
+ if (zap_test_flag(zchan, ZAP_CHANNEL_WINK) || zap_test_flag(zchan, ZAP_CHANNEL_FLASH)) {
+ l = 5;
}
+
j++;
+
+ if (zap_test_flag(zchan, ZAP_CHANNEL_RINGING)) {
+ l = 5;
+ }
+
+ if (zap_test_flag(zchan, ZAP_CHANNEL_RINGING) && zap_current_time_in_ms() >= zchan->ring_time) {
+ wanpipe_tdm_api_t tdm_api;
+ int err;
+ memset(&tdm_api, 0, sizeof(tdm_api));
+ if (zap_test_pflag(zchan, WP_RINGING)) {
+ tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT;
+ tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_RING;
+ tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_DISABLE;
+ if ((err = wp_tdm_cmd_exec(zchan, &tdm_api))) {
+ snprintf(zchan->last_error, sizeof(zchan->last_error), "Ring-off Failed");
+ return ZAP_FAIL;
+ }
+ zap_clear_pflag_locked(zchan, WP_RINGING);
+ zchan->ring_time = zap_current_time_in_ms() + wp_globals.ring_off_ms;
+ } else {
+ tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT;
+ tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_RING;
+ tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE;
+ if ((err = wp_tdm_cmd_exec(zchan, &tdm_api))) {
+ snprintf(zchan->last_error, sizeof(zchan->last_error), "Ring Failed");
+ return ZAP_FAIL;
+ }
+ zap_set_pflag_locked(zchan, WP_RINGING);
+ zchan->ring_time = zap_current_time_in_ms() + wp_globals.ring_on_ms;
+ }
+ }
}
if (l) {
- ms = 5;
+ ms = l;
}
r = poll(pfds, j, ms);
}
for(i = 1; i <= span->chan_count; i++) {
+ zap_channel_t *zchan = &span->channels[i];
+
if (pfds[i-1].revents & POLLPRI) {
- zap_set_flag((&span->channels[i]), ZAP_CHANNEL_EVENT);
- span->channels[i].last_event_time = zap_current_time_in_ms();
+ zap_set_flag(zchan, ZAP_CHANNEL_EVENT);
+ zchan->last_event_time = zap_current_time_in_ms();
k++;
}
}
+
+
return k ? ZAP_SUCCESS : ZAP_FAIL;
}
zap_clear_flag_locked((&span->channels[i]), ZAP_CHANNEL_WINK);
zap_clear_flag_locked((&span->channels[i]), ZAP_CHANNEL_OFFHOOK);
event_id = ZAP_OOB_ONHOOK;
+
+ if (span->channels[i].type == ZAP_CHAN_TYPE_FXO) {
+ wanpipe_tdm_api_t tdm_api;
+ memset(&tdm_api, 0, sizeof(tdm_api));
+ tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT;
+ tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_TXSIG_ONHOOK;
+ tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE;
+ wp_tdm_cmd_exec(&span->channels[i], &tdm_api);
+ }
goto event;
}
}
}
if (zap_test_flag((&span->channels[i]), ZAP_CHANNEL_EVENT)) {
wanpipe_tdm_api_t tdm_api;
+ memset(&tdm_api, 0, sizeof(tdm_api));
zap_clear_flag((&span->channels[i]), ZAP_CHANNEL_EVENT);
tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_READ_EVENT;
switch(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type) {
case WP_TDMAPI_EVENT_RXHOOK:
{
- event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_hook_state & WP_TDMAPI_EVENT_RXHOOK_OFF ? ZAP_OOB_OFFHOOK : ZAP_OOB_ONHOOK;
-
- if (event_id == ZAP_OOB_OFFHOOK) {
- if (zap_test_flag((&span->channels[i]), ZAP_CHANNEL_FLASH)) {
- zap_clear_flag_locked((&span->channels[i]), ZAP_CHANNEL_FLASH);
- zap_clear_flag_locked((&span->channels[i]), ZAP_CHANNEL_WINK);
- event_id = ZAP_OOB_FLASH;
- goto event;
+ if (span->channels[i].type == ZAP_CHAN_TYPE_FXS) {
+ event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_hook_state & WP_TDMAPI_EVENT_RXHOOK_OFF ? ZAP_OOB_OFFHOOK : ZAP_OOB_ONHOOK;
+ if (event_id == ZAP_OOB_OFFHOOK) {
+ if (zap_test_flag((&span->channels[i]), ZAP_CHANNEL_FLASH)) {
+ zap_clear_flag_locked((&span->channels[i]), ZAP_CHANNEL_FLASH);
+ zap_clear_flag_locked((&span->channels[i]), ZAP_CHANNEL_WINK);
+ event_id = ZAP_OOB_FLASH;
+ goto event;
+ } else {
+ zap_set_flag_locked((&span->channels[i]), ZAP_CHANNEL_WINK);
+ }
} else {
- zap_set_flag_locked((&span->channels[i]), ZAP_CHANNEL_WINK);
- }
+ if (zap_test_flag((&span->channels[i]), ZAP_CHANNEL_WINK)) {
+ zap_clear_flag_locked((&span->channels[i]), ZAP_CHANNEL_WINK);
+ zap_clear_flag_locked((&span->channels[i]), ZAP_CHANNEL_FLASH);
+ event_id = ZAP_OOB_WINK;
+ goto event;
+ } else {
+ zap_set_flag_locked((&span->channels[i]), ZAP_CHANNEL_FLASH);
+ }
+ }
+ continue;
} else {
- if (zap_test_flag((&span->channels[i]), ZAP_CHANNEL_WINK)) {
- zap_clear_flag_locked((&span->channels[i]), ZAP_CHANNEL_WINK);
- zap_clear_flag_locked((&span->channels[i]), ZAP_CHANNEL_FLASH);
- event_id = ZAP_OOB_WINK;
- goto event;
- } else {
- zap_set_flag_locked((&span->channels[i]), ZAP_CHANNEL_FLASH);
+ int err;
+
+ tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_EVENT;
+ tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_type = WP_TDMAPI_EVENT_TXSIG_ONHOOK;
+ tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_mode = WP_TDMAPI_EVENT_ENABLE;
+ if ((err = wp_tdm_cmd_exec(&span->channels[i], &tdm_api))) {
+ snprintf(span->channels[i].last_error, sizeof(span->channels[i].last_error), "ONHOOK Failed");
+ return ZAP_FAIL;
}
+ event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_hook_state & WP_TDMAPI_EVENT_RXHOOK_OFF ? ZAP_OOB_ONHOOK : ZAP_OOB_NOOP;
}
- continue;
}
break;
case WP_TDMAPI_EVENT_RING_DETECT:
{
- printf("you fucking suck: ring\n");
- event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_ring_state & WP_TDMAPI_EVENT_RING_PRESENT ? ZAP_OOB_RING_START : ZAP_OOB_RING_STOP;
-
+ event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_ring_state == WP_TDMAPI_EVENT_RING_PRESENT ? ZAP_OOB_RING_START : ZAP_OOB_RING_STOP;
}
break;
case WP_TDMAPI_EVENT_RING_TRIP_DETECT:
{
- printf("you fucking suck: trip\n");
- event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_ring_state & WP_TDMAPI_EVENT_RING_PRESENT ? ZAP_OOB_ONHOOK : ZAP_OOB_OFFHOOK;
-
+ event_id = tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_ring_state == WP_TDMAPI_EVENT_RING_PRESENT ? ZAP_OOB_ONHOOK : ZAP_OOB_OFFHOOK;
}
break;
default:
}
event:
+
span->channels[i].last_event_time = 0;
span->event_header.e_type = ZAP_EVENT_OOB;
span->event_header.enum_id = event_id;
wp_globals.codec_ms = 20;
wp_globals.wink_ms = 150;
wp_globals.flash_ms = 750;
+ wp_globals.ring_on_ms = 2000;
+ wp_globals.ring_off_ms = 4000;
wanpipe_interface.name = "wanpipe";
wanpipe_interface.configure_span = wanpipe_configure_span;
wanpipe_interface.configure = wanpipe_configure;