root/src/ftmod/ftmod_analog/ftmod_analog.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. FIO_CHANNEL_OUTGOING_CALL_FUNCTION
  2. FIO_CHANNEL_OUTGOING_CALL_FUNCTION
  3. FIO_CHANNEL_GET_SIG_STATUS_FUNCTION
  4. FIO_SPAN_GET_SIG_STATUS_FUNCTION
  5. ftdm_analog_start
  6. ftdm_analog_stop
  7. FIO_SIG_CONFIGURE_FUNCTION
  8. teletone_handler
  9. send_caller_id
  10. ftdm_analog_channel_run
  11. process_event
  12. ftdm_analog_run
  13. FIO_SIG_LOAD_FUNCTION

   1 /*
   2  * Copyright (c) 2007, Anthony Minessale II
   3  * All rights reserved.
   4  * 
   5  * Redistribution and use in source and binary forms, with or without
   6  * modification, are permitted provided that the following conditions
   7  * are met:
   8  * 
   9  * * Redistributions of source code must retain the above copyright
  10  * notice, this list of conditions and the following disclaimer.
  11  * 
  12  * * Redistributions in binary form must reproduce the above copyright
  13  * notice, this list of conditions and the following disclaimer in the
  14  * documentation and/or other materials provided with the distribution.
  15  * 
  16  * * Neither the name of the original author; nor the names of any contributors
  17  * may be used to endorse or promote products derived from this software
  18  * without specific prior written permission.
  19  * 
  20  * 
  21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  24  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
  25  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  26  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  27  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  28  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  29  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  30  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  31  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32  */
  33 
  34 #include "private/ftdm_core.h"
  35 #include "ftdm_analog.h"
  36 
  37 #ifndef localtime_r
  38 struct tm * localtime_r(const time_t *clock, struct tm *result);
  39 #endif
  40 
  41 static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj);
  42 
  43 /**
  44  * \brief Starts an FXO channel thread (outgoing call)
  45  * \param ftdmchan Channel to initiate call on
  46  * \return Success or failure
  47  *
  48  * Initialises state, starts tone progress detection and runs the channel in a new a thread.
  49  */
  50 static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(analog_fxo_outgoing_call)
  51 {
  52         if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) && !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INTHREAD)) {              
  53                 ftdm_channel_clear_needed_tones(ftdmchan);
  54                 ftdm_channel_clear_detected_tones(ftdmchan);
  55 
  56                 ftdm_channel_command(ftdmchan, FTDM_COMMAND_OFFHOOK, NULL);
  57                 ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_PROGRESS_DETECT, NULL);
  58                 ftdmchan->needed_tones[FTDM_TONEMAP_DIAL] = 1;
  59                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DIALING);
  60                 ftdm_thread_create_detached(ftdm_analog_channel_run, ftdmchan);
  61                 return FTDM_SUCCESS;
  62         }
  63 
  64         return FTDM_FAIL;
  65 }
  66 
  67 /**
  68  * \brief Starts an FXS channel thread (outgoing call)
  69  * \param ftdmchan Channel to initiate call on
  70  * \return Success or failure
  71  *
  72  * Indicates call waiting if channel is already in use, otherwise runs the channel in a new thread.
  73  */
  74 static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(analog_fxs_outgoing_call)
  75 {
  76 
  77         if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INTHREAD)) {
  78                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_CALLWAITING);
  79         } else {
  80                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_GENRING);
  81                 ftdm_thread_create_detached(ftdm_analog_channel_run, ftdmchan);
  82         }
  83 
  84         return FTDM_SUCCESS;
  85 }
  86 
  87 /**
  88  * \brief Returns the signalling status on a channel
  89  * \param ftdmchan Channel to get status on
  90  * \param status        Pointer to set signalling status
  91  * \return Success or failure
  92  */
  93 
  94 static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(analog_get_channel_sig_status)
  95 {
  96         *status = FTDM_SIG_STATE_UP;
  97         return FTDM_SUCCESS;
  98 }
  99 
 100 /**
 101  * \brief Returns the signalling status on a span
 102  * \param span Span to get status on
 103  * \param status        Pointer to set signalling status
 104  * \return Success or failure
 105  */
 106 
 107 static FIO_SPAN_GET_SIG_STATUS_FUNCTION(analog_get_span_sig_status)
 108 {
 109         *status = FTDM_SIG_STATE_UP;
 110         return FTDM_SUCCESS;
 111 }
 112 
 113 /**
 114  * \brief Starts an analog span thread (monitor)
 115  * \param span Span to monitor
 116  * \return Success or failure
 117  */
 118 static ftdm_status_t ftdm_analog_start(ftdm_span_t *span)
 119 {
 120         ftdm_analog_data_t *analog_data = span->signal_data;
 121         ftdm_set_flag(analog_data, FTDM_ANALOG_RUNNING);
 122         return ftdm_thread_create_detached(ftdm_analog_run, span);
 123 }
 124 
 125 /**
 126  * \brief Stops the analog span thread (monitor)
 127  * \param span Span to stop 
 128  * \return Success or failure
 129  */
 130 static ftdm_status_t ftdm_analog_stop(ftdm_span_t *span)
 131 {
 132         ftdm_analog_data_t *analog_data = span->signal_data;
 133         int32_t sanity = 100;
 134         while (ftdm_test_flag(analog_data, FTDM_ANALOG_RUNNING) && sanity--) {
 135                 ftdm_sleep(100);
 136                 ftdm_log(FTDM_LOG_DEBUG, "Waiting for analog thread for span %s to stop\n", span->name);
 137         }
 138 
 139         if (!sanity) {
 140                 ftdm_log(FTDM_LOG_ERROR, "The analog thread for span %s is probably still running, we may crash :(\n", span->name);
 141                 return FTDM_FAIL;
 142         }
 143         return FTDM_SUCCESS;
 144 }
 145 
 146 /**
 147  * \brief Initialises an analog span from configuration variables
 148  * \param span Span to configure
 149  * \param sig_cb Callback function for event signals
 150  * \param ap List of configuration variables
 151  * \return Success or failure
 152  */
 153 static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_configure_span)
 154 //ftdm_status_t ftdm_analog_configure_span(ftdm_span_t *span, char *tonemap, uint32_t digit_timeout, uint32_t max_dialstr, fio_signal_cb_t sig_cb)
 155 {
 156         ftdm_analog_data_t *analog_data;
 157         const char *tonemap = "us";
 158         const char *hotline = "";
 159         uint32_t digit_timeout = 10;
 160         uint32_t max_dialstr = MAX_DTMF;
 161         const char *var, *val;
 162         int *intval;
 163         uint32_t flags = FTDM_ANALOG_CALLERID;
 164         int callwaiting = 1;
 165         unsigned int i = 0;
 166 
 167         assert(sig_cb != NULL);
 168         ftdm_log(FTDM_LOG_DEBUG, "Configuring span %s for analog signaling ...\n", span->name);
 169 
 170         if (span->signal_type) {
 171                 ftdm_log(FTDM_LOG_ERROR, "Span %s is already configured for signaling %d\n", span->name, span->signal_type);
 172                 snprintf(span->last_error, sizeof(span->last_error), "Span is already configured for signalling.");
 173                 return FTDM_FAIL;
 174         }
 175         
 176         analog_data = ftdm_malloc(sizeof(*analog_data));
 177         
 178         ftdm_assert_return(analog_data != NULL, FTDM_FAIL, "malloc failure\n");
 179 
 180         memset(analog_data, 0, sizeof(*analog_data));
 181 
 182         while ((var = va_arg(ap, char *))) {
 183                 ftdm_log(FTDM_LOG_DEBUG, "Analog config var = %s\n", var);
 184                 if (!strcasecmp(var, "tonemap")) {
 185                         if (!(val = va_arg(ap, char *))) {
 186                                 break;
 187                         }
 188                         tonemap = val;
 189                 } else if (!strcasecmp(var, "digit_timeout")) {
 190                         if (!(intval = va_arg(ap, int *))) {
 191                                 break;
 192                         }
 193                         digit_timeout = *intval;
 194                 } else if (!strcasecmp(var, "enable_callerid")) {
 195                         if (!(val = va_arg(ap, char *))) {
 196                                 break;
 197                         }
 198                         
 199                         if (ftdm_true(val)) {
 200                                 flags |= FTDM_ANALOG_CALLERID;
 201                         } else {
 202                                 flags &= ~FTDM_ANALOG_CALLERID;
 203                         }
 204                 } else if (!strcasecmp(var, "callwaiting")) {
 205                         if (!(intval = va_arg(ap, int *))) {
 206                                 break;
 207                         }
 208                         callwaiting = *intval;
 209                 } else if (!strcasecmp(var, "max_dialstr")) {
 210                         if (!(intval = va_arg(ap, int *))) {
 211                                 break;
 212                         }
 213                         max_dialstr = *intval;
 214                 } else if (!strcasecmp(var, "hotline")) {
 215                         if (!(val = va_arg(ap, char *))) {
 216                                 break;
 217                         }
 218                         hotline = val;
 219                 } else {
 220                         ftdm_log(FTDM_LOG_ERROR, "Unknown parameter %s in span %s\n", var, span->name);
 221                 }                       
 222         }
 223 
 224 
 225         if (digit_timeout < 2000 || digit_timeout > 10000) {
 226                 digit_timeout = 2000;
 227         }
 228 
 229         if ((max_dialstr < 1 && !strlen(hotline)) || max_dialstr > MAX_DTMF) {
 230                 max_dialstr = MAX_DTMF;
 231         }
 232 
 233         if (callwaiting) {
 234                 for (i = 1; i <= span->chan_count; i++) {
 235                         ftdm_log_chan_msg(span->channels[i], FTDM_LOG_DEBUG, "Enabled call waiting\n");
 236                         ftdm_channel_set_feature(span->channels[i], FTDM_CHANNEL_FEATURE_CALLWAITING);
 237                 }
 238         }
 239         
 240         span->start = ftdm_analog_start;
 241         span->stop = ftdm_analog_stop;
 242         analog_data->flags = flags;
 243         analog_data->digit_timeout = digit_timeout;
 244         analog_data->max_dialstr = max_dialstr;
 245         span->signal_cb = sig_cb;
 246         strncpy(analog_data->hotline, hotline, sizeof(analog_data->hotline));
 247         span->signal_type = FTDM_SIGTYPE_ANALOG;
 248         span->signal_data = analog_data;
 249         span->outgoing_call = span->trunk_type == FTDM_TRUNK_FXS ? analog_fxs_outgoing_call : analog_fxo_outgoing_call;
 250         span->get_channel_sig_status = analog_get_channel_sig_status;
 251         span->get_span_sig_status = analog_get_span_sig_status;
 252 
 253         ftdm_span_load_tones(span, tonemap);
 254 
 255         ftdm_log(FTDM_LOG_DEBUG, "Configuration of analog signaling for span %s is done\n", span->name);
 256         return FTDM_SUCCESS;
 257 
 258 }
 259 
 260 /**
 261  * \brief Retrieves tone generation output to be sent
 262  * \param ts Teletone generator
 263  * \param map Tone map
 264  * \return -1 on error, 0 on success
 265  */
 266 static int teletone_handler(teletone_generation_session_t *ts, teletone_tone_map_t *map)
 267 {
 268         ftdm_buffer_t *dt_buffer = ts->user_data;
 269         int wrote;
 270 
 271         if (!dt_buffer) {
 272                 return -1;
 273         }
 274         wrote = teletone_mux_tones(ts, map);
 275         ftdm_buffer_write(dt_buffer, ts->buffer, wrote * 2);
 276         return 0;
 277 }
 278 
 279 /**
 280  * \brief Sends caller id on an analog channel (FSK coded)
 281  * \param ftdmchan Channel to send caller id on
 282  */
 283 static void send_caller_id(ftdm_channel_t *ftdmchan)
 284 {
 285         ftdm_fsk_data_state_t fsk_data;
 286         uint8_t databuf[1024] = "";
 287         char time_str[9];
 288         struct tm tm;
 289         time_t now;
 290         ftdm_mdmf_type_t mt = MDMF_INVALID;
 291 
 292         time(&now);
 293 #ifdef WIN32
 294         _tzset();
 295         _localtime64_s(&tm, &now);
 296 #else
 297         localtime_r(&now, &tm);
 298 #endif
 299         strftime(time_str, sizeof(time_str), "%m%d%H%M", &tm);
 300 
 301         ftdm_fsk_data_init(&fsk_data, databuf, sizeof(databuf));
 302         ftdm_fsk_data_add_mdmf(&fsk_data, MDMF_DATETIME, (uint8_t *) time_str, 8);
 303                                         
 304         if (ftdm_strlen_zero(ftdmchan->caller_data.cid_num.digits)) {
 305                 mt = MDMF_NO_NUM;
 306                 ftdm_set_string(ftdmchan->caller_data.cid_num.digits, "O");
 307         } else if (!strcasecmp(ftdmchan->caller_data.cid_num.digits, "P") || !strcasecmp(ftdmchan->caller_data.cid_num.digits, "O")) {
 308                 mt = MDMF_NO_NUM;
 309         } else {
 310                 mt = MDMF_PHONE_NUM;
 311         }
 312         ftdm_fsk_data_add_mdmf(&fsk_data, mt, (uint8_t *) ftdmchan->caller_data.cid_num.digits, (uint8_t)strlen(ftdmchan->caller_data.cid_num.digits));
 313 
 314         if (ftdm_strlen_zero(ftdmchan->caller_data.cid_name)) {
 315                 mt = MDMF_NO_NAME;
 316                 ftdm_set_string(ftdmchan->caller_data.cid_name, "O");
 317         } else if (!strcasecmp(ftdmchan->caller_data.cid_name, "P") || !strcasecmp(ftdmchan->caller_data.cid_name, "O")) {
 318                 mt = MDMF_NO_NAME;
 319         } else {
 320                 mt = MDMF_PHONE_NAME;
 321         }
 322         ftdm_fsk_data_add_mdmf(&fsk_data, mt, (uint8_t *) ftdmchan->caller_data.cid_name, (uint8_t)strlen(ftdmchan->caller_data.cid_name));
 323                                         
 324         ftdm_fsk_data_add_checksum(&fsk_data);
 325         ftdm_channel_send_fsk_data(ftdmchan, &fsk_data, -14);
 326 }
 327 
 328 /**
 329  * \brief Main thread function for analog channel (outgoing call)
 330  * \param me Current thread
 331  * \param obj Channel to run in this thread
 332  */
 333 static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
 334 {
 335         ftdm_channel_t *ftdmchan = (ftdm_channel_t *) obj;
 336         ftdm_buffer_t *dt_buffer = NULL;
 337         teletone_generation_session_t ts;
 338         uint8_t frame[1024];
 339         ftdm_size_t len, rlen;
 340         ftdm_tone_type_t tt = FTDM_TONE_DTMF;
 341         char dtmf[MAX_DTMF+1] = "";
 342         ftdm_size_t dtmf_offset = 0;
 343         ftdm_analog_data_t *analog_data = ftdmchan->span->signal_data;
 344         ftdm_channel_t *closed_chan;
 345         uint32_t state_counter = 0, elapsed = 0, collecting = 0, interval = 0, last_digit = 0, indicate = 0, dial_timeout = 30000;
 346         ftdm_sigmsg_t sig;
 347         ftdm_status_t status;
 348         
 349         ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "ANALOG CHANNEL thread starting.\n");
 350 
 351         ts.buffer = NULL;
 352 
 353         if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) {
 354                 ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "OPEN ERROR [%s]\n", ftdmchan->last_error);
 355                 goto done;
 356         }
 357 
 358         if (ftdm_buffer_create(&dt_buffer, 1024, 3192, 0) != FTDM_SUCCESS) {
 359                 snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "memory error!");
 360                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "MEM ERROR\n");
 361                 goto done;
 362         }
 363 
 364         if (ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_DTMF_DETECT, &tt) != FTDM_SUCCESS) {
 365                 snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "error initilizing tone detector!");
 366                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "failed to initialize DTMF detector\n");
 367                 goto done;
 368         }
 369         ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Initialized DTMF detection\n");
 370 
 371         ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_INTHREAD);
 372         teletone_init_session(&ts, 0, teletone_handler, dt_buffer);
 373         ts.rate = 8000;
 374 #if 0
 375         ts.debug = 1;
 376         ts.debug_stream = stdout;
 377 #endif
 378         ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_INTERVAL, &interval);
 379         ftdm_buffer_set_loops(dt_buffer, -1);
 380         
 381         memset(&sig, 0, sizeof(sig));
 382         sig.chan_id = ftdmchan->chan_id;
 383         sig.span_id = ftdmchan->span_id;
 384         sig.channel = ftdmchan;
 385         
 386         assert(interval != 0);
 387 
 388         while (ftdm_running() && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INTHREAD)) {
 389                 ftdm_wait_flag_t flags = FTDM_READ;
 390                 ftdm_size_t dlen = 0;
 391                 
 392                 len = sizeof(frame);
 393                 
 394                 elapsed += interval;
 395                 state_counter += interval;
 396                 
 397                 if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
 398                         switch(ftdmchan->state) {
 399                         case FTDM_CHANNEL_STATE_GET_CALLERID:
 400                                 {
 401                                         if (state_counter > 5000 || !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_CALLERID_DETECT)) {
 402                                                 ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_CALLERID_DETECT, NULL);
 403                                                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE);
 404                                         }
 405                                 }
 406                                 break;
 407                         case FTDM_CHANNEL_STATE_DIALING:
 408                                 {
 409                                         if (state_counter > dial_timeout) {
 410                                                 if (ftdmchan->needed_tones[FTDM_TONEMAP_DIAL]) {
 411                                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY);
 412                                                 } else {
 413                                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP);
 414                                                 }
 415                                         } 
 416                                 }
 417                                 break;
 418                         case FTDM_CHANNEL_STATE_GENRING:
 419                                 {
 420                                         if (state_counter > 60000) {
 421                                                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
 422                                         } else if (!ftdmchan->fsk_buffer || !ftdm_buffer_inuse(ftdmchan->fsk_buffer)) {
 423                                                 ftdm_sleep(interval);
 424                                                 continue;
 425                                         }
 426                                 }
 427                                 break;
 428                         case FTDM_CHANNEL_STATE_DIALTONE:
 429                                 {
 430                                         if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_HOLD) && state_counter > 10000) {
 431                                                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY);
 432                                         }
 433                                 }
 434                                 break;
 435                         case FTDM_CHANNEL_STATE_BUSY:
 436                                 {
 437                                         if (state_counter > 20000) {
 438                                                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_ATTN);
 439                                         }
 440                                 }
 441                                 break;
 442                         case FTDM_CHANNEL_STATE_ATTN:
 443                                 {
 444                                         if (state_counter > 20000) {
 445                                                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
 446                                         }
 447                                 }
 448                                 break;
 449                         case FTDM_CHANNEL_STATE_HANGUP:
 450                                 {
 451                                         if (state_counter > 500) {
 452                                                 if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_RINGING)) {
 453                                                         ftdm_channel_command(ftdmchan, FTDM_COMMAND_GENERATE_RING_OFF, NULL);
 454                                                 }
 455                                                 
 456                                                 if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) && 
 457                                                         (ftdmchan->last_state == FTDM_CHANNEL_STATE_RING || ftdmchan->last_state == FTDM_CHANNEL_STATE_DIALTONE 
 458                                                          || ftdmchan->last_state >= FTDM_CHANNEL_STATE_IDLE)) {
 459                                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY);
 460                                                 } else {
 461                                                         ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_CLEARING;
 462                                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
 463                                                 }
 464                                         }
 465                                 }
 466                                 break;
 467                         case FTDM_CHANNEL_STATE_CALLWAITING:
 468                                 {
 469                                         int done = 0;
 470                                         
 471                                         if (ftdmchan->detected_tones[FTDM_TONEMAP_CALLWAITING_ACK] == 1) {
 472                                                 send_caller_id(ftdmchan);
 473                                                 ftdmchan->detected_tones[FTDM_TONEMAP_CALLWAITING_ACK]++;
 474                                         } else if (state_counter > 600 && !ftdmchan->detected_tones[FTDM_TONEMAP_CALLWAITING_ACK]) {
 475                                                 send_caller_id(ftdmchan);
 476                                                 ftdmchan->detected_tones[FTDM_TONEMAP_CALLWAITING_ACK]++;
 477                                         } else if (state_counter > 1000 && !ftdmchan->detected_tones[FTDM_TONEMAP_CALLWAITING_ACK]) {
 478                                                 done = 1;
 479                                         } else if (state_counter > 10000) {
 480                                                 if (ftdmchan->fsk_buffer) {
 481                                                         ftdm_buffer_zero(ftdmchan->fsk_buffer);
 482                                                 } else {
 483                                                         ftdm_buffer_create(&ftdmchan->fsk_buffer, 128, 128, 0);
 484                                                 }
 485                                                 
 486                                                 ts.user_data = ftdmchan->fsk_buffer;
 487                                                 teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_CALLWAITING_SAS]);
 488                                                 ts.user_data = dt_buffer;
 489                                                 done = 1;
 490                                         }
 491 
 492                                         if (done) {
 493                                                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP);
 494                                                 ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_STATE_CHANGE);
 495                                                 ftdm_clear_flag_locked(ftdmchan->span, FTDM_SPAN_STATE_CHANGE);
 496                                                 ftdmchan->detected_tones[FTDM_TONEMAP_CALLWAITING_ACK] = 0;
 497                                         }
 498                                 }
 499                         case FTDM_CHANNEL_STATE_UP:
 500                         case FTDM_CHANNEL_STATE_IDLE:
 501                                 {
 502                                         ftdm_sleep(interval);
 503                                         continue;
 504                                 }
 505                                 break;
 506                         case FTDM_CHANNEL_STATE_DOWN:
 507                                 {
 508                                         goto done;
 509                                 }
 510                                 break;
 511                         default:
 512                                 break;
 513                         }
 514                 } else {
 515                         ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_STATE_CHANGE);
 516                         ftdm_clear_flag_locked(ftdmchan->span, FTDM_SPAN_STATE_CHANGE);
 517                         ftdm_channel_complete_state(ftdmchan);
 518                         indicate = 0;
 519                         state_counter = 0;
 520 
 521                         ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Executing state handler on %d:%d for %s\n", 
 522                                         ftdmchan->span_id, ftdmchan->chan_id,
 523                                         ftdm_channel_state2str(ftdmchan->state));
 524                         switch(ftdmchan->state) {
 525                         case FTDM_CHANNEL_STATE_UP:
 526                                 {
 527                                         ftdm_channel_use(ftdmchan);
 528                                         ftdm_channel_clear_needed_tones(ftdmchan);
 529                                         ftdm_channel_flush_dtmf(ftdmchan);
 530                                                 
 531                                         if (ftdmchan->type == FTDM_CHAN_TYPE_FXO && !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK)) {
 532                                                 ftdm_channel_command(ftdmchan, FTDM_COMMAND_OFFHOOK, NULL);
 533                                         }
 534 
 535                                         if (ftdmchan->fsk_buffer && ftdm_buffer_inuse(ftdmchan->fsk_buffer)) {
 536                                                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Cancel FSK transmit due to early answer.\n");
 537                                                 ftdm_buffer_zero(ftdmchan->fsk_buffer);
 538                                         }
 539 
 540                                         if (ftdmchan->type == FTDM_CHAN_TYPE_FXS && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_RINGING)) {
 541                                                 ftdm_channel_command(ftdmchan, FTDM_COMMAND_GENERATE_RING_OFF, NULL);
 542                                         }
 543 
 544                                         if (ftdmchan->token_count == 1) {
 545                                                 ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_HOLD);
 546                                         }
 547 
 548                                         if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_HOLD)) {
 549                                                 ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_HOLD);
 550                                                 sig.event_id = FTDM_SIGEVENT_ADD_CALL;
 551                                         } else {
 552                                                 sig.event_id = FTDM_SIGEVENT_UP;
 553                                         }
 554 
 555                                         ftdm_span_send_signal(ftdmchan->span, &sig);
 556                                         continue;
 557                                 }
 558                                 break;
 559                         case FTDM_CHANNEL_STATE_DIALING:
 560                                 {
 561                                         ftdm_channel_use(ftdmchan);
 562                                 }
 563                                 break;
 564                         case FTDM_CHANNEL_STATE_IDLE:
 565                                 {
 566                                         ftdm_channel_use(ftdmchan);
 567                                         sig.event_id = FTDM_SIGEVENT_START;
 568 
 569                                         if (ftdmchan->type == FTDM_CHAN_TYPE_FXO) {
 570                                                 ftdm_set_string(ftdmchan->caller_data.dnis.digits, ftdmchan->chan_number);
 571                                         } else {
 572                                                 ftdm_set_string(ftdmchan->caller_data.dnis.digits, dtmf);
 573                                         }
 574 
 575                                         ftdm_span_send_signal(ftdmchan->span, &sig);
 576                                         continue;
 577                                 }
 578                                 break;
 579                         case FTDM_CHANNEL_STATE_DOWN:
 580                                 {
 581                                         sig.event_id = FTDM_SIGEVENT_STOP;
 582                                         ftdm_span_send_signal(ftdmchan->span, &sig);
 583                                         goto done;
 584                                 }
 585                                 break;
 586                         case FTDM_CHANNEL_STATE_DIALTONE:
 587                                 {
 588                                         memset(&ftdmchan->caller_data, 0, sizeof(ftdmchan->caller_data));
 589                                         *dtmf = '\0';
 590                                         dtmf_offset = 0;
 591                                         ftdm_buffer_zero(dt_buffer);
 592                                         teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_DIAL]);
 593                                         indicate = 1;
 594                                 }
 595                                 break;
 596                         case FTDM_CHANNEL_STATE_CALLWAITING:
 597                                 {
 598                                         ftdmchan->detected_tones[FTDM_TONEMAP_CALLWAITING_ACK] = 0;
 599                                         if (ftdmchan->fsk_buffer) {
 600                                                 ftdm_buffer_zero(ftdmchan->fsk_buffer);
 601                                         } else {
 602                                                 ftdm_buffer_create(&ftdmchan->fsk_buffer, 128, 128, 0);
 603                                         }
 604                                         
 605                                         ts.user_data = ftdmchan->fsk_buffer;
 606                                         teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_CALLWAITING_SAS]);
 607                                         teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_CALLWAITING_CAS]);
 608                                         ts.user_data = dt_buffer;
 609                                 }
 610                                 break;
 611                         case FTDM_CHANNEL_STATE_GENRING:
 612                                 {
 613                                         ftdm_sigmsg_t sig;
 614 
 615                                         send_caller_id(ftdmchan);
 616                                         ftdm_channel_command(ftdmchan, FTDM_COMMAND_GENERATE_RING_ON, NULL);
 617 
 618                                         memset(&sig, 0, sizeof(sig));
 619                                         sig.chan_id = ftdmchan->chan_id;
 620                                         sig.span_id = ftdmchan->span_id;
 621                                         sig.channel = ftdmchan;
 622                                         sig.event_id = FTDM_SIGEVENT_PROGRESS;
 623                                         ftdm_span_send_signal(ftdmchan->span, &sig);
 624                                         
 625                                 }
 626                                 break;
 627                         case FTDM_CHANNEL_STATE_GET_CALLERID:
 628                                 {
 629                                         memset(&ftdmchan->caller_data, 0, sizeof(ftdmchan->caller_data));
 630                                         ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_CALLERID_DETECT, NULL);
 631                                         continue;
 632                                 }
 633                                 break;
 634                         case FTDM_CHANNEL_STATE_RING:
 635                                 {
 636                                         ftdm_buffer_zero(dt_buffer);
 637                                         teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_RING]);
 638                                         indicate = 1;
 639                                         
 640                                 }
 641                                 break;
 642                         case FTDM_CHANNEL_STATE_BUSY:
 643                                 {
 644                                         ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_CIRCUIT_CONGESTION;
 645                                         if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) && !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
 646                                                 ftdm_buffer_zero(dt_buffer);
 647                                                 teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_BUSY]);
 648                                                 indicate = 1;
 649                                         } else {
 650                                                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
 651                                         }
 652                                 }
 653                                 break;
 654                         case FTDM_CHANNEL_STATE_ATTN:
 655                                 {
 656                                         if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) && !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
 657                                                 ftdm_buffer_zero(dt_buffer);
 658                                                 teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_ATTN]);
 659                                                 indicate = 1;
 660                                         } else {
 661                                                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
 662                                         }
 663                                 }
 664                                 break;
 665                         default:
 666                                 break;
 667                         }
 668                 }
 669 
 670 
 671                 if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALTONE || ftdmchan->state == FTDM_CHANNEL_STATE_COLLECT) {
 672                         if ((dlen = ftdm_channel_dequeue_dtmf(ftdmchan, dtmf + dtmf_offset, sizeof(dtmf) - strlen(dtmf)))) {
 673 
 674                                 if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALTONE) {
 675                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_COLLECT);
 676                                         collecting = 1;
 677                                 }
 678                                 dtmf_offset = strlen(dtmf);
 679                                 last_digit = elapsed;
 680                                 sig.event_id = FTDM_SIGEVENT_COLLECTED_DIGIT;
 681                                 sig.raw_data = dtmf;
 682                                 if (ftdm_span_send_signal(ftdmchan->span, &sig) == FTDM_BREAK) {
 683                                         collecting = 0;
 684                                 }
 685                         }
 686                         else if(!analog_data->max_dialstr)
 687                         {
 688                                 last_digit = elapsed;
 689                                 collecting = 0;
 690                                 strcpy(dtmf, analog_data->hotline);
 691                         }
 692                 }
 693 
 694 
 695                 if (last_digit && (!collecting || ((elapsed - last_digit > analog_data->digit_timeout) || strlen(dtmf) >= analog_data->max_dialstr))) {
 696                         ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Number obtained [%s]\n", dtmf);
 697                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE);
 698                         last_digit = 0;
 699                         collecting = 0;
 700                 }
 701 
 702                 if (ftdm_channel_wait(ftdmchan, &flags, interval * 2) != FTDM_SUCCESS) {
 703                         continue;
 704                 }
 705 
 706                 if (!(flags & FTDM_READ)) {
 707                         continue;
 708                 }
 709 
 710                 if (ftdm_channel_read(ftdmchan, frame, &len) != FTDM_SUCCESS) {
 711                         ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "read error [%s]\n", ftdmchan->last_error);
 712                         continue;
 713                 }
 714 
 715                 if (ftdmchan->type == FTDM_CHAN_TYPE_FXO && ftdmchan->detected_tones[0]) {
 716                         int i;
 717                         
 718                         for (i = 1; i < FTDM_TONEMAP_INVALID; i++) {
 719                                 if (ftdmchan->detected_tones[i]) {
 720                                         ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Detected tone %s on %d:%d\n", ftdm_tonemap2str(i), ftdmchan->span_id, ftdmchan->chan_id);
 721                                 }
 722                         }
 723                         
 724                         if (ftdmchan->detected_tones[FTDM_TONEMAP_BUSY] || 
 725                                 ftdmchan->detected_tones[FTDM_TONEMAP_FAIL1] ||
 726                                 ftdmchan->detected_tones[FTDM_TONEMAP_FAIL2] ||
 727                                 ftdmchan->detected_tones[FTDM_TONEMAP_FAIL3] ||
 728                                 ftdmchan->detected_tones[FTDM_TONEMAP_ATTN]
 729                                 ) {
 730                                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failure indication detected!\n");
 731                                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY);
 732                         } else if (ftdmchan->detected_tones[FTDM_TONEMAP_DIAL]) {
 733                                 if (ftdm_strlen_zero(ftdmchan->caller_data.dnis.digits)) {
 734                                         ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "No Digits to send!\n");
 735                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY);
 736                                 } else {
 737                                         if (ftdm_channel_command(ftdmchan, FTDM_COMMAND_SEND_DTMF, ftdmchan->caller_data.dnis.digits) != FTDM_SUCCESS) {
 738                                                 ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Send Digits Failed [%s]\n", ftdmchan->last_error);
 739                                                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY);
 740                                         } else {
 741                                                 state_counter = 0;
 742                                                 ftdmchan->needed_tones[FTDM_TONEMAP_RING] = 1;
 743                                                 ftdmchan->needed_tones[FTDM_TONEMAP_BUSY] = 1;
 744                                                 ftdmchan->needed_tones[FTDM_TONEMAP_FAIL1] = 1;
 745                                                 ftdmchan->needed_tones[FTDM_TONEMAP_FAIL2] = 1;
 746                                                 ftdmchan->needed_tones[FTDM_TONEMAP_FAIL3] = 1;
 747                                                 dial_timeout = ((ftdmchan->dtmf_on + ftdmchan->dtmf_off) * strlen(ftdmchan->caller_data.dnis.digits)) + 2000;
 748                                         }
 749                                 }
 750                         } else if (ftdmchan->detected_tones[FTDM_TONEMAP_RING]) {
 751                                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP);
 752                         }
 753                         
 754                         ftdm_channel_clear_detected_tones(ftdmchan);
 755                 }
 756 
 757                 if ((ftdmchan->dtmf_buffer && ftdm_buffer_inuse(ftdmchan->dtmf_buffer)) || (ftdmchan->fsk_buffer && ftdm_buffer_inuse(ftdmchan->fsk_buffer))) {
 758                         //rlen = len;
 759                         //memset(frame, 0, len);
 760                         //ftdm_channel_write(ftdmchan, frame, sizeof(frame), &rlen);
 761                         continue;
 762                 }
 763                 
 764                 if (!indicate) {
 765                         continue;
 766                 }
 767 
 768                 if (ftdmchan->type == FTDM_CHAN_TYPE_FXO && !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK)) {
 769                         ftdm_channel_command(ftdmchan, FTDM_COMMAND_OFFHOOK, NULL);
 770                 }
 771 
 772                 if (ftdmchan->effective_codec != FTDM_CODEC_SLIN) {
 773                         len *= 2;
 774                 }
 775 
 776                 rlen = ftdm_buffer_read_loop(dt_buffer, frame, len);                                    
 777                 
 778                 if (ftdmchan->effective_codec != FTDM_CODEC_SLIN) {
 779                         fio_codec_t codec_func = NULL;
 780 
 781                         if (ftdmchan->native_codec == FTDM_CODEC_ULAW) {
 782                                 codec_func = fio_slin2ulaw;
 783                         } else if (ftdmchan->native_codec == FTDM_CODEC_ALAW) {
 784                                 codec_func = fio_slin2alaw;
 785                         }
 786 
 787                         if (codec_func) {
 788                                 status = codec_func(frame, sizeof(frame), &rlen);
 789                         } else {
 790                                 snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "codec error!");
 791                                 goto done;
 792                         }
 793                 }
 794 
 795                 ftdm_channel_write(ftdmchan, frame, sizeof(frame), &rlen);
 796         }
 797 
 798  done:
 799 
 800 
 801         if (ftdmchan->type == FTDM_CHAN_TYPE_FXO && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK)) {
 802                 ftdm_channel_command(ftdmchan, FTDM_COMMAND_ONHOOK, NULL);
 803         }
 804 
 805         if (ftdmchan->type == FTDM_CHAN_TYPE_FXS && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_RINGING)) {
 806                 ftdm_channel_command(ftdmchan, FTDM_COMMAND_GENERATE_RING_OFF, NULL);
 807         }
 808 
 809         
 810         closed_chan = ftdmchan;
 811         ftdm_channel_close(&ftdmchan);
 812 
 813         ftdm_channel_command(closed_chan, FTDM_COMMAND_SET_NATIVE_CODEC, NULL);
 814 
 815         if (ts.buffer) {
 816                 teletone_destroy_session(&ts);
 817         }
 818 
 819         if (dt_buffer) {
 820                 ftdm_buffer_destroy(&dt_buffer);
 821         }
 822 
 823         if (closed_chan->state != FTDM_CHANNEL_STATE_DOWN) {
 824                 ftdm_set_state_locked(closed_chan, FTDM_CHANNEL_STATE_DOWN);
 825         }
 826 
 827         ftdm_log_chan(closed_chan, FTDM_LOG_DEBUG, "ANALOG CHANNEL %d:%d thread ended.\n", closed_chan->span_id, closed_chan->chan_id);
 828         ftdm_clear_flag(closed_chan, FTDM_CHANNEL_INTHREAD);
 829 
 830         return NULL;
 831 }
 832 
 833 /**
 834  * \brief Processes freetdm event
 835  * \param span Span on which the event was fired
 836  * \param event Event to be treated
 837  * \return Success or failure
 838  */
 839 static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *event)
 840 {
 841         ftdm_sigmsg_t sig;
 842         ftdm_analog_data_t *analog_data = event->channel->span->signal_data;
 843         int locked = 0;
 844         
 845         memset(&sig, 0, sizeof(sig));
 846         sig.chan_id = event->channel->chan_id;
 847         sig.span_id = event->channel->span_id;
 848         sig.channel = event->channel;
 849 
 850 
 851         ftdm_log_chan(event->channel, FTDM_LOG_DEBUG, "Received event [%s] in state [%s]\n", ftdm_oob_event2str(event->enum_id), ftdm_channel_state2str(event->channel->state));
 852 
 853         ftdm_mutex_lock(event->channel->mutex);
 854         locked++;
 855 
 856         switch(event->enum_id) {
 857         case FTDM_OOB_RING_START:
 858                 {
 859                         if (event->channel->type != FTDM_CHAN_TYPE_FXO) {
 860                                 ftdm_log_chan_msg(event->channel, FTDM_LOG_ERROR, "Cannot get a RING_START event on a non-fxo channel, please check your config.\n");
 861                                 ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_DOWN);
 862                                 goto end;
 863                         }
 864                         if (!event->channel->ring_count && (event->channel->state == FTDM_CHANNEL_STATE_DOWN && !ftdm_test_flag(event->channel, FTDM_CHANNEL_INTHREAD))) {
 865                                 if (ftdm_test_flag(analog_data, FTDM_ANALOG_CALLERID)) {
 866                                         ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_GET_CALLERID);
 867                                 } else {
 868                                         ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_IDLE);
 869                                 }
 870                                 event->channel->ring_count = 1;
 871                                 ftdm_mutex_unlock(event->channel->mutex);
 872                                 locked = 0;
 873                                 ftdm_thread_create_detached(ftdm_analog_channel_run, event->channel);
 874                         } else {
 875                                 event->channel->ring_count++;
 876                         }
 877                 }
 878                 break;
 879         case FTDM_OOB_ONHOOK:
 880                 {
 881                         if (ftdm_test_flag(event->channel, FTDM_CHANNEL_RINGING)) {
 882                                 ftdm_channel_command(event->channel, FTDM_COMMAND_GENERATE_RING_OFF, NULL);
 883                         }
 884 
 885                         if (event->channel->state != FTDM_CHANNEL_STATE_DOWN) {
 886                                 ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_DOWN);
 887                         }
 888 
 889                 }
 890                 break;
 891         case FTDM_OOB_FLASH:
 892                 {
 893                         if (event->channel->state == FTDM_CHANNEL_STATE_CALLWAITING) {
 894                                 ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_UP);
 895                                 ftdm_clear_flag_locked(event->channel, FTDM_CHANNEL_STATE_CHANGE);
 896                                 ftdm_clear_flag_locked(event->channel->span, FTDM_SPAN_STATE_CHANGE);
 897                                 event->channel->detected_tones[FTDM_TONEMAP_CALLWAITING_ACK] = 0;
 898                         } 
 899 
 900                         ftdm_channel_rotate_tokens(event->channel);
 901                         
 902                         if (ftdm_test_flag(event->channel, FTDM_CHANNEL_HOLD) && event->channel->token_count != 1) {
 903                                 ftdm_set_state_locked(event->channel,  FTDM_CHANNEL_STATE_UP);
 904                         } else {
 905                                 sig.event_id = FTDM_SIGEVENT_FLASH;
 906                                 ftdm_span_send_signal(span, &sig);
 907                         }
 908                 }
 909                 break;
 910         case FTDM_OOB_OFFHOOK:
 911                 {
 912                         if (event->channel->type == FTDM_CHAN_TYPE_FXS) {
 913                                 if (ftdm_test_flag(event->channel, FTDM_CHANNEL_INTHREAD)) {
 914                                         if (ftdm_test_flag(event->channel, FTDM_CHANNEL_RINGING)) {
 915                                                 ftdm_channel_command(event->channel, FTDM_COMMAND_GENERATE_RING_OFF, NULL);
 916                                         }
 917                                         ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_UP);
 918                                 } else {
 919                                         if(!analog_data->max_dialstr) {
 920                                                 ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_COLLECT);
 921                                         } else {
 922                                                 ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_DIALTONE);
 923                                         }                                               
 924                                         ftdm_mutex_unlock(event->channel->mutex);
 925                                         locked = 0;
 926                                         ftdm_thread_create_detached(ftdm_analog_channel_run, event->channel);
 927                                 }
 928                         } else {
 929                                 if (!ftdm_test_flag(event->channel, FTDM_CHANNEL_INTHREAD)) {
 930                                         if (ftdm_test_flag(event->channel, FTDM_CHANNEL_OFFHOOK)) {
 931                                                 ftdm_channel_command(event->channel, FTDM_COMMAND_ONHOOK, NULL);
 932                                         }
 933                                 }
 934                                 ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_DOWN);
 935                         }
 936                 }
 937         default:
 938                 {
 939                         ftdm_log_chan(event->channel, FTDM_LOG_DEBUG, "Ignoring event [%s] in state [%s]\n", ftdm_oob_event2str(event->enum_id), ftdm_channel_state2str(event->channel->state));
 940                 }
 941                 break;
 942         }
 943 
 944  end:
 945 
 946         if (locked) {
 947                 ftdm_mutex_unlock(event->channel->mutex);
 948         }
 949         return FTDM_SUCCESS;
 950 }
 951 
 952 /**
 953  * \brief Main thread function for analog span (monitor)
 954  * \param me Current thread
 955  * \param obj Span to run in this thread
 956  */
 957 static void *ftdm_analog_run(ftdm_thread_t *me, void *obj)
 958 {
 959         ftdm_span_t *span = (ftdm_span_t *) obj;
 960         ftdm_analog_data_t *analog_data = span->signal_data;
 961         int errs = 0;
 962         
 963         ftdm_log(FTDM_LOG_DEBUG, "ANALOG thread starting.\n");
 964 
 965         while(ftdm_running() && ftdm_test_flag(analog_data, FTDM_ANALOG_RUNNING)) {
 966                 int waitms = 1000;
 967                 ftdm_status_t status;
 968 
 969                 if ((status = ftdm_span_poll_event(span, waitms)) != FTDM_FAIL) {
 970                         errs = 0;
 971                 }
 972                 
 973                 switch(status) {
 974                 case FTDM_SUCCESS:
 975                         {
 976                                 ftdm_event_t *event;
 977                                 while (ftdm_span_next_event(span, &event) == FTDM_SUCCESS) {
 978                                         if (event->enum_id == FTDM_OOB_NOOP) {
 979                                                 continue;
 980                                         }
 981                                         if (process_event(span, event) != FTDM_SUCCESS) {
 982                                                 goto end;
 983                                         }
 984                                 }
 985                         }
 986                         break;
 987                 case FTDM_FAIL:
 988                         {
 989                                 ftdm_log(FTDM_LOG_ERROR, "Failure Polling event! [%s]\n", span->last_error);
 990                                 if (++errs > 300) {
 991                                         ftdm_log(FTDM_LOG_CRIT, "Too Many Errors!\n");
 992                                         goto end;
 993                                 }
 994                         }
 995                         break;
 996                 default:
 997                         break;
 998                 }
 999 
1000         }
1001 
1002  end:
1003 
1004         ftdm_clear_flag(analog_data, FTDM_ANALOG_RUNNING);
1005         
1006         ftdm_log(FTDM_LOG_DEBUG, "ANALOG thread ending.\n");
1007 
1008         return NULL;
1009 }
1010 
1011 /**
1012  * \brief FreeTDM analog signaling module initialisation
1013  * \return Success
1014  */
1015 static FIO_SIG_LOAD_FUNCTION(ftdm_analog_init)
1016 {
1017         return FTDM_SUCCESS;
1018 }
1019 
1020 /**
1021  * \brief FreeTDM analog signaling module definition
1022  */
1023 EX_DECLARE_DATA ftdm_module_t ftdm_module = {
1024         "analog",
1025         NULL,
1026         NULL,
1027         ftdm_analog_init,
1028         ftdm_analog_configure_span,
1029         NULL
1030 };
1031 
1032 
1033 /* For Emacs:
1034  * Local Variables:
1035  * mode:c
1036  * indent-tabs-mode:t
1037  * tab-width:4
1038  * c-basic-offset:4
1039  * End:
1040  * For VIM:
1041  * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
1042  */

/* [<][>][^][v][top][bottom][index][help] */