update
git-svn-id: http://svn.openzap.org/svn/openzap/trunk@189 a93c3328-9c30-0410-af19-c9cd2b2d52af
This commit is contained in:
parent
f5f5991fc8
commit
4c9db695b5
|
@ -126,7 +126,6 @@ static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *ses
|
|||
zap_channel_command(zchan, ZAP_COMMAND_GET_INTERVAL, &interval);
|
||||
zap_channel_command(zchan, ZAP_COMMAND_GET_CODEC, &codec);
|
||||
|
||||
|
||||
switch(codec) {
|
||||
case ZAP_CODEC_ULAW:
|
||||
{
|
||||
|
@ -252,6 +251,12 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
|
|||
|
||||
switch (tech_pvt->zchan->type) {
|
||||
case ZAP_CHAN_TYPE_FXO:
|
||||
{
|
||||
if (tech_pvt->zchan->state != ZAP_CHANNEL_STATE_DOWN) {
|
||||
zap_set_state_locked(tech_pvt->zchan, ZAP_CHANNEL_STATE_HANGUP);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZAP_CHAN_TYPE_FXS:
|
||||
{
|
||||
if (tech_pvt->zchan->state != ZAP_CHANNEL_STATE_DOWN) {
|
||||
|
@ -366,7 +371,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
|
|||
char dtmf[128] = "";
|
||||
zap_status_t status;
|
||||
int total_to = timeout;
|
||||
int chunk;
|
||||
int chunk, do_break = 0;
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
assert(channel != NULL);
|
||||
|
@ -377,8 +382,15 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
|
|||
assert(tech_pvt->zchan != NULL);
|
||||
|
||||
chunk = tech_pvt->zchan->effective_interval * 2;
|
||||
|
||||
top:
|
||||
if (switch_test_flag(tech_pvt, TFLAG_HOLD)) {
|
||||
|
||||
if (switch_test_flag(tech_pvt, TFLAG_BREAK)) {
|
||||
switch_clear_flag_locked(tech_pvt, TFLAG_BREAK);
|
||||
do_break = 1;
|
||||
}
|
||||
|
||||
if (switch_test_flag(tech_pvt, TFLAG_HOLD) || do_break) {
|
||||
switch_yield(tech_pvt->zchan->effective_interval * 1000);
|
||||
*frame = &tech_pvt->cng_frame;
|
||||
tech_pvt->cng_frame.datalen = tech_pvt->zchan->packet_len;
|
||||
|
@ -406,6 +418,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
|
|||
return SWITCH_STATUS_BREAK;
|
||||
}
|
||||
}
|
||||
|
||||
goto top;
|
||||
}
|
||||
|
||||
|
@ -461,15 +474,20 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
|
|||
if (++tech_pvt->wr_error > 10) {
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
tech_pvt->wr_error = 0;
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
static switch_status_t channel_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg)
|
||||
static switch_status_t channel_receive_message_b(switch_core_session_t *session, switch_core_session_message_t *msg)
|
||||
{
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
static switch_status_t channel_receive_message_fxo(switch_core_session_t *session, switch_core_session_message_t *msg)
|
||||
{
|
||||
switch_channel_t *channel;
|
||||
private_t *tech_pvt;
|
||||
|
@ -481,8 +499,36 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s
|
|||
assert(tech_pvt != NULL);
|
||||
|
||||
switch (msg->message_id) {
|
||||
case SWITCH_MESSAGE_INDICATE_PROGRESS:
|
||||
case SWITCH_MESSAGE_INDICATE_ANSWER:
|
||||
if (!switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
zap_set_state_locked(tech_pvt->zchan, ZAP_CHANNEL_STATE_UP);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t channel_receive_message_fxs(switch_core_session_t *session, switch_core_session_message_t *msg)
|
||||
{
|
||||
switch_channel_t *channel;
|
||||
private_t *tech_pvt;
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
assert(channel != NULL);
|
||||
|
||||
tech_pvt = (private_t *) switch_core_session_get_private(session);
|
||||
assert(tech_pvt != NULL);
|
||||
|
||||
switch (msg->message_id) {
|
||||
case SWITCH_MESSAGE_INDICATE_PROGRESS:
|
||||
case SWITCH_MESSAGE_INDICATE_ANSWER:
|
||||
if (!switch_channel_test_flag(channel, CF_OUTBOUND)) {
|
||||
zap_set_state_locked(tech_pvt->zchan, ZAP_CHANNEL_STATE_UP);
|
||||
}
|
||||
break;
|
||||
case SWITCH_MESSAGE_INDICATE_RINGING:
|
||||
zap_set_state_locked(tech_pvt->zchan, ZAP_CHANNEL_STATE_RING);
|
||||
|
@ -494,6 +540,25 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s
|
|||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t channel_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg)
|
||||
{
|
||||
private_t *tech_pvt;
|
||||
|
||||
tech_pvt = (private_t *) switch_core_session_get_private(session);
|
||||
assert(tech_pvt != NULL);
|
||||
|
||||
switch (tech_pvt->zchan->type) {
|
||||
case ZAP_CHAN_TYPE_FXS:
|
||||
return channel_receive_message_fxs(session, msg);
|
||||
case ZAP_CHAN_TYPE_FXO:
|
||||
return channel_receive_message_fxo(session, msg);
|
||||
case ZAP_CHAN_TYPE_B:
|
||||
return channel_receive_message_b(session, msg);
|
||||
default:
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static const switch_state_handler_table_t channel_event_handlers = {
|
||||
/*.on_init */ channel_on_init,
|
||||
/*.on_ring */ channel_on_ring,
|
||||
|
@ -540,20 +605,25 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
|||
switch_core_session_t **new_session, switch_memory_pool_t **pool)
|
||||
{
|
||||
|
||||
char *dest;
|
||||
int span_id = 0;
|
||||
char *p, *dest;
|
||||
int span_id = 0, chan_id = 0;
|
||||
zap_channel_t *zchan = NULL;
|
||||
switch_call_cause_t cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
|
||||
char name[128];
|
||||
zap_status_t status;
|
||||
|
||||
if (!outbound_profile) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing caller profile\n");
|
||||
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
|
||||
}
|
||||
|
||||
if ((dest = strchr('/', outbound_profile->destination_number))) {
|
||||
dest++;
|
||||
if ((p = strchr(outbound_profile->destination_number, '/'))) {
|
||||
dest = p + 1;
|
||||
span_id = atoi(outbound_profile->destination_number);
|
||||
if ((p = strchr(dest, '/'))) {
|
||||
chan_id = atoi(dest);
|
||||
dest = p + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!span_id) {
|
||||
|
@ -561,7 +631,14 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
|||
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
|
||||
}
|
||||
|
||||
if (zap_channel_open_any(span_id, ZAP_TOP_DOWN, &zchan) != ZAP_SUCCESS) {
|
||||
if (chan_id) {
|
||||
status = zap_channel_open(span_id, chan_id, &zchan);
|
||||
} else {
|
||||
status = zap_channel_open_any(span_id, ZAP_TOP_DOWN, &zchan);
|
||||
|
||||
}
|
||||
|
||||
if (status != ZAP_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No channels available\n");
|
||||
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
|
||||
}
|
||||
|
@ -582,9 +659,9 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
|||
goto fail;
|
||||
}
|
||||
|
||||
snprintf(name, sizeof(name), "OPENZAP/%s", outbound_profile->destination_number);
|
||||
snprintf(name, sizeof(name), "OPENZAP/%s", dest);
|
||||
switch_channel_set_name(channel, name);
|
||||
|
||||
zap_set_string(zchan->caller_data.ani, dest);
|
||||
caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
|
||||
switch_channel_set_caller_profile(channel, caller_profile);
|
||||
tech_pvt->caller_profile = caller_profile;
|
||||
|
@ -592,6 +669,13 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
|||
|
||||
switch_channel_set_flag(channel, CF_OUTBOUND);
|
||||
switch_channel_set_state(channel, CS_INIT);
|
||||
if ((tech_pvt->token_id = zap_channel_add_token(zchan, switch_core_session_get_uuid(*new_session))) < 0) {
|
||||
switch_core_session_destroy(new_session);
|
||||
cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
zap_channel_outgoing_call(zchan);
|
||||
return SWITCH_CAUSE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -630,7 +714,7 @@ zap_status_t zap_channel_from_event(zap_sigmsg_t *sigmsg, switch_core_session_t
|
|||
|
||||
tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
|
||||
"OpenZAP",
|
||||
SPAN_CONFIG[sigmsg->span->span_id].dialplan,
|
||||
SPAN_CONFIG[sigmsg->channel->span_id].dialplan,
|
||||
sigmsg->channel->chan_name,
|
||||
sigmsg->channel->chan_number,
|
||||
NULL,
|
||||
|
@ -638,8 +722,8 @@ zap_status_t zap_channel_from_event(zap_sigmsg_t *sigmsg, switch_core_session_t
|
|||
NULL,
|
||||
NULL,
|
||||
(char *) modname,
|
||||
SPAN_CONFIG[sigmsg->span->span_id].context,
|
||||
sigmsg->dnis);
|
||||
SPAN_CONFIG[sigmsg->channel->span_id].context,
|
||||
sigmsg->channel->caller_data.dnis);
|
||||
assert(tech_pvt->caller_profile != NULL);
|
||||
|
||||
snprintf(name, sizeof(name), "OpenZAP/%s", tech_pvt->caller_profile->destination_number);
|
||||
|
@ -679,7 +763,22 @@ static switch_core_session_t *zap_channel_get_session(zap_channel_t *channel, in
|
|||
|
||||
static ZIO_SIGNAL_CB_FUNCTION(on_fxo_signal)
|
||||
{
|
||||
zap_log(ZAP_LOG_DEBUG, "got sig [%s]\n", zap_signal_event2str(sigmsg->event_id));
|
||||
switch_core_session_t *session = NULL;
|
||||
zap_status_t status;
|
||||
|
||||
zap_log(ZAP_LOG_DEBUG, "got fxo sig [%s]\n", zap_signal_event2str(sigmsg->event_id));
|
||||
|
||||
switch(sigmsg->event_id) {
|
||||
case ZAP_SIGEVENT_START:
|
||||
{
|
||||
status = zap_channel_from_event(sigmsg, &session);
|
||||
if (status != ZAP_SUCCESS) {
|
||||
zap_set_state_locked(sigmsg->channel, ZAP_CHANNEL_STATE_DOWN);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return ZAP_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -693,6 +792,15 @@ static ZIO_SIGNAL_CB_FUNCTION(on_fxs_signal)
|
|||
zap_log(ZAP_LOG_DEBUG, "got fxs sig [%s]\n", zap_signal_event2str(sigmsg->event_id));
|
||||
|
||||
switch(sigmsg->event_id) {
|
||||
case ZAP_SIGEVENT_UP:
|
||||
{
|
||||
if ((session = zap_channel_get_session(sigmsg->channel, 0))) {
|
||||
channel = switch_core_session_get_channel(session);
|
||||
switch_channel_mark_answered(channel);
|
||||
switch_core_session_rwunlock(session);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZAP_SIGEVENT_START:
|
||||
{
|
||||
status = zap_channel_from_event(sigmsg, &session);
|
||||
|
|
|
@ -151,6 +151,7 @@
|
|||
#define GOTO_STATUS(label,st) status = st; goto label ;
|
||||
|
||||
#define zap_copy_string(x,y,z) strncpy(x, y, z - 1)
|
||||
#define zap_set_string(x,y) strncpy(x, y, sizeof(x)-1)
|
||||
#define zap_strlen_zero(s) (!s || *s == '\0')
|
||||
|
||||
|
||||
|
@ -222,6 +223,15 @@ struct zap_event {
|
|||
#define ZAP_TOKEN_STRLEN 128
|
||||
#define ZAP_MAX_TOKENS 10
|
||||
|
||||
|
||||
|
||||
struct zap_caller_data {
|
||||
char cid_name[80];
|
||||
char ani[25];
|
||||
char aniII[25];
|
||||
char dnis[25];
|
||||
};
|
||||
|
||||
struct zap_channel {
|
||||
uint32_t span_id;
|
||||
uint32_t chan_id;
|
||||
|
@ -253,6 +263,7 @@ struct zap_channel {
|
|||
uint32_t token_count;
|
||||
char chan_name[128];
|
||||
char chan_number[32];
|
||||
struct zap_caller_data caller_data;
|
||||
struct zap_span *span;
|
||||
struct zap_io_interface *zio;
|
||||
};
|
||||
|
@ -263,11 +274,6 @@ struct zap_sigmsg {
|
|||
uint32_t chan_id;
|
||||
uint32_t span_id;
|
||||
zap_channel_t *channel;
|
||||
zap_span_t *span;
|
||||
char cid_name[80];
|
||||
char ani[25];
|
||||
char aniII[25];
|
||||
char dnis[25];
|
||||
void *raw_data;
|
||||
uint32_t raw_data_len;
|
||||
};
|
||||
|
@ -305,6 +311,7 @@ struct zap_span {
|
|||
char last_error[256];
|
||||
char tone_map[ZAP_TONEMAP_INVALID+1][ZAP_TONEMAP_LEN];
|
||||
zap_channel_t channels[ZAP_MAX_CHANNELS_SPAN];
|
||||
zio_channel_outgoing_call_t outgoing_call;
|
||||
void *app_data;
|
||||
};
|
||||
|
||||
|
@ -326,6 +333,7 @@ struct zap_io_interface {
|
|||
zio_span_next_event_t next_event;
|
||||
};
|
||||
|
||||
zap_status_t zap_channel_outgoing_call(zap_channel_t *zchan);
|
||||
void zap_channel_rotate_tokens(zap_channel_t *zchan);
|
||||
zap_status_t zap_channel_clear_token(zap_channel_t *zchan, int32_t token_id);
|
||||
zap_status_t zap_channel_add_token(zap_channel_t *zchan, char *token);
|
||||
|
|
|
@ -79,7 +79,8 @@ typedef enum {
|
|||
ZAP_STR2ENUM_P(zap_str2zap_trunk_type, zap_trunk_type2str, zap_trunk_type_t)
|
||||
|
||||
typedef enum {
|
||||
ZAP_OOB_DTMF, ZAP_OOB_ONHOOK,
|
||||
ZAP_OOB_DTMF,
|
||||
ZAP_OOB_ONHOOK,
|
||||
ZAP_OOB_OFFHOOK,
|
||||
ZAP_OOB_WINK,
|
||||
ZAP_OOB_FLASH,
|
||||
|
@ -168,7 +169,10 @@ typedef enum {
|
|||
ZAP_COMMAND_GET_DTMF_ON_PERIOD,
|
||||
ZAP_COMMAND_SET_DTMF_OFF_PERIOD,
|
||||
ZAP_COMMAND_GET_DTMF_OFF_PERIOD,
|
||||
|
||||
ZAP_COMMAND_GENERATE_RING_ON,
|
||||
ZAP_COMMAND_GENERATE_RING_OFF,
|
||||
ZAP_COMMAND_OFFHOOK,
|
||||
ZAP_COMMAND_ONHOOK,
|
||||
ZAP_COMMAND_COUNT
|
||||
} zap_command_t;
|
||||
|
||||
|
@ -203,9 +207,10 @@ typedef enum {
|
|||
ZAP_CHANNEL_STATE_BUSY,
|
||||
ZAP_CHANNEL_STATE_ATTN,
|
||||
ZAP_CHANNEL_STATE_IDLE,
|
||||
ZAP_CHANNEL_STATE_GENRING,
|
||||
ZAP_CHANNEL_STATE_INVALID
|
||||
} zap_channel_state_t;
|
||||
#define CHANNEL_STATE_STRINGS "DOWN", "UP", "HANGUP", "HOLD", "DIALTONE", "COLLECT", "RING", "BUSY", "ATTN", "IDLE", "INVALID"
|
||||
#define CHANNEL_STATE_STRINGS "DOWN", "UP", "HANGUP", "HOLD", "DIALTONE", "COLLECT", "RING", "BUSY", "ATTN", "IDLE", "GENRING", "INVALID"
|
||||
ZAP_STR2ENUM_P(zap_str2zap_channel_state, zap_channel_state2str, zap_channel_state_t)
|
||||
|
||||
typedef enum {
|
||||
|
@ -222,7 +227,9 @@ typedef enum {
|
|||
ZAP_CHANNEL_FLASH = (1 << 10),
|
||||
ZAP_CHANNEL_STATE_CHANGE = (1 << 11),
|
||||
ZAP_CHANNEL_HOLD = (1 << 12),
|
||||
ZAP_CHANNEL_INUSE = (1 << 13)
|
||||
ZAP_CHANNEL_INUSE = (1 << 13),
|
||||
ZAP_CHANNEL_OFFHOOK = (1 << 14),
|
||||
ZAP_CHANNEL_RINGING = (1 << 15)
|
||||
} zap_channel_flag_t;
|
||||
|
||||
|
||||
|
@ -231,6 +238,7 @@ typedef struct zap_event zap_event_t;
|
|||
typedef struct zap_sigmsg zap_sigmsg_t;
|
||||
typedef struct zap_span zap_span_t;
|
||||
|
||||
#define ZIO_CHANNEL_OUTGOING_CALL_ARGS (zap_channel_t *zchan)
|
||||
#define ZIO_SPAN_POLL_EVENT_ARGS (zap_span_t *span, uint32_t ms)
|
||||
#define ZIO_SPAN_NEXT_EVENT_ARGS (zap_span_t *span, zap_event_t **event)
|
||||
#define ZIO_SIGNAL_CB_ARGS (zap_sigmsg_t *sigmsg)
|
||||
|
@ -246,6 +254,7 @@ typedef struct zap_span zap_span_t;
|
|||
#define ZIO_READ_ARGS (zap_channel_t *zchan, void *data, zap_size_t *datalen)
|
||||
#define ZIO_WRITE_ARGS (zap_channel_t *zchan, void *data, zap_size_t *datalen)
|
||||
|
||||
typedef zap_status_t (*zio_channel_outgoing_call_t) ZIO_CHANNEL_OUTGOING_CALL_ARGS ;
|
||||
typedef zap_status_t (*zio_span_poll_event_t) ZIO_SPAN_POLL_EVENT_ARGS ;
|
||||
typedef zap_status_t (*zio_span_next_event_t) ZIO_SPAN_NEXT_EVENT_ARGS ;
|
||||
typedef zap_status_t (*zio_signal_cb_t) ZIO_SIGNAL_CB_ARGS ;
|
||||
|
@ -261,6 +270,7 @@ typedef zap_status_t (*zio_wait_t) ZIO_WAIT_ARGS ;
|
|||
typedef zap_status_t (*zio_read_t) ZIO_READ_ARGS ;
|
||||
typedef zap_status_t (*zio_write_t) ZIO_WRITE_ARGS ;
|
||||
|
||||
#define ZIO_CHANNEL_OUTGOING_CALL_FUNCTION(name) zap_status_t name ZIO_CHANNEL_OUTGOING_CALL_ARGS
|
||||
#define ZIO_SPAN_POLL_EVENT_FUNCTION(name) zap_status_t name ZIO_SPAN_POLL_EVENT_ARGS
|
||||
#define ZIO_SPAN_NEXT_EVENT_FUNCTION(name) zap_status_t name ZIO_SPAN_NEXT_EVENT_ARGS
|
||||
#define ZIO_SIGNAL_CB_FUNCTION(name) zap_status_t name ZIO_SIGNAL_CB_ARGS
|
||||
|
@ -276,16 +286,7 @@ typedef zap_status_t (*zio_write_t) ZIO_WRITE_ARGS ;
|
|||
#define ZIO_READ_FUNCTION(name) zap_status_t name ZIO_READ_ARGS
|
||||
#define ZIO_WRITE_FUNCTION(name) zap_status_t name ZIO_WRITE_ARGS
|
||||
|
||||
#define ZIO_CONFIGURE_SPAN_MUZZLE assert(zio != NULL)
|
||||
#define ZIO_OPEN_MUZZLE assert(zchan != NULL)
|
||||
#define ZIO_CLOSE_MUZZLE assert(zchan != NULL)
|
||||
#define ZIO_COMMAND_MUZZLE assert(zchan != NULL); assert(command != 0); assert(obj != NULL)
|
||||
#define ZIO_WAIT_MUZZLE assert(zchan != NULL); assert(flags != 0); assert(to != 0)
|
||||
#define ZIO_READ_MUZZLE assert(zchan != NULL); assert(data != NULL); assert(datalen != NULL)
|
||||
#define ZIO_WRITE_MUZZLE assert(zchan != NULL); assert(data != NULL); assert(datalen != NULL)
|
||||
|
||||
#define ZAP_PRE __FILE__, __FUNCTION__, __LINE__
|
||||
|
||||
#define ZAP_LOG_LEVEL_DEBUG 7
|
||||
#define ZAP_LOG_LEVEL_INFO 6
|
||||
#define ZAP_LOG_LEVEL_NOTICE 5
|
||||
|
|
|
@ -34,6 +34,24 @@
|
|||
#include "openzap.h"
|
||||
#include "zap_analog.h"
|
||||
|
||||
static void *zap_analog_channel_run(zap_thread_t *me, void *obj);
|
||||
|
||||
static ZIO_CHANNEL_OUTGOING_CALL_FUNCTION(analog_fxo_outgoing_call)
|
||||
{
|
||||
return ZAP_FAIL;
|
||||
}
|
||||
|
||||
static ZIO_CHANNEL_OUTGOING_CALL_FUNCTION(analog_fxs_outgoing_call)
|
||||
{
|
||||
|
||||
if (!zap_test_flag(zchan, ZAP_CHANNEL_INTHREAD)) {
|
||||
zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_GENRING);
|
||||
zap_thread_create_detached(zap_analog_channel_run, zchan);
|
||||
}
|
||||
|
||||
return ZAP_SUCCESS;
|
||||
}
|
||||
|
||||
zap_status_t zap_analog_configure_span(zap_span_t *span, char *tonemap, uint32_t digit_timeout, uint32_t max_dialstr, zio_signal_cb_t sig_cb)
|
||||
{
|
||||
|
||||
|
@ -60,6 +78,7 @@ zap_status_t zap_analog_configure_span(zap_span_t *span, char *tonemap, uint32_t
|
|||
span->analog_data->max_dialstr = max_dialstr;
|
||||
span->analog_data->sig_cb = sig_cb;
|
||||
span->signal_type = ZAP_SIGTYPE_ANALOG;
|
||||
span->outgoing_call = span->trunk_type == ZAP_TRUNK_FXS ? analog_fxs_outgoing_call : analog_fxo_outgoing_call;
|
||||
zap_span_load_tones(span, tonemap);
|
||||
|
||||
return ZAP_SUCCESS;
|
||||
|
@ -124,7 +143,7 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
|
|||
sig.chan_id = chan->chan_id;
|
||||
sig.span_id = chan->span_id;
|
||||
sig.channel = chan;
|
||||
sig.span = chan->span;
|
||||
|
||||
|
||||
while (zap_test_flag(chan, ZAP_CHANNEL_INTHREAD)) {
|
||||
zap_wait_flag_t flags = ZAP_READ;
|
||||
|
@ -137,6 +156,16 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
|
|||
|
||||
if (!zap_test_flag(chan, ZAP_CHANNEL_STATE_CHANGE)) {
|
||||
switch(chan->state) {
|
||||
case ZAP_CHANNEL_STATE_GENRING:
|
||||
{
|
||||
if (state_counter > 60000) {
|
||||
zap_set_state_locked(chan, ZAP_CHANNEL_STATE_DOWN);
|
||||
} else {
|
||||
zap_sleep(interval);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZAP_CHANNEL_STATE_DIALTONE:
|
||||
{
|
||||
if (state_counter > 10000) {
|
||||
|
@ -182,6 +211,15 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
|
|||
case ZAP_CHANNEL_STATE_UP:
|
||||
{
|
||||
zap_channel_use(chan);
|
||||
|
||||
if (chan->type == ZAP_CHAN_TYPE_FXO && !zap_test_flag(chan, ZAP_CHANNEL_OFFHOOK)) {
|
||||
zap_channel_command(chan, ZAP_COMMAND_OFFHOOK, NULL);
|
||||
}
|
||||
|
||||
if (chan->type == ZAP_CHAN_TYPE_FXS && zap_test_flag(chan, ZAP_CHANNEL_RINGING)) {
|
||||
zap_channel_command(chan, ZAP_COMMAND_GENERATE_RING_OFF, NULL);
|
||||
}
|
||||
|
||||
if (zap_test_flag(chan, ZAP_CHANNEL_HOLD)) {
|
||||
zap_clear_flag(chan, ZAP_CHANNEL_HOLD);
|
||||
sig.event_id = ZAP_SIGEVENT_FLASH;
|
||||
|
@ -197,7 +235,7 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
|
|||
{
|
||||
zap_channel_use(chan);
|
||||
sig.event_id = ZAP_SIGEVENT_START;
|
||||
zap_copy_string(sig.dnis, dtmf, sizeof(sig.dnis));
|
||||
zap_copy_string(chan->caller_data.dnis, dtmf, sizeof(chan->caller_data.dnis));
|
||||
data->sig_cb(&sig);
|
||||
continue;
|
||||
}
|
||||
|
@ -220,6 +258,11 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
|
|||
indicate = 1;
|
||||
}
|
||||
break;
|
||||
case ZAP_CHANNEL_STATE_GENRING:
|
||||
{
|
||||
zap_channel_command(chan, ZAP_COMMAND_GENERATE_RING_ON, NULL);
|
||||
}
|
||||
break;
|
||||
case ZAP_CHANNEL_STATE_RING:
|
||||
{
|
||||
zap_channel_done(chan);
|
||||
|
@ -284,6 +327,10 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (chan->type == ZAP_CHAN_TYPE_FXO && !zap_test_flag(chan, ZAP_CHANNEL_OFFHOOK)) {
|
||||
zap_channel_command(chan, ZAP_COMMAND_OFFHOOK, NULL);
|
||||
}
|
||||
|
||||
if (chan->effective_codec != ZAP_CODEC_SLIN) {
|
||||
len *= 2;
|
||||
}
|
||||
|
@ -312,6 +359,15 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
|
|||
|
||||
done:
|
||||
|
||||
if (chan->type == ZAP_CHAN_TYPE_FXO && zap_test_flag(chan, ZAP_CHANNEL_OFFHOOK)) {
|
||||
zap_channel_command(chan, ZAP_COMMAND_ONHOOK, NULL);
|
||||
}
|
||||
|
||||
if (chan->type == ZAP_CHAN_TYPE_FXS && zap_test_flag(chan, ZAP_CHANNEL_RINGING)) {
|
||||
zap_channel_command(chan, ZAP_COMMAND_GENERATE_RING_OFF, NULL);
|
||||
}
|
||||
|
||||
|
||||
closed_chan = chan;
|
||||
zap_channel_close(&chan);
|
||||
|
||||
|
@ -341,7 +397,7 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
|
|||
sig.chan_id = event->channel->chan_id;
|
||||
sig.span_id = event->channel->span_id;
|
||||
sig.channel = event->channel;
|
||||
sig.span = event->channel->span;
|
||||
|
||||
|
||||
zap_log(ZAP_LOG_DEBUG, "EVENT [%s][%d:%d] STATE [%s]\n",
|
||||
zap_oob_event2str(event->enum_id), event->channel->span_id, event->channel->chan_id, zap_channel_state2str(event->channel->state));
|
||||
|
@ -350,6 +406,19 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
|
|||
|
||||
|
||||
switch(event->enum_id) {
|
||||
case ZAP_OOB_RING_START:
|
||||
{
|
||||
|
||||
if (event->channel->state == ZAP_CHANNEL_STATE_DOWN && !zap_test_flag(event->channel, ZAP_CHANNEL_INTHREAD)) {
|
||||
sig.event_id = ZAP_SIGEVENT_START;
|
||||
zap_set_string(event->channel->caller_data.dnis, event->channel->chan_number);
|
||||
data->sig_cb(&sig);
|
||||
zap_channel_command(event->channel, ZAP_COMMAND_OFFHOOK, NULL);
|
||||
zap_set_state_locked(event->channel, ZAP_CHANNEL_STATE_RING);
|
||||
zap_thread_create_detached(zap_analog_channel_run, event->channel);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZAP_OOB_ONHOOK:
|
||||
{
|
||||
zap_set_state_locked(event->channel, ZAP_CHANNEL_STATE_DOWN);
|
||||
|
@ -374,7 +443,12 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
|
|||
break;
|
||||
case ZAP_OOB_OFFHOOK:
|
||||
{
|
||||
if (!zap_test_flag(event->channel, ZAP_CHANNEL_INTHREAD)) {
|
||||
if (zap_test_flag(event->channel, ZAP_CHANNEL_INTHREAD)) {
|
||||
if (event->channel->type == ZAP_CHAN_TYPE_FXS && zap_test_flag(event->channel, ZAP_CHANNEL_RINGING)) {
|
||||
zap_channel_command(event->channel, ZAP_COMMAND_GENERATE_RING_OFF, NULL);
|
||||
}
|
||||
zap_set_state_locked(event->channel, ZAP_CHANNEL_STATE_UP);
|
||||
} else {
|
||||
zap_set_state_locked(event->channel, ZAP_CHANNEL_STATE_DIALTONE);
|
||||
zap_thread_create_detached(zap_analog_channel_run, event->channel);
|
||||
}
|
||||
|
|
|
@ -474,19 +474,18 @@ zap_status_t zap_channel_open_any(uint32_t span_id, zap_direction_t direction, z
|
|||
|
||||
if (span_id) {
|
||||
span_max = span_id;
|
||||
j = span_id;
|
||||
} else {
|
||||
span_max = globals.span_index;
|
||||
}
|
||||
|
||||
if (direction == ZAP_TOP_DOWN) {
|
||||
j = 1;
|
||||
} else {
|
||||
j = span_max;
|
||||
}
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
span = &globals.spans[j];
|
||||
|
||||
if (!zap_test_flag(span, ZAP_SPAN_CONFIGURED)) {
|
||||
goto next_loop;
|
||||
}
|
||||
|
@ -527,6 +526,7 @@ zap_status_t zap_channel_open_any(uint32_t span_id, zap_direction_t direction, z
|
|||
|
||||
if (status == ZAP_SUCCESS) {
|
||||
zap_set_flag(check, ZAP_CHANNEL_INUSE);
|
||||
zap_channel_open_chan(check);
|
||||
*zchan = check;
|
||||
return status;
|
||||
}
|
||||
|
@ -560,7 +560,7 @@ static zap_status_t zap_channel_reset(zap_channel_t *zchan)
|
|||
zchan->event_callback = NULL;
|
||||
zap_clear_flag(zchan, ZAP_CHANNEL_DTMF_DETECT);
|
||||
zap_clear_flag(zchan, ZAP_CHANNEL_SUPRESS_DTMF);
|
||||
zap_clear_flag(zchan, ZAP_CHANNEL_INUSE);
|
||||
zap_channel_done(zchan);
|
||||
zap_clear_flag_locked(zchan, ZAP_CHANNEL_HOLD);
|
||||
memset(zchan->tokens, 0, sizeof(zchan->tokens));
|
||||
zchan->token_count = 0;
|
||||
|
@ -644,11 +644,24 @@ zap_status_t zap_channel_open(uint32_t span_id, uint32_t chan_id, zap_channel_t
|
|||
return status;
|
||||
}
|
||||
|
||||
zap_status_t zap_channel_outgoing_call(zap_channel_t *zchan)
|
||||
{
|
||||
assert(zchan != NULL);
|
||||
if (zchan->span->outgoing_call) {
|
||||
return zchan->span->outgoing_call(zchan);
|
||||
} else {
|
||||
zap_log(ZAP_LOG_ERROR, "outgoing_call method not implemented!\n");
|
||||
}
|
||||
|
||||
return ZAP_FAIL;
|
||||
}
|
||||
|
||||
zap_status_t zap_channel_done(zap_channel_t *zchan)
|
||||
{
|
||||
|
||||
assert(zchan != NULL);
|
||||
|
||||
memset(&zchan->caller_data, 0, sizeof(zchan->caller_data));
|
||||
zap_clear_flag_locked(zchan, ZAP_CHANNEL_INUSE);
|
||||
|
||||
return ZAP_SUCCESS;
|
||||
|
@ -728,11 +741,6 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo
|
|||
assert(zchan != NULL);
|
||||
assert(zchan->zio != NULL);
|
||||
|
||||
if (!zap_test_flag(zchan, ZAP_CHANNEL_OPEN)) {
|
||||
snprintf(zchan->last_error, sizeof(zchan->last_error), "channel not open");
|
||||
return ZAP_FAIL;
|
||||
}
|
||||
|
||||
zap_mutex_lock(zchan->mutex);
|
||||
|
||||
switch(command) {
|
||||
|
|
|
@ -232,7 +232,6 @@ static ZIO_OPEN_FUNCTION(wanpipe_open)
|
|||
|
||||
static ZIO_CLOSE_FUNCTION(wanpipe_close)
|
||||
{
|
||||
ZIO_CLOSE_MUZZLE;
|
||||
return ZAP_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -241,8 +240,6 @@ static ZIO_COMMAND_FUNCTION(wanpipe_command)
|
|||
wanpipe_tdm_api_t tdm_api;
|
||||
int err = 0;
|
||||
|
||||
ZIO_COMMAND_MUZZLE;
|
||||
|
||||
memset(&tdm_api, 0, sizeof(tdm_api));
|
||||
|
||||
switch(command) {
|
||||
|
|
|
@ -53,25 +53,12 @@ static unsigned zt_open_range(zap_span_t *span, unsigned start, unsigned end, za
|
|||
for(x = start; x < end; x++) {
|
||||
zap_channel_t *chan;
|
||||
zap_socket_t sockfd = ZT_INVALID_SOCKET;
|
||||
int command;
|
||||
int len;
|
||||
|
||||
snprintf(path, sizeof(path), "/dev/zap/%d", x);
|
||||
sockfd = open(path, O_RDWR);
|
||||
|
||||
if (sockfd != ZT_INVALID_SOCKET && zap_span_add_channel(span, sockfd, type, &chan) == ZAP_SUCCESS) {
|
||||
command = ZT_START;
|
||||
#if 0
|
||||
|
||||
if (ioctl(sockfd, ZT_HOOK, &command)) {
|
||||
zap_log(ZAP_LOG_INFO, "failure configuring device %s as OpenZAP device %d:%d fd:%d err:%s\n",
|
||||
path, chan->span_id, chan->chan_id, sockfd, strerror(errno));
|
||||
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
len = zt_globals.codec_ms * 8;
|
||||
if (ioctl(chan->sockfd, ZT_SET_BLOCKSIZE, &len)) {
|
||||
zap_log(ZAP_LOG_INFO, "failure configuring device %s as OpenZAP device %d:%d fd:%d err:%s\n",
|
||||
|
@ -218,13 +205,11 @@ static ZIO_CONFIGURE_FUNCTION(zt_configure)
|
|||
|
||||
static ZIO_OPEN_FUNCTION(zt_open)
|
||||
{
|
||||
ZIO_OPEN_MUZZLE;
|
||||
return ZAP_SUCCESS;
|
||||
}
|
||||
|
||||
static ZIO_CLOSE_FUNCTION(zt_close)
|
||||
{
|
||||
ZIO_CLOSE_MUZZLE;
|
||||
return ZAP_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -233,9 +218,47 @@ static ZIO_COMMAND_FUNCTION(zt_command)
|
|||
zt_params_t ztp = {0};
|
||||
int err = 0;
|
||||
|
||||
ZIO_COMMAND_MUZZLE;
|
||||
|
||||
switch(command) {
|
||||
case ZAP_COMMAND_OFFHOOK:
|
||||
{
|
||||
int command = ZT_OFFHOOK;
|
||||
if (ioctl(zchan->sockfd, ZT_HOOK, &command)) {
|
||||
snprintf(zchan->last_error, sizeof(zchan->last_error), "OFFHOOK Failed");
|
||||
return ZAP_FAIL;
|
||||
}
|
||||
zap_set_flag_locked(zchan, ZAP_CHANNEL_OFFHOOK);
|
||||
}
|
||||
break;
|
||||
case ZAP_COMMAND_ONHOOK:
|
||||
{
|
||||
int command = ZT_ONHOOK;
|
||||
if (ioctl(zchan->sockfd, ZT_HOOK, &command)) {
|
||||
snprintf(zchan->last_error, sizeof(zchan->last_error), "ONHOOK Failed");
|
||||
return ZAP_FAIL;
|
||||
}
|
||||
zap_clear_flag_locked(zchan, ZAP_CHANNEL_OFFHOOK);
|
||||
}
|
||||
break;
|
||||
case ZAP_COMMAND_GENERATE_RING_ON:
|
||||
{
|
||||
int command = ZT_RING;
|
||||
if (ioctl(zchan->sockfd, ZT_HOOK, &command)) {
|
||||
snprintf(zchan->last_error, sizeof(zchan->last_error), "Ring Failed");
|
||||
return ZAP_FAIL;
|
||||
}
|
||||
zap_set_flag_locked(zchan, ZAP_CHANNEL_RINGING);
|
||||
}
|
||||
break;
|
||||
case ZAP_COMMAND_GENERATE_RING_OFF:
|
||||
{
|
||||
int command = ZT_RINGOFF;
|
||||
if (ioctl(zchan->sockfd, ZT_HOOK, &command)) {
|
||||
snprintf(zchan->last_error, sizeof(zchan->last_error), "Ring-off failed");
|
||||
return ZAP_FAIL;
|
||||
}
|
||||
zap_clear_flag_locked(zchan, ZAP_CHANNEL_RINGING);
|
||||
}
|
||||
break;
|
||||
case ZAP_COMMAND_GET_INTERVAL:
|
||||
{
|
||||
if (!(err = ioctl(zchan->sockfd, ZT_GET_BLOCKSIZE, &zchan->packet_len))) {
|
||||
|
@ -344,11 +367,9 @@ ZIO_SPAN_POLL_EVENT_FUNCTION(zt_poll_event)
|
|||
int i, j = 0, k = 0, r, e;
|
||||
|
||||
for(i = 1; i <= span->chan_count; i++) {
|
||||
e = ZT_IOMUX_SIGEVENT;
|
||||
memset(&pfds[j], 0, sizeof(pfds[j]));
|
||||
pfds[j].fd = span->channels[i].sockfd;
|
||||
pfds[j].events = POLLPRI;
|
||||
ioctl(span->channels[i].sockfd ,ZT_IOMUX, &e);
|
||||
j++;
|
||||
}
|
||||
|
||||
|
@ -386,6 +407,21 @@ ZIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event)
|
|||
}
|
||||
|
||||
switch(zt_event_id) {
|
||||
case ZT_EVENT_RINGEROFF:
|
||||
{
|
||||
return ZAP_FAIL;
|
||||
}
|
||||
break;
|
||||
case ZT_EVENT_RINGERON:
|
||||
{
|
||||
return ZAP_FAIL;
|
||||
}
|
||||
break;
|
||||
case ZT_EVENT_RINGBEGIN:
|
||||
{
|
||||
event_id = ZAP_OOB_RING_START;
|
||||
}
|
||||
break;
|
||||
case ZT_EVENT_ONHOOK:
|
||||
{
|
||||
event_id = ZAP_OOB_ONHOOK;
|
||||
|
@ -486,6 +522,7 @@ zap_status_t zt_init(zap_io_interface_t **zio)
|
|||
zt_interface.configure_span = zt_configure_span;
|
||||
zt_interface.open = zt_open;
|
||||
zt_interface.close = zt_close;
|
||||
zt_interface.command = zt_command;
|
||||
zt_interface.wait = zt_wait;
|
||||
zt_interface.read = zt_read;
|
||||
zt_interface.write = zt_write;
|
||||
|
|
Loading…
Reference in New Issue