git-svn-id: http://svn.openzap.org/svn/openzap/trunk@163 a93c3328-9c30-0410-af19-c9cd2b2d52af
This commit is contained in:
Anthony Minessale 2007-05-27 14:58:01 +00:00
parent f26e35023c
commit 3f6d31484a
6 changed files with 162 additions and 86 deletions

View File

@ -113,7 +113,7 @@ $(SRC)/zap_zt.o: $(SRC)/zap_zt.c
dox: dox:
cd docs && doxygen $(PWD)/docs/Doxygen.conf cd docs && doxygen $(PWD)/docs/Doxygen.conf
mod_openzap/mod_openzap.so: $(MYLIB) mod_openzap/mod_openzap.so: $(MYLIB) mod_openzap/mod_openzap.c
cd mod_openzap && make cd mod_openzap && make
mod_openzap: mod_openzap/mod_openzap.so mod_openzap: mod_openzap/mod_openzap.so

View File

@ -47,20 +47,14 @@ struct span_config {
static struct span_config SPAN_CONFIG[ZAP_MAX_SPANS_INTERFACE] = {0}; static struct span_config SPAN_CONFIG[ZAP_MAX_SPANS_INTERFACE] = {0};
typedef enum { typedef enum {
TFLAG_IO = (1 << 0), TFLAG_IO = (1 << 0),
TFLAG_INBOUND = (1 << 1), TFLAG_OUTBOUND = (1 << 1),
TFLAG_OUTBOUND = (1 << 2), TFLAG_DTMF = (1 << 2),
TFLAG_DTMF = (1 << 3), TFLAG_CODEC = (1 << 3),
TFLAG_VOICE = (1 << 4), TFLAG_BREAK = (1 << 4)
TFLAG_HANGUP = (1 << 5),
TFLAG_LINEAR = (1 << 6),
TFLAG_CODEC = (1 << 7),
TFLAG_BREAK = (1 << 8)
} TFLAGS; } TFLAGS;
static struct { static struct {
int debug; int debug;
char *dialplan; char *dialplan;
@ -247,13 +241,26 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
tech_pvt = switch_core_session_get_private(session); tech_pvt = switch_core_session_get_private(session);
assert(tech_pvt != NULL); assert(tech_pvt != NULL);
switch_clear_flag_locked(tech_pvt, TFLAG_IO); zap_channel_set_token(tech_pvt->zchan, NULL);
switch_clear_flag_locked(tech_pvt, TFLAG_VOICE);
if (tech_pvt->zchan->state != ZAP_CHANNEL_STATE_DOWN) { switch (tech_pvt->zchan->type) {
zap_set_state_locked(tech_pvt->zchan, ZAP_CHANNEL_STATE_BUSY); case ZAP_CHAN_TYPE_FXO:
case ZAP_CHAN_TYPE_FXS:
{
if (tech_pvt->zchan->state != ZAP_CHANNEL_STATE_DOWN) {
zap_set_state_locked(tech_pvt->zchan, ZAP_CHANNEL_STATE_HANGUP);
}
}
break;
default:
{
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled type for channel %s\n", switch_channel_get_name(channel));
}
break;
} }
switch_clear_flag_locked(tech_pvt, TFLAG_IO);
if (tech_pvt->read_codec.implementation) { if (tech_pvt->read_codec.implementation) {
switch_core_codec_destroy(&tech_pvt->read_codec); switch_core_codec_destroy(&tech_pvt->read_codec);
} }
@ -287,10 +294,6 @@ static switch_status_t channel_kill_channel(switch_core_session_t *session, int
switch (sig) { switch (sig) {
case SWITCH_SIG_KILL: case SWITCH_SIG_KILL:
switch_clear_flag_locked(tech_pvt, TFLAG_IO); switch_clear_flag_locked(tech_pvt, TFLAG_IO);
switch_clear_flag_locked(tech_pvt, TFLAG_VOICE);
if (tech_pvt->zchan->state != ZAP_CHANNEL_STATE_DOWN) {
zap_set_state_locked(tech_pvt->zchan, ZAP_CHANNEL_STATE_BUSY);
}
break; break;
case SWITCH_SIG_BREAK: case SWITCH_SIG_BREAK:
switch_set_flag_locked(tech_pvt, TFLAG_BREAK); switch_set_flag_locked(tech_pvt, TFLAG_BREAK);
@ -364,8 +367,8 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
assert(tech_pvt->zchan != NULL); assert(tech_pvt->zchan != NULL);
if (tech_pvt->zchan->state != ZAP_CHANNEL_STATE_UP) { if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
return SWITCH_STATUS_GENERR; return SWITCH_STATUS_FALSE;
} }
status = zap_channel_wait(tech_pvt->zchan, &wflags, timeout); status = zap_channel_wait(tech_pvt->zchan, &wflags, timeout);
@ -417,10 +420,6 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
assert(tech_pvt->zchan != NULL); assert(tech_pvt->zchan != NULL);
if (tech_pvt->zchan->state != ZAP_CHANNEL_STATE_UP) {
return SWITCH_STATUS_GENERR;
}
if (!switch_test_flag(tech_pvt, TFLAG_IO)) { if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
} }
@ -545,75 +544,130 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
} }
static ZIO_SIGNAL_CB_FUNCTION(on_fxo_signal) zap_status_t zap_channel_from_event(zap_sigmsg_t *sigmsg, switch_core_session_t **sp)
{
zap_log(ZAP_LOG_DEBUG, "got sig [%s]\n", zap_signal_event2str(sigmsg->event_id));
return ZAP_SUCCESS;
}
static ZIO_SIGNAL_CB_FUNCTION(on_fxs_signal)
{ {
switch_core_session_t *session = NULL; switch_core_session_t *session = NULL;
private_t *tech_pvt = NULL; private_t *tech_pvt = NULL;
switch_channel_t *channel = NULL; switch_channel_t *channel = NULL;
char name[128]; char name[128];
zap_log(ZAP_LOG_DEBUG, "got sig [%s]\n", zap_signal_event2str(sigmsg->event_id));
switch(sigmsg->event_id) { *sp = NULL;
case ZAP_SIGEVENT_START:
if (!(session = switch_core_session_request(&channel_endpoint_interface, NULL))) { if (!(session = switch_core_session_request(&channel_endpoint_interface, NULL))) {
zap_set_state_locked(sigmsg->channel, ZAP_CHANNEL_STATE_BUSY); return ZAP_FAIL;
return ZAP_SUCCESS; }
}
switch_core_session_add_stream(session, NULL);
tech_pvt = (private_t *) switch_core_session_alloc(session, sizeof(private_t));
assert(tech_pvt != NULL);
channel = switch_core_session_get_channel(session);
if (tech_init(tech_pvt, session, sigmsg->channel) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Initilization Error!\n");
switch_core_session_destroy(&session);
return ZAP_FAIL;
}
tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
"OpenZAP",
SPAN_CONFIG[sigmsg->span->span_id].dialplan,
sigmsg->channel->chan_name,
sigmsg->channel->chan_number,
NULL,
sigmsg->channel->chan_number,
NULL,
NULL,
(char *) modname,
SPAN_CONFIG[sigmsg->span->span_id].context,
sigmsg->dnis);
assert(tech_pvt->caller_profile != NULL);
snprintf(name, sizeof(name), "OpenZAP/%s", tech_pvt->caller_profile->destination_number);
switch_channel_set_name(channel, name);
switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
switch_channel_set_state(channel, CS_INIT);
if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error spawning thread\n");
switch_core_session_destroy(&session);
return ZAP_FAIL;
}
switch_core_session_add_stream(session, NULL); switch_copy_string(sigmsg->channel->token, switch_core_session_get_uuid(session), sizeof(sigmsg->channel->token));
*sp = session;
tech_pvt = (private_t *) switch_core_session_alloc(session, sizeof(private_t));
assert(tech_pvt != NULL);
channel = switch_core_session_get_channel(session);
if (tech_init(tech_pvt, session, sigmsg->channel) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Initilization Error!\n");
switch_core_session_destroy(&session);
zap_set_state_locked(sigmsg->channel, ZAP_CHANNEL_STATE_BUSY);
return ZAP_SUCCESS;
}
tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
"OpenZAP",
SPAN_CONFIG[sigmsg->span->span_id].dialplan,
sigmsg->channel->chan_name,
sigmsg->channel->chan_number,
NULL,
sigmsg->channel->chan_number,
NULL,
NULL,
(char *) modname,
SPAN_CONFIG[sigmsg->span->span_id].context,
sigmsg->dnis);
assert(tech_pvt->caller_profile != NULL);
snprintf(name, sizeof(name), "OpenZAP/%s", tech_pvt->caller_profile->destination_number);
switch_channel_set_name(channel, name);
switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
switch_channel_set_state(channel, CS_INIT);
if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error spawning thread\n");
switch_core_session_destroy(&session);
zap_set_state_locked(sigmsg->channel, ZAP_CHANNEL_STATE_BUSY);
return ZAP_SUCCESS;
}
//zap_set_state_locked(sigmsg->channel, ZAP_CHANNEL_STATE_RING);
break;
default:
break;
}
return ZAP_SUCCESS; return ZAP_SUCCESS;
} }
static ZIO_SIGNAL_CB_FUNCTION(on_fxo_signal)
{
zap_log(ZAP_LOG_DEBUG, "got sig [%s]\n", zap_signal_event2str(sigmsg->event_id));
return ZAP_SUCCESS;
}
static ZIO_SIGNAL_CB_FUNCTION(on_fxs_signal)
{
switch_core_session_t *session = NULL;
switch_channel_t *channel = NULL;
zap_status_t status;
int rwlock = 0;
zap_log(ZAP_LOG_DEBUG, "got sig [%s]\n", zap_signal_event2str(sigmsg->event_id));
if (!switch_strlen_zero(sigmsg->channel->token)) {
if ((session = switch_core_session_locate(sigmsg->channel->token))) {
channel = switch_core_session_get_channel(session);
rwlock++;
}
}
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_BUSY);
}
}
break;
case ZAP_SIGEVENT_STOP:
{
if (channel) {
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
zap_channel_set_token(sigmsg->channel, NULL);
}
}
break;
}
if (session && rwlock) {
switch_core_session_rwunlock(session);
}
return status;
}
static ZIO_SIGNAL_CB_FUNCTION(on_zap_signal)
{
switch (sigmsg->channel->type) {
case ZAP_CHAN_TYPE_FXO:
{
on_fxo_signal(sigmsg);
}
break;
case ZAP_CHAN_TYPE_FXS:
{
on_fxs_signal(sigmsg);
}
break;
default:
{
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled type for channel %d:%d\n",
sigmsg->channel->span_id, sigmsg->channel->chan_id);
}
break;
}
}
static void zap_logger(char *file, const char *func, int line, int level, char *fmt, ...) static void zap_logger(char *file, const char *func, int line, int level, char *fmt, ...)
{ {
@ -710,7 +764,7 @@ static switch_status_t load_config(void)
continue; continue;
} }
if (zap_analog_configure_span(span, tonegroup, to, max, span->trunk_type == ZAP_TRUNK_FXS ? on_fxs_signal : on_fxo_signal) != ZAP_SUCCESS) { if (zap_analog_configure_span(span, tonegroup, to, max, on_zap_signal) != ZAP_SUCCESS) {
zap_log(ZAP_LOG_ERROR, "Error starting OpenZAP span %s:%d\n", mod, span_id); zap_log(ZAP_LOG_ERROR, "Error starting OpenZAP span %s:%d\n", mod, span_id);
continue; continue;
} }

View File

@ -245,8 +245,9 @@ struct zap_channel {
uint32_t dtmf_off; uint32_t dtmf_off;
teletone_generation_session_t tone_session; teletone_generation_session_t tone_session;
zap_time_t last_event_time; zap_time_t last_event_time;
char chan_name[80]; char token[128];
char chan_number[25]; char chan_name[128];
char chan_number[32];
struct zap_span *span; struct zap_span *span;
struct zap_io_interface *zio; struct zap_io_interface *zio;
}; };
@ -321,6 +322,7 @@ struct zap_io_interface {
struct zap_span spans[ZAP_MAX_SPANS_INTERFACE]; struct zap_span spans[ZAP_MAX_SPANS_INTERFACE];
}; };
zap_status_t zap_channel_set_token(zap_channel_t *zchan, char *token);
zap_status_t zap_channel_set_state(zap_channel_t *zchan, zap_channel_state_t state); zap_status_t zap_channel_set_state(zap_channel_t *zchan, zap_channel_state_t state);
zap_status_t zap_span_load_tones(zap_span_t *span, char *mapname); zap_status_t zap_span_load_tones(zap_span_t *span, char *mapname);
zap_size_t zap_channel_dequeue_dtmf(zap_channel_t *zchan, char *dtmf, zap_size_t len); zap_size_t zap_channel_dequeue_dtmf(zap_channel_t *zchan, char *dtmf, zap_size_t len);

View File

@ -192,6 +192,7 @@ typedef enum {
typedef enum { typedef enum {
ZAP_CHANNEL_STATE_DOWN, ZAP_CHANNEL_STATE_DOWN,
ZAP_CHANNEL_STATE_UP, ZAP_CHANNEL_STATE_UP,
ZAP_CHANNEL_STATE_HANGUP,
ZAP_CHANNEL_STATE_DIALTONE, ZAP_CHANNEL_STATE_DIALTONE,
ZAP_CHANNEL_STATE_COLLECT, ZAP_CHANNEL_STATE_COLLECT,
ZAP_CHANNEL_STATE_RING, ZAP_CHANNEL_STATE_RING,
@ -200,7 +201,7 @@ typedef enum {
ZAP_CHANNEL_STATE_IDLE, ZAP_CHANNEL_STATE_IDLE,
ZAP_CHANNEL_STATE_INVALID ZAP_CHANNEL_STATE_INVALID
} zap_channel_state_t; } zap_channel_state_t;
#define CHANNEL_STATE_STRINGS "DOWN", "UP", "DIALTONE", "COLLECT", "RING", "BUSY", "ATTN", "IDLE", "INVALID" #define CHANNEL_STATE_STRINGS "DOWN", "UP", "HANGUP", "DIALTONE", "COLLECT", "RING", "BUSY", "ATTN", "IDLE", "INVALID"
ZAP_STR2ENUM_P(zap_str2zap_channel_state, zap_channel_state2str, zap_channel_state_t) ZAP_STR2ENUM_P(zap_str2zap_channel_state, zap_channel_state2str, zap_channel_state_t)
typedef enum { typedef enum {

View File

@ -145,6 +145,13 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
} }
} }
break; break;
case ZAP_CHANNEL_STATE_HANGUP:
{
if (state_counter > 2000) {
zap_set_state_locked(chan, ZAP_CHANNEL_STATE_BUSY);
}
}
break;
case ZAP_CHANNEL_STATE_UP: case ZAP_CHANNEL_STATE_UP:
case ZAP_CHANNEL_STATE_IDLE: case ZAP_CHANNEL_STATE_IDLE:
{ {

View File

@ -370,6 +370,18 @@ zap_status_t zap_channel_set_event_callback(zap_channel_t *zchan, zio_event_cb_t
return ZAP_SUCCESS; return ZAP_SUCCESS;
} }
zap_status_t zap_channel_set_token(zap_channel_t *zchan, char *token)
{
zap_mutex_lock(zchan->mutex);
if (token) {
zap_copy_string(zchan->token, token, sizeof(zchan->token));
} else {
*zchan->token = '\0';
}
zap_mutex_unlock(zchan->mutex);
return ZAP_SUCCESS;
}
zap_status_t zap_channel_set_state(zap_channel_t *zchan, zap_channel_state_t state) zap_status_t zap_channel_set_state(zap_channel_t *zchan, zap_channel_state_t state)
{ {