]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
update
authorAnthony Minessale <anthony.minessale@gmail.com>
Thu, 31 May 2007 20:15:16 +0000 (20:15 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Thu, 31 May 2007 20:15:16 +0000 (20:15 +0000)
git-svn-id: http://svn.openzap.org/svn/openzap/trunk@189 a93c3328-9c30-0410-af19-c9cd2b2d52af

libs/openzap/mod_openzap/mod_openzap.c
libs/openzap/src/include/openzap.h
libs/openzap/src/include/zap_types.h
libs/openzap/src/testanalog.c
libs/openzap/src/zap_analog.c
libs/openzap/src/zap_io.c
libs/openzap/src/zap_wanpipe.c
libs/openzap/src/zap_zt.c

index db17d6a95f5d4631a0819aeb4ce61a19e0ad3c97..0e970d772d69b0bab61e5fa51a584649f4589b87 100644 (file)
@@ -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,45 @@ 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;
        }
 
-       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;
+
+       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;
+       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;
@@ -481,8 +524,11 @@ 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:
-               zap_set_state_locked(tech_pvt->zchan, ZAP_CHANNEL_STATE_UP);
+               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);
index acddd89f23c151ef8f23fccdb7d72169acbaf8d6..1804090136efead7612ca1aced4e3c0c9ec30dc7 100644 (file)
 #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);
index 4abc83a23c9ff94990d743a63d2abaaa556a12f2..b1431878f1e8d93e486b0e93a9d29deaef20e5a0 100644 (file)
@@ -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
index 5e2750925979138dbab5e3cca829a9081fab6e12..086eab751405becd0c6ba72e69376e04b08419c7 100644 (file)
@@ -62,7 +62,7 @@ int main(int argc, char *argv[])
 {
        zap_span_t *span;
        int span_id;
-       
+
        if (argc < 2) {
                printf("usage %s <spanno>\n", argv[0]);
                exit(-1);
index dd41ebe8fa8ce8c4601080fce4d56f9784e3399a..400a8999ac215ae23ccb5a6871dff7f84820280f 100644 (file)
 #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);
@@ -250,137 +293,168 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
                        }
                }
 
-                if ((dlen = zap_channel_dequeue_dtmf(chan, dtmf + dtmf_offset, sizeof(dtmf) - strlen(dtmf)))) {
-                        if (chan->state == ZAP_CHANNEL_STATE_DIALTONE || chan->state == ZAP_CHANNEL_STATE_COLLECT) {
-                                zap_log(ZAP_LOG_DEBUG, "DTMF %s\n", dtmf + dtmf_offset);
-                                if (chan->state == ZAP_CHANNEL_STATE_DIALTONE) {
-                                        zap_set_state_locked(chan, ZAP_CHANNEL_STATE_COLLECT);
-                                }
-                                dtmf_offset = strlen(dtmf);
-                                last_digit = elapsed;
-                        }
-                }
+               if ((dlen = zap_channel_dequeue_dtmf(chan, dtmf + dtmf_offset, sizeof(dtmf) - strlen(dtmf)))) {
+                       if (chan->state == ZAP_CHANNEL_STATE_DIALTONE || chan->state == ZAP_CHANNEL_STATE_COLLECT) {
+                               zap_log(ZAP_LOG_DEBUG, "DTMF %s\n", dtmf + dtmf_offset);
+                               if (chan->state == ZAP_CHANNEL_STATE_DIALTONE) {
+                                       zap_set_state_locked(chan, ZAP_CHANNEL_STATE_COLLECT);
+                               }
+                               dtmf_offset = strlen(dtmf);
+                               last_digit = elapsed;
+                       }
+               }
+
 
+               if (last_digit && ((elapsed - last_digit > data->digit_timeout) || strlen(dtmf) > data->max_dialstr)) {
+                       zap_log(ZAP_LOG_DEBUG, "Number obtained [%s]\n", dtmf);
+                       zap_set_state_locked(chan, ZAP_CHANNEL_STATE_IDLE);
+                       last_digit = 0;
+               }
+
+               if (zap_channel_wait(chan, &flags, interval * 2) != ZAP_SUCCESS) {
+                       continue;
+               }
 
-                if (last_digit && ((elapsed - last_digit > data->digit_timeout) || strlen(dtmf) > data->max_dialstr)) {
-                        zap_log(ZAP_LOG_DEBUG, "Number obtained [%s]\n", dtmf);
-                        zap_set_state_locked(chan, ZAP_CHANNEL_STATE_IDLE);
-                        last_digit = 0;
-                }
+               if (!(flags & ZAP_READ)) {
+                       continue;
+               }
 
-                if (zap_channel_wait(chan, &flags, interval * 2) != ZAP_SUCCESS) {
-                        continue;
-                }
-
-                if (!(flags & ZAP_READ)) {
-                        continue;
-                }
-
-                if (zap_channel_read(chan, frame, &len) != ZAP_SUCCESS) {
-                        goto done;
-                }
-
-                if (!indicate) {
-                        continue;
-                }
-
-                if (chan->effective_codec != ZAP_CODEC_SLIN) {
-                        len *= 2;
-                }
-
-                rlen = zap_buffer_read_loop(dt_buffer, frame, len);                                    
-
-                if (chan->effective_codec != ZAP_CODEC_SLIN) {
-                        zio_codec_t codec_func = NULL;
-
-                        if (chan->native_codec == ZAP_CODEC_ULAW) {
-                                codec_func = zio_slin2ulaw;
-                        } else if (chan->native_codec == ZAP_CODEC_ALAW) {
-                                codec_func = zio_slin2alaw;
-                        }
-
-                        if (codec_func) {
-                                status = codec_func(frame, sizeof(frame), &rlen);
-                        } else {
-                                snprintf(chan->last_error, sizeof(chan->last_error), "codec error!");
-                                goto done;
-                        }
-                }
-
-                zap_channel_write(chan, frame, &rlen);
-        }
-
-  done:
-
-        closed_chan = chan;
-        zap_channel_close(&chan);
-
-        zap_channel_command(closed_chan, ZAP_COMMAND_SET_NATIVE_CODEC, NULL);
-
-        if (ts.buffer) {
-                teletone_destroy_session(&ts);
-        }
-
-        if (dt_buffer) {
-                zap_buffer_destroy(&dt_buffer);
-        }
-
-        zap_clear_flag(closed_chan, ZAP_CHANNEL_INTHREAD);
-
-        zap_log(ZAP_LOG_DEBUG, "ANALOG CHANNEL thread ended.\n");
-
-        return NULL;
- }
-
- static zap_status_t process_event(zap_span_t *span, zap_event_t *event)
- {
-        zap_sigmsg_t sig;
-        zap_analog_data_t *data = event->channel->span->analog_data;
-
-        memset(&sig, 0, sizeof(sig));
-        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));
-
-        zap_mutex_lock(event->channel->mutex);
-
-
-        switch(event->enum_id) {
-        case ZAP_OOB_ONHOOK:
-                {
-                        zap_set_state_locked(event->channel, ZAP_CHANNEL_STATE_DOWN);
-                }
-                break;
-        case ZAP_OOB_FLASH:
-                {
+               if (zap_channel_read(chan, frame, &len) != ZAP_SUCCESS) {
+                       goto done;
+               }
 
-                        sig.event_id = ZAP_SIGEVENT_FLASH;
-                        zap_channel_rotate_tokens(event->channel);
+               if (!indicate) {
+                       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;
+               }
+
+               rlen = zap_buffer_read_loop(dt_buffer, frame, len);                                     
+
+               if (chan->effective_codec != ZAP_CODEC_SLIN) {
+                       zio_codec_t codec_func = NULL;
+
+                       if (chan->native_codec == ZAP_CODEC_ULAW) {
+                               codec_func = zio_slin2ulaw;
+                       } else if (chan->native_codec == ZAP_CODEC_ALAW) {
+                               codec_func = zio_slin2alaw;
+                       }
+
+                       if (codec_func) {
+                               status = codec_func(frame, sizeof(frame), &rlen);
+                       } else {
+                               snprintf(chan->last_error, sizeof(chan->last_error), "codec error!");
+                               goto done;
+                       }
+               }
 
-                        if (zap_test_flag(event->channel, ZAP_CHANNEL_HOLD)) {
-                                zap_set_state_locked(event->channel,  ZAP_CHANNEL_STATE_UP);
-                        } else {
-                                data->sig_cb(&sig);
-                                if (event->channel->token_count == 1) {
-                                        zap_set_flag_locked(event->channel, ZAP_CHANNEL_HOLD);
-                                        zap_set_state_locked(event->channel, ZAP_CHANNEL_STATE_DIALTONE);
-                                }
-                        }
-                }
+               zap_channel_write(chan, frame, &rlen);
+       }
+
+ 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);
+
+       zap_channel_command(closed_chan, ZAP_COMMAND_SET_NATIVE_CODEC, NULL);
+
+       if (ts.buffer) {
+               teletone_destroy_session(&ts);
+       }
+
+       if (dt_buffer) {
+               zap_buffer_destroy(&dt_buffer);
+       }
+
+       zap_clear_flag(closed_chan, ZAP_CHANNEL_INTHREAD);
+
+       zap_log(ZAP_LOG_DEBUG, "ANALOG CHANNEL thread ended.\n");
+
+       return NULL;
+}
+
+static zap_status_t process_event(zap_span_t *span, zap_event_t *event)
+{
+       zap_sigmsg_t sig;
+       zap_analog_data_t *data = event->channel->span->analog_data;
+
+       memset(&sig, 0, sizeof(sig));
+       sig.chan_id = event->channel->chan_id;
+       sig.span_id = event->channel->span_id;
+       sig.channel = event->channel;
+
+
+       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));
+
+       zap_mutex_lock(event->channel->mutex);
+
+
+       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);
+               }
+               break;
+       case ZAP_OOB_FLASH:
+               {
+
+                       sig.event_id = ZAP_SIGEVENT_FLASH;
+                       zap_channel_rotate_tokens(event->channel);
+
+                       if (zap_test_flag(event->channel, ZAP_CHANNEL_HOLD)) {
+                               zap_set_state_locked(event->channel,  ZAP_CHANNEL_STATE_UP);
+                       } else {
+                               data->sig_cb(&sig);
+                               if (event->channel->token_count == 1) {
+                                       zap_set_flag_locked(event->channel, ZAP_CHANNEL_HOLD);
+                                       zap_set_state_locked(event->channel, ZAP_CHANNEL_STATE_DIALTONE);
+                               }
+                       }
+               }
                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);
                        }
                }
        }
-
+        
        zap_mutex_unlock(event->channel->mutex);
        return ZAP_SUCCESS;
 }
index 813a263846495343f2ebf9d50b60cfc8f390d6b3..49bc73e73aaa579c9b6f05ef1f34f2863c66bd60 100644 (file)
@@ -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;
+               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) {
index 9d3dcc43f1a0ec1151bd01948730285099e3d36b..191e010c417be42634fc612e9432263cb5f49985 100644 (file)
@@ -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) {
index 9f86ffe01fe17fa20c6c56cfa23ac84f24b68fb3..c5486ab8cf79c1b4955d8234e6414936374ef6e0 100644 (file)
@@ -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;