]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add fsk callerid stuff to analog fxo
authorAnthony Minessale <anthony.minessale@gmail.com>
Tue, 5 Jun 2007 16:57:32 +0000 (16:57 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Tue, 5 Jun 2007 16:57:32 +0000 (16:57 +0000)
git-svn-id: http://svn.openzap.org/svn/openzap/trunk@220 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/testcid.c
libs/openzap/src/zap_analog.c
libs/openzap/src/zap_io.c
libs/openzap/src/zap_wanpipe.c

index 2a0e13c37e2f511ebd5fe60f4663fcf885ce5f1d..822459a1be46cd61460a30d67cd4705b83c4d883 100644 (file)
@@ -699,7 +699,7 @@ zap_status_t zap_channel_from_event(zap_sigmsg_t *sigmsg, switch_core_session_t
        private_t *tech_pvt = NULL;
        switch_channel_t *channel = NULL;
        char name[128];
-
+       
        *sp = NULL;
        
        if (!(session = switch_core_session_request(&channel_endpoint_interface, NULL))) {
@@ -716,16 +716,29 @@ zap_status_t zap_channel_from_event(zap_sigmsg_t *sigmsg, switch_core_session_t
                switch_core_session_destroy(&session);
                return ZAP_FAIL;
        }
-               
+       
+
+       if (switch_strlen_zero(sigmsg->channel->caller_data.cid_name)) {
+               switch_set_string(sigmsg->channel->caller_data.cid_name, sigmsg->channel->chan_name);
+       }
+
+       if (switch_strlen_zero(sigmsg->channel->caller_data.cid_num)) {
+               if (!switch_strlen_zero(sigmsg->channel->caller_data.ani)) {
+                       switch_set_string(sigmsg->channel->caller_data.cid_num, sigmsg->channel->caller_data.ani);
+               } else {
+                       switch_set_string(sigmsg->channel->caller_data.cid_num, sigmsg->channel->chan_number);
+               }
+       }
+       
        tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
                                                                                                                 "OpenZAP",
                                                                                                                 SPAN_CONFIG[sigmsg->channel->span_id].dialplan,
-                                                                                                                sigmsg->channel->chan_name,
-                                                                                                                sigmsg->channel->chan_number,
-                                                                                                                NULL,
-                                                                                                                sigmsg->channel->chan_number,
-                                                                                                                NULL,
+                                                                                                                sigmsg->channel->caller_data.cid_name,
+                                                                                                                sigmsg->channel->caller_data.cid_num,
                                                                                                                 NULL,
+                                                                                                                sigmsg->channel->caller_data.ani,
+                                                                                                                sigmsg->channel->caller_data.aniII,
+                                                                                                                sigmsg->channel->caller_data.rdnis,
                                                                                                                 (char *) modname,
                                                                                                                 SPAN_CONFIG[sigmsg->channel->span_id].context,
                                                                                                                 sigmsg->channel->caller_data.dnis);
index f7a020d4c8b17b664c98a93ba12ebf10e90bfbec..dfa483784594833597d44671b386acb51b710cef 100644 (file)
@@ -223,13 +223,28 @@ struct zap_event {
 #define ZAP_TOKEN_STRLEN 128
 #define ZAP_MAX_TOKENS 10
 
+static __inline__ char *zap_clean_string(char *s)
+{
+       char *p;
 
+       for (p = s; p && *p; p++) {
+               uint8_t x = (uint8_t) *p;
+               if (x < 32 || x > 127) {
+                       *p = ' ';
+               }
+       }
+
+       return s;
+}
 
 struct zap_caller_data {
        char cid_name[80];
+       char cid_num[80];
+       char cid_date[8];
        char ani[25];
        char aniII[25];
        char dnis[25];
+       char rdnis[25];
 };
 
 struct zap_channel {
@@ -271,6 +286,8 @@ struct zap_channel {
        char chan_name[128];
        char chan_number[32];
        zap_filehandle_t fds[2];
+       zap_fsk_data_state_t fsk;
+       uint8_t fsk_buf[80];
        struct zap_caller_data caller_data;
        struct zap_span *span;
        struct zap_io_interface *zio;
@@ -343,7 +360,7 @@ struct zap_io_interface {
        zio_span_next_event_t next_event;
 };
 
-zap_status_t zap_fsk_data_parse(zap_fsk_data_state_t *state, zap_size_t *type, zap_size_t *len, char *data, size_t datalen);
+zap_status_t zap_fsk_data_parse(zap_fsk_data_state_t *state, zap_size_t *type, char **data, zap_size_t *len);
 zap_status_t zap_fsk_demod_feed(zap_fsk_data_state_t *state, int16_t *data, size_t samples);
 zap_status_t zap_fsk_demod_destroy(zap_fsk_data_state_t *state);
 int zap_fsk_demod_init(zap_fsk_data_state_t *state, int rate, uint8_t *buf, size_t bufsize);
index d77f56cf98cbdad2954ec181a95d60d1877132c2..ef0269fb6747d6bc47a2fc96f23a43c0eb776736 100644 (file)
@@ -63,14 +63,22 @@ struct zap_io_interface;
 
 typedef uint64_t zap_time_t; 
 
+typedef enum {
+       ZAP_CID_TYPE_SDMF = 0x04,
+       ZAP_CID_TYPE_MDMF = 0x80
+} zap_cid_type_t;
+
 typedef enum {
        MDMF_DATETIME = 1,
        MDMF_PHONE_NUM = 2,
+       MDMF_DDN = 3,
        MDMF_NO_NUM = 4,
-       MDMF_NAME = 7,
-       MDMF_NO_NAME = 8
+       MDMF_PHONE_NAME = 7,
+       MDMF_NO_NAME = 8,
+       MDMF_INVALID = 9
 } zap_mdmf_type_t;
-
+#define MDMF_STRINGS "X", "DATETIME", "PHONE_NUM", "DDN", "NO_NUM", "X", "X", "PHONE_NAME", "NO_NAME", "INVALID"
+ZAP_STR2ENUM_P(zap_str2zap_mdmf_type, zap_mdmf_type2str, zap_mdmf_type_t)
 
 struct zap_fsk_data_state {
        dsp_fsk_handle_t *fsk1200_handle;
@@ -216,6 +224,8 @@ typedef enum {
        ZAP_COMMAND_DISABLE_PROGRESS_DETECT,
        ZAP_COMMAND_TRACE_INPUT,
        ZAP_COMMAND_TRACE_OUTPUT,
+       ZAP_COMMAND_ENABLE_CALLERID_DETECT,
+       ZAP_COMMAND_DISABLE_CALLERID_DETECT,
        ZAP_COMMAND_COUNT
 } zap_command_t;
 
@@ -236,7 +246,8 @@ typedef enum {
 typedef enum {
        ZAP_CHANNEL_FEATURE_DTMF = (1 << 0),
        ZAP_CHANNEL_FEATURE_CODECS = (1 << 1),
-       ZAP_CHANNEL_FEATURE_INTERVAL = (1 << 2)
+       ZAP_CHANNEL_FEATURE_INTERVAL = (1 << 2),
+       ZAP_CHANNEL_FEATURE_CALLERID = (1 << 3)
 } zap_channel_feature_t;
 
 typedef enum {
@@ -252,9 +263,11 @@ typedef enum {
        ZAP_CHANNEL_STATE_IDLE,
        ZAP_CHANNEL_STATE_GENRING,
        ZAP_CHANNEL_STATE_DIALING,
+       ZAP_CHANNEL_STATE_GET_CALLERID,
        ZAP_CHANNEL_STATE_INVALID
 } zap_channel_state_t;
-#define CHANNEL_STATE_STRINGS "DOWN", "UP", "HANGUP", "HOLD", "DIALTONE", "COLLECT", "RING", "BUSY", "ATTN", "IDLE", "GENRING", "DIALING", "INVALID"
+#define CHANNEL_STATE_STRINGS "DOWN", "UP", "HANGUP", "HOLD", "DIALTONE", "COLLECT", \
+               "RING", "BUSY", "ATTN", "IDLE", "GENRING", "DIALING", "GET_CALLERID", "INVALID"
 ZAP_STR2ENUM_P(zap_str2zap_channel_state, zap_channel_state2str, zap_channel_state_t)
 
 typedef enum {
@@ -274,7 +287,8 @@ typedef enum {
        ZAP_CHANNEL_INUSE = (1 << 13),
        ZAP_CHANNEL_OFFHOOK = (1 << 14),
        ZAP_CHANNEL_RINGING = (1 << 15),
-       ZAP_CHANNEL_PROGRESS_DETECT = (1 << 16)
+       ZAP_CHANNEL_PROGRESS_DETECT = (1 << 16),
+       ZAP_CHANNEL_CALLERID_DETECT = (1 << 17)
 } zap_channel_flag_t;
 
 
index f91ee59d966f79dd5a9a368da9dca4a4bfc504f8..545794689c45caef6cafbe253a0223565b7e4c1f 100644 (file)
@@ -7,7 +7,8 @@ int main(int argc, char *argv[])
        int16_t buf[160] = {0};
        ssize_t len = 0;
        int type, mlen;
-       char str[128];
+       char *sp;
+       char str[128] = "";
        char fbuf[256];
 
        if (argc < 2 || zap_fsk_demod_init(&state, 8000, fbuf, sizeof(fbuf))) {
@@ -26,10 +27,14 @@ int main(int argc, char *argv[])
                }
        }
 
-       while(zap_fsk_data_parse(&state, &type, &mlen, str, sizeof(str)) == ZAP_SUCCESS) {
-               printf("TYPE %d LEN %d VAL [%s]\n", type, mlen, str);
+       while(zap_fsk_data_parse(&state, &type, &sp, &mlen) == ZAP_SUCCESS) {
+               zap_copy_string(str, sp, mlen+1);
+               *(str+mlen) = '\0';
+               zap_clean_string(str);
+               printf("TYPE %d (%s) LEN %d VAL [%s]\n", type, zap_mdmf_type2str(type), mlen, str);
        }
 
+       zap_fsk_demod_destroy(&state);
 
        close(fd);
 }
index e8944f2db6c984c06c76124cd874ebc190c029f0..7290d38d88c03cc37e34762d528ea136309d53b0 100644 (file)
@@ -164,6 +164,13 @@ 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_GET_CALLERID:
+                               {
+                                       if (state_counter > 5000 || !zap_test_flag(chan, ZAP_CHANNEL_CALLERID_DETECT)) {
+                                               zap_set_state_locked(chan, ZAP_CHANNEL_STATE_IDLE);
+                                       }
+                               }
+                               break;
                        case ZAP_CHANNEL_STATE_DIALING:
                                {
                                        if (state_counter > dial_timeout) {
@@ -199,14 +206,17 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
                                        }
                                }
                                break;
+                       case ZAP_CHANNEL_STATE_ATTN:
+                               {
+                                       if (state_counter > 20000) {
+                                               zap_set_state_locked(chan, ZAP_CHANNEL_STATE_DOWN);
+                                       }
+                               }
+                               break;
                        case ZAP_CHANNEL_STATE_HANGUP:
                                {
-                                       if (state_counter > 2000) {
-                                               if (chan->type == ZAP_CHAN_TYPE_FXO) {
-                                                       zap_set_state_locked(chan, ZAP_CHANNEL_STATE_DOWN);
-                                               } else {
-                                                       zap_set_state_locked(chan, ZAP_CHANNEL_STATE_BUSY);
-                                               }
+                                       if (state_counter > 1000) {
+                                               zap_set_state_locked(chan, ZAP_CHANNEL_STATE_BUSY);
                                        }
                                }
                                break;
@@ -230,6 +240,7 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
                        zap_clear_flag_locked(chan, ZAP_CHANNEL_STATE_CHANGE);
                        indicate = 0;
                        state_counter = 0;
+                       zap_log(ZAP_LOG_DEBUG, "Executing state handler for %s\n", zap_channel_state2str(chan->state));
                        switch(chan->state) {
                        case ZAP_CHANNEL_STATE_UP:
                                {
@@ -264,7 +275,13 @@ 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(chan->caller_data.dnis, dtmf, sizeof(chan->caller_data.dnis));
+
+                                       if (chan->type == ZAP_CHAN_TYPE_FXO) {
+                                               zap_set_string(chan->caller_data.dnis, chan->chan_number);
+                                       } else {
+                                               zap_set_string(chan->caller_data.dnis, dtmf);
+                                       }
+
                                        data->sig_cb(&sig);
                                        continue;
                                }
@@ -292,12 +309,18 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
                                        zap_channel_command(chan, ZAP_COMMAND_GENERATE_RING_ON, NULL);
                                }
                                break;
-                       case ZAP_CHANNEL_STATE_RING:
+                       case ZAP_CHANNEL_STATE_GET_CALLERID:
                                {
                                        zap_channel_done(chan);
+                                       zap_channel_command(chan, ZAP_COMMAND_ENABLE_CALLERID_DETECT, NULL);
+                               }
+                               break;
+                       case ZAP_CHANNEL_STATE_RING:
+                               {
                                        zap_buffer_zero(dt_buffer);
                                        teletone_run(&ts, chan->span->tone_map[ZAP_TONEMAP_RING]);
                                        indicate = 1;
+                                       
                                }
                                break;
                        case ZAP_CHANNEL_STATE_BUSY:
@@ -317,7 +340,6 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
                                }
                                break;
                        default:
-                               zap_channel_done(chan);
                                break;
                        }
                }
@@ -393,8 +415,7 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
                        zap_channel_write(chan, frame, sizeof(frame), &rlen);
                        continue;
                }
-
-
+               
                if (!indicate) {
                        continue;
                }
@@ -408,7 +429,6 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
                }
 
                rlen = zap_buffer_read_loop(dt_buffer, frame, len);                                     
-
                
                if (chan->effective_codec != ZAP_CODEC_SLIN) {
                        zio_codec_t codec_func = NULL;
@@ -431,7 +451,7 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
        }
 
  done:
-
+       zap_channel_done(chan);
        if (chan->type == ZAP_CHAN_TYPE_FXO && zap_test_flag(chan, ZAP_CHANNEL_OFFHOOK)) {
                zap_channel_command(chan, ZAP_COMMAND_ONHOOK, NULL);
        }
@@ -484,11 +504,7 @@ static zap_status_t process_event(zap_span_t *span, zap_event_t *event)
 
                        if (event->channel->state == ZAP_CHANNEL_STATE_DOWN && !zap_test_flag(event->channel, ZAP_CHANNEL_INTHREAD)) {
                                /*zap_channel_command(event->channel, ZAP_COMMAND_TRACE_INPUT, "/tmp/inbound.ul");*/
-                               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_set_state_locked(event->channel, ZAP_CHANNEL_STATE_GET_CALLERID);
                                zap_thread_create_detached(zap_analog_channel_run, event->channel);
                        }
                }
index 9c251c9c427d8709776293285e594f745d816d54..d0da23752f830006eef175f30f9daa26809eb222 100644 (file)
@@ -101,6 +101,9 @@ ZAP_STR2ENUM(zap_str2zap_signal_event, zap_signal_event2str, zap_signal_event_t,
 ZAP_ENUM_NAMES(CHANNEL_STATE_NAMES, CHANNEL_STATE_STRINGS)
 ZAP_STR2ENUM(zap_str2zap_channel_state, zap_channel_state2str, zap_channel_state_t, CHANNEL_STATE_NAMES, ZAP_CHANNEL_STATE_INVALID)
 
+ZAP_ENUM_NAMES(MDMF_TYPE_NAMES, MDMF_STRINGS)
+ZAP_STR2ENUM(zap_str2zap_mdmf_type, zap_mdmf_type2str, zap_mdmf_type_t, MDMF_TYPE_NAMES, MDMF_INVALID)
+
 static char *cut_path(char *in)
 {
        char *p, *ret = in;
@@ -795,6 +798,26 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo
        zap_mutex_lock(zchan->mutex);
 
        switch(command) {
+
+       case ZAP_COMMAND_ENABLE_CALLERID_DETECT:
+               {
+                       if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_CALLERID)) {
+                               if (zap_fsk_demod_init(&zchan->fsk, zchan->rate, zchan->fsk_buf, sizeof(zchan->fsk_buf)) != ZAP_SUCCESS) {
+                                       snprintf(zchan->last_error, sizeof(zchan->last_error), "%s", strerror(errno));
+                                       GOTO_STATUS(done, ZAP_FAIL);
+                               }
+                               zap_set_flag_locked(zchan, ZAP_CHANNEL_CALLERID_DETECT);
+                       }
+               }
+               break;
+       case ZAP_COMMAND_DISABLE_CALLERID_DETECT:
+               {
+                       if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_CALLERID)) {
+                               zap_fsk_demod_destroy(&zchan->fsk);
+                               zap_clear_flag_locked(zchan, ZAP_CHANNEL_CALLERID_DETECT);
+                       }
+               }
+               break;
        case ZAP_COMMAND_TRACE_INPUT:
                {
                        char *path = (char *) obj;
@@ -1285,7 +1308,8 @@ zap_status_t zap_channel_read(zap_channel_t *zchan, void *data, zap_size_t *data
                }
        }
 
-       if (zap_test_flag(zchan, ZAP_CHANNEL_DTMF_DETECT) || zap_test_flag(zchan, ZAP_CHANNEL_PROGRESS_DETECT)) {
+       if (zap_test_flag(zchan, ZAP_CHANNEL_DTMF_DETECT) || zap_test_flag(zchan, ZAP_CHANNEL_PROGRESS_DETECT) || 
+               zap_test_flag(zchan, ZAP_CHANNEL_CALLERID_DETECT)) {
                uint8_t sln_buf[1024] = {0};
                int16_t *sln;
                zap_size_t slen = 0;
@@ -1319,6 +1343,61 @@ zap_status_t zap_channel_read(zap_channel_t *zchan, void *data, zap_size_t *data
                        slen = len;
                }
 
+               if (zap_test_flag(zchan, ZAP_CHANNEL_CALLERID_DETECT)) {
+                       if (zap_fsk_demod_feed(&zchan->fsk, sln, slen) != ZAP_SUCCESS) {
+                               uint32_t type, mlen;
+                               char str[128], *sp;
+
+
+                               while(zap_fsk_data_parse(&zchan->fsk, &type, &sp, &mlen) == ZAP_SUCCESS) {
+                                       *(str+mlen) = '\0';
+                                       zap_copy_string(str, sp, ++mlen);
+                                       zap_clean_string(str);
+                                       zap_log(ZAP_LOG_DEBUG, "FSK: TYPE %s LEN %d VAL [%s]\n", zap_mdmf_type2str(type), mlen-1, str);
+                                       
+                                       switch(type) {
+                                       case MDMF_DDN:
+                                       case MDMF_PHONE_NUM:
+                                               {
+                                                       if (mlen > sizeof(zchan->caller_data.ani)) {
+                                                               mlen = sizeof(zchan->caller_data.ani);
+                                                       }
+                                                       zap_set_string(zchan->caller_data.ani, str);
+                                                       zap_set_string(zchan->caller_data.cid_num, zchan->caller_data.ani);
+                                               }
+                                               break;
+                                       case MDMF_NO_NUM:
+                                               {
+                                                       zap_set_string(zchan->caller_data.ani, *str == 'P' ? "private" : "unknown");
+                                                       zap_set_string(zchan->caller_data.cid_name, zchan->caller_data.ani);
+                                               }
+                                               break;
+                                       case MDMF_PHONE_NAME:
+                                               {
+                                                       if (mlen > sizeof(zchan->caller_data.cid_name)) {
+                                                               mlen = sizeof(zchan->caller_data.cid_name);
+                                                       }
+                                                       zap_set_string(zchan->caller_data.cid_name, str);
+                                               }
+                                               break;
+                                       case MDMF_NO_NAME:
+                                               {
+                                                       zap_set_string(zchan->caller_data.cid_name, *str == 'P' ? "private" : "unknown");
+                                               }
+                                       case MDMF_DATETIME:
+                                               {
+                                                       if (mlen > sizeof(zchan->caller_data.cid_date)) {
+                                                               mlen = sizeof(zchan->caller_data.cid_date);
+                                                       }
+                                                       zap_set_string(zchan->caller_data.cid_date, str);
+                                               }
+                                               break;
+                                       }
+                               }
+                               zap_channel_command(zchan, ZAP_COMMAND_DISABLE_CALLERID_DETECT, NULL);
+                       }
+               }
+
                if (zap_test_flag(zchan, ZAP_CHANNEL_PROGRESS_DETECT)) {
                        uint32_t i;
                        
index 4edce625cd89735e6aa56fcc8ced9c08c62f58bd..b9acfc2b0c2adae68929b2da55c9e60c8ea96944 100644 (file)
@@ -358,12 +358,13 @@ static unsigned wp_open_range(zap_span_t *span, unsigned spanno, unsigned start,
                                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);
-                               
+#if 0                          
                                if (type == ZAP_CHAN_TYPE_FXS) {
                                        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;
                                        wp_tdm_cmd_exec(chan, &tdm_api);
                                }
+#endif
 
                                tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_HW_CODING;
                                wp_tdm_cmd_exec(chan, &tdm_api);