root/src/ftmod/ftmod_isdn/ftmod_isdn.c

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

DEFINITIONS

This source file includes following definitions.
  1. isdn_pcap_is_open
  2. isdn_pcap_capture_both
  3. isdn_pcap_capture_l3only
  4. isdn_pcap_open
  5. isdn_pcap_close
  6. isdn_pcap_start
  7. isdn_pcap_stop
  8. isdn_pcap_write
  9. ftdm_time_now
  10. FIO_CHANNEL_GET_SIG_STATUS_FUNCTION
  11. FIO_SPAN_GET_SIG_STATUS_FUNCTION
  12. FIO_CHANNEL_OUTGOING_CALL_FUNCTION
  13. FIO_CHANNEL_REQUEST_FUNCTION
  14. ftdm_isdn_931_err
  15. ftdm_isdn_call_event
  16. __isdn_get_number
  17. ftdm_isdn_931_34
  18. ftdm_isdn_921_23
  19. ftdm_isdn_921_21
  20. state_advance
  21. check_state
  22. process_event
  23. check_events
  24. teletone_handler
  25. ftdm_isdn_tones_run
  26. ftdm_isdn_run
  27. q931_rx_32
  28. ftdm_isdn_q921_log
  29. ftdm_isdn_q931_log
  30. ftdm_isdn_stop
  31. ftdm_isdn_start
  32. parse_loglevel
  33. parse_opts
  34. parse_dialect
  35. FIO_API_FUNCTION
  36. parse_mode
  37. FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION
  38. FIO_IO_LOAD_FUNCTION
  39. FIO_SIG_LOAD_FUNCTION
  40. FIO_SIG_UNLOAD_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 #ifdef HAVE_CONFIG_H
  34 #include "config.h"
  35 #endif
  36 #include <private/ftdm_core.h>
  37 #include <libisdn/Q931.h>
  38 #include <libisdn/Q921.h>
  39 
  40 #ifdef WIN32
  41 #include <windows.h>
  42 #else
  43 #include <sys/time.h>
  44 #endif
  45 
  46 #include "ftmod_isdn.h"
  47 
  48 #define LINE "--------------------------------------------------------------------------------"
  49 
  50 /* helper macros */
  51 #define FTDM_SPAN_IS_NT(x)      (((ftdm_isdn_data_t *)(x)->signal_data)->mode == Q921_NT)
  52 
  53 #define DEFAULT_NATIONAL_PREFIX         "0"
  54 #define DEFAULT_INTERNATIONAL_PREFIX    "00"
  55 
  56 /*****************************************************************************************
  57  * PCAP
  58  *          Based on Helmut Kuper's (<helmut.kuper@ewetel.de>) implementation,
  59  *          but using a different approach (needs a recent libpcap + wireshark)
  60  *****************************************************************************************/
  61 #ifdef HAVE_PCAP
  62 #include <arpa/inet.h>          /* htons() */
  63 #include <pcap.h>
  64 
  65 #define PCAP_SNAPLEN    1500
  66 
  67 struct pcap_context {
  68         pcap_dumper_t           *dump;          /*!< pcap file handle  */
  69         pcap_t                  *handle;        /*!< pcap lib context  */
  70         char                    *filename;      /*!< capture file name */
  71 };
  72 
  73 static inline ftdm_status_t isdn_pcap_is_open(struct ftdm_isdn_data *isdn)
  74 {
  75         return (isdn->pcap) ? 1 : 0;
  76 }
  77 
  78 static inline ftdm_status_t isdn_pcap_capture_both(struct ftdm_isdn_data *isdn)
  79 {
  80         return ((isdn->flags & (FTDM_ISDN_CAPTURE | FTDM_ISDN_CAPTURE_L3ONLY)) == FTDM_ISDN_CAPTURE) ? 1 : 0;
  81 }
  82 
  83 static inline ftdm_status_t isdn_pcap_capture_l3only(struct ftdm_isdn_data *isdn)
  84 {
  85         return ((isdn->flags & FTDM_ISDN_CAPTURE) && (isdn->flags & FTDM_ISDN_CAPTURE_L3ONLY)) ? 1 : 0;
  86 }
  87 
  88 static ftdm_status_t isdn_pcap_open(struct ftdm_isdn_data *isdn, char *filename)
  89 {
  90         struct pcap_context *pcap = NULL;
  91 
  92         if (!isdn || ftdm_strlen_zero(filename))
  93                 return FTDM_FAIL;
  94 
  95         pcap = malloc(sizeof(struct pcap_context));
  96         if (!pcap) {
  97                 ftdm_log(FTDM_LOG_ERROR, "Failed to allocate isdn pcap context\n");
  98                 return FTDM_FAIL;
  99         }
 100 
 101         memset(pcap, 0, sizeof(struct pcap_context));
 102 
 103         pcap->filename = strdup(filename);
 104 
 105         pcap->handle = pcap_open_dead(DLT_LINUX_LAPD, PCAP_SNAPLEN);
 106         if (!pcap->handle) {
 107                 ftdm_log(FTDM_LOG_ERROR, "Failed to open pcap handle\n");
 108                 goto error;
 109         }
 110 
 111         pcap->dump = pcap_dump_open(pcap->handle, pcap->filename);
 112         if (!pcap->dump) {
 113                 ftdm_log(FTDM_LOG_ERROR, "Failed to open capture file: '%s'\n", pcap_geterr(pcap->handle));
 114                 goto error;
 115         }
 116 
 117         ftdm_log(FTDM_LOG_INFO, "Capture file '%s' opened\n", pcap->filename);
 118 
 119         isdn->pcap = pcap;
 120 
 121         return FTDM_SUCCESS;
 122 error:
 123         if (pcap->handle)
 124                 pcap_close(pcap->handle);
 125         if (pcap->filename)
 126                 free(pcap->filename);
 127 
 128         free(pcap);
 129 
 130         return FTDM_FAIL;
 131 }
 132 
 133 static ftdm_status_t isdn_pcap_close(struct ftdm_isdn_data *isdn)
 134 {
 135         struct pcap_context *pcap = NULL;
 136         long size;
 137 
 138         if (!isdn || !isdn->pcap)
 139                 return FTDM_FAIL;
 140 
 141         pcap = isdn->pcap;
 142 
 143         isdn->flags &= ~(FTDM_ISDN_CAPTURE | FTDM_ISDN_CAPTURE_L3ONLY);
 144         isdn->pcap   = NULL;
 145 
 146         pcap_dump_flush(pcap->dump);
 147 
 148         size = pcap_dump_ftell(pcap->dump);
 149         ftdm_log(FTDM_LOG_INFO, "File '%s' captured %ld bytes of data\n", pcap->filename, size);
 150 
 151         pcap_dump_close(pcap->dump);
 152         pcap_close(pcap->handle);
 153 
 154         free(pcap->filename);
 155         free(pcap);
 156 
 157         return FTDM_SUCCESS;
 158 }
 159 
 160 static inline void isdn_pcap_start(struct ftdm_isdn_data *isdn)
 161 {
 162         if (!isdn->pcap)
 163                 return;
 164 
 165         isdn->flags |= FTDM_ISDN_CAPTURE;
 166 }
 167 
 168 static inline void isdn_pcap_stop(struct ftdm_isdn_data *isdn)
 169 {
 170         isdn->flags &= ~FTDM_ISDN_CAPTURE;
 171 }
 172 
 173 #ifndef ETH_P_LAPD
 174 #define ETH_P_LAPD 0x0030
 175 #endif
 176 
 177 struct isdn_sll_hdr {
 178         uint16_t slltype;
 179         uint16_t sllhatype;
 180         uint16_t slladdrlen;
 181         uint8_t  slladdr[8];
 182         uint16_t sllproto;
 183 };
 184 
 185 /* Fake Q.921 I-frame */
 186 //static const char q921_fake_frame[] = { 0x00, 0x00, 0x00, 0x00 };
 187 
 188 enum {
 189         ISDN_PCAP_INCOMING = 0,
 190         ISDN_PCAP_INCOMING_BCAST = 1,
 191         ISDN_PCAP_OUTGOING = 4,
 192 };
 193 
 194 static ftdm_status_t isdn_pcap_write(struct ftdm_isdn_data *isdn, unsigned char *buf, ftdm_ssize_t len, int direction)
 195 {
 196         unsigned char frame[PCAP_SNAPLEN];
 197         struct pcap_context *pcap;
 198         struct isdn_sll_hdr *sll_hdr = (struct isdn_sll_hdr *)frame;
 199         struct pcap_pkthdr hdr;
 200         int offset = sizeof(struct isdn_sll_hdr);
 201         int nbytes;
 202 
 203         if (!isdn || !isdn->pcap || !buf || !len)
 204                 return FTDM_FAIL;
 205 
 206         pcap = isdn->pcap;
 207 
 208         /* Update SLL header */
 209         sll_hdr->slltype    = htons(direction);
 210         sll_hdr->sllhatype  = 0;
 211         sll_hdr->slladdrlen = 1;
 212         sll_hdr->slladdr[0] = (isdn->mode == Q921_NT) ? 1 : 0;  /* TODO: NT/TE */
 213         sll_hdr->sllproto   = htons(ETH_P_LAPD);
 214 
 215 #if 0
 216         /* Q.931-only mode: copy fake Q.921 header */
 217         if (isdn->flags & FTDM_ISDN_CAPTURE_L3ONLY) {
 218                 /* copy fake q921 header */
 219                 memcpy(frame + offset, q921_fake_frame, sizeof(q921_fake_frame));
 220                 offset += sizeof(q921_fake_frame);
 221         }
 222 #endif
 223 
 224         /* Copy data */
 225         nbytes = (len > (PCAP_SNAPLEN - offset)) ? (PCAP_SNAPLEN - offset) : len;
 226         memcpy(frame + offset, buf, nbytes);
 227 
 228         /* Update timestamp */
 229         memset(&hdr, 0, sizeof(struct pcap_pkthdr));
 230         gettimeofday(&hdr.ts, NULL);
 231         hdr.caplen = offset + nbytes;
 232         hdr.len    = hdr.caplen;
 233 
 234         /* Write packet */
 235         pcap_dump((unsigned char *)pcap->dump, &hdr, frame);
 236 
 237         return FTDM_SUCCESS;
 238 }
 239 #endif  /* HAVE_PCAP */
 240 
 241 
 242 static L2ULONG ftdm_time_now(void)
 243 {
 244         return (L2ULONG)ftdm_current_time_in_ms();
 245 }
 246 
 247 /**
 248  * \brief       Returns the signalling status on a channel
 249  * \param       ftdmchan        Channel to get status on
 250  * \param       status          Pointer to set signalling status
 251  * \return      Success or failure
 252  */
 253 static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(isdn_get_channel_sig_status)
 254 {
 255         *status = FTDM_SIG_STATE_DOWN;
 256 
 257         ftdm_isdn_data_t *isdn_data = ftdmchan->span->signal_data;
 258         if (ftdm_test_flag(isdn_data, FTDM_ISDN_RUNNING)) {
 259                 *status = FTDM_SIG_STATE_UP;
 260         }
 261         return FTDM_SUCCESS;
 262 }
 263 
 264 /**
 265  * \brief       Returns the signalling status on a span
 266  * \param       span    Span to get status on
 267  * \param       status  Pointer to set signalling status
 268  * \return      Success or failure
 269  */
 270 static FIO_SPAN_GET_SIG_STATUS_FUNCTION(isdn_get_span_sig_status)
 271 {
 272         *status = FTDM_SIG_STATE_DOWN;
 273 
 274         ftdm_isdn_data_t *isdn_data = span->signal_data;
 275         if (ftdm_test_flag(isdn_data, FTDM_ISDN_RUNNING)) {
 276                 *status = FTDM_SIG_STATE_UP;
 277         }
 278         return FTDM_SUCCESS;
 279 }
 280 
 281 /**
 282  * \brief       Create outgoing channel
 283  * \param       ftdmchan        Channel to create outgoing call on
 284  * \return      Success or failure
 285  */
 286 static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(isdn_outgoing_call)
 287 {
 288         ftdm_status_t status = FTDM_SUCCESS;
 289         ftdm_set_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND);
 290         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DIALING);
 291         return status;
 292 }
 293 
 294 /**
 295  * \brief       Create outgoing channel, let module select the channel to use
 296  * \param       span            Span to create outgoing call on
 297  * \param       caller_data
 298  * \return      Success or failure
 299  */
 300 #ifdef __TODO__
 301 static FIO_CHANNEL_REQUEST_FUNCTION(isdn_channel_request)
 302 {
 303         Q931mes_Generic *gen = (Q931mes_Generic *) caller_data->raw_data;
 304         Q931ie_BearerCap BearerCap;
 305         Q931ie_ChanID ChanID = { 0 };
 306         Q931ie_CallingNum CallingNum;
 307         Q931ie_CallingNum *ptrCallingNum;
 308         Q931ie_CalledNum CalledNum;
 309         Q931ie_CalledNum *ptrCalledNum;
 310         Q931ie_Display Display, *ptrDisplay;
 311         Q931ie_HLComp HLComp;                   /* High-Layer Compatibility IE */
 312         Q931ie_ProgInd Progress;                /* Progress Indicator IE */
 313         ftdm_status_t status = FTDM_FAIL;
 314         ftdm_isdn_data_t *isdn_data = span->signal_data;
 315         int sanity = 60000;
 316         int codec  = 0;
 317 
 318         /*
 319          * get codec type
 320          */
 321         ftdm_channel_command(span->channels[chan_id], FTDM_COMMAND_GET_NATIVE_CODEC, &codec);
 322 
 323         /*
 324          * Q.931 Setup Message
 325          */
 326         Q931InitMesGeneric(gen);
 327         gen->MesType = Q931mes_SETUP;
 328         gen->CRVFlag = 0;               /* outgoing call */
 329 
 330         /*
 331          * Bearer Capability IE
 332          */
 333         Q931InitIEBearerCap(&BearerCap);
 334         BearerCap.CodStand  = Q931_CODING_ITU;          /* ITU-T = 0, ISO/IEC = 1, National = 2, Network = 3 */
 335         BearerCap.ITC       = Q931_ITC_SPEECH;          /* Speech */
 336         BearerCap.TransMode = 0;                        /* Circuit = 0, Packet = 1 */
 337         BearerCap.ITR       = Q931_ITR_64K;             /* 64k */
 338         BearerCap.Layer1Ident = 1;
 339         BearerCap.UIL1Prot = (codec == FTDM_CODEC_ALAW) ? Q931_UIL1P_G711A : Q931_UIL1P_G711U;  /* U-law = 2, A-law = 3 */
 340         gen->BearerCap = Q931AppendIE(gen, (L3UCHAR *) &BearerCap);
 341 
 342         /*
 343          * Channel ID IE
 344          */
 345         Q931InitIEChanID(&ChanID);
 346         ChanID.IntType = FTDM_SPAN_IS_BRI(span) ? 0 : 1;                /* PRI = 1, BRI = 0 */
 347 
 348         if (!FTDM_SPAN_IS_NT(span)) {
 349                 ChanID.PrefExcl = (isdn_data->opts & FTDM_ISDN_OPT_SUGGEST_CHANNEL) ? 0 : 1; /* 0 = preferred, 1 exclusive */
 350         } else {
 351                 ChanID.PrefExcl = 1;    /* always exclusive in NT-mode */
 352         }
 353 
 354         if (ChanID.IntType) {
 355                 ChanID.InfoChanSel = 1;                         /* None = 0, See Slot = 1, Any = 3 */
 356                 ChanID.ChanMapType = 3;                         /* B-Chan */
 357                 ChanID.ChanSlot = (unsigned char)chan_id;
 358         } else {
 359                 ChanID.InfoChanSel = (unsigned char)chan_id & 0x03;     /* None = 0, B1 = 1, B2 = 2, Any = 3 */
 360         }
 361         gen->ChanID = Q931AppendIE(gen, (L3UCHAR *) &ChanID);
 362 
 363         /*
 364          * Progress IE
 365          */
 366         Q931InitIEProgInd(&Progress);
 367         Progress.CodStand = Q931_CODING_ITU;    /* 0 = ITU */
 368         Progress.Location = 0;  /* 0 = User, 1 = Private Network */
 369         Progress.ProgDesc = 3;  /* 1 = Not end-to-end ISDN */
 370         gen->ProgInd = Q931AppendIE(gen, (L3UCHAR *)&Progress);
 371 
 372         /*
 373          * Display IE
 374          */
 375         if (!(isdn_data->opts & FTDM_ISDN_OPT_OMIT_DISPLAY_IE) && FTDM_SPAN_IS_NT(span)) {
 376                 Q931InitIEDisplay(&Display);
 377                 Display.Size = Display.Size + (unsigned char)strlen(caller_data->cid_name);
 378                 gen->Display = Q931AppendIE(gen, (L3UCHAR *) &Display);
 379                 ptrDisplay = Q931GetIEPtr(gen->Display, gen->buf);
 380                 ftdm_copy_string((char *)ptrDisplay->Display, caller_data->cid_name, strlen(caller_data->cid_name)+1);
 381         }
 382 
 383         /*
 384          * Calling Number IE
 385          */
 386         Q931InitIECallingNum(&CallingNum);
 387         CallingNum.TypNum    = Q931_TON_UNKNOWN;
 388         CallingNum.NumPlanID = Q931_NUMPLAN_E164;
 389         CallingNum.PresInd   = Q931_PRES_ALLOWED;
 390         CallingNum.ScreenInd = Q931_SCREEN_USER_NOT_SCREENED;
 391         CallingNum.Size = CallingNum.Size + (unsigned char)strlen(caller_data->cid_num.digits);
 392         gen->CallingNum = Q931AppendIE(gen, (L3UCHAR *) &CallingNum);
 393         ptrCallingNum = Q931GetIEPtr(gen->CallingNum, gen->buf);
 394         ftdm_copy_string((char *)ptrCallingNum->Digit, caller_data->cid_num.digits, strlen(caller_data->cid_num.digits)+1);
 395 
 396 
 397         /*
 398          * Called number IE
 399          */
 400         Q931InitIECalledNum(&CalledNum);
 401         CalledNum.TypNum    = Q931_TON_UNKNOWN;
 402         CalledNum.NumPlanID = Q931_NUMPLAN_E164;
 403         CalledNum.Size = CalledNum.Size + (unsigned char)strlen(caller_data->ani.digits);
 404         gen->CalledNum = Q931AppendIE(gen, (L3UCHAR *) &CalledNum);
 405         ptrCalledNum = Q931GetIEPtr(gen->CalledNum, gen->buf);
 406         ftdm_copy_string((char *)ptrCalledNum->Digit, caller_data->ani.digits, strlen(caller_data->ani.digits)+1);
 407 
 408         /*
 409          * High-Layer Compatibility IE   (Note: Required for AVM FritzBox)
 410          */
 411         Q931InitIEHLComp(&HLComp);
 412         HLComp.CodStand  = Q931_CODING_ITU;     /* ITU */
 413         HLComp.Interpret = 4;   /* only possible value */
 414         HLComp.PresMeth  = 1;   /* High-layer protocol profile */
 415         HLComp.HLCharID  = 1;   /* Telephony = 1, Fax G2+3 = 4, Fax G4 = 65 (Class I)/ 68 (Class II or III) */
 416         gen->HLComp = Q931AppendIE(gen, (L3UCHAR *) &HLComp);
 417 
 418         caller_data->call_state = FTDM_CALLER_STATE_DIALING;
 419         Q931Rx43(&isdn_data->q931, gen, gen->Size);
 420 
 421         isdn_data->outbound_crv[gen->CRV] = caller_data;
 422         //isdn_data->channels_local_crv[gen->CRV] = ftdmchan;
 423 
 424         while (ftdm_running() && caller_data->call_state == FTDM_CALLER_STATE_DIALING) {
 425                 ftdm_sleep(1);
 426 
 427                 if (!--sanity) {
 428                         caller_data->call_state = FTDM_CALLER_STATE_FAIL;
 429                         break;
 430                 }
 431         }
 432         isdn_data->outbound_crv[gen->CRV] = NULL;
 433 
 434         if (caller_data->call_state == FTDM_CALLER_STATE_SUCCESS) {
 435                 ftdm_channel_t *new_chan = NULL;
 436                 int fail = 1;
 437 
 438                 new_chan = NULL;
 439                 if (caller_data->chan_id > 0 && caller_data->chan_id <= ftdm_span_get_chan_count(span)) {
 440                         new_chan = ftdm_span_get_channel(span, caller_data->chan_id);
 441                 }
 442 
 443                 if (new_chan && (status = ftdm_channel_open_chan(new_chan) == FTDM_SUCCESS)) {
 444                         if (ftdm_test_flag(new_chan, FTDM_CHANNEL_INUSE) || new_chan->state != FTDM_CHANNEL_STATE_DOWN) {
 445                                 if (new_chan->state == FTDM_CHANNEL_STATE_DOWN || new_chan->state >= FTDM_CHANNEL_STATE_TERMINATING) {
 446                                         int x = 0;
 447                                         ftdm_log(FTDM_LOG_WARNING, "Channel %d:%d ~ %d:%d is already in use waiting for it to become available.\n");
 448 
 449                                         for (x = 0; x < 200; x++) {
 450                                                 if (!ftdm_test_flag(new_chan, FTDM_CHANNEL_INUSE)) {
 451                                                         break;
 452                                                 }
 453                                                 ftdm_sleep(5);
 454                                         }
 455                                 }
 456                                 if (ftdm_test_flag(new_chan, FTDM_CHANNEL_INUSE)) {
 457                                         ftdm_log(FTDM_LOG_ERROR, "Channel %d:%d ~ %d:%d is already in use.\n",
 458                                                         new_chan->span_id,
 459                                                         new_chan->chan_id,
 460                                                         new_chan->physical_span_id,
 461                                                         new_chan->physical_chan_id
 462                                                         );
 463                                         new_chan = NULL;
 464                                 }
 465                         }
 466 
 467                         if (new_chan && new_chan->state == FTDM_CHANNEL_STATE_DOWN) {
 468                                 isdn_data->channels_local_crv[gen->CRV] = new_chan;
 469                                 memset(&new_chan->caller_data, 0, sizeof(new_chan->caller_data));
 470                                 ftdm_set_flag(new_chan, FTDM_CHANNEL_OUTBOUND);
 471                                 ftdm_set_state_locked(new_chan, FTDM_CHANNEL_STATE_DIALING);
 472                                 switch(gen->MesType) {
 473                                 case Q931mes_ALERTING:
 474                                         new_chan->init_state = FTDM_CHANNEL_STATE_PROGRESS_MEDIA;
 475                                         break;
 476                                 case Q931mes_CONNECT:
 477                                         new_chan->init_state = FTDM_CHANNEL_STATE_UP;
 478                                         break;
 479                                 default:
 480                                         new_chan->init_state = FTDM_CHANNEL_STATE_PROGRESS;
 481                                         break;
 482                                 }
 483 
 484                                 fail = 0;
 485                         }
 486                 }
 487 
 488                 if (!fail) {
 489                         *ftdmchan = new_chan;
 490                         return FTDM_SUCCESS;
 491                 } else {
 492                         Q931ie_Cause cause;
 493                         gen->MesType = Q931mes_DISCONNECT;
 494                         cause.IEId = Q931ie_CAUSE;
 495                         cause.Size = sizeof(Q931ie_Cause);
 496                         cause.CodStand  = 0;
 497                         cause.Location = 1;
 498                         cause.Recom = 1;
 499                         //should we be casting here.. or do we need to translate value?
 500                         cause.Value = (unsigned char) FTDM_CAUSE_WRONG_CALL_STATE;
 501                         *cause.Diag = '\0';
 502                         gen->Cause = Q931AppendIE(gen, (L3UCHAR *) &cause);
 503                         Q931Rx43(&isdn_data->q931, gen, gen->Size);
 504 
 505                         if (gen->CRV) {
 506                                 Q931ReleaseCRV(&isdn_data->q931, gen->CRV);
 507                         }
 508 
 509                         if (new_chan) {
 510                                 ftdm_log(FTDM_LOG_CRIT, "Channel is busy\n");
 511                         } else {
 512                                 ftdm_log(FTDM_LOG_CRIT, "Failed to open channel for new setup message\n");
 513                         }
 514                 }
 515         }
 516 
 517         *ftdmchan = NULL;
 518         return FTDM_FAIL;
 519 
 520 }
 521 #endif /* __TODO__ */
 522 
 523 static L3INT ftdm_isdn_931_err(void *pvt, L3INT id, L3INT p1, L3INT p2)
 524 {
 525         ftdm_log(FTDM_LOG_ERROR, "ERROR: [%s] [%d] [%d]\n", q931_error_to_name(id), p1, p2);
 526         return 0;
 527 }
 528 
 529 /**
 530  * \brief       The new call event handler
 531  * \note        W000t!!! \o/  ;D
 532  * \todo        A lot
 533  */
 534 static void ftdm_isdn_call_event(struct Q931_Call *call, struct Q931_CallEvent *event, void *priv)
 535 {
 536         Q931_TrunkInfo_t *trunk = NULL;
 537         ftdm_isdn_data_t *isdn_data = NULL;
 538         ftdm_span_t *zspan = NULL;
 539         assert(call);
 540         assert(event);
 541 
 542         trunk = Q931CallGetTrunk(call);
 543         assert(trunk);
 544 
 545         zspan = Q931CallGetPrivate(call);
 546         if (!zspan) {
 547                 zspan = priv;
 548                 Q931CallSetPrivate(call, zspan);
 549         }
 550         assert(zspan);
 551 
 552         isdn_data = zspan->signal_data;
 553 
 554         if (Q931CallIsGlobal(call)) {
 555                 /*
 556                  * Global event
 557                  */
 558                 ftdm_log(FTDM_LOG_DEBUG, "Received global event from Q.931\n");
 559         } else {
 560                 ftdm_channel_t *ftdmchan = NULL;
 561                 ftdm_sigmsg_t sig;
 562                 int call_crv = Q931CallGetCRV(call);
 563                 int type;
 564 
 565                 /*
 566                  * Call-specific event
 567                  */
 568                 ftdm_log(FTDM_LOG_DEBUG, "Received call-specific event from Q.931 for call %d [%hu]\n", Q931CallGetCRV(call), Q931CallGetCRV(call));
 569 
 570                 /*
 571                  * Try to get associated zap channel
 572                  * and init sigmsg struct if there is one
 573                  */
 574                 ftdmchan = Q931CallIsOutgoing(call) ? isdn_data->channels_local_crv[call_crv] : isdn_data->channels_remote_crv[call_crv];
 575                 if (ftdmchan) {
 576                         memset(&sig, 0, sizeof(ftdm_sigmsg_t));
 577                         sig.chan_id = ftdmchan->chan_id;
 578                         sig.span_id = ftdmchan->span_id;
 579                         sig.channel = ftdmchan;
 580                 }
 581 
 582                 type = Q931CallEventGetType(event);
 583 
 584                 if (type == Q931_EVENT_TYPE_CRV) {
 585 
 586                         ftdm_log(FTDM_LOG_DEBUG, "\tCRV event\n");
 587 
 588                         switch (Q931CallEventGetId(event)) {
 589                         case Q931_EVENT_RELEASE_CRV:
 590                                 {
 591                                         /* WARNING contains old interface code, yuck! */
 592                                         if (!ftdmchan) {
 593                                                 ftdm_log(FTDM_LOG_DEBUG, "Call %d [0x%x] not associated to zap channel\n", call_crv, call_crv);
 594                                                 return;
 595                                         }
 596 
 597                                         if (ftdm_channel_get_state(ftdmchan) != FTDM_CHANNEL_STATE_DOWN) {
 598                                                 ftdm_log(FTDM_LOG_DEBUG, "Channel %d:%d not in DOWN state, cleaning up\n",
 599                                                                         ftdm_channel_get_span_id(ftdmchan),
 600                                                                         ftdm_channel_get_id(ftdmchan));
 601 
 602                                                 /*
 603                                                  * Send hangup signal to mod_openzap
 604                                                  */
 605                                                 if (!sig.channel->caller_data.hangup_cause) {
 606                                                         sig.channel->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_CLEARING;
 607                                                 }
 608 
 609                                                 sig.event_id = FTDM_SIGEVENT_STOP;
 610                                                 ftdm_span_send_signal(ftdm_channel_get_span(ftdmchan), &sig);
 611 
 612                                                 /* Release zap channel */
 613                                                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
 614                                         }
 615                                         return;
 616                                 }
 617                                 break;
 618                         default:
 619                                 ftdm_log(FTDM_LOG_ERROR, "Unknown CRV event: %d\n", Q931CallEventGetId(event));
 620                                 return;
 621                         }
 622                 }
 623                 else if (type == Q931_EVENT_TYPE_TIMER) {
 624                         struct Q931_CallTimerEvent *timer_evt = Q931CallEventGetData(event);
 625 
 626                         ftdm_log(FTDM_LOG_DEBUG, "\tTimer event\n");
 627                         assert(timer_evt->id);
 628 
 629                         switch (timer_evt->id) {
 630                         case Q931_TIMER_T303:
 631                                 /*
 632                                  * SETUP timeout
 633                                  *
 634                                  * TE-mode: Q931_EVENT_SETUP_CONFIRM (error)
 635                                  * NT-mode: Q931_EVENT_RELEASE_INDICATION
 636                                  */
 637                                 {
 638                                         /* WARNING contains old interface code, yuck! */
 639                                         if (!ftdmchan) {
 640                                                 ftdm_log(FTDM_LOG_ERROR, "Call %d [0x%x] not associated to zap channel\n", call_crv, call_crv);
 641                                                 return;
 642                                         }
 643 
 644                                         ftdm_log(FTDM_LOG_DEBUG, "Call setup failed on channel %d:%d\n",
 645                                                                 ftdm_channel_get_span_id(ftdmchan),
 646                                                                 ftdm_channel_get_id(ftdmchan));
 647 
 648                                         /*
 649                                          * Send signal to mod_openzap
 650                                          */
 651                                         sig.channel->caller_data.hangup_cause = FTDM_CAUSE_NETWORK_OUT_OF_ORDER;
 652 
 653                                         sig.event_id = FTDM_SIGEVENT_STOP;
 654                                         ftdm_span_send_signal(ftdm_channel_get_span(ftdmchan), &sig);
 655 
 656                                         /* Release zap channel */
 657                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
 658                                         return;
 659                                 }
 660                                 break;
 661 
 662                         default:
 663                                 ftdm_log(FTDM_LOG_ERROR, "Unhandled timer event %d\n", timer_evt->id);
 664                         }
 665                 }
 666                 else if (type == Q931_EVENT_TYPE_MESSAGE) {
 667                         struct Q931_CallMessageEvent *msg_evt = Q931CallEventGetData(event);
 668 
 669                         ftdm_log(FTDM_LOG_DEBUG, "\tMessage event\n");
 670                         assert(msg_evt);
 671 
 672                         /*
 673                          * Slowly move stuff from the old event handler into this part...
 674                          */
 675                         switch (Q931CallEventGetId(event)) {
 676                         case Q931_EVENT_SETUP_CONFIRM:
 677                         case Q931_EVENT_SETUP_COMPLETE_INDICATION:      /* CONNECT */
 678                                 {
 679                                         /* WARNING contains old interface code, yuck! */
 680                                         if (!ftdmchan) {
 681                                                 ftdm_log(FTDM_LOG_ERROR, "Call %d [0x%x] not associated to zap channel\n", call_crv, call_crv);
 682                                                 return;
 683                                         }
 684                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP);
 685                                 }
 686                                 break;
 687 
 688                         default:
 689                                 ftdm_log(FTDM_LOG_DEBUG, "Not yet handled message event %d\n", Q931CallEventGetId(event));
 690                         }
 691                 }
 692                 else {
 693                         ftdm_log(FTDM_LOG_ERROR, "Unknown event type %d\n", type);
 694                 }
 695         }
 696 }
 697 
 698 /**
 699  * Copy callednum, readding prefix as needed
 700  */
 701 static void __isdn_get_number(const char *digits, const int ton, char *buf, int size)
 702 {
 703         int offset = 0;
 704 
 705         if (!digits || !buf || size <= 0)
 706                 return;
 707 
 708         switch (ton) {
 709         case Q931_TON_NATIONAL:
 710                 offset = strlen(DEFAULT_NATIONAL_PREFIX);
 711                 memcpy(buf, DEFAULT_NATIONAL_PREFIX, offset);
 712                 break;
 713         case Q931_TON_INTERNATIONAL:
 714                 offset = strlen(DEFAULT_INTERNATIONAL_PREFIX);
 715                 memcpy(buf, DEFAULT_INTERNATIONAL_PREFIX, offset);
 716                 break;
 717         default:
 718                 break;
 719         }
 720 
 721         strncpy(&buf[offset], digits, size - (offset + 1));
 722         buf[size - 1] = '\0';
 723 }
 724 
 725 #define isdn_get_number(num, buf) \
 726         __isdn_get_number((const char *)(num)->Digit, (num)->TypNum, (char *)buf, sizeof(buf))
 727 
 728 
 729 /**
 730  * \brief       The old call event handler (err, call message handler)
 731  * \todo        This one must die!
 732  */
 733 static L3INT ftdm_isdn_931_34(void *pvt, struct Q931_Call *call, Q931mes_Generic *msg, int mlen)
 734 {
 735         Q931mes_Generic *gen = (Q931mes_Generic *) msg;
 736         ftdm_span_t *span = (ftdm_span_t *) pvt;
 737         ftdm_isdn_data_t *isdn_data = span->signal_data;
 738         ftdm_channel_t *ftdmchan = NULL;
 739         int chan_id = 0;
 740         int chan_hunt = 0;
 741 
 742         if (Q931IsIEPresent(gen->ChanID)) {
 743                 Q931ie_ChanID *chanid = Q931GetIEPtr(gen->ChanID, gen->buf);
 744 
 745                 if (chanid->IntType)
 746                         chan_id = chanid->ChanSlot;
 747                 else
 748                         chan_id = chanid->InfoChanSel;
 749 
 750                 /* "any" channel specified */
 751                 if (chanid->InfoChanSel == 3) {
 752                         chan_hunt++;
 753                 }
 754         } else if (FTDM_SPAN_IS_NT(span)) {
 755                 /* no channel ie */
 756                 chan_hunt++;
 757         }
 758 
 759         assert(span != NULL);
 760         assert(isdn_data != NULL);
 761 
 762         /*
 763          * Support code for the new event handling system
 764          * Remove this as soon as we have the new api to set up calls
 765          */
 766 #ifdef __OLD__
 767         if (gen->CRV) {
 768                 struct Q931_Call *call;
 769 
 770                 call = Q931GetCallByCRV(&isdn_data->q931, gen->CRV);
 771                 if (call && !Q931CallGetPrivate(call)) {
 772                         ftdm_log(FTDM_LOG_DEBUG, "Storing reference to current span in call %d [0x%x]\n", gen->CRV, gen->CRV);
 773                         Q931CallSetPrivate(call, span);
 774                 }
 775         }
 776 #else
 777         if (call && !Q931CallGetPrivate(call)) {
 778                 ftdm_log(FTDM_LOG_DEBUG, "Storing reference to current span in call %d [0x%x]\n", gen->CRV, gen->CRV);
 779                 Q931CallSetPrivate(call, span);
 780         }
 781 #endif
 782         ftdm_log(FTDM_LOG_DEBUG, "Yay I got an event! Type:[%02x] Size:[%d] CRV: %d (%#hx, CTX: %s)\n", gen->MesType, gen->Size, gen->CRV, gen->CRV, gen->CRVFlag ? "Terminator" : "Originator");
 783 
 784 #ifdef __TODO_OR_REMOVE__
 785         if (gen->CRVFlag && (caller_data = isdn_data->outbound_crv[gen->CRV])) {
 786                 if (chan_id) {
 787                         caller_data->chan_id = chan_id;
 788                 }
 789 
 790                 switch(gen->MesType) {
 791                 case Q931mes_STATUS:
 792                 case Q931mes_CALL_PROCEEDING:
 793                         break;
 794                 case Q931mes_ALERTING:
 795                 case Q931mes_PROGRESS:
 796                 case Q931mes_CONNECT:
 797                         caller_data->call_state = FTDM_CALLER_STATE_SUCCESS;
 798                         break;
 799                 default:
 800                         caller_data->call_state = FTDM_CALLER_STATE_FAIL;
 801                         break;
 802                 }
 803 
 804                 return 0;
 805         }
 806 #endif
 807 
 808         if (gen->CRVFlag) {
 809                 ftdmchan = isdn_data->channels_local_crv[gen->CRV];
 810         } else {
 811                 ftdmchan = isdn_data->channels_remote_crv[gen->CRV];
 812         }
 813 
 814         ftdm_log(FTDM_LOG_DEBUG, "ftdmchan %x (%d:%d) source isdn_data->channels_%s_crv[%#hx]\n",
 815                         ftdmchan,
 816                         ((ftdmchan) ? ftdm_channel_get_span_id(ftdmchan) : -1),
 817                         ((ftdmchan) ? ftdm_channel_get_id(ftdmchan) : -1),
 818                         ((gen->CRVFlag) ? "local" : "remote"),
 819                         gen->CRV);
 820 
 821         if (gen->ProtDisc == 3) {
 822                 switch(gen->MesType) {
 823                 case Q931mes_SERVICE:
 824                         {
 825                                 Q931ie_ChangeStatus *changestatus = Q931GetIEPtr(gen->ChangeStatus, gen->buf);
 826                                 if (ftdmchan) {
 827                                         switch (changestatus->NewStatus) {
 828                                         case 0: /* change status to "in service" */
 829                                                 {
 830                                                         ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_SUSPENDED);
 831                                                         ftdm_log(FTDM_LOG_DEBUG, "Channel %d:%d in service\n",
 832                                                                         ftdm_channel_get_span_id(ftdmchan),
 833                                                                         ftdm_channel_get_id(ftdmchan));
 834                                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
 835                                                 }
 836                                                 break;
 837                                         case 1:
 838                                                 { /* change status to "maintenance" */
 839                                                         ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_SUSPENDED);
 840                                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
 841                                                 }
 842                                                 break;
 843                                         case 2:
 844                                                 { /* change status to "out of service" */
 845                                                         ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_SUSPENDED);
 846                                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
 847                                                 }
 848                                                 break;
 849                                         default: /* unknown */
 850                                                 {
 851                                                         break;
 852                                                 }
 853                                         }
 854                                 }
 855                         }
 856                         break;
 857                 default:
 858                         break;
 859                 }
 860         } else {
 861                 switch(gen->MesType) {
 862                 case Q931mes_RESTART:
 863                         {
 864                                 if (chan_id) {
 865                                         ftdmchan = ftdm_span_get_channel(span, chan_id);
 866                                 }
 867                                 if (ftdmchan) {
 868                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
 869                                 } else {
 870                                         uint32_t i;
 871 
 872                                         for (i = 1; i < ftdm_span_get_chan_count(span); i++) {
 873                                                 /* Skip channels that are down and D-Channels (#OpenZAP-39) */
 874                                                 if (ftdm_channel_get_state(span->channels[i]) == FTDM_CHANNEL_STATE_DOWN ||
 875                                                     ftdm_channel_get_type(span->channels[i]) == FTDM_CHAN_TYPE_DQ921)
 876                                                         continue;
 877 
 878                                                 ftdm_set_state_locked(span->channels[i], FTDM_CHANNEL_STATE_RESTART);
 879                                         }
 880                                 }
 881                         }
 882                         break;
 883                 case Q931mes_RELEASE:
 884                 case Q931mes_RELEASE_COMPLETE:
 885                         {
 886                                 const char *what = gen->MesType == Q931mes_RELEASE ? "Release" : "Release Complete";
 887                                 if (ftdmchan) {
 888                                         if (ftdm_channel_get_state(ftdmchan) == FTDM_CHANNEL_STATE_TERMINATING ||
 889                                             ftdm_channel_get_state(ftdmchan) == FTDM_CHANNEL_STATE_HANGUP)
 890                                         {
 891                                                 if (gen->MesType == Q931mes_RELEASE) {
 892                                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
 893                                                 } else {
 894                                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
 895                                                 }
 896                                         }
 897                                         else if ((gen->MesType == Q931mes_RELEASE && ftdm_channel_get_state(ftdmchan) <= FTDM_CHANNEL_STATE_UP) ||
 898                                                  (gen->MesType == Q931mes_RELEASE_COMPLETE && ftdm_channel_get_state(ftdmchan) == FTDM_CHANNEL_STATE_DIALING)) {
 899 
 900                                                 /*
 901                                                  * Don't keep inbound channels open if the remote side hangs up before we answered
 902                                                  */
 903                                                 Q931ie_Cause *cause = Q931GetIEPtr(gen->Cause, gen->buf);
 904                                                 ftdm_sigmsg_t sig;
 905                                                 ftdm_status_t status;
 906 
 907                                                 memset(&sig, 0, sizeof(sig));
 908                                                 sig.span_id = ftdm_channel_get_span_id(ftdmchan);
 909                                                 sig.chan_id = ftdm_channel_get_id(ftdmchan);
 910                                                 sig.channel = ftdmchan;
 911                                                 sig.channel->caller_data.hangup_cause = (cause) ? cause->Value : FTDM_CAUSE_NORMAL_UNSPECIFIED;
 912 
 913                                                 sig.event_id = FTDM_SIGEVENT_STOP;
 914                                                 status = ftdm_span_send_signal(span, &sig);
 915 
 916                                                 ftdm_log(FTDM_LOG_DEBUG, "Received %s in state %s, requested hangup for channel %d:%d\n", what,
 917                                                                 ftdm_channel_get_state_str(ftdmchan),
 918                                                                 ftdm_channel_get_span_id(ftdmchan),
 919                                                                 ftdm_channel_get_id(ftdmchan));
 920                                         } else {
 921                                                 ftdm_log(FTDM_LOG_DEBUG, "Ignoring %s on channel %d\n", what, ftdm_channel_get_id(ftdmchan));
 922                                         }
 923                                 } else {
 924                                         ftdm_log(FTDM_LOG_CRIT, "Received %s with no matching channel %d\n", what, chan_id);
 925                                 }
 926                         }
 927                         break;
 928                 case Q931mes_DISCONNECT:
 929                         {
 930                                 if (ftdmchan) {
 931                                         Q931ie_Cause *cause = Q931GetIEPtr(gen->Cause, gen->buf);
 932                                         ftdmchan->caller_data.hangup_cause = cause->Value;
 933                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
 934                                 } else {
 935                                         ftdm_log(FTDM_LOG_CRIT, "Received Disconnect with no matching channel %d\n", chan_id);
 936                                 }
 937                         }
 938                         break;
 939                 case Q931mes_ALERTING:
 940                         {
 941                                 if (ftdmchan) {
 942                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
 943                                 } else {
 944                                         ftdm_log(FTDM_LOG_CRIT, "Received Alerting with no matching channel %d\n", chan_id);
 945                                 }
 946                         }
 947                         break;
 948                 case Q931mes_PROGRESS:
 949                         {
 950                                 if (ftdmchan) {
 951                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
 952                                 } else {
 953                                         ftdm_log(FTDM_LOG_CRIT, "Received Progress with no matching channel %d\n", chan_id);
 954                                 }
 955                         }
 956                         break;
 957                 case Q931mes_CONNECT:
 958 #if 0   /* Handled by new event code */
 959                         {
 960                                 if (ftdmchan) {
 961                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP);
 962 
 963 #if 0   /* Auto-Ack is enabled, we actually don't need this */
 964                                         gen->MesType = Q931mes_CONNECT_ACKNOWLEDGE;
 965                                         gen->CRVFlag = 0;       /* outbound */
 966                                         Q931Rx43(&isdn_data->q931, gen, gen->Size);
 967 #endif
 968                                 } else {
 969                                         ftdm_log(FTDM_LOG_CRIT, "Received Connect with no matching channel %d\n", chan_id);
 970                                 }
 971                         }
 972 #endif
 973                         break;
 974                 case Q931mes_SETUP:
 975                         {
 976                                 Q931ie_CallingNum *callingnum = Q931GetIEPtr(gen->CallingNum, gen->buf);
 977                                 Q931ie_CalledNum *callednum = Q931GetIEPtr(gen->CalledNum, gen->buf);
 978                                 uint32_t cplen = mlen;
 979                                 int overlap_dial = 0;
 980                                 int fail_cause = 0;
 981                                 int fail = 1;
 982 
 983                                 if (ftdmchan && ftdmchan == isdn_data->channels_remote_crv[gen->CRV]) {
 984                                         ftdm_log(FTDM_LOG_INFO, "Duplicate SETUP message(?) for Channel %d:%d ~ %d:%d in state %s [ignoring]\n",
 985                                                                         ftdm_channel_get_span_id(ftdmchan),
 986                                                                         ftdm_channel_get_id(ftdmchan),
 987                                                                         ftdm_channel_get_ph_span_id(ftdmchan),
 988                                                                         ftdm_channel_get_ph_id(ftdmchan),
 989                                                                         ftdm_channel_get_state_str(ftdmchan));
 990                                         break;
 991                                 }
 992 
 993                                 ftdmchan = NULL;
 994                                 /*
 995                                  * Channel selection for incoming calls:
 996                                  */
 997                                 if (FTDM_SPAN_IS_NT(span) && chan_hunt) {
 998                                         int x;
 999 
1000                                         /*
1001                                          * In NT-mode with channel selection "any",
1002                                          * try to find a free channel
1003                                          */
1004                                         for (x = 1; x <= ftdm_span_get_chan_count(span); x++) {
1005                                                 ftdm_channel_t *zc = ftdm_span_get_channel(span, x);
1006 
1007                                                 if (!ftdm_test_flag(zc, FTDM_CHANNEL_INUSE) && ftdm_channel_get_state(zc) == FTDM_CHANNEL_STATE_DOWN) {
1008                                                         ftdmchan = zc;
1009                                                         break;
1010                                                 }
1011                                         }
1012                                 }
1013                                 else if (!FTDM_SPAN_IS_NT(span) && chan_hunt) {
1014                                         /*
1015                                          * In TE-mode this ("any") is invalid
1016                                          */
1017                                         fail_cause = FTDM_CAUSE_CHANNEL_UNACCEPTABLE;
1018 
1019                                         ftdm_log(FTDM_LOG_ERROR, "Invalid channel selection in incoming call (network side didn't specify a channel)\n");
1020                                 }
1021                                 else {
1022                                         /*
1023                                          * Otherwise simply try to select the channel we've been told
1024                                          *
1025                                          * TODO: NT mode is abled to select a different channel if the one chosen
1026                                          *       by the TE side is already in use
1027                                          */
1028                                         if (chan_id > 0 && chan_id < FTDM_MAX_CHANNELS_SPAN && chan_id <= ftdm_span_get_chan_count(span)) {
1029                                                 ftdmchan = ftdm_span_get_channel(span, chan_id);
1030                                         }
1031                                         else {
1032                                                 /* invalid channel id */
1033                                                 fail_cause = FTDM_CAUSE_CHANNEL_UNACCEPTABLE;
1034 
1035                                                 ftdm_log(FTDM_LOG_ERROR, "Invalid channel selection in incoming call (none selected or out of bounds)\n");
1036                                         }
1037                                 }
1038 
1039                                 if (!callednum || !strlen((char *)callednum->Digit)) {
1040                                         if (FTDM_SPAN_IS_NT(span)) {
1041                                                 ftdm_log(FTDM_LOG_NOTICE, "No destination number found, assuming overlap dial\n");
1042                                                 overlap_dial++;
1043                                         } else {
1044                                                 ftdm_log(FTDM_LOG_ERROR, "No destination number found\n");
1045                                                 ftdmchan = NULL;
1046                                         }
1047                                 }
1048 
1049                                 if (ftdmchan) {
1050                                         if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE) || ftdm_channel_get_state(ftdmchan) != FTDM_CHANNEL_STATE_DOWN) {
1051                                                 if (ftdm_channel_get_state(ftdmchan) == FTDM_CHANNEL_STATE_DOWN || ftdm_channel_get_state(ftdmchan) >= FTDM_CHANNEL_STATE_TERMINATING)
1052                                                 {
1053                                                         int x = 0;
1054                                                         ftdm_log(FTDM_LOG_WARNING, "Channel %d:%d ~ %d:%d is already in use waiting for it to become available.\n",
1055                                                                         ftdm_channel_get_span_id(ftdmchan),
1056                                                                         ftdm_channel_get_id(ftdmchan),
1057                                                                         ftdm_channel_get_ph_span_id(ftdmchan),
1058                                                                         ftdm_channel_get_ph_id(ftdmchan));
1059 
1060                                                         for (x = 0; x < 200; x++) {
1061                                                                 if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE)) {
1062                                                                         break;
1063                                                                 }
1064                                                                 ftdm_sleep(5);
1065                                                         }
1066                                                 }
1067                                                 if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE)) {
1068                                                         ftdm_log(FTDM_LOG_ERROR, "Channel %d:%d ~ %d:%d is already in use.\n",
1069                                                                         ftdm_channel_get_span_id(ftdmchan),
1070                                                                         ftdm_channel_get_id(ftdmchan),
1071                                                                         ftdm_channel_get_ph_span_id(ftdmchan),
1072                                                                         ftdm_channel_get_ph_id(ftdmchan));
1073                                                         ftdmchan = NULL;
1074                                                 }
1075                                         }
1076 
1077                                         if (ftdmchan && ftdm_channel_get_state(ftdmchan) == FTDM_CHANNEL_STATE_DOWN) {
1078                                                 ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(ftdmchan);
1079 
1080                                                 isdn_data->channels_remote_crv[gen->CRV] = ftdmchan;
1081                                                 memset(&ftdmchan->caller_data, 0, sizeof(ftdmchan->caller_data));
1082 
1083                                                 if (ftdmchan->call_data) {
1084                                                         memset(ftdmchan->call_data, 0, sizeof(ftdm_isdn_bchan_data_t));
1085                                                 }
1086 
1087                                                 /* copy number readd prefix as needed */
1088                                                 isdn_get_number(callingnum, caller_data->cid_num.digits);
1089                                                 isdn_get_number(callingnum, caller_data->cid_name);
1090                                                 isdn_get_number(callingnum, caller_data->ani.digits);
1091 
1092                                                 if (!overlap_dial) {
1093                                                         isdn_get_number(callednum, caller_data->dnis.digits);
1094                                                 }
1095 #ifdef __TODO_OR_REMOVE__
1096                                                 ftdmchan->caller_data.CRV = gen->CRV;
1097 #endif
1098                                                 if (cplen > sizeof(caller_data->raw_data)) {
1099                                                         cplen = sizeof(caller_data->raw_data);
1100                                                 }
1101                                                 gen->CRVFlag = !(gen->CRVFlag);
1102                                                 memcpy(caller_data->raw_data, msg, cplen);
1103                                                 caller_data->raw_data_len = cplen;
1104                                                 fail = 0;
1105                                         }
1106                                 }
1107 
1108                                 if (fail) {
1109                                         Q931ie_Cause cause;
1110 
1111                                         gen->MesType = Q931mes_DISCONNECT;
1112                                         gen->CRVFlag = 1;       /* inbound call */
1113 
1114                                         cause.IEId = Q931ie_CAUSE;
1115                                         cause.Size = sizeof(Q931ie_Cause);
1116                                         cause.CodStand = Q931_CODING_ITU;
1117                                         cause.Location = 1;
1118                                         cause.Recom = 1;
1119                                         //should we be casting here.. or do we need to translate value?
1120                                         cause.Value = (unsigned char)((fail_cause) ? fail_cause : FTDM_CAUSE_WRONG_CALL_STATE);
1121                                         *cause.Diag = '\0';
1122                                         gen->Cause = Q931AppendIE(gen, (L3UCHAR *) &cause);
1123                                         Q931Rx43(&isdn_data->q931, gen, gen->Size);
1124 
1125                                         if (gen->CRV) {
1126                                                 Q931ReleaseCRV(&isdn_data->q931, gen->CRV);
1127                                         }
1128 
1129                                         if (ftdmchan) {
1130                                                 ftdm_log(FTDM_LOG_CRIT, "Channel is busy\n");
1131                                         } else {
1132                                                 ftdm_log(FTDM_LOG_CRIT, "Failed to open channel for new setup message\n");
1133                                         }
1134 
1135                                 } else {
1136                                         Q931ie_ChanID ChanID;
1137 
1138                                         /*
1139                                          * Update Channel ID IE
1140                                          */
1141                                         Q931InitIEChanID(&ChanID);
1142                                         ChanID.IntType = FTDM_SPAN_IS_BRI(ftdmchan->span) ? 0 : 1;      /* PRI = 1, BRI = 0 */
1143                                         ChanID.PrefExcl = FTDM_SPAN_IS_NT(ftdmchan->span) ? 1 : 0;  /* Exclusive in NT-mode = 1, Preferred otherwise = 0 */
1144                                         if (ChanID.IntType) {
1145                                                 ChanID.InfoChanSel = 1;         /* None = 0, See Slot = 1, Any = 3 */
1146                                                 ChanID.ChanMapType = 3;         /* B-Chan */
1147                                                 ChanID.ChanSlot = (unsigned char)ftdm_channel_get_id(ftdmchan);
1148                                         } else {
1149                                                 ChanID.InfoChanSel = (unsigned char)ftdm_channel_get_id(ftdmchan) & 0x03;       /* None = 0, B1 = 1, B2 = 2, Any = 3 */
1150                                         }
1151                                         gen->ChanID = Q931AppendIE(gen, (L3UCHAR *) &ChanID);
1152 
1153                                         if (overlap_dial) {
1154                                                 Q931ie_ProgInd progress;
1155 
1156                                                 /*
1157                                                  * Setup Progress indicator
1158                                                  */
1159                                                 progress.IEId = Q931ie_PROGRESS_INDICATOR;
1160                                                 progress.Size = sizeof(Q931ie_ProgInd);
1161                                                 progress.CodStand = Q931_CODING_ITU;    /* ITU */
1162                                                 progress.Location = 1;  /* private network serving the local user */
1163                                                 progress.ProgDesc = 8;  /* call is not end-to-end isdn = 1, in-band information available = 8 */
1164                                                 gen->ProgInd = Q931AppendIE(gen, (L3UCHAR *) &progress);
1165 
1166                                                 /*
1167                                                  * Send SETUP ACK
1168                                                  */
1169                                                 gen->MesType = Q931mes_SETUP_ACKNOWLEDGE;
1170                                                 gen->CRVFlag = 1;       /* inbound call */
1171                                                 Q931Rx43(&isdn_data->q931, gen, gen->Size);
1172 
1173                                                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DIALTONE);
1174                                         } else {
1175                                                 /*
1176                                                  * Advance to RING state
1177                                                  */
1178                                                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RING);
1179                                         }
1180                                 }
1181                         }
1182                         break;
1183 
1184                 case Q931mes_CALL_PROCEEDING:
1185                         {
1186                                 if (ftdmchan) {
1187                                         ftdm_log(FTDM_LOG_CRIT, "Received CALL PROCEEDING message for channel %d\n", ftdm_channel_get_id(ftdmchan));
1188                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
1189                                 } else {
1190                                         ftdm_log(FTDM_LOG_CRIT, "Received CALL PROCEEDING with no matching channel %d\n", chan_id);
1191                                 }
1192                         }
1193                         break;
1194                 case Q931mes_CONNECT_ACKNOWLEDGE:
1195                         {
1196                                 if (ftdmchan) {
1197                                         ftdm_log(FTDM_LOG_DEBUG, "Received CONNECT_ACK message for channel %d\n", ftdm_channel_get_id(ftdmchan));
1198                                 } else {
1199                                         ftdm_log(FTDM_LOG_DEBUG, "Received CONNECT_ACK with no matching channel %d\n", chan_id);
1200                                 }
1201                         }
1202                         break;
1203 
1204                 case Q931mes_INFORMATION:
1205                         {
1206                                 if (ftdmchan) {
1207                                         ftdm_log(FTDM_LOG_CRIT, "Received INFORMATION message for channel %d\n", ftdm_channel_get_id(ftdmchan));
1208 
1209                                         if (ftdm_channel_get_state(ftdmchan) == FTDM_CHANNEL_STATE_DIALTONE) {
1210                                                 char digit = '\0';
1211 
1212                                                 /*
1213                                                  * overlap dial digit indication
1214                                                  */
1215                                                 if (Q931IsIEPresent(gen->CalledNum)) {
1216                                                         ftdm_isdn_bchan_data_t *data = (ftdm_isdn_bchan_data_t *)ftdmchan->call_data;
1217                                                         Q931ie_CalledNum *callednum = Q931GetIEPtr(gen->CalledNum, gen->buf);
1218                                                         int pos;
1219 
1220                                                         digit = callednum->Digit[strlen((char *)callednum->Digit) - 1];
1221                                                         if (digit == '#') {
1222                                                                 callednum->Digit[strlen((char *)callednum->Digit) - 1] = '\0';
1223                                                         }
1224 
1225                                                         /* TODO: make this more safe with strncat() */
1226                                                         pos = strlen(ftdmchan->caller_data.dnis.digits);
1227                                                         strcat(&ftdmchan->caller_data.dnis.digits[pos], (char *)callednum->Digit);
1228 
1229                                                         /* update timer */
1230                                                         data->digit_timeout = ftdm_time_now() + isdn_data->digit_timeout;
1231 
1232                                                         ftdm_log(FTDM_LOG_DEBUG, "Received new overlap digit (%s), destination number: %s\n", callednum->Digit, ftdmchan->caller_data.dnis.digits);
1233                                                 }
1234 
1235                                                 if (Q931IsIEPresent(gen->SendComplete) || digit == '#') {
1236                                                         ftdm_log(FTDM_LOG_DEBUG, "Leaving overlap dial mode\n");
1237 
1238                                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RING);
1239                                                 }
1240                                         }
1241                                 } else {
1242                                         ftdm_log(FTDM_LOG_CRIT, "Received INFORMATION message with no matching channel\n");
1243                                 }
1244                         }
1245                         break;
1246 
1247                 default:
1248                         ftdm_log(FTDM_LOG_CRIT, "Received unhandled message %d (%#x)\n", (int)gen->MesType, (int)gen->MesType);
1249                         break;
1250                 }
1251         }
1252 
1253         return 0;
1254 }
1255 
1256 static int ftdm_isdn_921_23(void *pvt, Q921DLMsg_t ind, L2UCHAR tei, L2UCHAR *msg, L2INT mlen)
1257 {
1258         ftdm_span_t *span = pvt;
1259         ftdm_isdn_data_t *isdn_data = span->signal_data;
1260         int ret, offset = (ind == Q921_DL_DATA) ? 4 : 3;
1261         char bb[4096] = "";
1262 
1263         switch(ind) {
1264         case Q921_DL_DATA:
1265         case Q921_DL_UNIT_DATA:
1266                 print_hex_bytes(msg + offset, mlen - offset, bb, sizeof(bb));
1267                 ftdm_log(FTDM_LOG_DEBUG, "READ %d\n%s\n%s\n\n", (int)mlen - offset, LINE, bb);
1268 #ifdef HAVE_PCAP
1269                 if (isdn_pcap_capture_l3only(isdn_data)) {
1270                         isdn_pcap_write(isdn_data, msg, mlen, (ind == Q921_DL_UNIT_DATA) ? ISDN_PCAP_INCOMING_BCAST : ISDN_PCAP_INCOMING);
1271                 }
1272 #endif
1273         default:
1274                 ret = Q931Rx23(&isdn_data->q931, ind, tei, msg, mlen);
1275                 if (ret != 0)
1276                         ftdm_log(FTDM_LOG_DEBUG, "931 parse error [%d] [%s]\n", ret, q931_error_to_name(ret));
1277                 break;
1278         }
1279 
1280         return ((ret >= 0) ? 1 : 0);
1281 }
1282 
1283 static int ftdm_isdn_921_21(void *pvt, L2UCHAR *msg, L2INT mlen)
1284 {
1285         ftdm_span_t *span = (ftdm_span_t *) pvt;
1286         ftdm_size_t len = (ftdm_size_t) mlen;
1287         ftdm_isdn_data_t *isdn_data = span->signal_data;
1288 
1289         assert(span != NULL);
1290 
1291 #ifdef HAVE_PCAP
1292         if (isdn_pcap_capture_both(isdn_data)) {
1293                 isdn_pcap_write(isdn_data, msg, mlen, ISDN_PCAP_OUTGOING);
1294         }
1295 #endif
1296         return ftdm_channel_write(isdn_data->dchan, msg, len, &len) == FTDM_SUCCESS ? 0 : -1;
1297 }
1298 
1299 static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
1300 {
1301         Q931mes_Generic *gen = (Q931mes_Generic *) ftdmchan->caller_data.raw_data;
1302         ftdm_isdn_data_t *isdn_data = ftdmchan->span->signal_data;
1303         ftdm_span_t *span = ftdm_channel_get_span(ftdmchan);
1304         ftdm_sigmsg_t sig;
1305         ftdm_status_t status;
1306 
1307         ftdm_log(FTDM_LOG_DEBUG, "%d:%d STATE [%s]\n",
1308                         ftdm_channel_get_span_id(ftdmchan),
1309                         ftdm_channel_get_id(ftdmchan),
1310                         ftdm_channel_get_state_str(ftdmchan));
1311 
1312         memset(&sig, 0, sizeof(sig));
1313         sig.span_id = ftdm_channel_get_span_id(ftdmchan);
1314         sig.chan_id = ftdm_channel_get_id(ftdmchan);
1315         sig.channel = ftdmchan;
1316 
1317         switch (ftdm_channel_get_state(ftdmchan)) {
1318         case FTDM_CHANNEL_STATE_DOWN:
1319                 {
1320                         if (gen->CRV) {
1321                                 if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
1322                                         isdn_data->channels_local_crv[gen->CRV] = NULL;
1323                                 } else {
1324                                         isdn_data->channels_remote_crv[gen->CRV] = NULL;
1325                                 }
1326                                 Q931ReleaseCRV(&isdn_data->q931, gen->CRV);
1327                         }
1328                         ftdm_channel_close(&ftdmchan);
1329                 }
1330                 break;
1331         case FTDM_CHANNEL_STATE_PROGRESS:
1332                 {
1333                         if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
1334                                 sig.event_id = FTDM_SIGEVENT_PROGRESS;
1335                                 if ((status = ftdm_span_send_signal(ftdm_channel_get_span(ftdmchan), &sig) != FTDM_SUCCESS)) {
1336                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
1337                                 }
1338                         } else {
1339                                 int crv = gen->CRV;
1340 
1341                                 Q931InitMesGeneric(gen);
1342                                 gen->MesType = Q931mes_CALL_PROCEEDING;
1343                                 gen->CRV     = crv;
1344                                 gen->CRVFlag = 1;       /* inbound */
1345 
1346                                 if (FTDM_SPAN_IS_NT(ftdm_channel_get_span(ftdmchan))) {
1347                                         Q931ie_ChanID ChanID;
1348 
1349                                         /*
1350                                          * Set new Channel ID
1351                                          */
1352                                         Q931InitIEChanID(&ChanID);
1353                                         ChanID.IntType = FTDM_SPAN_IS_BRI(ftdm_channel_get_span(ftdmchan)) ? 0 : 1;             /* PRI = 1, BRI = 0 */
1354                                         ChanID.PrefExcl = 1;    /* always exclusive in NT-mode */
1355 
1356                                         if (ChanID.IntType) {
1357                                                 ChanID.InfoChanSel = 1;         /* None = 0, See Slot = 1, Any = 3 */
1358                                                 ChanID.ChanMapType = 3;         /* B-Chan */
1359                                                 ChanID.ChanSlot = (unsigned char)ftdm_channel_get_id(ftdmchan);
1360                                         } else {
1361                                                 ChanID.InfoChanSel = (unsigned char)ftdm_channel_get_id(ftdmchan) & 0x03;       /* None = 0, B1 = 1, B2 = 2, Any = 3 */
1362                                         }
1363                                         gen->ChanID = Q931AppendIE(gen, (L3UCHAR *) &ChanID);
1364                                 }
1365 
1366                                 Q931Rx43(&isdn_data->q931, gen, gen->Size);
1367                         }
1368                 }
1369                 break;
1370         case FTDM_CHANNEL_STATE_DIALTONE:
1371                 {
1372                         ftdm_isdn_bchan_data_t *data = (ftdm_isdn_bchan_data_t *)ftdmchan->call_data;
1373 
1374                         if (data) {
1375                                 data->digit_timeout = ftdm_time_now() + isdn_data->digit_timeout;
1376                         }
1377                 }
1378                 break;
1379         case FTDM_CHANNEL_STATE_RING:
1380                 {
1381                         if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
1382                                 sig.event_id = FTDM_SIGEVENT_START;
1383                                 if ((status = ftdm_span_send_signal(span, &sig) != FTDM_SUCCESS)) {
1384                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
1385                                 }
1386                         }
1387                 }
1388                 break;
1389         case FTDM_CHANNEL_STATE_RESTART:
1390                 {
1391                         ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_UNSPECIFIED;
1392                         sig.event_id = FTDM_SIGEVENT_RESTART;
1393                         status = ftdm_span_send_signal(span, &sig);
1394                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
1395                 }
1396                 break;
1397         case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
1398                 {
1399                         if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
1400                                 sig.event_id = FTDM_SIGEVENT_PROGRESS_MEDIA;
1401                                 if ((status = ftdm_span_send_signal(span, &sig) != FTDM_SUCCESS)) {
1402                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
1403                                 }
1404                         } else {
1405                                 if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) {
1406                                         if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) {
1407                                                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
1408                                                 return;
1409                                         }
1410                                 }
1411                                 gen->MesType = Q931mes_ALERTING;
1412                                 gen->CRVFlag = 1;       /* inbound call */
1413                                 Q931Rx43(&isdn_data->q931, gen, gen->Size);
1414                         }
1415                 }
1416                 break;
1417         case FTDM_CHANNEL_STATE_UP:
1418                 {
1419                         if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
1420                                 sig.event_id = FTDM_SIGEVENT_UP;
1421                                 if ((status = ftdm_span_send_signal(span, &sig) != FTDM_SUCCESS)) {
1422                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
1423                                 }
1424                         } else {
1425                                 if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) {
1426                                         if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) {
1427                                                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
1428                                                 return;
1429                                         }
1430                                 }
1431                                 gen->MesType = Q931mes_CONNECT;
1432                                 gen->BearerCap = 0;
1433                                 gen->CRVFlag = 1;       /* inbound call */
1434                                 Q931Rx43(&isdn_data->q931, gen, ftdmchan->caller_data.raw_data_len);
1435                         }
1436                 }
1437                 break;
1438         case FTDM_CHANNEL_STATE_DIALING:
1439                 if (!(isdn_data->opts & FTDM_ISDN_OPT_SUGGEST_CHANNEL)) {
1440                         ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(ftdmchan);
1441                         Q931ie_BearerCap BearerCap;
1442                         Q931ie_ChanID ChanID;
1443                         Q931ie_CallingNum CallingNum;
1444                         Q931ie_CallingNum *ptrCallingNum;
1445                         Q931ie_CalledNum CalledNum;
1446                         Q931ie_CalledNum *ptrCalledNum;
1447                         Q931ie_Display Display, *ptrDisplay;
1448                         Q931ie_HLComp HLComp;                   /* High-Layer Compatibility IE */
1449                         Q931ie_ProgInd Progress;                /* Progress Indicator IE */
1450                         int codec  = 0;
1451 
1452                         /*
1453                          * get codec type
1454                          */
1455                         ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_NATIVE_CODEC, &codec);
1456 
1457                         /*
1458                          * Q.931 Setup Message
1459                          */
1460                         Q931InitMesGeneric(gen);
1461                         gen->MesType = Q931mes_SETUP;
1462                         gen->CRVFlag = 0;               /* outbound(?) */
1463 
1464                         /*
1465                          * Bearer Capability IE
1466                          */
1467                         Q931InitIEBearerCap(&BearerCap);
1468                         BearerCap.CodStand  = Q931_CODING_ITU;  /* ITU-T = 0, ISO/IEC = 1, National = 2, Network = 3 */
1469                         BearerCap.ITC       = Q931_ITC_SPEECH;  /* Speech */
1470                         BearerCap.TransMode = 0;                /* Circuit = 0, Packet = 1 */
1471                         BearerCap.ITR       = Q931_ITR_64K;     /* 64k = 16, Packet mode = 0 */
1472                         BearerCap.Layer1Ident = 1;
1473                         BearerCap.UIL1Prot = (codec == FTDM_CODEC_ALAW) ? 3 : 2;        /* U-law = 2, A-law = 3 */
1474                         gen->BearerCap = Q931AppendIE(gen, (L3UCHAR *) &BearerCap);
1475 
1476                         /*
1477                          * ChannelID IE
1478                          */
1479                         Q931InitIEChanID(&ChanID);
1480                         ChanID.IntType = FTDM_SPAN_IS_BRI(ftdm_channel_get_span(ftdmchan)) ? 0 : 1;     /* PRI = 1, BRI = 0 */
1481                         ChanID.PrefExcl = FTDM_SPAN_IS_NT(ftdm_channel_get_span(ftdmchan)) ? 1 : 0;  /* Exclusive in NT-mode = 1, Preferred otherwise = 0 */
1482                         if (ChanID.IntType) {
1483                                 ChanID.InfoChanSel = 1;         /* None = 0, See Slot = 1, Any = 3 */
1484                                 ChanID.ChanMapType = 3;         /* B-Chan */
1485                                 ChanID.ChanSlot = (unsigned char)ftdm_channel_get_id(ftdmchan);
1486                         } else {
1487                                 ChanID.InfoChanSel = (unsigned char)ftdm_channel_get_id(ftdmchan) & 0x03;       /* None = 0, B1 = 1, B2 = 2, Any = 3 */
1488                         }
1489                         gen->ChanID = Q931AppendIE(gen, (L3UCHAR *) &ChanID);
1490 
1491                         /*
1492                          * Progress IE
1493                          */
1494                         Q931InitIEProgInd(&Progress);
1495                         Progress.CodStand = Q931_CODING_ITU;    /* 0 = ITU */
1496                         Progress.Location = 0;  /* 0 = User, 1 = Private Network */
1497                         Progress.ProgDesc = 3;  /* 1 = Not end-to-end ISDN */
1498                         gen->ProgInd = Q931AppendIE(gen, (L3UCHAR *)&Progress);
1499 
1500                         /*
1501                          * Display IE
1502                          */
1503                         if (!(isdn_data->opts & FTDM_ISDN_OPT_OMIT_DISPLAY_IE) && FTDM_SPAN_IS_NT(ftdm_channel_get_span(ftdmchan))) {
1504                                 Q931InitIEDisplay(&Display);
1505                                 Display.Size = Display.Size + (unsigned char)strlen(caller_data->cid_name);
1506                                 gen->Display = Q931AppendIE(gen, (L3UCHAR *) &Display);
1507                                 ptrDisplay = Q931GetIEPtr(gen->Display, gen->buf);
1508                                 ftdm_copy_string((char *)ptrDisplay->Display, caller_data->cid_name, strlen(caller_data->cid_name) + 1);
1509                         }
1510 
1511                         /*
1512                          * CallingNum IE
1513                          */
1514                         Q931InitIECallingNum(&CallingNum);
1515                         CallingNum.TypNum    = caller_data->ani.type;
1516                         CallingNum.NumPlanID = Q931_NUMPLAN_E164;
1517                         CallingNum.PresInd   = Q931_PRES_ALLOWED;
1518                         CallingNum.ScreenInd = Q931_SCREEN_USER_NOT_SCREENED;
1519                         CallingNum.Size = CallingNum.Size + (unsigned char)strlen(caller_data->cid_num.digits);
1520                         gen->CallingNum = Q931AppendIE(gen, (L3UCHAR *) &CallingNum);
1521                         ptrCallingNum = Q931GetIEPtr(gen->CallingNum, gen->buf);
1522                         ftdm_copy_string((char *)ptrCallingNum->Digit, caller_data->cid_num.digits, strlen(caller_data->cid_num.digits) + 1);
1523 
1524                         /*
1525                          * CalledNum IE
1526                          */
1527                         Q931InitIECalledNum(&CalledNum);
1528                         CalledNum.TypNum    = Q931_TON_UNKNOWN;
1529                         CalledNum.NumPlanID = Q931_NUMPLAN_E164;
1530                         CalledNum.Size = CalledNum.Size + (unsigned char)strlen(caller_data->ani.digits);
1531                         gen->CalledNum = Q931AppendIE(gen, (L3UCHAR *) &CalledNum);
1532                         ptrCalledNum = Q931GetIEPtr(gen->CalledNum, gen->buf);
1533                         ftdm_copy_string((char *)ptrCalledNum->Digit, caller_data->ani.digits, strlen(caller_data->ani.digits) + 1);
1534 
1535                         /*
1536                          * High-Layer Compatibility IE   (Note: Required for AVM FritzBox)
1537                          */
1538                         Q931InitIEHLComp(&HLComp);
1539                         HLComp.CodStand  = Q931_CODING_ITU;     /* ITU */
1540                         HLComp.Interpret = 4;   /* only possible value */
1541                         HLComp.PresMeth  = 1;   /* High-layer protocol profile */
1542                         HLComp.HLCharID  = Q931_HLCHAR_TELEPHONY;       /* Telephony = 1, Fax G2+3 = 4, Fax G4 = 65 (Class I)/ 68 (Class II or III) */   /* TODO: make accessible from user layer */
1543                         gen->HLComp = Q931AppendIE(gen, (L3UCHAR *) &HLComp);
1544 
1545                         Q931Rx43(&isdn_data->q931, gen, gen->Size);
1546                         isdn_data->channels_local_crv[gen->CRV] = ftdmchan;
1547 
1548                         /*
1549                          * Support code for the new event handling system
1550                          * Remove this as soon as we have the new api to set up calls
1551                          */
1552                         if (gen->CRV) {
1553                                 struct Q931_Call *call;
1554 
1555                                 call = Q931GetCallByCRV(&isdn_data->q931, gen->CRV);
1556                                 if (call) {
1557                                         ftdm_log(FTDM_LOG_DEBUG, "Storing reference to current span in call %d [0x%x]\n", gen->CRV, gen->CRV);
1558                                         Q931CallSetPrivate(call, ftdm_channel_get_span(ftdmchan));
1559                                 }
1560                         }
1561                 }
1562                 break;
1563         case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
1564                 {
1565                         /* reply RELEASE with RELEASE_COMPLETE message */
1566                         if (ftdm_channel_get_last_state(ftdmchan) == FTDM_CHANNEL_STATE_HANGUP) {
1567                                 gen->MesType = Q931mes_RELEASE_COMPLETE;
1568 
1569                                 Q931Rx43(&isdn_data->q931, gen, gen->Size);
1570                         }
1571                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
1572                 }
1573                 break;
1574         case FTDM_CHANNEL_STATE_HANGUP:
1575                 {
1576                         ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(ftdmchan);
1577                         Q931ie_Cause cause;
1578 
1579                         ftdm_log(FTDM_LOG_DEBUG, "Hangup: Direction %s\n", ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) ? "Outbound" : "Inbound");
1580 
1581                         gen->CRVFlag = ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) ? 0 : 1;
1582 
1583                         cause.IEId = Q931ie_CAUSE;
1584                         cause.Size = sizeof(Q931ie_Cause);
1585                         cause.CodStand = Q931_CODING_ITU;       /* ITU */
1586                         cause.Location = 1;     /* private network */
1587                         cause.Recom    = 1;     /* */
1588 
1589                         /*
1590                          * BRI PTMP needs special handling here...
1591                          * TODO: cleanup / refine (see above)
1592                          */
1593                         if (ftdm_channel_get_last_state(ftdmchan) == FTDM_CHANNEL_STATE_RING) {
1594                                 /*
1595                                  * inbound call [was: number unknown (= not found in routing state)]
1596                                  * (in Q.931 spec terms: Reject request)
1597                                  */
1598                                 gen->MesType = Q931mes_RELEASE_COMPLETE;
1599 
1600                                 //cause.Value = (unsigned char) FTDM_CAUSE_UNALLOCATED;
1601                                 cause.Value = (unsigned char) caller_data->hangup_cause;
1602                                 *cause.Diag = '\0';
1603                                 gen->Cause = Q931AppendIE(gen, (L3UCHAR *) &cause);
1604                                 Q931Rx43(&isdn_data->q931, gen, gen->Size);
1605 
1606                                 /* we're done, release channel */
1607                                 //ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
1608                                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
1609                         }
1610                         else if (ftdm_channel_get_last_state(ftdmchan) <= FTDM_CHANNEL_STATE_PROGRESS) {
1611                                 /*
1612                                  * just release all unanswered calls [was: inbound call, remote side hung up before we answered]
1613                                  */
1614                                 gen->MesType = Q931mes_RELEASE;
1615 
1616                                 cause.Value = (unsigned char) caller_data->hangup_cause;
1617                                 *cause.Diag = '\0';
1618                                 gen->Cause = Q931AppendIE(gen, (L3UCHAR *) &cause);
1619                                 Q931Rx43(&isdn_data->q931, gen, gen->Size);
1620 
1621                                 /* this will be triggered by the RELEASE_COMPLETE reply */
1622                                 /* ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); */
1623                         }
1624                         else {
1625                                 /*
1626                                  * call connected, hangup
1627                                  */
1628                                 gen->MesType = Q931mes_DISCONNECT;
1629 
1630                                 cause.Value = (unsigned char) caller_data->hangup_cause;
1631                                 *cause.Diag = '\0';
1632                                 gen->Cause = Q931AppendIE(gen, (L3UCHAR *) &cause);
1633                                 Q931Rx43(&isdn_data->q931, gen, gen->Size);
1634                         }
1635                 }
1636                 break;
1637         case FTDM_CHANNEL_STATE_TERMINATING:
1638                 {
1639                         ftdm_log(FTDM_LOG_DEBUG, "Terminating: Direction %s\n", ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) ? "Outbound" : "Inbound");
1640 
1641                         sig.event_id = FTDM_SIGEVENT_STOP;
1642                         status = ftdm_span_send_signal(span, &sig);
1643 
1644                         gen->MesType = Q931mes_RELEASE;
1645                         gen->CRVFlag = ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) ? 0 : 1;
1646                         Q931Rx43(&isdn_data->q931, gen, gen->Size);
1647                 }
1648         default:
1649                 break;
1650         }
1651 }
1652 
1653 static __inline__ void check_state(ftdm_span_t *span)
1654 {
1655         if (ftdm_test_flag(span, FTDM_SPAN_STATE_CHANGE)) {
1656                 uint32_t j;
1657 
1658                 ftdm_clear_flag_locked(span, FTDM_SPAN_STATE_CHANGE);
1659 
1660                 for (j = 1; j <= ftdm_span_get_chan_count(span); j++) {
1661                         ftdm_channel_t *chan = ftdm_span_get_channel(span, j);
1662 
1663                         if (ftdm_test_flag(chan, FTDM_CHANNEL_STATE_CHANGE)) {
1664                                 ftdm_channel_lock(chan);
1665 
1666                                 ftdm_clear_flag(chan, FTDM_CHANNEL_STATE_CHANGE);
1667                                 state_advance(chan);
1668                                 ftdm_channel_complete_state(chan);
1669 
1670                                 ftdm_channel_unlock(chan);
1671                         }
1672                 }
1673         }
1674 }
1675 
1676 
1677 static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *event)
1678 {
1679         ftdm_alarm_flag_t alarmbits;
1680         ftdm_sigmsg_t sig;
1681 
1682         memset(&sig, 0, sizeof(sig));
1683         sig.span_id = ftdm_channel_get_span_id(event->channel);
1684         sig.chan_id = ftdm_channel_get_id(event->channel);
1685         sig.channel = event->channel;
1686 
1687         ftdm_log(FTDM_LOG_DEBUG, "EVENT [%s][%d:%d] STATE [%s]\n",
1688                         ftdm_oob_event2str(event->enum_id),
1689                         ftdm_channel_get_span_id(event->channel),
1690                         ftdm_channel_get_id(event->channel),
1691                         ftdm_channel_get_state_str(event->channel));
1692 
1693         switch (event->enum_id) {
1694         case FTDM_OOB_ALARM_TRAP:
1695                 {
1696                         sig.event_id = FTDM_OOB_ALARM_TRAP;
1697                         if (ftdm_channel_get_state(event->channel) != FTDM_CHANNEL_STATE_DOWN) {
1698                                 ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_RESTART);
1699                         }
1700                         ftdm_set_flag(event->channel, FTDM_CHANNEL_SUSPENDED);
1701                         ftdm_channel_get_alarms(event->channel, &alarmbits);
1702                         ftdm_span_send_signal(span, &sig);
1703 
1704                         ftdm_log(FTDM_LOG_WARNING, "channel %d:%d (%d:%d) has alarms [%s]\n",
1705                                         ftdm_channel_get_span_id(event->channel),
1706                                         ftdm_channel_get_id(event->channel),
1707                                         ftdm_channel_get_ph_span_id(event->channel),
1708                                         ftdm_channel_get_ph_id(event->channel),
1709                                         ftdm_channel_get_last_error(event->channel));
1710                 }
1711                 break;
1712         case FTDM_OOB_ALARM_CLEAR:
1713                 {
1714                         sig.event_id = FTDM_OOB_ALARM_CLEAR;
1715                         ftdm_clear_flag(event->channel, FTDM_CHANNEL_SUSPENDED);
1716                         ftdm_channel_get_alarms(event->channel, &alarmbits);
1717                         ftdm_span_send_signal(span, &sig);
1718                 }
1719                 break;
1720 #ifdef __BROKEN_BY_FREETDM_CONVERSION__
1721         case FTDM_OOB_DTMF:     /* Taken from ozmod_analog, minus the CALLWAITING state handling */
1722                 {
1723                         const char * digit_str = (const char *)event->data;
1724 
1725                         if (digit_str) {
1726                                 fio_event_cb_t event_callback = NULL;
1727 
1728                                 ftdm_channel_queue_dtmf(event->channel, digit_str);
1729                                 if (span->event_callback) {
1730                                         event_callback = span->event_callback;
1731                                 } else if (event->channel->event_callback) {
1732                                         event_callback = event->channel->event_callback;
1733                                 }
1734 
1735                                 if (event_callback) {
1736                                         event->channel->event_header.channel = event->channel;
1737                                         event->channel->event_header.e_type = FTDM_EVENT_DTMF;
1738                                         event->channel->event_header.data = (void *)digit_str;
1739                                         event_callback(event->channel, &event->channel->event_header);
1740                                         event->channel->event_header.e_type = FTDM_EVENT_NONE;
1741                                         event->channel->event_header.data = NULL;
1742                                 }
1743                                 ftdm_safe_free(event->data);
1744                         }
1745                 }
1746                 break;
1747 #endif
1748         }
1749 
1750         return FTDM_SUCCESS;
1751 }
1752 
1753 
1754 static __inline__ void check_events(ftdm_span_t *span)
1755 {
1756         ftdm_status_t status = ftdm_span_poll_event(span, 5, NULL);
1757 
1758         switch (status) {
1759         case FTDM_SUCCESS:
1760                 {
1761                         ftdm_event_t *event;
1762 
1763                         while (ftdm_span_next_event(span, &event) == FTDM_SUCCESS) {
1764                                 if (event->enum_id == FTDM_OOB_NOOP) {
1765                                         continue;
1766                                 }
1767                                 if (process_event(span, event) != FTDM_SUCCESS) {
1768                                         break;
1769                                 }
1770                         }
1771                 }
1772                 break;
1773         case FTDM_FAIL:
1774                 {
1775                         ftdm_log(FTDM_LOG_DEBUG, "Event Failure! %d\n", ftdm_running());
1776                 }
1777                 break;
1778         default:
1779                 break;
1780         }
1781 }
1782 
1783 
1784 static int teletone_handler(teletone_generation_session_t *ts, teletone_tone_map_t *map)
1785 {
1786         ftdm_buffer_t *dt_buffer = ts->user_data;
1787         int wrote;
1788 
1789         if (!dt_buffer) {
1790                 return -1;
1791         }
1792 
1793         wrote = teletone_mux_tones(ts, map);
1794         ftdm_buffer_write(dt_buffer, ts->buffer, wrote * 2);
1795         return 0;
1796 }
1797 
1798 static void *ftdm_isdn_tones_run(ftdm_thread_t *me, void *obj)
1799 {
1800         ftdm_span_t *span = (ftdm_span_t *) obj;
1801         ftdm_isdn_data_t *isdn_data = span->signal_data;
1802         ftdm_buffer_t *dt_buffer = NULL;
1803         teletone_generation_session_t ts = {{{{0}}}};;
1804         unsigned char frame[1024];
1805         int x, interval;
1806         int offset = 0;
1807 
1808         ftdm_log(FTDM_LOG_DEBUG, "ISDN tones thread starting.\n");
1809         ftdm_set_flag(isdn_data, FTDM_ISDN_TONES_RUNNING);
1810 
1811         if (ftdm_buffer_create(&dt_buffer, 1024, 1024, 0) != FTDM_SUCCESS) {
1812                 snprintf(isdn_data->dchan->last_error, sizeof(isdn_data->dchan->last_error), "memory error!");
1813                 ftdm_log(FTDM_LOG_ERROR, "MEM ERROR\n");
1814                 goto done;
1815         }
1816         ftdm_buffer_set_loops(dt_buffer, -1);
1817 
1818         /* get a tone generation friendly interval to avoid distortions */
1819         for (x = 1; x <= ftdm_span_get_chan_count(span); x++) {
1820                 ftdm_channel_t *chan = ftdm_span_get_channel(span, x);
1821 
1822                 if (ftdm_channel_get_type(chan) != FTDM_CHAN_TYPE_DQ921) {
1823                         ftdm_channel_command(chan, FTDM_COMMAND_GET_INTERVAL, &interval);
1824                         break;
1825                 }
1826         }
1827         if (!interval) {
1828                 interval = 20;
1829         }
1830         ftdm_log(FTDM_LOG_NOTICE, "Tone generating interval %d\n", interval);
1831 
1832         /* init teletone */
1833         teletone_init_session(&ts, 0, teletone_handler, dt_buffer);
1834         ts.rate     = 8000;
1835         ts.duration = ts.rate;
1836 
1837         /* main loop */
1838         while (ftdm_running() && ftdm_test_flag(isdn_data, FTDM_ISDN_RUNNING)) {
1839                 ftdm_wait_flag_t flags;
1840                 ftdm_status_t status;
1841                 int last_chan_state = 0;
1842                 int gated = 0;
1843                 L2ULONG now = ftdm_time_now();
1844 
1845                 /*
1846                  * check b-channel states and generate & send tones if neccessary
1847                  */
1848                 for (x = 1; x <= ftdm_span_get_chan_count(span); x++) {
1849                         ftdm_channel_t *chan = ftdm_span_get_channel(span, x);
1850                         ftdm_size_t len = sizeof(frame), rlen;
1851 
1852                         if (ftdm_channel_get_type(chan) == FTDM_CHAN_TYPE_DQ921) {
1853                                 continue;
1854                         }
1855 
1856                         /*
1857                          * Generate tones based on current bchan state
1858                          * (Recycle buffer content if succeeding channels share the
1859                          *  same state, this saves some cpu cycles)
1860                          */
1861                         switch (ftdm_channel_get_state(chan)) {
1862                         case FTDM_CHANNEL_STATE_DIALTONE:
1863                                 {
1864                                         ftdm_isdn_bchan_data_t *data = (ftdm_isdn_bchan_data_t *)chan->call_data;
1865                                         ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(chan);
1866 
1867                                         /* check overlap dial timeout first before generating tone */
1868                                         if (data && data->digit_timeout && data->digit_timeout <= now) {
1869                                                 if (strlen(caller_data->dnis.digits) > 0) {
1870                                                         ftdm_log(FTDM_LOG_DEBUG, "Overlap dial timeout, advancing to RING state\n");
1871                                                         ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_RING);
1872                                                 } else {
1873                                                         /* no digits received, hangup */
1874                                                         ftdm_log(FTDM_LOG_DEBUG, "Overlap dial timeout, no digits received, going to HANGUP state\n");
1875                                                         caller_data->hangup_cause = FTDM_CAUSE_RECOVERY_ON_TIMER_EXPIRE;        /* TODO: probably wrong cause value */
1876                                                         ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP);
1877                                                 }
1878                                                 data->digit_timeout = 0;
1879                                                 continue;
1880                                         }
1881 
1882                                         if (last_chan_state != ftdm_channel_get_state(chan)) {
1883                                                 ftdm_buffer_zero(dt_buffer);
1884                                                 teletone_run(&ts, span->tone_map[FTDM_TONEMAP_DIAL]);
1885                                                 last_chan_state = ftdm_channel_get_state(chan);
1886                                         }
1887                                 }
1888                                 break;
1889 
1890                         case FTDM_CHANNEL_STATE_RING:
1891                                 {
1892                                         if (last_chan_state != ftdm_channel_get_state(chan)) {
1893                                                 ftdm_buffer_zero(dt_buffer);
1894                                                 teletone_run(&ts, span->tone_map[FTDM_TONEMAP_RING]);
1895                                                 last_chan_state = ftdm_channel_get_state(chan);
1896                                         }
1897                                 }
1898                                 break;
1899 
1900                         default:        /* Not in a tone generating state, go to next round */
1901                                 continue;
1902                         }
1903 
1904                         if (!ftdm_test_flag(chan, FTDM_CHANNEL_OPEN)) {
1905                                 if (ftdm_channel_open_chan(chan) != FTDM_SUCCESS) {
1906                                         ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP);
1907                                         continue;
1908                                 }
1909                                 ftdm_log(FTDM_LOG_NOTICE, "Successfully opened channel %d:%d\n",
1910                                                 ftdm_channel_get_span_id(chan),
1911                                                 ftdm_channel_get_id(chan));
1912                         }
1913 
1914                         flags = FTDM_READ;
1915 
1916                         status = ftdm_channel_wait(chan, &flags, (gated) ? 0 : interval);
1917                         switch (status) {
1918                         case FTDM_FAIL:
1919                                 continue;
1920 
1921                         case FTDM_TIMEOUT:
1922                                 gated = 1;
1923                                 continue;
1924 
1925                         default:
1926                                 if (!(flags & FTDM_READ)) {
1927                                         continue;
1928                                 }
1929                         }
1930                         gated = 1;
1931 
1932                         status = ftdm_channel_read(chan, frame, &len);
1933                         if (status != FTDM_SUCCESS || len <= 0) {
1934                                 continue;
1935                         }
1936 
1937                         if (chan->effective_codec != FTDM_CODEC_SLIN) {
1938                                 len *= 2;
1939                         }
1940 
1941                         /* seek to current offset */
1942                         ftdm_buffer_seek(dt_buffer, offset);
1943 
1944                         rlen = ftdm_buffer_read_loop(dt_buffer, frame, len);
1945 
1946                         if (chan->effective_codec != FTDM_CODEC_SLIN) {
1947                                 fio_codec_t codec_func = NULL;
1948 
1949                                 if (chan->native_codec == FTDM_CODEC_ULAW) {
1950                                         codec_func = fio_slin2ulaw;
1951                                 } else if (chan->native_codec == FTDM_CODEC_ALAW) {
1952                                         codec_func = fio_slin2alaw;
1953                                 }
1954 
1955                                 if (codec_func) {
1956                                         status = codec_func(frame, sizeof(frame), &rlen);
1957                                 } else {
1958                                         snprintf(chan->last_error, sizeof(chan->last_error), "codec error!");
1959                                         goto done;
1960                                 }
1961                         }
1962                         ftdm_channel_write(chan, frame, sizeof(frame), &rlen);
1963                 }
1964 
1965                 /*
1966                  * sleep a bit if there was nothing to do
1967                  */
1968                 if (!gated) {
1969                         ftdm_sleep(interval);
1970                 }
1971 
1972                 offset += (ts.rate / (1000 / interval)) << 1;
1973                 if (offset >= ts.rate) {
1974                         offset = 0;
1975                 }
1976         }
1977 
1978 done:
1979         if (ts.buffer) {
1980                 teletone_destroy_session(&ts);
1981         }
1982 
1983         if (dt_buffer) {
1984                 ftdm_buffer_destroy(&dt_buffer);
1985         }
1986 
1987         ftdm_log(FTDM_LOG_DEBUG, "ISDN tone thread ended.\n");
1988         ftdm_clear_flag(isdn_data, FTDM_ISDN_TONES_RUNNING);
1989 
1990         return NULL;
1991 }
1992 
1993 static void *ftdm_isdn_run(ftdm_thread_t *me, void *obj)
1994 {
1995         ftdm_span_t *span = (ftdm_span_t *) obj;
1996         ftdm_isdn_data_t *isdn_data = span->signal_data;
1997         unsigned char frame[1024];
1998         ftdm_size_t len = sizeof(frame);
1999         int errs = 0;
2000 
2001 #ifdef WIN32
2002         timeBeginPeriod(1);
2003 #endif
2004 
2005         ftdm_log(FTDM_LOG_DEBUG, "ISDN thread starting.\n");
2006         ftdm_set_flag(isdn_data, FTDM_ISDN_RUNNING);
2007 
2008         Q921Start(&isdn_data->q921);
2009         Q931Start(&isdn_data->q931);
2010 
2011         while (ftdm_running() && ftdm_test_flag(isdn_data, FTDM_ISDN_RUNNING)) {
2012                 ftdm_wait_flag_t flags = FTDM_READ;
2013                 ftdm_status_t status = ftdm_channel_wait(isdn_data->dchan, &flags, 100);
2014 
2015                 Q921TimerTick(&isdn_data->q921);
2016                 Q931TimerTick(&isdn_data->q931);
2017                 check_state(span);
2018                 check_events(span);
2019 
2020                 /*
2021                  *
2022                  */
2023                 switch (status) {
2024                 case FTDM_FAIL:
2025                         {
2026                                 ftdm_log(FTDM_LOG_ERROR, "D-Chan Read Error!\n");
2027                                 snprintf(span->last_error, sizeof(span->last_error), "D-Chan Read Error!");
2028                                 if (++errs == 10) {
2029                                         isdn_data->dchan->state = FTDM_CHANNEL_STATE_UP;
2030                                         goto done;
2031                                 }
2032                         }
2033                         break;
2034                 case FTDM_TIMEOUT:
2035                         {
2036                                 errs = 0;
2037                         }
2038                         break;
2039                 default:
2040                         {
2041                                 errs = 0;
2042                                 if (flags & FTDM_READ) {
2043                                         len = sizeof(frame);
2044                                         if (ftdm_channel_read(isdn_data->dchan, frame, &len) == FTDM_SUCCESS) {
2045 #ifdef HAVE_PCAP
2046                                                 if (isdn_pcap_capture_both(isdn_data)) {
2047                                                         isdn_pcap_write(isdn_data, frame, len, ISDN_PCAP_INCOMING);
2048                                                 }
2049 #endif
2050                                                 Q921QueueHDLCFrame(&isdn_data->q921, frame, (int)len);
2051                                                 Q921Rx12(&isdn_data->q921);
2052                                         }
2053                                 } else {
2054                                         ftdm_log(FTDM_LOG_DEBUG, "No Read FLAG!\n");
2055                                 }
2056                         }
2057                         break;
2058                 }
2059         }
2060 
2061 done:
2062         ftdm_channel_close(&isdn_data->dchan);
2063         ftdm_clear_flag(isdn_data, FTDM_ISDN_RUNNING);
2064 
2065 #ifdef WIN32
2066         timeEndPeriod(1);
2067 #endif
2068 #ifdef HAVE_PCAP
2069         if (isdn_pcap_is_open(isdn_data)) {
2070                 isdn_pcap_close(isdn_data);
2071         }
2072 #endif
2073         ftdm_log(FTDM_LOG_DEBUG, "ISDN thread ended.\n");
2074         return NULL;
2075 }
2076 
2077 static int q931_rx_32(void *pvt, Q921DLMsg_t ind, L3UCHAR tei, L3UCHAR *msg, L3INT mlen)
2078 {
2079         ftdm_span_t *span = pvt;
2080         ftdm_isdn_data_t *isdn_data = span->signal_data;
2081         int offset = 4;
2082         char bb[4096] = "";
2083 
2084         switch(ind) {
2085         case Q921_DL_UNIT_DATA:
2086                 offset = 3;
2087 
2088         case Q921_DL_DATA:
2089                 print_hex_bytes(msg + offset, mlen - offset, bb, sizeof(bb));
2090                 ftdm_log(FTDM_LOG_DEBUG, "WRITE %d\n%s\n%s\n\n", (int)mlen - offset, LINE, bb);
2091                 break;
2092 
2093         default:
2094                 break;
2095         }
2096 
2097 #ifdef HAVE_PCAP
2098         if (isdn_pcap_capture_l3only(isdn_data)) {
2099                 isdn_pcap_write(isdn_data, msg, mlen, ISDN_PCAP_OUTGOING);
2100         }
2101 #endif
2102         return Q921Rx32(&isdn_data->q921, ind, tei, msg, mlen);
2103 }
2104 
2105 static int ftdm_isdn_q921_log(void *pvt, Q921LogLevel_t level, char *msg, L2INT size)
2106 {
2107         ftdm_span_t *span = (ftdm_span_t *) pvt;
2108 
2109         ftdm_log("Span", "Q.921", span->span_id, (int)level, "%s", msg);
2110         return 0;
2111 }
2112 
2113 static L3INT ftdm_isdn_q931_log(void *pvt, Q931LogLevel_t level, char *msg, L3INT size)
2114 {
2115         ftdm_span_t *span = (ftdm_span_t *) pvt;
2116 
2117         ftdm_log("Span", "Q.931", span->span_id, (int)level, "%s", msg);
2118         return 0;
2119 }
2120 
2121 static ftdm_state_map_t isdn_state_map = {
2122         {
2123                 {
2124                         ZSD_OUTBOUND,
2125                         ZSM_UNACCEPTABLE,
2126                         {FTDM_ANY_STATE},
2127                         {FTDM_CHANNEL_STATE_RESTART, FTDM_END}
2128                 },
2129                 {
2130                         ZSD_OUTBOUND,
2131                         ZSM_UNACCEPTABLE,
2132                         {FTDM_CHANNEL_STATE_RESTART, FTDM_END},
2133                         {FTDM_CHANNEL_STATE_DOWN, FTDM_END}
2134                 },
2135                 {
2136                         ZSD_OUTBOUND,
2137                         ZSM_UNACCEPTABLE,
2138                         {FTDM_CHANNEL_STATE_DOWN, FTDM_END},
2139                         {FTDM_CHANNEL_STATE_DIALING, FTDM_END}
2140                 },
2141                 {
2142                         ZSD_OUTBOUND,
2143                         ZSM_UNACCEPTABLE,
2144                         {FTDM_CHANNEL_STATE_DIALING, FTDM_END},
2145                         {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_DOWN, FTDM_END}
2146                 },
2147                 {
2148                         ZSD_OUTBOUND,
2149                         ZSM_UNACCEPTABLE,
2150                         {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_PROGRESS, FTDM_END},
2151                         {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_UP, FTDM_END}
2152                 },
2153                 {
2154                         ZSD_OUTBOUND,
2155                         ZSM_UNACCEPTABLE,
2156                         {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END},
2157                         {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_DOWN, FTDM_END}
2158                 },
2159                 {
2160                         ZSD_OUTBOUND,
2161                         ZSM_UNACCEPTABLE,
2162                         {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END},
2163                         {FTDM_CHANNEL_STATE_DOWN, FTDM_END},
2164                 },
2165                 {
2166                         ZSD_OUTBOUND,
2167                         ZSM_UNACCEPTABLE,
2168                         {FTDM_CHANNEL_STATE_UP, FTDM_END},
2169                         {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}
2170                 },
2171 
2172                 /****************************************/
2173                 {
2174                         ZSD_INBOUND,
2175                         ZSM_UNACCEPTABLE,
2176                         {FTDM_ANY_STATE},
2177                         {FTDM_CHANNEL_STATE_RESTART, FTDM_END}
2178                 },
2179                 {
2180                         ZSD_INBOUND,
2181                         ZSM_UNACCEPTABLE,
2182                         {FTDM_CHANNEL_STATE_RESTART, FTDM_END},
2183                         {FTDM_CHANNEL_STATE_DOWN, FTDM_END}
2184                 },
2185                 {
2186                         ZSD_INBOUND,
2187                         ZSM_UNACCEPTABLE,
2188                         {FTDM_CHANNEL_STATE_DOWN, FTDM_END},
2189                         {FTDM_CHANNEL_STATE_DIALTONE, FTDM_CHANNEL_STATE_RING, FTDM_END}
2190                 },
2191                 {
2192                         ZSD_INBOUND,
2193                         ZSM_UNACCEPTABLE,
2194                         {FTDM_CHANNEL_STATE_DIALTONE, FTDM_END},
2195                         {FTDM_CHANNEL_STATE_RING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}
2196                 },
2197                 {
2198                         ZSD_INBOUND,
2199                         ZSM_UNACCEPTABLE,
2200                         {FTDM_CHANNEL_STATE_RING, FTDM_END},
2201                         {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END}
2202                 },
2203                 {
2204                         ZSD_INBOUND,
2205                         ZSM_UNACCEPTABLE,
2206                         {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END},
2207                         {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_DOWN, FTDM_END},
2208                 },
2209                 {
2210                         ZSD_INBOUND,
2211                         ZSM_UNACCEPTABLE,
2212                         {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END},
2213                         {FTDM_CHANNEL_STATE_DOWN, FTDM_END},
2214                 },
2215                 {
2216                         ZSD_INBOUND,
2217                         ZSM_UNACCEPTABLE,
2218                         {FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_END},
2219                         {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_PROGRESS_MEDIA,
2220                          FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_UP, FTDM_END},
2221                 },
2222                 {
2223                         ZSD_INBOUND,
2224                         ZSM_UNACCEPTABLE,
2225                         {FTDM_CHANNEL_STATE_UP, FTDM_END},
2226                         {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END},
2227                 },
2228         }
2229 };
2230 
2231 /**
2232  * \brief       Stop signalling on span
2233  */
2234 static ftdm_status_t ftdm_isdn_stop(ftdm_span_t *span)
2235 {
2236         ftdm_isdn_data_t *isdn_data = span->signal_data;
2237 
2238         if (!ftdm_test_flag(isdn_data, FTDM_ISDN_RUNNING)) {
2239                 return FTDM_FAIL;
2240         }
2241 
2242         ftdm_set_flag(isdn_data, FTDM_ISDN_STOP);
2243 
2244         while (ftdm_test_flag(isdn_data, FTDM_ISDN_RUNNING)) {
2245                 ftdm_sleep(100);
2246         }
2247 
2248         while (ftdm_test_flag(isdn_data, FTDM_ISDN_TONES_RUNNING)) {
2249                 ftdm_sleep(100);
2250         }
2251 
2252         return FTDM_SUCCESS;
2253 }
2254 
2255 /**
2256  * \brief       Start signalling on span
2257  */
2258 static ftdm_status_t ftdm_isdn_start(ftdm_span_t *span)
2259 {
2260         ftdm_isdn_data_t *isdn_data = span->signal_data;
2261         ftdm_status_t ret;
2262 
2263         if (ftdm_test_flag(isdn_data, FTDM_ISDN_RUNNING)) {
2264                 return FTDM_FAIL;
2265         }
2266 
2267         ftdm_clear_flag(isdn_data, FTDM_ISDN_STOP);
2268         ret = ftdm_thread_create_detached(ftdm_isdn_run, span);
2269 
2270         if (ret != FTDM_SUCCESS) {
2271                 return ret;
2272         }
2273 
2274         if (FTDM_SPAN_IS_NT(span) && !(isdn_data->opts & FTDM_ISDN_OPT_DISABLE_TONES)) {
2275                 ret = ftdm_thread_create_detached(ftdm_isdn_tones_run, span);
2276         }
2277         return ret;
2278 }
2279 
2280 
2281 /*###################################################################*
2282  * (text) value parsing / translation
2283  *###################################################################*/
2284 
2285 static int32_t parse_loglevel(const char *level)
2286 {
2287         if (!level)
2288                 return -1;
2289 
2290         if (!strcasecmp(level, "debug")) {
2291                 return FTDM_LOG_LEVEL_DEBUG;
2292         } else if (!strcasecmp(level, "info")) {
2293                 return FTDM_LOG_LEVEL_INFO;
2294         } else if (!strcasecmp(level, "notice")) {
2295                 return FTDM_LOG_LEVEL_NOTICE;
2296         } else if (!strcasecmp(level, "warning")) {
2297                 return FTDM_LOG_LEVEL_WARNING;
2298         } else if (!strcasecmp(level, "error")) {
2299                 return FTDM_LOG_LEVEL_ERROR;
2300         } else if (!strcasecmp(level, "alert")) {
2301                 return FTDM_LOG_LEVEL_ALERT;
2302         } else if (!strcasecmp(level, "crit")) {
2303                 return FTDM_LOG_LEVEL_CRIT;
2304         } else if (!strcasecmp(level, "emerg")) {
2305                 return FTDM_LOG_LEVEL_EMERG;
2306         } else {
2307                 return -1;
2308         }
2309 }
2310 
2311 static int parse_opts(const char *in, uint32_t *flags)
2312 {
2313         if (!in || !flags)
2314                 return -1;
2315 
2316         if (strstr(in, "suggest_channel")) {
2317                 *flags |= FTDM_ISDN_OPT_SUGGEST_CHANNEL;
2318         }
2319         if (strstr(in, "omit_display")) {
2320                 *flags |= FTDM_ISDN_OPT_OMIT_DISPLAY_IE;
2321         }
2322         if (strstr(in, "disable_tones")) {
2323                 *flags |= FTDM_ISDN_OPT_DISABLE_TONES;
2324         }
2325 
2326         return 0;
2327 }
2328 
2329 static int parse_dialect(const char *in, uint32_t *dialect)
2330 {
2331         if (!in || !dialect)
2332                 return -1;
2333 
2334 #if __UNSUPPORTED__
2335         if (!strcasecmp(in, "national")) {
2336                 *dialect = Q931_Dialect_National;
2337                 return 0;
2338         }
2339         if (!strcasecmp(in, "dms")) {
2340                 *dialect = Q931_Dialect_DMS;
2341                 return 0;
2342         }
2343 #endif
2344         if (!strcasecmp(in, "5ess")) {
2345                 *dialect = Q931_Dialect_5ESS;
2346                 return 0;
2347         }
2348         if (!strcasecmp(in, "dss1") || !strcasecmp(in, "euroisdn")) {
2349                 *dialect = Q931_Dialect_DSS1;
2350                 return 0;
2351         }
2352         if (!strcasecmp(in, "q931")) {
2353                 *dialect = Q931_Dialect_Q931;
2354                 return 0;
2355         }
2356 
2357         return -1;
2358 }
2359 
2360 
2361 /*###################################################################*
2362  * API commands
2363  *###################################################################*/
2364 
2365 static const char isdn_api_usage[] =
2366 #ifdef HAVE_PCAP
2367         "isdn capture <span> <start> <filename> [q931only]\n"
2368         "isdn capture <span> <stop|suspend|resume>\n"
2369 #endif
2370         "isdn loglevel <span> <q921|q931|all> <loglevel>\n"
2371         "isdn dump <span> calls\n"
2372         "isdn help";
2373 
2374 
2375 /**
2376  * isdn_api
2377  */
2378 static FIO_API_FUNCTION(isdn_api)
2379 {
2380         char *mycmd = NULL, *argv[10] = { 0 };
2381         int argc = 0;
2382 
2383         if (data) {
2384                 mycmd = strdup(data);
2385                 argc = ftdm_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
2386         }
2387 
2388         if (!argc || !strcasecmp(argv[0], "help")) {
2389                 stream->write_function(stream, "%s\n", isdn_api_usage);
2390                 goto done;
2391         }
2392         else if (!strcasecmp(argv[0], "dump")) {
2393                 ftdm_isdn_data_t *isdn_data = NULL;
2394                 ftdm_span_t *span = NULL;
2395                 int span_id = 0;
2396 
2397                 /* dump <span> calls */
2398 
2399                 if (argc < 3) {
2400                         stream->write_function(stream, "-ERR not enough arguments.\n");
2401                         goto done;
2402                 }
2403 
2404                 span_id = atoi(argv[1]);
2405 
2406                 if (ftdm_span_find_by_name(argv[1], &span) == FTDM_SUCCESS || ftdm_span_find(span_id, &span) == FTDM_SUCCESS) {
2407                         isdn_data = span->signal_data;
2408                 } else {
2409                         stream->write_function(stream, "-ERR invalid span.\n");
2410                         goto done;
2411                 }
2412 
2413                 if (!strcasecmp(argv[2], "calls")) {
2414                         /* dump all calls to log */
2415                         Q931DumpAllCalls(&isdn_data->q931);
2416                         stream->write_function(stream, "+OK call information dumped to log\n");
2417                         goto done;
2418                 }
2419         }
2420         else if (!strcasecmp(argv[0], "loglevel")) {
2421                 ftdm_isdn_data_t *isdn_data = NULL;
2422                 ftdm_span_t *span = NULL;
2423                 int span_id = 0;
2424                 int layer   = 0;
2425                 int level   = 0;
2426 
2427                 /* loglevel <span> <q921|q931|all> [level] */
2428 
2429                 if (argc < 3) {
2430                         stream->write_function(stream, "-ERR not enough arguments.\n");
2431                         goto done;
2432                 }
2433 
2434                 span_id = atoi(argv[1]);
2435 
2436                 if (ftdm_span_find_by_name(argv[1], &span) == FTDM_SUCCESS || ftdm_span_find(span_id, &span) == FTDM_SUCCESS) {
2437                         isdn_data = span->signal_data;
2438                 } else {
2439                         stream->write_function(stream, "-ERR invalid span.\n");
2440                         goto done;
2441                 }
2442 
2443                 if (!strcasecmp(argv[2], "q921")) {
2444                         layer = 0x01;
2445                 } else if (!strcasecmp(argv[2], "q931")) {
2446                         layer = 0x02;
2447                 } else if (!strcasecmp(argv[2], "all")) {
2448                         layer = 0x03;
2449                 } else {
2450                         stream->write_function(stream, "-ERR invalid layer\n");
2451                         goto done;
2452                 }
2453 
2454                 if (argc > 3) {
2455                         /* set loglevel  */
2456                         if ((level = parse_loglevel(argv[3])) < 0) {
2457                                 stream->write_function(stream, "-ERR invalid loglevel\n");
2458                                 goto done;
2459                         }
2460 
2461                         if (layer & 0x01) {     /* q921 */
2462                                 Q921SetLogLevel(&isdn_data->q921, (Q921LogLevel_t)level);
2463                         }
2464                         if (layer & 0x02) {     /* q931 */
2465                                 Q931SetLogLevel(&isdn_data->q931, (Q931LogLevel_t)level);
2466                         }
2467                         stream->write_function(stream, "+OK loglevel set");
2468                 } else {
2469                         /* get loglevel */
2470                         if (layer & 0x01) {
2471                                 stream->write_function(stream, "Q.921 loglevel: %s\n",
2472                                         Q921GetLogLevelName(&isdn_data->q921));
2473                         }
2474                         if (layer & 0x02) {
2475                                 stream->write_function(stream, "Q.931 loglevel: %s\n",
2476                                         Q931GetLogLevelName(&isdn_data->q931));
2477                         }
2478                         stream->write_function(stream, "+OK");
2479                 }
2480                 goto done;
2481         }
2482 #ifdef HAVE_PCAP
2483         else if (!strcasecmp(argv[0], "capture")) {
2484                 ftdm_isdn_data_t *isdn_data = NULL;
2485                 ftdm_span_t *span = NULL;
2486                 int span_id = 0;
2487 
2488                 /* capture <span> <start> <filename> [q931only] */
2489                 /* capture <span> <stop|suspend|resume> */
2490 
2491                 if (argc < 3) {
2492                         stream->write_function(stream, "-ERR not enough arguments.\n");
2493                         goto done;
2494                 }
2495 
2496                 span_id = atoi(argv[1]);
2497 
2498                 if (ftdm_span_find_by_name(argv[1], &span) == FTDM_SUCCESS || ftdm_span_find(span_id, &span) == FTDM_SUCCESS) {
2499                         isdn_data = span->signal_data;
2500                 } else {
2501                         stream->write_function(stream, "-ERR invalid span.\n");
2502                         goto done;
2503                 }
2504 
2505                 if (!strcasecmp(argv[2], "start")) {
2506                         char *filename = NULL;
2507 
2508                         if (argc < 4) {
2509                                 stream->write_function(stream, "-ERR not enough parameters.\n");
2510                                 goto done;
2511                         }
2512 
2513                         if (isdn_pcap_is_open(isdn_data)) {
2514                                 stream->write_function(stream, "-ERR capture is already running.\n");
2515                                 goto done;
2516                         }
2517 
2518                         filename = argv[3];
2519 
2520                         if (isdn_pcap_open(isdn_data, filename) != FTDM_SUCCESS) {
2521                                 stream->write_function(stream, "-ERR failed to open capture file.\n");
2522                                 goto done;
2523                         }
2524 
2525                         if (argc > 4 && !strcasecmp(argv[4], "q931only")) {
2526                                 isdn_data->flags |= FTDM_ISDN_CAPTURE_L3ONLY;
2527                         }
2528                         isdn_pcap_start(isdn_data);
2529 
2530                         stream->write_function(stream, "+OK capture started.\n");
2531                         goto done;
2532                 }
2533                 else if (!strcasecmp(argv[2], "stop")) {
2534 
2535                         if (!isdn_pcap_is_open(isdn_data)) {
2536                                 stream->write_function(stream, "-ERR capture is not running.\n");
2537                                 goto done;
2538                         }
2539 
2540                         isdn_pcap_stop(isdn_data);
2541                         isdn_pcap_close(isdn_data);
2542 
2543                         stream->write_function(stream, "+OK capture stopped.\n");
2544                         goto done;
2545                 }
2546                 else if (!strcasecmp(argv[2], "suspend")) {
2547 
2548                         if (!isdn_pcap_is_open(isdn_data)) {
2549                                 stream->write_function(stream, "-ERR capture is not running.\n");
2550                                 goto done;
2551                         }
2552                         isdn_pcap_stop(isdn_data);
2553 
2554                         stream->write_function(stream, "+OK capture suspended.\n");
2555                         goto done;
2556                 }
2557                 else if (!strcasecmp(argv[2], "resume")) {
2558 
2559                         if (!isdn_pcap_is_open(isdn_data)) {
2560                                 stream->write_function(stream, "-ERR capture is not running.\n");
2561                                 goto done;
2562                         }
2563                         isdn_pcap_start(isdn_data);
2564 
2565                         stream->write_function(stream, "+OK capture resumed.\n");
2566                         goto done;
2567                 }
2568                 else {
2569                         stream->write_function(stream, "-ERR wrong action.\n");
2570                         goto done;
2571                 }
2572         }
2573 #endif
2574         else {
2575                 stream->write_function(stream, "-ERR invalid command.\n");
2576         }
2577 done:
2578         ftdm_safe_free(mycmd);
2579 
2580         return FTDM_SUCCESS;
2581 }
2582 
2583 static int parse_mode(const char *mode)
2584 {
2585         if (!mode)
2586                 return -1;
2587 
2588         if (!strcasecmp(mode, "user") || !strcasecmp(mode, "cpe")) {
2589                 return Q931_TE;
2590         }
2591         if (!strcasecmp(mode, "net") || !strcasecmp(mode, "network")) {
2592                 return Q931_NT;
2593         }
2594 
2595         return -1;
2596 }
2597 
2598 static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(isdn_configure_span)
2599 {
2600         Q931Dialect_t dialect = Q931_Dialect_National;
2601         ftdm_channel_t *dchan = NULL;
2602         ftdm_isdn_data_t *isdn_data;
2603         int32_t digit_timeout = 0;
2604         const char *tonemap = "us";
2605         int dchan_count = 0, bchan_count = 0;
2606         int q921loglevel = -1;
2607         int q931loglevel = -1;
2608         uint32_t i;
2609 
2610         if (span->signal_type) {
2611                 ftdm_log(FTDM_LOG_ERROR, "Span is already configured for signalling [%d]\n", span->signal_type);
2612                 snprintf(span->last_error, sizeof(span->last_error), "Span is already configured for signalling [%d]", span->signal_type);
2613                 return FTDM_FAIL;
2614         }
2615 
2616         if (ftdm_span_get_trunk_type(span) >= FTDM_TRUNK_NONE) {
2617                 ftdm_log(FTDM_LOG_WARNING, "Invalid trunk type '%s' defaulting to T1\n", ftdm_span_get_trunk_type_str(span));
2618                 span->trunk_type = FTDM_TRUNK_T1;
2619         }
2620 
2621         for (i = 1; i <= ftdm_span_get_chan_count(span); i++) {
2622                 ftdm_channel_t *chan = ftdm_span_get_channel(span, i);
2623 
2624                 switch (ftdm_channel_get_type(chan)) {
2625                 case FTDM_CHAN_TYPE_DQ921:
2626                         if (dchan_count > 1) {
2627                                 ftdm_log(FTDM_LOG_ERROR, "Span has more than 1 D-Channel!\n");
2628                                 snprintf(span->last_error, sizeof(span->last_error), "Span has more than 1 D-Channel!");
2629                                 return FTDM_FAIL;
2630                         }
2631 
2632                         if (ftdm_channel_open(ftdm_span_get_id(span), i, &dchan) == FTDM_SUCCESS) {
2633                                 ftdm_log(FTDM_LOG_DEBUG, "opening d-channel #%d %d:%d\n", dchan_count,
2634                                         ftdm_channel_get_span_id(dchan), ftdm_channel_get_id(dchan));
2635                                 dchan->state = FTDM_CHANNEL_STATE_UP;
2636                         }
2637 
2638                         dchan_count++;
2639                         break;
2640 
2641                 case FTDM_CHAN_TYPE_B:
2642                         bchan_count++;
2643                         break;
2644 
2645                 default:
2646                         break;
2647                 }
2648         }
2649         if (!dchan_count) {
2650                 ftdm_log(FTDM_LOG_ERROR, "Span has no D-Channel!\n");
2651                 snprintf(span->last_error, sizeof(span->last_error), "Span has no D-Channel!");
2652                 return FTDM_FAIL;
2653         }
2654         if (!bchan_count) {
2655                 ftdm_log(FTDM_LOG_ERROR, "Span has no B-Channels!\n");
2656                 snprintf(span->last_error, sizeof(span->last_error), "Span has no B-Channels!");
2657                 return FTDM_FAIL;
2658         }
2659 
2660         isdn_data = malloc(sizeof(*isdn_data));
2661         assert(isdn_data != NULL);
2662         memset(isdn_data, 0, sizeof(*isdn_data));
2663 
2664         isdn_data->mode = Q931_TE;
2665         dialect = Q931_Dialect_Q931;
2666 
2667         for (i = 0; ftdm_parameters[i].var; i++) {
2668                 const char *var = ftdm_parameters[i].var;
2669                 const char *val = ftdm_parameters[i].val;
2670 
2671                 if (ftdm_strlen_zero(var)) {
2672                         ftdm_log(FTDM_LOG_WARNING, "Skipping variable with no name\n");
2673                         continue;
2674                 }
2675 
2676                 if (ftdm_strlen_zero(val)) {
2677                         ftdm_log(FTDM_LOG_ERROR, "Variable '%s' has no value\n", var);
2678                         return FTDM_FAIL;
2679                 }
2680 
2681                 if (!strcasecmp(var, "mode")) {
2682                         if ((isdn_data->mode = parse_mode(val)) < 0) {
2683                                 ftdm_log(FTDM_LOG_ERROR, "Invalid/unknown mode '%s'\n", val);
2684                                 snprintf(span->last_error, sizeof(span->last_error), "Invalid/unknown mode [%s]!", val);
2685                                 return FTDM_FAIL;
2686                         }
2687                 } else if (!strcasecmp(var, "dialect")) {
2688                         if (parse_dialect(val, &dialect) < 0) {
2689                                 ftdm_log(FTDM_LOG_ERROR, "Invalid/unknown dialect '%s'\n", val);
2690                                 snprintf(span->last_error, sizeof(span->last_error), "Invalid/unknown dialect [%s]!", val);
2691                                 return FTDM_FAIL;
2692                         }
2693                 } else if (!strcasecmp(var, "opts")) {
2694                         if (parse_opts(val, &isdn_data->opts) < 0) {
2695                                 ftdm_log(FTDM_LOG_ERROR, "Invalid/unknown options '%s'\n", val);
2696                                 snprintf(span->last_error, sizeof(span->last_error), "Invalid/unknown options [%s]!", val);
2697                                 return FTDM_FAIL;
2698                         }
2699                 } else if (!strcasecmp(var, "tonemap")) {
2700                         tonemap = (const char *)val;
2701                 } else if (!strcasecmp(var, "digit_timeout")) {
2702                         digit_timeout = atoi(val);
2703                         if (digit_timeout < 3000 || digit_timeout > 30000) {
2704                                 ftdm_log(FTDM_LOG_WARNING, "Digit timeout %d ms outside of range (3000 - 30000 ms), using default (10000 ms)\n", digit_timeout);
2705                                 digit_timeout = DEFAULT_DIGIT_TIMEOUT;
2706                         }
2707                 } else if (!strcasecmp(var, "q921loglevel")) {
2708                         if ((q921loglevel = parse_loglevel(val)) < 0) {
2709                                 ftdm_log(FTDM_LOG_ERROR, "Invalid/unknown loglevel '%s'\n", val);
2710                                 snprintf(span->last_error, sizeof(span->last_error), "Invalid/unknown loglevel [%s]!", val);
2711                                 return FTDM_FAIL;
2712                         }
2713                 } else if (!strcasecmp(var, "q931loglevel")) {
2714                         if ((q931loglevel = parse_loglevel(val)) < 0) {
2715                                 ftdm_log(FTDM_LOG_ERROR, "Invalid/unknown loglevel '%s'\n", val);
2716                                 snprintf(span->last_error, sizeof(span->last_error), "Invalid/unknown loglevel [%s]!", val);
2717                                 return FTDM_FAIL;
2718                         }
2719                 } else {
2720                         ftdm_log(FTDM_LOG_ERROR, "Unknown parameter '%s'\n", var);
2721                         snprintf(span->last_error, sizeof(span->last_error), "Unknown parameter [%s]", var);
2722                         return FTDM_FAIL;
2723                 }
2724         }
2725 
2726         if (!digit_timeout) {
2727                 digit_timeout = DEFAULT_DIGIT_TIMEOUT;
2728         }
2729 
2730         /* allocate per b-chan data */
2731         if (isdn_data->mode == Q931_NT) {
2732                 ftdm_isdn_bchan_data_t *data;
2733 
2734                 data = malloc(bchan_count * sizeof(ftdm_isdn_bchan_data_t));
2735                 if (!data) {
2736                         return FTDM_FAIL;
2737                 }
2738 
2739                 for (i = 1; i <= ftdm_span_get_chan_count(span); i++, data++) {
2740                         ftdm_channel_t *chan = ftdm_span_get_channel(span, i);
2741 
2742                         if (ftdm_channel_get_type(chan) == FTDM_CHAN_TYPE_B) {
2743                                 chan->call_data = data;
2744                                 memset(data, 0, sizeof(ftdm_isdn_bchan_data_t));
2745                         }
2746                 }
2747         }
2748 
2749         isdn_data->dchan = dchan;
2750         isdn_data->digit_timeout = digit_timeout;
2751 
2752         Q921_InitTrunk(&isdn_data->q921,
2753                                    0,
2754                                    0,
2755                                    isdn_data->mode,
2756                                    (ftdm_span_get_trunk_type(span) == FTDM_TRUNK_BRI_PTMP) ? Q921_PTMP : Q921_PTP,
2757                                    0,
2758                                    ftdm_isdn_921_21,
2759                                    (Q921Tx23CB_t)ftdm_isdn_921_23,
2760                                    span,
2761                                    span);
2762 
2763         Q921SetLogCB(&isdn_data->q921, &ftdm_isdn_q921_log, span);
2764         Q921SetLogLevel(&isdn_data->q921, (Q921LogLevel_t)q921loglevel);
2765 
2766         Q931InitTrunk(&isdn_data->q931,
2767                                           dialect,
2768                                           isdn_data->mode,
2769                                           span->trunk_type,
2770                                           ftdm_isdn_931_34,
2771                                           (Q931Tx32CB_t)q931_rx_32,
2772                                           ftdm_isdn_931_err,
2773                                           span,
2774                                           span);
2775 
2776         Q931SetLogCB(&isdn_data->q931, &ftdm_isdn_q931_log, span);
2777         Q931SetLogLevel(&isdn_data->q931, (Q931LogLevel_t)q931loglevel);
2778 
2779         /* Register new event hander CB */
2780         Q931SetCallEventCB(&isdn_data->q931, ftdm_isdn_call_event, span);
2781 
2782         /* TODO: hmm, maybe drop the "Trunk" prefix */
2783         Q931TrunkSetAutoRestartAck(&isdn_data->q931, 1);
2784         Q931TrunkSetAutoConnectAck(&isdn_data->q931, 1);
2785         Q931TrunkSetAutoServiceAck(&isdn_data->q931, 1);
2786         Q931TrunkSetStatusEnquiry(&isdn_data->q931, 0);
2787 
2788         span->state_map     = &isdn_state_map;
2789         span->signal_data   = isdn_data;
2790         span->signal_type   = FTDM_SIGTYPE_ISDN;
2791         span->signal_cb     = sig_cb;
2792         span->start         = ftdm_isdn_start;
2793         span->stop          = ftdm_isdn_stop;
2794         span->outgoing_call = isdn_outgoing_call;
2795 
2796         span->get_channel_sig_status = isdn_get_channel_sig_status;
2797         span->get_span_sig_status    = isdn_get_span_sig_status;
2798 
2799 #ifdef __TODO__
2800         if ((isdn_data->opts & FTDM_ISDN_OPT_SUGGEST_CHANNEL)) {
2801                 span->channel_request = isdn_channel_request;
2802                 span->flags |= FTDM_SPAN_SUGGEST_CHAN_ID;
2803         }
2804 #endif
2805         ftdm_span_load_tones(span, tonemap);
2806 
2807         return FTDM_SUCCESS;
2808 }
2809 
2810 /**
2811  * ISDN module io interface
2812  * \note        This is really ugly...
2813  */
2814 static ftdm_io_interface_t isdn_interface = {
2815         .name = "isdn",
2816         .api  = isdn_api
2817 };
2818 
2819 /**
2820  * \brief       ISDN module io interface init callback
2821  */
2822 static FIO_IO_LOAD_FUNCTION(isdn_io_load)
2823 {
2824         assert(fio != NULL);
2825 
2826         *fio = &isdn_interface;
2827 
2828         return FTDM_SUCCESS;
2829 }
2830 
2831 /**
2832  * \brief       ISDN module load callback
2833  */
2834 static FIO_SIG_LOAD_FUNCTION(isdn_load)
2835 {
2836         Q931Initialize();
2837 
2838         Q921SetGetTimeCB(ftdm_time_now);
2839         Q931SetGetTimeCB(ftdm_time_now);
2840 
2841         return FTDM_SUCCESS;
2842 }
2843 
2844 /**
2845  * \brief       ISDN module shutdown callback
2846  */
2847 static FIO_SIG_UNLOAD_FUNCTION(isdn_unload)
2848 {
2849         return FTDM_SUCCESS;
2850 };
2851 
2852 ftdm_module_t ftdm_module = {
2853         .name          = "isdn",
2854         .io_load       = isdn_io_load,
2855         .io_unload     = NULL,
2856         .sig_load      = isdn_load,
2857         .sig_unload    = isdn_unload,
2858         .configure_span_signaling = isdn_configure_span
2859 };
2860 
2861 /* For Emacs:
2862  * Local Variables:
2863  * mode:c
2864  * indent-tabs-mode:t
2865  * tab-width:4
2866  * c-basic-offset:4
2867  * End:
2868  * For VIM:
2869  * vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
2870  */

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