root/src/ftmod/ftmod_isdn/ftmod_isdn.c

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

DEFINITIONS

This source file includes following definitions.
  1. openPcapFile
  2. closePcapFile
  3. writeQ931PacketToPcap
  4. FIO_IO_UNLOAD_FUNCTION
  5. ftdm_time_now
  6. FIO_CHANNEL_OUTGOING_CALL_FUNCTION
  7. FIO_CHANNEL_REQUEST_FUNCTION
  8. ftdm_isdn_931_err
  9. ftdm_isdn_931_34
  10. ftdm_isdn_921_23
  11. ftdm_isdn_921_21
  12. state_advance
  13. check_state
  14. process_event
  15. check_events
  16. teletone_handler
  17. ftdm_isdn_tones_run
  18. ftdm_isdn_run
  19. FIO_SIG_LOAD_FUNCTION
  20. q931_rx_32
  21. ftdm_isdn_q921_log
  22. ftdm_isdn_q931_log
  23. ftdm_isdn_stop
  24. ftdm_isdn_start
  25. parse_opts
  26. FIO_SIG_CONFIGURE_FUNCTION

   1 /*
   2  * Copyright (c) 2007, Anthony Minessale II
   3  * All rights reserved.
   4  * 
   5  * Redistribution and use in source and binary forms, with or without
   6  * modification, are permitted provided that the following conditions
   7  * are met:
   8  * 
   9  * * Redistributions of source code must retain the above copyright
  10  * notice, this list of conditions and the following disclaimer.
  11  * 
  12  * * Redistributions in binary form must reproduce the above copyright
  13  * notice, this list of conditions and the following disclaimer in the
  14  * documentation and/or other materials provided with the distribution.
  15  * 
  16  * * Neither the name of the original author; nor the names of any contributors
  17  * may be used to endorse or promote products derived from this software
  18  * without specific prior written permission.
  19  * 
  20  * 
  21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  24  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
  25  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  26  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  27  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  28  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  29  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  30  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  31  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32  */
  33 
  34 /**
  35  * Workaround for missing u_int / u_short types on solaris
  36  */
  37 #if defined(HAVE_LIBPCAP) && defined(__SunOS)
  38 #define __EXTENSIONS__
  39 #endif
  40 
  41 #include "private/ftdm_core.h"
  42 #include "Q931.h"
  43 #include "Q921.h"
  44 #ifdef WIN32
  45 #include <windows.h>
  46 #else
  47 #include <sys/time.h>
  48 #endif
  49 
  50 #include "ftdm_isdn.h"
  51 
  52 #define LINE "--------------------------------------------------------------------------------"
  53 //#define IODEBUG
  54 
  55 /* helper macros */
  56 #define FTDM_SPAN_IS_BRI(x)     ((x)->trunk_type == FTDM_TRUNK_BRI || (x)->trunk_type == FTDM_TRUNK_BRI_PTMP)
  57 #define FTDM_SPAN_IS_NT(x)      (((ftdm_isdn_data_t *)(x)->signal_data)->mode == Q921_NT)
  58 
  59 
  60 #ifdef HAVE_LIBPCAP
  61 /*-------------------------------------------------------------------------*/
  62 /*Q931ToPcap functions*/
  63 #include <pcap.h>
  64 #endif
  65 
  66 #define SNAPLEN 1522
  67 #define MAX_ETHER_PAYLOAD_SIZE 1500
  68 #define MIN_ETHER_PAYLOAD_SIZE 42
  69 #define SIZE_ETHERNET           18
  70 #define VLANID_OFFSET           15
  71 #define SIZE_IP                 20
  72 #define SIZE_TCP                20
  73 #define SIZE_TPKT               4
  74 #define SIZE_ETHERNET_CRC       4
  75 #define OVERHEAD                SIZE_ETHERNET+SIZE_IP+SIZE_TCP+SIZE_TPKT
  76 #define MAX_Q931_SIZE           MAX_ETHER_PAYLOAD_SIZE-SIZE_IP-SIZE_TCP-SIZE_TPKT
  77 #define TPKT_SIZE_OFFSET        SIZE_ETHERNET+SIZE_IP+SIZE_TCP+2
  78 #define IP_SIZE_OFFSET          SIZE_ETHERNET+2
  79 #define TCP_SEQ_OFFSET          SIZE_ETHERNET+SIZE_IP+4
  80 
  81 #ifdef HAVE_LIBPCAP
  82 /*Some globals*/
  83 unsigned long           pcapfilesize = 0;
  84 unsigned long           tcp_next_seq_no_send = 0;
  85 unsigned long           tcp_next_seq_no_rec = 0;
  86 pcap_dumper_t           *pcapfile    = NULL;
  87 struct pcap_pkthdr      pcaphdr;
  88 pcap_t                  *pcaphandle  = NULL;
  89 char                    *pcapfn      = NULL;
  90 int                     do_q931ToPcap= 0;
  91 
  92 /*Predefined Ethernet Frame with Q931-over-IP encapsulated - From remote TDM host to FreeSWITCH*/
  93 L3UCHAR  recFrame[SNAPLEN]= {
  94                                 /*IEEE 802.3 VLAN 802.1q Ethernet Frame Header*/
  95                                 2,0,1,0xAA,0xAA,0xAA,2,0,1,0xBB,0xBB,0xBB,0x81,0,0xE0,0,0x08,0,
  96                                 /*IPv4 Header (minimal size; no options)*/
  97                                 0x45,0,0,44,0,0,0,0,64,6,0,0,2,2,2,2,1,1,1,1,
  98                                 /*TCP-Header*/
  99                                 0,0x66,0,0x66,0,0,0,0,0,0,0,0,0x50,0,0,1,0,0,0,0,
 100                                 /*TPKT-Header RFC 1006*/
 101                                 3,0,0,0
 102                             };
 103 
 104 /*Predefined Ethernet Frame with Q931-over-IP encapsulated - Frome FreeSWITCH to remote TDM host*/
 105 L3UCHAR  sendFrame[SNAPLEN]= {
 106                                 /*IEEE 802.3 VLAN 802.1q Ethernet Frame Header*/
 107                                 2,0,1,0xBB,0xBB,0xBB,2,0,1,0xAA,0xAA,0xAA,0x81,0,0xE0,0,0x08,0,
 108                                 /*IPv4 Header (minimal size; no options)*/
 109                                 0x45,0,0,44,0,0,0,0,64,6,0,0,1,1,1,1,2,2,2,2,
 110                                 /*TCP-Header*/
 111                                 0,0x66,0,0x66,0,0,0,0,0,0,0,0,0x50,0,0,1,0,0,0,0,
 112                                 /*TPKT-Header RFC 1006*/
 113                                 3,0,0,0
 114                              };
 115 
 116 /**
 117  * \brief Opens a pcap file for capture
 118  * \return Success or failure
 119  */
 120 static ftdm_status_t openPcapFile(void)
 121 {
 122         if(!pcaphandle)
 123         {
 124                 pcaphandle = pcap_open_dead(DLT_EN10MB, SNAPLEN);
 125                 if (!pcaphandle)
 126                 {
 127                         ftdm_log(FTDM_LOG_ERROR, "Can't open pcap session: (%s)\n", pcap_geterr(pcaphandle));
 128                         return FTDM_FAIL;
 129                 }
 130         }
 131 
 132         if(!pcapfile){
 133                 /* Open the dump file */
 134                 if(!(pcapfile=pcap_dump_open(pcaphandle, pcapfn))){
 135                         ftdm_log(FTDM_LOG_ERROR, "Error opening output file (%s)\n", pcap_geterr(pcaphandle));
 136                         return FTDM_FAIL;
 137                 }
 138         }
 139         else{
 140                 ftdm_log(FTDM_LOG_WARNING, "Pcap file is already open!\n");
 141                 return FTDM_FAIL;
 142         }
 143 
 144         ftdm_log(FTDM_LOG_DEBUG, "Pcap file '%s' successfully opened!\n", pcapfn);
 145 
 146         pcaphdr.ts.tv_sec       = 0;
 147         pcaphdr.ts.tv_usec      = 0;
 148         pcapfilesize            = 24;   /*current pcap file header seems to be 24 bytes*/
 149         tcp_next_seq_no_send    = 0;
 150         tcp_next_seq_no_rec     = 0;
 151 
 152         return FTDM_SUCCESS;
 153 }
 154 
 155 /**
 156  * \brief Closes a pcap file
 157  * \return Success
 158  */
 159 static ftdm_status_t closePcapFile(void)
 160 {
 161         if (pcapfile) {
 162                 pcap_dump_close(pcapfile);
 163                 if (pcaphandle) pcap_close(pcaphandle);
 164 
 165                 ftdm_log(FTDM_LOG_DEBUG, "Pcap file closed! File size is %lu bytes.\n", pcapfilesize);
 166 
 167                 pcaphdr.ts.tv_sec       = 0;
 168                 pcaphdr.ts.tv_usec      = 0;
 169                 pcapfile                = NULL;
 170                 pcaphandle              = NULL;
 171                 pcapfilesize            = 0;
 172                 tcp_next_seq_no_send    = 0;
 173                 tcp_next_seq_no_rec     = 0;
 174         }
 175 
 176         /*We have allways success with this? I think so*/
 177         return FTDM_SUCCESS;
 178 }
 179 
 180 /**
 181  * \brief Writes a Q931 packet to a pcap file
 182  * \return Success or failure
 183  */
 184 static ftdm_status_t writeQ931PacketToPcap(L3UCHAR* q931buf, L3USHORT q931size, L3ULONG span_id, L3USHORT direction)
 185 {
 186         L3UCHAR                 *frame          = NULL;
 187         struct timeval          ts;
 188         u_char                  spanid          = (u_char)span_id;
 189         unsigned long           *tcp_next_seq_no = NULL;
 190 
 191         spanid=span_id;
 192         
 193         /*The total length of the ethernet frame generated by this function has a min length of 66
 194         so we don't have to care about padding :)*/
 195 
 196 
 197         /*FS is sending the packet*/
 198         if(direction==0){
 199                 frame=sendFrame;
 200                 tcp_next_seq_no = &tcp_next_seq_no_send;
 201         } 
 202         /*FS is receiving the packet*/
 203         else{
 204                 frame=recFrame;
 205                 tcp_next_seq_no = &tcp_next_seq_no_rec;
 206         }
 207 
 208         /*Set spanid in VLAN-ID tag*/
 209         frame[VLANID_OFFSET]    = spanid;
 210 
 211         /*** Write sent packet ***/
 212         if(q931size > MAX_Q931_SIZE)
 213         {
 214                 /*WARNING*/
 215                 ftdm_log(FTDM_LOG_WARNING, "Q931 packet size is too big (%u)! Ignoring it!\n", q931size);
 216                 return FTDM_FAIL;
 217         }
 218 
 219         /*Copy q931 buffer into frame*/
 220         memcpy(frame+OVERHEAD,q931buf,q931size);
 221 
 222         /*Store TCP sequence number in TCP header*/
 223         frame[TCP_SEQ_OFFSET]=(*tcp_next_seq_no>>24)&0xFF;
 224         frame[TCP_SEQ_OFFSET+1]=(*tcp_next_seq_no>>16)&0xFF;
 225         frame[TCP_SEQ_OFFSET+2]=(*tcp_next_seq_no>>8)&0xFF;
 226         frame[TCP_SEQ_OFFSET+3]=*tcp_next_seq_no & 0xFF;
 227 
 228         /*Store size of TPKT packet*/
 229         q931size+=4;
 230         frame[TPKT_SIZE_OFFSET]=(q931size>>8)&0xFF;
 231         frame[TPKT_SIZE_OFFSET+1]=q931size&0xFF;
 232 
 233         /*Calc next TCP sequence number*/
 234         *tcp_next_seq_no+=q931size;
 235 
 236         /*Store size of IP packet*/
 237         q931size+=SIZE_IP+SIZE_TCP;
 238         frame[IP_SIZE_OFFSET]=(q931size>>8)&0xFF;
 239         frame[IP_SIZE_OFFSET+1]=q931size&0xFF;
 240 
 241         pcaphdr.caplen = SIZE_ETHERNET+SIZE_ETHERNET_CRC+q931size;
 242         pcaphdr.len = pcaphdr.caplen;
 243 
 244         /* Set Timestamp */
 245         /* Get Time in ms. usecs would be better ...  */
 246         gettimeofday(&ts, NULL);
 247         /*Write it into packet header*/
 248         pcaphdr.ts.tv_sec = ts.tv_sec;
 249         pcaphdr.ts.tv_usec = ts.tv_usec;
 250 
 251         pcap_dump((u_char*)pcapfile, &pcaphdr, frame);
 252         pcap_dump_flush(pcapfile);
 253 
 254         /*Maintain pcap file size*/
 255         pcapfilesize+=pcaphdr.caplen;
 256         pcapfilesize+=sizeof(struct pcap_pkthdr);
 257 
 258         ftdm_log(FTDM_LOG_DEBUG, "Added %u bytes to pcap file. File size is now %lu, \n", q931size, pcapfilesize);
 259 
 260         return FTDM_SUCCESS;
 261 }
 262 
 263 #endif
 264 
 265 /**
 266  * \brief Unloads pcap IO
 267  * \return Success or failure
 268  */
 269 static FIO_IO_UNLOAD_FUNCTION(close_pcap)
 270 {
 271 #ifdef HAVE_LIBPCAP
 272         return closePcapFile();
 273 #else
 274         return FTDM_SUCCESS;
 275 #endif
 276 }
 277 
 278 /*Q931ToPcap functions DONE*/
 279 /*-------------------------------------------------------------------------*/
 280 
 281 /**
 282  * \brief Gets current time
 283  * \return Current time (in ms)
 284  */
 285 static L2ULONG ftdm_time_now(void)
 286 {
 287         return (L2ULONG)ftdm_current_time_in_ms();
 288 }
 289 
 290 /**
 291  * \brief Initialises an ISDN channel (outgoing call)
 292  * \param ftdmchan Channel to initiate call on
 293  * \return Success or failure
 294  */
 295 static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(isdn_outgoing_call)
 296 {
 297         ftdm_status_t status = FTDM_SUCCESS;
 298         ftdm_set_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND);
 299         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DIALING);
 300         return status;
 301 }
 302 
 303 /**
 304  * \brief Requests an ISDN channel on a span (outgoing call)
 305  * \param span Span where to get a channel
 306  * \param chan_id Specific channel to get (0 for any)
 307  * \param direction Call direction (inbound, outbound)
 308  * \param caller_data Caller information
 309  * \param ftdmchan Channel to initialise
 310  * \return Success or failure
 311  */
 312 static FIO_CHANNEL_REQUEST_FUNCTION(isdn_channel_request)
 313 {
 314         Q931mes_Generic *gen = (Q931mes_Generic *) caller_data->raw_data;
 315         Q931ie_BearerCap BearerCap;
 316         Q931ie_ChanID ChanID = { 0 };
 317         Q931ie_CallingNum CallingNum;
 318         Q931ie_CallingNum *ptrCallingNum;
 319         Q931ie_CalledNum CalledNum;
 320         Q931ie_CalledNum *ptrCalledNum;
 321         Q931ie_Display Display, *ptrDisplay;
 322         Q931ie_HLComp HLComp;                   /* High-Layer Compatibility IE */
 323         Q931ie_ProgInd Progress;                /* Progress Indicator IE */
 324         ftdm_status_t status = FTDM_FAIL;
 325         ftdm_isdn_data_t *isdn_data = span->signal_data;
 326         int sanity = 60000;
 327         int codec  = 0;
 328 
 329         /*
 330          * get codec type
 331          */
 332         ftdm_channel_command(span->channels[chan_id], FTDM_COMMAND_GET_NATIVE_CODEC, &codec);
 333 
 334         /*
 335          * Q.931 Setup Message
 336          */
 337         Q931InitMesGeneric(gen);
 338         gen->MesType = Q931mes_SETUP;
 339         gen->CRVFlag = 0;               /* outgoing call */
 340 
 341         /*
 342          * Bearer Capability IE
 343          */
 344         Q931InitIEBearerCap(&BearerCap);
 345         BearerCap.CodStand  = Q931_CODING_ITU;          /* ITU-T = 0, ISO/IEC = 1, National = 2, Network = 3 */
 346         BearerCap.ITC       = Q931_ITC_SPEECH;          /* Speech */
 347         BearerCap.TransMode = 0;                        /* Circuit = 0, Packet = 1 */
 348         BearerCap.ITR       = Q931_ITR_64K;             /* 64k */
 349         BearerCap.Layer1Ident = 1;
 350         BearerCap.UIL1Prot = (codec == FTDM_CODEC_ALAW) ? Q931_UIL1P_G711A : Q931_UIL1P_G711U;  /* U-law = 2, A-law = 3 */
 351         gen->BearerCap = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &BearerCap);
 352 
 353         /*
 354          * Channel ID IE
 355          */
 356         Q931InitIEChanID(&ChanID);
 357         ChanID.IntType = FTDM_SPAN_IS_BRI(span) ? 0 : 1;                /* PRI = 1, BRI = 0 */
 358 
 359         if(!FTDM_SPAN_IS_NT(span)) {
 360                 ChanID.PrefExcl = (isdn_data->opts & FTDM_ISDN_OPT_SUGGEST_CHANNEL) ? 0 : 1; /* 0 = preferred, 1 exclusive */
 361         } else {
 362                 ChanID.PrefExcl = 1;    /* always exclusive in NT-mode */
 363         }
 364 
 365         if(ChanID.IntType) {
 366                 ChanID.InfoChanSel = 1;                         /* None = 0, See Slot = 1, Any = 3 */
 367                 ChanID.ChanMapType = 3;                         /* B-Chan */
 368                 ChanID.ChanSlot = (unsigned char)chan_id;
 369         } else {
 370                 ChanID.InfoChanSel = (unsigned char)chan_id & 0x03;     /* None = 0, B1 = 1, B2 = 2, Any = 3 */
 371         }
 372         gen->ChanID = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &ChanID);
 373 
 374         /*
 375          * Progress IE
 376          */
 377         Q931InitIEProgInd(&Progress);
 378         Progress.CodStand = Q931_CODING_ITU;    /* 0 = ITU */
 379         Progress.Location = 0;  /* 0 = User, 1 = Private Network */
 380         Progress.ProgDesc = 3;  /* 1 = Not end-to-end ISDN */
 381         gen->ProgInd = Q931AppendIE((L3UCHAR *)gen, (L3UCHAR *)&Progress);
 382 
 383         /*
 384          * Display IE
 385          */
 386         if (!(isdn_data->opts & FTDM_ISDN_OPT_OMIT_DISPLAY_IE)) {
 387                 Q931InitIEDisplay(&Display);
 388                 Display.Size = Display.Size + (unsigned char)strlen(caller_data->cid_name);
 389                 gen->Display = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &Display);                     
 390                 ptrDisplay = Q931GetIEPtr(gen->Display, gen->buf);
 391                 ftdm_copy_string((char *)ptrDisplay->Display, caller_data->cid_name, strlen(caller_data->cid_name)+1);
 392         }
 393 
 394         /*
 395          * Calling Number IE
 396          */
 397         Q931InitIECallingNum(&CallingNum);
 398         CallingNum.TypNum    = Q931_TON_UNKNOWN;
 399         CallingNum.NumPlanID = Q931_NUMPLAN_E164;
 400         CallingNum.PresInd   = Q931_PRES_ALLOWED;
 401         CallingNum.ScreenInd = Q931_SCREEN_USER_NOT_SCREENED;
 402         CallingNum.Size = CallingNum.Size + (unsigned char)strlen(caller_data->cid_num.digits);
 403         gen->CallingNum = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &CallingNum);                       
 404         ptrCallingNum = Q931GetIEPtr(gen->CallingNum, gen->buf);
 405         ftdm_copy_string((char *)ptrCallingNum->Digit, caller_data->cid_num.digits, strlen(caller_data->cid_num.digits)+1);
 406 
 407 
 408         /*
 409          * Called number IE
 410          */
 411         Q931InitIECalledNum(&CalledNum);
 412         CalledNum.TypNum    = Q931_TON_UNKNOWN;
 413         CalledNum.NumPlanID = Q931_NUMPLAN_E164;
 414         CalledNum.Size = CalledNum.Size + (unsigned char)strlen(caller_data->dnis.digits);
 415         gen->CalledNum = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &CalledNum);
 416         ptrCalledNum = Q931GetIEPtr(gen->CalledNum, gen->buf);
 417         ftdm_copy_string((char *)ptrCalledNum->Digit, caller_data->dnis.digits, strlen(caller_data->dnis.digits)+1);
 418 
 419         /*
 420          * High-Layer Compatibility IE   (Note: Required for AVM FritzBox)
 421          */
 422         Q931InitIEHLComp(&HLComp);
 423         HLComp.CodStand  = Q931_CODING_ITU;     /* ITU */
 424         HLComp.Interpret = 4;   /* only possible value */
 425         HLComp.PresMeth  = 1;   /* High-layer protocol profile */
 426         HLComp.HLCharID  = 1;   /* Telephony = 1, Fax G2+3 = 4, Fax G4 = 65 (Class I)/ 68 (Class II or III) */
 427         gen->HLComp = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &HLComp);
 428 
 429         caller_data->call_state = FTDM_CALLER_STATE_DIALING;
 430         Q931Rx43(&isdn_data->q931, (L3UCHAR *) gen, gen->Size);
 431         
 432         isdn_data->outbound_crv[gen->CRV] = caller_data;
 433         //isdn_data->channels_local_crv[gen->CRV] = ftdmchan;
 434 
 435         while(ftdm_running() && caller_data->call_state == FTDM_CALLER_STATE_DIALING) {
 436                 ftdm_sleep(1);
 437                 
 438                 if (!--sanity) {
 439                         caller_data->call_state = FTDM_CALLER_STATE_FAIL;
 440                         break;
 441                 }
 442         }
 443         isdn_data->outbound_crv[gen->CRV] = NULL;
 444         
 445         if (caller_data->call_state == FTDM_CALLER_STATE_SUCCESS) {
 446                 ftdm_channel_t *new_chan = NULL;
 447                 int fail = 1;
 448                 
 449                 new_chan = NULL;
 450                 if (caller_data->chan_id < FTDM_MAX_CHANNELS_SPAN && caller_data->chan_id <= span->chan_count) {
 451                         new_chan = span->channels[caller_data->chan_id];
 452                 }
 453 
 454                 if (new_chan && (status = ftdm_channel_open_chan(new_chan) == FTDM_SUCCESS)) {
 455                         if (ftdm_test_flag(new_chan, FTDM_CHANNEL_INUSE) || new_chan->state != FTDM_CHANNEL_STATE_DOWN) {
 456                                 if (new_chan->state == FTDM_CHANNEL_STATE_DOWN || new_chan->state >= FTDM_CHANNEL_STATE_TERMINATING) {
 457                                         int x = 0;
 458                                         ftdm_log(FTDM_LOG_WARNING, "Channel %d:%d ~ %d:%d is already in use waiting for it to become available.\n");
 459                                         
 460                                         for (x = 0; x < 200; x++) {
 461                                                 if (!ftdm_test_flag(new_chan, FTDM_CHANNEL_INUSE)) {
 462                                                         break;
 463                                                 }
 464                                                 ftdm_sleep(5);
 465                                         }
 466                                 }
 467                                 if (ftdm_test_flag(new_chan, FTDM_CHANNEL_INUSE)) {
 468                                         ftdm_log(FTDM_LOG_ERROR, "Channel %d:%d ~ %d:%d is already in use.\n",
 469                                                         new_chan->span_id,
 470                                                         new_chan->chan_id,
 471                                                         new_chan->physical_span_id,
 472                                                         new_chan->physical_chan_id
 473                                                         );
 474                                         new_chan = NULL;
 475                                 }
 476                         }
 477 
 478                         if (new_chan && new_chan->state == FTDM_CHANNEL_STATE_DOWN) {
 479                                 isdn_data->channels_local_crv[gen->CRV] = new_chan;
 480                                 memset(&new_chan->caller_data, 0, sizeof(new_chan->caller_data));
 481                                 ftdm_set_flag(new_chan, FTDM_CHANNEL_OUTBOUND);
 482                                 ftdm_set_state_locked(new_chan, FTDM_CHANNEL_STATE_DIALING);
 483                                 switch(gen->MesType) {
 484                                 case Q931mes_ALERTING:
 485                                         new_chan->init_state = FTDM_CHANNEL_STATE_PROGRESS_MEDIA;
 486                                         break;
 487                                 case Q931mes_CONNECT:
 488                                         new_chan->init_state = FTDM_CHANNEL_STATE_UP;
 489                                         break;
 490                                 default:
 491                                         new_chan->init_state = FTDM_CHANNEL_STATE_PROGRESS;
 492                                         break;
 493                                 }
 494 
 495                                 fail = 0;
 496                         } 
 497                 }
 498                 
 499                 if (!fail) {
 500                         *ftdmchan = new_chan;
 501                         return FTDM_SUCCESS;
 502                 } else {
 503                         Q931ie_Cause cause;
 504                         gen->MesType = Q931mes_DISCONNECT;
 505                         cause.IEId = Q931ie_CAUSE;
 506                         cause.Size = sizeof(Q931ie_Cause);
 507                         cause.CodStand  = 0;
 508                         cause.Location = 1;
 509                         cause.Recom = 1;
 510                         //should we be casting here.. or do we need to translate value?
 511                         cause.Value = (unsigned char) FTDM_CAUSE_WRONG_CALL_STATE;
 512                         *cause.Diag = '\0';
 513                         gen->Cause = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &cause);
 514                         Q931Rx43(&isdn_data->q931, (L3UCHAR *) gen, gen->Size);
 515 
 516                         if (gen->CRV) {
 517                                 Q931ReleaseCRV(&isdn_data->q931, gen->CRV);
 518                         }
 519                         
 520                         if (new_chan) {
 521                                 ftdm_log(FTDM_LOG_CRIT, "Channel is busy\n");
 522                         } else {
 523                                 ftdm_log(FTDM_LOG_CRIT, "Failed to open channel for new setup message\n");
 524                         }
 525                 }
 526         }
 527         
 528         *ftdmchan = NULL;
 529         return FTDM_FAIL;
 530 
 531 }
 532 
 533 /**
 534  * \brief Handler for Q931 error
 535  * \param pvt Private structure (span?)
 536  * \param id Error number
 537  * \param p1 ??
 538  * \param p2 ??
 539  * \return 0
 540  */
 541 static L3INT ftdm_isdn_931_err(void *pvt, L3INT id, L3INT p1, L3INT p2)
 542 {
 543         ftdm_log(FTDM_LOG_ERROR, "ERROR: [%s] [%d] [%d]\n", q931_error_to_name(id), p1, p2);
 544         return 0;
 545 }
 546 
 547 /**
 548  * \brief Handler for Q931 event message
 549  * \param pvt Span to handle
 550  * \param msg Message string
 551  * \param mlen Message string length
 552  * \return 0
 553  */
 554 static L3INT ftdm_isdn_931_34(void *pvt, L2UCHAR *msg, L2INT mlen)
 555 {
 556         ftdm_span_t *span = (ftdm_span_t *) pvt;
 557         ftdm_isdn_data_t *isdn_data = span->signal_data;
 558         Q931mes_Generic *gen = (Q931mes_Generic *) msg;
 559         uint32_t chan_id = 0;
 560         int chan_hunt = 0;
 561         ftdm_channel_t *ftdmchan = NULL;
 562         ftdm_caller_data_t *caller_data = NULL;
 563 
 564         if (Q931IsIEPresent(gen->ChanID)) {
 565                 Q931ie_ChanID *chanid = Q931GetIEPtr(gen->ChanID, gen->buf);
 566 
 567                 if(chanid->IntType)
 568                         chan_id = chanid->ChanSlot;
 569                 else
 570                         chan_id = chanid->InfoChanSel;
 571 
 572                 /* "any" channel specified */
 573                 if(chanid->InfoChanSel == 3) {
 574                         chan_hunt++;
 575                 }
 576         } else if (FTDM_SPAN_IS_NT(span)) {
 577                 /* no channel ie */
 578                 chan_hunt++;
 579         }
 580 
 581         assert(span != NULL);
 582         assert(isdn_data != NULL);
 583         
 584         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");
 585 
 586         if (gen->CRVFlag && (caller_data = isdn_data->outbound_crv[gen->CRV])) {
 587                 if (chan_id) {
 588                         caller_data->chan_id = chan_id;
 589                 }
 590 
 591                 switch(gen->MesType) {
 592                 case Q931mes_STATUS:
 593                 case Q931mes_CALL_PROCEEDING:
 594                         break;
 595                 case Q931mes_ALERTING:
 596                 case Q931mes_PROGRESS:
 597                 case Q931mes_CONNECT:
 598                         {
 599                                 caller_data->call_state = FTDM_CALLER_STATE_SUCCESS;
 600                         }
 601                         break;
 602                 default:
 603                         caller_data->call_state = FTDM_CALLER_STATE_FAIL;
 604                         break;
 605                 }
 606         
 607                 return 0;
 608         }
 609 
 610         if (gen->CRVFlag) {
 611                 ftdmchan = isdn_data->channels_local_crv[gen->CRV];
 612         } else {
 613                 ftdmchan = isdn_data->channels_remote_crv[gen->CRV];
 614         }
 615 
 616         ftdm_log(FTDM_LOG_DEBUG, "ftdmchan %x (%d:%d) source isdn_data->channels_%s_crv[%#hx]\n", ftdmchan, ftdmchan ? ftdmchan->span_id : -1, ftdmchan ? ftdmchan->chan_id : -1, gen->CRVFlag ? "local" : "remote", gen->CRV);
 617 
 618 
 619         if (gen->ProtDisc == 3) {
 620                 switch(gen->MesType) {
 621                 case Q931mes_SERVICE:
 622                         {
 623                                 Q931ie_ChangeStatus *changestatus = Q931GetIEPtr(gen->ChangeStatus, gen->buf);
 624                                 if (ftdmchan) {
 625                                         switch (changestatus->NewStatus) {
 626                                         case 0: /* change status to "in service" */
 627                                                 {
 628                                                         ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_SUSPENDED);
 629                                                         ftdm_log(FTDM_LOG_DEBUG, "Channel %d:%d in service\n", ftdmchan->span_id, ftdmchan->chan_id);
 630                                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
 631                                                 }
 632                                                 break;
 633                                         case 1: 
 634                                                 { /* change status to "maintenance" */
 635                                                         ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_SUSPENDED);
 636                                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
 637                                                 }
 638                                                 break;
 639                                         case 2:
 640                                                 { /* change status to "out of service" */
 641                                                         ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_SUSPENDED);
 642                                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
 643                                                 }
 644                                                 break;
 645                                         default: /* unknown */
 646                                                 {
 647                                                         break;
 648                                                 }
 649                                         }
 650                                 }
 651                         }
 652                         break;
 653                 default:
 654                         break;
 655                 }
 656         } else {
 657                 switch(gen->MesType) {
 658                 case Q931mes_RESTART:
 659                         {
 660                                 if (chan_id) {
 661                                         ftdmchan = span->channels[chan_id];
 662                                 }
 663                                 if (ftdmchan) {
 664                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
 665                                 } else {
 666                                         uint32_t i;
 667                                         for (i = 1; i < span->chan_count; i++) {
 668                                                 ftdm_set_state_locked((span->channels[i]), FTDM_CHANNEL_STATE_RESTART);
 669                                         }
 670                                 }
 671                         }
 672                         break;
 673                 case Q931mes_RELEASE:
 674                 case Q931mes_RELEASE_COMPLETE:
 675                         {
 676                                 const char *what = gen->MesType == Q931mes_RELEASE ? "Release" : "Release Complete";
 677                                 if (ftdmchan) {
 678                                         if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING || ftdmchan->state == FTDM_CHANNEL_STATE_HANGUP) {
 679                                                 if (gen->MesType == Q931mes_RELEASE) {
 680                                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
 681                                                 } else {
 682                                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
 683                                                 }
 684                                         }
 685                                         else if((gen->MesType == Q931mes_RELEASE && ftdmchan->state <= FTDM_CHANNEL_STATE_UP) ||
 686                                                 (gen->MesType == Q931mes_RELEASE_COMPLETE && ftdmchan->state == FTDM_CHANNEL_STATE_DIALING)) {
 687 
 688                                                 /*
 689                                                  * Don't keep inbound channels open if the remote side hangs up before we answered
 690                                                  */
 691                                                 Q931ie_Cause *cause = Q931GetIEPtr(gen->Cause, gen->buf);
 692                                                 ftdm_sigmsg_t sig;
 693                                                 ftdm_status_t status;
 694 
 695                                                 memset(&sig, 0, sizeof(sig));
 696                                                 sig.chan_id = ftdmchan->chan_id;
 697                                                 sig.span_id = ftdmchan->span_id;
 698                                                 sig.channel = ftdmchan;
 699                                                 sig.channel->caller_data.hangup_cause = (cause) ? cause->Value : FTDM_CAUSE_NORMAL_UNSPECIFIED;
 700 
 701                                                 sig.event_id = FTDM_SIGEVENT_STOP;
 702                                                 status = ftdm_span_send_signal(ftdmchan->span, &sig);
 703 
 704                                                 ftdm_log(FTDM_LOG_DEBUG, "Received %s in state %s, requested hangup for channel %d:%d\n", what, ftdm_channel_state2str(ftdmchan->state), ftdmchan->span_id, chan_id);
 705                                         }
 706                                         else {
 707                                                 ftdm_log(FTDM_LOG_DEBUG, "Ignoring %s on channel %d\n", what, chan_id);
 708                                         }
 709                                 } else {
 710                                         ftdm_log(FTDM_LOG_CRIT, "Received %s with no matching channel %d\n", what, chan_id);
 711                                 }
 712                         }
 713                         break;
 714                 case Q931mes_DISCONNECT:
 715                         {
 716                                 if (ftdmchan) {
 717                                         Q931ie_Cause *cause = Q931GetIEPtr(gen->Cause, gen->buf);
 718                                         ftdmchan->caller_data.hangup_cause = cause->Value;
 719                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
 720                                 } else {
 721                                         ftdm_log(FTDM_LOG_CRIT, "Received Disconnect with no matching channel %d\n", chan_id);
 722                                 }
 723                         }
 724                         break;
 725                 case Q931mes_ALERTING:
 726                         {
 727                                 if (ftdmchan) {
 728                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
 729                                 } else {
 730                                         ftdm_log(FTDM_LOG_CRIT, "Received Alerting with no matching channel %d\n", chan_id);
 731                                 }
 732                         }
 733                         break;
 734                 case Q931mes_PROGRESS:
 735                         {
 736                                 if (ftdmchan) {
 737                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
 738                                 } else {
 739                                         ftdm_log(FTDM_LOG_CRIT, "Received Progress with no matching channel %d\n", chan_id);
 740                                 }
 741                         }
 742                         break;
 743                 case Q931mes_CONNECT:
 744                         {
 745                                 if (ftdmchan) {
 746                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP);
 747 
 748                                         gen->MesType = Q931mes_CONNECT_ACKNOWLEDGE;
 749                                         gen->CRVFlag = 0;       /* outbound */
 750                                         Q931Rx43(&isdn_data->q931, (L3UCHAR *) gen, gen->Size);
 751                                 } else {
 752                                         ftdm_log(FTDM_LOG_CRIT, "Received Connect with no matching channel %d\n", chan_id);
 753                                 }
 754                         }
 755                         break;
 756                 case Q931mes_SETUP:
 757                         {
 758                                 Q931ie_CallingNum *callingnum = Q931GetIEPtr(gen->CallingNum, gen->buf);
 759                                 Q931ie_CalledNum *callednum = Q931GetIEPtr(gen->CalledNum, gen->buf);
 760                                 int fail = 1;
 761                                 int fail_cause = 0;
 762                                 int overlap_dial = 0;
 763                                 uint32_t cplen = mlen;
 764 
 765                                 if(ftdmchan && ftdmchan == isdn_data->channels_remote_crv[gen->CRV]) {
 766                                         ftdm_log(FTDM_LOG_INFO, "Duplicate SETUP message(?) for Channel %d:%d ~ %d:%d in state %s [ignoring]\n",
 767                                                                         ftdmchan->span_id,
 768                                                                         ftdmchan->chan_id,
 769                                                                         ftdmchan->physical_span_id,
 770                                                                         ftdmchan->physical_chan_id,
 771                                                                         ftdm_channel_state2str(ftdmchan->state));
 772                                         break;
 773                                 }
 774                                 
 775                                 ftdmchan = NULL;
 776                                 /*
 777                                  * Channel selection for incoming calls:
 778                                  */
 779                                 if (FTDM_SPAN_IS_NT(span) && chan_hunt) {
 780                                         uint32_t x;
 781 
 782                                         /*
 783                                          * In NT-mode with channel selection "any",
 784                                          * try to find a free channel
 785                                          */
 786                                         for (x = 1; x <= span->chan_count; x++) {
 787                                                 ftdm_channel_t *zc = span->channels[x];
 788 
 789                                                 if (!ftdm_test_flag(zc, FTDM_CHANNEL_INUSE) && zc->state == FTDM_CHANNEL_STATE_DOWN) {
 790                                                         ftdmchan = zc;
 791                                                         break;
 792                                                 }
 793                                         }
 794                                 }
 795                                 else if (!FTDM_SPAN_IS_NT(span) && chan_hunt) {
 796                                         /*
 797                                          * In TE-mode this ("any") is invalid
 798                                          */
 799                                         fail_cause = FTDM_CAUSE_CHANNEL_UNACCEPTABLE;
 800 
 801                                         ftdm_log(FTDM_LOG_ERROR, "Invalid channel selection in incoming call (network side didn't specify a channel)\n");
 802                                 }
 803                                 else {
 804                                         /*
 805                                          * Otherwise simply try to select the channel we've been told
 806                                          *
 807                                          * TODO: NT mode is abled to select a different channel if the one chosen
 808                                          *       by the TE side is already in use
 809                                          */
 810                                         if (chan_id > 0 && chan_id < FTDM_MAX_CHANNELS_SPAN && chan_id <= span->chan_count) {
 811                                                 ftdmchan = span->channels[chan_id];
 812                                         }
 813                                         else {
 814                                                 /* invalid channel id */
 815                                                 fail_cause = FTDM_CAUSE_CHANNEL_UNACCEPTABLE;
 816 
 817                                                 ftdm_log(FTDM_LOG_ERROR, "Invalid channel selection in incoming call (none selected or out of bounds)\n");
 818                                         }
 819                                 }
 820 
 821                                 if (!callednum || !strlen((char *)callednum->Digit)) {
 822                                         if (FTDM_SPAN_IS_NT(span)) {
 823                                                 ftdm_log(FTDM_LOG_NOTICE, "No destination number found, assuming overlap dial\n");
 824                                                 overlap_dial++;
 825                                         }
 826                                         else {
 827                                                 ftdm_log(FTDM_LOG_ERROR, "No destination number found\n");
 828                                                 ftdmchan = NULL;
 829                                         }
 830                                 }
 831 
 832                                 if (ftdmchan) {
 833                                         if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE) || ftdmchan->state != FTDM_CHANNEL_STATE_DOWN) {
 834                                                 if (ftdmchan->state == FTDM_CHANNEL_STATE_DOWN || ftdmchan->state >= FTDM_CHANNEL_STATE_TERMINATING) {
 835                                                         int x = 0;
 836                                                         ftdm_log(FTDM_LOG_WARNING, "Channel %d:%d ~ %d:%d is already in use waiting for it to become available.\n",
 837                                                                         ftdmchan->span_id,
 838                                                                         ftdmchan->chan_id,
 839                                                                         ftdmchan->physical_span_id,
 840                                                                         ftdmchan->physical_chan_id);
 841 
 842                                                         for (x = 0; x < 200; x++) {
 843                                                                 if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE)) {
 844                                                                         break;
 845                                                                 }
 846                                                                 ftdm_sleep(5);
 847                                                         }
 848                                                 }
 849                                                 if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE)) {
 850                                                         ftdm_log(FTDM_LOG_ERROR, "Channel %d:%d ~ %d:%d is already in use.\n",
 851                                                                         ftdmchan->span_id,
 852                                                                         ftdmchan->chan_id,
 853                                                                         ftdmchan->physical_span_id,
 854                                                                         ftdmchan->physical_chan_id
 855                                                                         );
 856                                                         ftdmchan = NULL;
 857                                                 }
 858                                         }
 859 
 860                                         if (ftdmchan && ftdmchan->state == FTDM_CHANNEL_STATE_DOWN) {
 861                                                 isdn_data->channels_remote_crv[gen->CRV] = ftdmchan;
 862                                                 memset(&ftdmchan->caller_data, 0, sizeof(ftdmchan->caller_data));
 863 
 864                                                 if (ftdmchan->mod_data) {
 865                                                         memset(ftdmchan->mod_data, 0, sizeof(ftdm_isdn_bchan_data_t));
 866                                                 }
 867 
 868                                                 ftdm_set_string(ftdmchan->caller_data.cid_num.digits, (char *)callingnum->Digit);
 869                                                 ftdm_set_string(ftdmchan->caller_data.cid_name, (char *)callingnum->Digit);
 870                                                 ftdm_set_string(ftdmchan->caller_data.ani.digits, (char *)callingnum->Digit);
 871                                                 if (!overlap_dial) {
 872                                                         ftdm_set_string(ftdmchan->caller_data.dnis.digits, (char *)callednum->Digit);
 873                                                 }
 874 
 875                                                 ftdmchan->caller_data.CRV = gen->CRV;
 876                                                 if (cplen > sizeof(ftdmchan->caller_data.raw_data)) {
 877                                                         cplen = sizeof(ftdmchan->caller_data.raw_data);
 878                                                 }
 879                                                 gen->CRVFlag = !(gen->CRVFlag);
 880                                                 memcpy(ftdmchan->caller_data.raw_data, msg, cplen);
 881                                                 ftdmchan->caller_data.raw_data_len = cplen;
 882                                                 fail = 0;
 883                                         } 
 884                                 } 
 885 
 886                                 if (fail) {
 887                                         Q931ie_Cause cause;
 888                                         gen->MesType = Q931mes_DISCONNECT;
 889                                         gen->CRVFlag = 1;       /* inbound call */
 890                                         cause.IEId = Q931ie_CAUSE;
 891                                         cause.Size = sizeof(Q931ie_Cause);
 892                                         cause.CodStand = Q931_CODING_ITU;
 893                                         cause.Location = 1;
 894                                         cause.Recom = 1;
 895                                         //should we be casting here.. or do we need to translate value?
 896                                         cause.Value = (unsigned char)((fail_cause) ? fail_cause : FTDM_CAUSE_WRONG_CALL_STATE);
 897                                         *cause.Diag = '\0';
 898                                         gen->Cause = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &cause);
 899                                         Q931Rx43(&isdn_data->q931, (L3UCHAR *) gen, gen->Size);
 900 
 901                                         if (gen->CRV) {
 902                                                 Q931ReleaseCRV(&isdn_data->q931, gen->CRV);
 903                                         }
 904 
 905                                         if (ftdmchan) {
 906                                                 ftdm_log(FTDM_LOG_CRIT, "Channel is busy\n");
 907                                         } else {
 908                                                 ftdm_log(FTDM_LOG_CRIT, "Failed to open channel for new setup message\n");
 909                                         }
 910                                         
 911                                 } else {
 912                                         Q931ie_ChanID ChanID;
 913 
 914                                         /*
 915                                          * Update Channel ID IE
 916                                          */
 917                                         Q931InitIEChanID(&ChanID);
 918                                         ChanID.IntType = FTDM_SPAN_IS_BRI(ftdmchan->span) ? 0 : 1;      /* PRI = 1, BRI = 0 */
 919                                         ChanID.PrefExcl = FTDM_SPAN_IS_NT(ftdmchan->span) ? 1 : 0;  /* Exclusive in NT-mode = 1, Preferred otherwise = 0 */
 920                                         if(ChanID.IntType) {
 921                                                 ChanID.InfoChanSel = 1;         /* None = 0, See Slot = 1, Any = 3 */
 922                                                 ChanID.ChanMapType = 3;         /* B-Chan */
 923                                                 ChanID.ChanSlot = (unsigned char)ftdmchan->chan_id;
 924                                         } else {
 925                                                 ChanID.InfoChanSel = (unsigned char)ftdmchan->chan_id & 0x03;   /* None = 0, B1 = 1, B2 = 2, Any = 3 */
 926                                         }
 927                                         gen->ChanID = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &ChanID);
 928 
 929                                         if (overlap_dial) {
 930                                                 Q931ie_ProgInd progress;
 931 
 932                                                 /*
 933                                                  * Setup Progress indicator
 934                                                  */
 935                                                 progress.IEId = Q931ie_PROGRESS_INDICATOR;
 936                                                 progress.Size = sizeof(Q931ie_ProgInd);
 937                                                 progress.CodStand = Q931_CODING_ITU;    /* ITU */ 
 938                                                 progress.Location = 1;  /* private network serving the local user */
 939                                                 progress.ProgDesc = 8;  /* call is not end-to-end isdn = 1, in-band information available = 8 */
 940                                                 gen->ProgInd = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &progress);
 941 
 942                                                 /*
 943                                                  * Send SETUP ACK
 944                                                  */
 945                                                 gen->MesType = Q931mes_SETUP_ACKNOWLEDGE;
 946                                                 gen->CRVFlag = 1;       /* inbound call */
 947                                                 Q931Rx43(&isdn_data->q931, (L3UCHAR *) gen, gen->Size);
 948 
 949                                                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DIALTONE);
 950                                         } else {
 951                                                 /*
 952                                                  * Advance to RING state
 953                                                  */
 954                                                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RING);
 955                                         }
 956                                 }
 957                         }
 958                         break;
 959 
 960                 case Q931mes_CALL_PROCEEDING:
 961                         {
 962                                 if (ftdmchan) {
 963                                         ftdm_log(FTDM_LOG_CRIT, "Received CALL PROCEEDING message for channel %d\n", chan_id);
 964                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
 965                                 } else {
 966                                         ftdm_log(FTDM_LOG_CRIT, "Received CALL PROCEEDING with no matching channel %d\n", chan_id);
 967                                 }
 968                         }
 969                         break;
 970                 case Q931mes_CONNECT_ACKNOWLEDGE:
 971                         {
 972                                 if (ftdmchan) {
 973                                         ftdm_log(FTDM_LOG_DEBUG, "Received CONNECT_ACK message for channel %d\n", chan_id);
 974                                 } else {
 975                                         ftdm_log(FTDM_LOG_DEBUG, "Received CONNECT_ACK with no matching channel %d\n", chan_id);
 976                                 }
 977                         }
 978                         break;
 979 
 980                 case Q931mes_INFORMATION:
 981                         {
 982                                 if (ftdmchan) {
 983                                         ftdm_log(FTDM_LOG_CRIT, "Received INFORMATION message for channel %d\n", ftdmchan->chan_id);
 984 
 985                                         if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALTONE) {
 986                                                 char digit = '\0';
 987 
 988                                                 /*
 989                                                  * overlap dial digit indication
 990                                                  */
 991                                                 if (Q931IsIEPresent(gen->CalledNum)) {
 992                                                         ftdm_isdn_bchan_data_t *data = (ftdm_isdn_bchan_data_t *)ftdmchan->mod_data;
 993                                                         Q931ie_CalledNum *callednum = Q931GetIEPtr(gen->CalledNum, gen->buf);
 994                                                         int pos;
 995 
 996                                                         digit = callednum->Digit[strlen((char *)callednum->Digit) - 1];
 997                                                         if (digit == '#') {
 998                                                                 callednum->Digit[strlen((char *)callednum->Digit) - 1] = '\0';
 999                                                         }
1000 
1001                                                         /* TODO: make this more safe with strncat() */
1002                                                         pos = (int)strlen(ftdmchan->caller_data.dnis.digits);
1003                                                         strcat(&ftdmchan->caller_data.dnis.digits[pos],    (char *)callednum->Digit);
1004 
1005                                                         /* update timer */
1006                                                         data->digit_timeout = ftdm_time_now() + isdn_data->digit_timeout;
1007 
1008                                                         ftdm_log(FTDM_LOG_DEBUG, "Received new overlap digit (%s), destination number: %s\n", callednum->Digit, ftdmchan->caller_data.dnis.digits);
1009                                                 }
1010 
1011                                                 if (Q931IsIEPresent(gen->SendComplete) || digit == '#') {
1012                                                         ftdm_log(FTDM_LOG_DEBUG, "Leaving overlap dial mode\n");
1013 
1014                                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RING);
1015                                                 }
1016                                         }
1017                                 } else {
1018                                         ftdm_log(FTDM_LOG_CRIT, "Received INFORMATION message with no matching channel\n");
1019                                 }
1020                         }
1021                         break;
1022 
1023                 case Q931mes_STATUS_ENQUIRY:
1024                         {
1025                                 /*
1026                                  * !! HACK ALERT !!
1027                                  *
1028                                  * Map FreeTDM channel states to Q.931 states
1029                                  */
1030                                 Q931ie_CallState state;
1031                                 Q931ie_Cause cause;
1032 
1033                                 gen->MesType = Q931mes_STATUS;
1034                                 gen->CRVFlag = gen->CRVFlag ? 0 : 1;
1035 
1036                                 state.CodStand  = Q931_CODING_ITU;      /* ITU-T */
1037                                 state.CallState = Q931_U0;              /* Default: Null */
1038 
1039                                 cause.IEId = Q931ie_CAUSE;
1040                                 cause.Size = sizeof(Q931ie_Cause);
1041                                 cause.CodStand = Q931_CODING_ITU;       /* ITU */
1042                                 cause.Location = 1;     /* private network */
1043                                 cause.Recom    = 1;     /* */
1044                                 *cause.Diag    = '\0';
1045 
1046                                 if(ftdmchan) {
1047                                         switch(ftdmchan->state) {
1048                                         case FTDM_CHANNEL_STATE_UP:
1049                                                 state.CallState = Q931_U10;     /* Active */
1050                                                 break;
1051                                         case FTDM_CHANNEL_STATE_RING:
1052                                                 state.CallState = Q931_U6;      /* Call present */
1053                                                 break;
1054                                         case FTDM_CHANNEL_STATE_DIALING:
1055                                                 state.CallState = Q931_U1;      /* Call initiated */
1056                                                 break;
1057                                         case FTDM_CHANNEL_STATE_DIALTONE:
1058                                                 state.CallState = Q931_U25;     /* Overlap receiving */
1059                                                 break;
1060 
1061                                         /* TODO: map missing states */
1062 
1063                                         default:
1064                                                 state.CallState = Q931_U0;
1065                                         }
1066 
1067                                         cause.Value = 30;       /* response to STATUS ENQUIRY */
1068                                 } else {
1069                                         cause.Value = 98;       /* */
1070                                 }
1071 
1072                                 gen->CallState = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &state);
1073                                 gen->Cause     = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &cause);
1074                                 Q931Rx43(&isdn_data->q931, (L3UCHAR *) gen, gen->Size);
1075                         }
1076                         break;
1077 
1078                 default:
1079                         ftdm_log(FTDM_LOG_CRIT, "Received unhandled message %d (%#x)\n", (int)gen->MesType, (int)gen->MesType);
1080                         break;
1081                 }
1082         }
1083 
1084         return 0;
1085 }
1086 
1087 /**
1088  * \brief Handler for Q921 read event
1089  * \param pvt Span were message is coming from
1090  * \param ind Q921 indication
1091  * \param tei Terminal Endpoint Identifier
1092  * \param msg Message string
1093  * \param mlen Message string length
1094  * \return 0 on success, 1 on failure
1095  */
1096 static int ftdm_isdn_921_23(void *pvt, Q921DLMsg_t ind, L2UCHAR tei, L2UCHAR *msg, L2INT mlen)
1097 {
1098         int ret, offset = (ind == Q921_DL_DATA) ? 4 : 3;
1099         char bb[4096] = "";
1100 
1101         switch(ind) {
1102         case Q921_DL_DATA:
1103         case Q921_DL_UNIT_DATA:
1104                 print_hex_bytes(msg + offset, mlen - offset, bb, sizeof(bb));
1105 #ifdef HAVE_LIBPCAP
1106                 /*Q931ToPcap*/
1107                 if(do_q931ToPcap==1){
1108                         ftdm_span_t *span = (ftdm_span_t *) pvt;
1109                         if(writeQ931PacketToPcap(msg + offset, mlen - offset, span->span_id, 1) != FTDM_SUCCESS){
1110                                 ftdm_log(FTDM_LOG_WARNING, "Couldn't write Q931 buffer to pcap file!\n");
1111                         }
1112                 }
1113                 /*Q931ToPcap done*/
1114 #endif
1115                 ftdm_log(FTDM_LOG_DEBUG, "READ %d\n%s\n%s\n\n\n", (int)mlen - offset, LINE, bb);
1116         
1117         default:
1118                 ret = Q931Rx23(pvt, ind, tei, msg, mlen);
1119                 if (ret != 0)
1120                         ftdm_log(FTDM_LOG_DEBUG, "931 parse error [%d] [%s]\n", ret, q931_error_to_name(ret));
1121                 break;
1122         }
1123 
1124         return ((ret >= 0) ? 1 : 0);
1125 }
1126 
1127 /**
1128  * \brief Handler for Q921 write event
1129  * \param pvt Span were message is coming from
1130  * \param msg Message string
1131  * \param mlen Message string length
1132  * \return 0 on success, -1 on failure
1133  */
1134 static int ftdm_isdn_921_21(void *pvt, L2UCHAR *msg, L2INT mlen)
1135 {
1136         ftdm_span_t *span = (ftdm_span_t *) pvt;
1137         ftdm_size_t len = (ftdm_size_t) mlen;
1138         ftdm_isdn_data_t *isdn_data = span->signal_data;
1139 
1140 #ifdef IODEBUG
1141         char bb[4096] = "";
1142         print_hex_bytes(msg, len, bb, sizeof(bb));
1143         print_bits(msg, (int)len, bb, sizeof(bb), FTDM_ENDIAN_LITTLE, 0);
1144         ftdm_log(FTDM_LOG_DEBUG, "WRITE %d\n%s\n%s\n\n", (int)len, LINE, bb);
1145 
1146 #endif
1147 
1148         assert(span != NULL);
1149         return ftdm_channel_write(isdn_data->dchan, msg, len, &len) == FTDM_SUCCESS ? 0 : -1;
1150 }
1151 
1152 /**
1153  * \brief Handler for channel state change
1154  * \param ftdmchan Channel to handle
1155  */
1156 static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
1157 {
1158         Q931mes_Generic *gen = (Q931mes_Generic *) ftdmchan->caller_data.raw_data;
1159         ftdm_isdn_data_t *isdn_data = ftdmchan->span->signal_data;
1160         ftdm_sigmsg_t sig;
1161         ftdm_status_t status;
1162 
1163         ftdm_log(FTDM_LOG_DEBUG, "%d:%d STATE [%s]\n", 
1164                         ftdmchan->span_id, ftdmchan->chan_id, ftdm_channel_state2str(ftdmchan->state));
1165 
1166         memset(&sig, 0, sizeof(sig));
1167         sig.chan_id = ftdmchan->chan_id;
1168         sig.span_id = ftdmchan->span_id;
1169         sig.channel = ftdmchan;
1170 
1171         switch (ftdmchan->state) {
1172         case FTDM_CHANNEL_STATE_DOWN:
1173                 {
1174                         if (gen->CRV) {
1175                                 if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
1176                                         isdn_data->channels_local_crv[gen->CRV] = NULL;
1177                                 } else {
1178                                         isdn_data->channels_remote_crv[gen->CRV] = NULL;
1179                                 }
1180                                 Q931ReleaseCRV(&isdn_data->q931, gen->CRV);
1181                         }
1182                         ftdm_channel_done(ftdmchan);
1183                 }
1184                 break;
1185         case FTDM_CHANNEL_STATE_PROGRESS:
1186                 {
1187                         if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
1188                                 sig.event_id = FTDM_SIGEVENT_PROGRESS;
1189                                 if ((status = ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS)) {
1190                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
1191                                 }
1192                         } else {
1193                                 gen->MesType = Q931mes_CALL_PROCEEDING;
1194                                 gen->CRVFlag = 1;       /* inbound */
1195 
1196                                 if (FTDM_SPAN_IS_NT(ftdmchan->span)) {
1197                                         Q931ie_ChanID ChanID;
1198 
1199                                         /*
1200                                          * Set new Channel ID
1201                                          */
1202                                         Q931InitIEChanID(&ChanID);
1203                                         ChanID.IntType = FTDM_SPAN_IS_BRI(ftdmchan->span) ? 0 : 1;              /* PRI = 1, BRI = 0 */
1204                                         ChanID.PrefExcl = 1;    /* always exclusive in NT-mode */
1205 
1206                                         if(ChanID.IntType) {
1207                                                 ChanID.InfoChanSel = 1;         /* None = 0, See Slot = 1, Any = 3 */
1208                                                 ChanID.ChanMapType = 3;         /* B-Chan */
1209                                                 ChanID.ChanSlot = (unsigned char)ftdmchan->chan_id;
1210                                         } else {
1211                                                 ChanID.InfoChanSel = (unsigned char)ftdmchan->chan_id & 0x03;   /* None = 0, B1 = 1, B2 = 2, Any = 3 */
1212                                         }
1213                                         gen->ChanID = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &ChanID);
1214                                 }
1215 
1216                                 Q931Rx43(&isdn_data->q931, (void *)gen, gen->Size);
1217                         }
1218                 }
1219                 break;
1220         case FTDM_CHANNEL_STATE_DIALTONE:
1221                 {
1222                         ftdm_isdn_bchan_data_t *data = (ftdm_isdn_bchan_data_t *)ftdmchan->mod_data;
1223 
1224                         if (data) {
1225                                 data->digit_timeout = ftdm_time_now() + isdn_data->digit_timeout;
1226                         }
1227                 }
1228                 break;
1229         case FTDM_CHANNEL_STATE_RING:
1230                 {
1231                         if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
1232                                 sig.event_id = FTDM_SIGEVENT_START;
1233                                 if ((status = ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS)) {
1234                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
1235                                 }
1236                         }
1237                 }
1238                 break;
1239         case FTDM_CHANNEL_STATE_RESTART:
1240                 {
1241                         ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_UNSPECIFIED;
1242                         sig.event_id = FTDM_SIGEVENT_RESTART;
1243                         status = ftdm_span_send_signal(ftdmchan->span, &sig);
1244                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
1245                 }
1246                 break;
1247         case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
1248                 {
1249                         if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
1250                                 sig.event_id = FTDM_SIGEVENT_PROGRESS_MEDIA;
1251                                 if ((status = ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS)) {
1252                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
1253                                 }
1254                         } else {
1255                                 if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) {
1256                                         if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) {
1257                                                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
1258                                                 return;
1259                                         }
1260                                 }
1261                                 gen->MesType = Q931mes_ALERTING;
1262                                 gen->CRVFlag = 1;       /* inbound call */
1263                                 Q931Rx43(&isdn_data->q931, (void *)gen, gen->Size);
1264                         }
1265                 }
1266                 break;
1267         case FTDM_CHANNEL_STATE_UP:
1268                 {
1269                         if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
1270                                 sig.event_id = FTDM_SIGEVENT_UP;
1271                                 if ((status = ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS)) {
1272                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
1273                                 }
1274                         } else {
1275                                 if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) {
1276                                         if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) {
1277                                                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
1278                                                 return;
1279                                         }
1280                                 }
1281                                 gen->MesType = Q931mes_CONNECT;
1282                                 gen->BearerCap = 0;
1283                                 gen->CRVFlag = 1;       /* inbound call */
1284                                 Q931Rx43(&isdn_data->q931, (void *)gen, ftdmchan->caller_data.raw_data_len);
1285                         }
1286                 }
1287                 break;
1288         case FTDM_CHANNEL_STATE_DIALING:
1289                 if (!(isdn_data->opts & FTDM_ISDN_OPT_SUGGEST_CHANNEL)) {
1290                         Q931ie_BearerCap BearerCap;
1291                         Q931ie_ChanID ChanID;
1292                         Q931ie_CallingNum CallingNum;
1293                         Q931ie_CallingNum *ptrCallingNum;
1294                         Q931ie_CalledNum CalledNum;
1295                         Q931ie_CalledNum *ptrCalledNum;
1296                         Q931ie_Display Display, *ptrDisplay;
1297                         Q931ie_HLComp HLComp;                   /* High-Layer Compatibility IE */
1298                         Q931ie_ProgInd Progress;                /* Progress Indicator IE */
1299                         int codec  = 0;
1300 
1301                         /*
1302                          * get codec type
1303                          */
1304                         ftdm_channel_command(ftdmchan->span->channels[ftdmchan->chan_id], FTDM_COMMAND_GET_NATIVE_CODEC, &codec);
1305 
1306                         /*
1307                          * Q.931 Setup Message
1308                          */ 
1309                         Q931InitMesGeneric(gen);
1310                         gen->MesType = Q931mes_SETUP;
1311                         gen->CRVFlag = 0;               /* outbound(?) */
1312 
1313                         /*
1314                          * Bearer Capability IE
1315                          */
1316                         Q931InitIEBearerCap(&BearerCap);
1317                         BearerCap.CodStand  = Q931_CODING_ITU;  /* ITU-T = 0, ISO/IEC = 1, National = 2, Network = 3 */
1318                         BearerCap.ITC       = Q931_ITC_SPEECH;  /* Speech */
1319                         BearerCap.TransMode = 0;                /* Circuit = 0, Packet = 1 */
1320                         BearerCap.ITR       = Q931_ITR_64K;     /* 64k = 16, Packet mode = 0 */
1321                         BearerCap.Layer1Ident = 1;
1322                         BearerCap.UIL1Prot = (codec == FTDM_CODEC_ALAW) ? 3 : 2;        /* U-law = 2, A-law = 3 */
1323                         gen->BearerCap = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &BearerCap);
1324 
1325                         /*
1326                          * ChannelID IE
1327                          */
1328                         Q931InitIEChanID(&ChanID);
1329                         ChanID.IntType = FTDM_SPAN_IS_BRI(ftdmchan->span) ? 0 : 1;      /* PRI = 1, BRI = 0 */
1330                         ChanID.PrefExcl = FTDM_SPAN_IS_NT(ftdmchan->span) ? 1 : 0;  /* Exclusive in NT-mode = 1, Preferred otherwise = 0 */
1331                         if(ChanID.IntType) {
1332                                 ChanID.InfoChanSel = 1;         /* None = 0, See Slot = 1, Any = 3 */
1333                                 ChanID.ChanMapType = 3;         /* B-Chan */
1334                                 ChanID.ChanSlot = (unsigned char)ftdmchan->chan_id;
1335                         } else {
1336                                 ChanID.InfoChanSel = (unsigned char)ftdmchan->chan_id & 0x03;   /* None = 0, B1 = 1, B2 = 2, Any = 3 */
1337                         }
1338                         gen->ChanID = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &ChanID);
1339 
1340                         /*
1341                          * Progress IE
1342                          */
1343                         Q931InitIEProgInd(&Progress);
1344                         Progress.CodStand = Q931_CODING_ITU;    /* 0 = ITU */
1345                         Progress.Location = 0;  /* 0 = User, 1 = Private Network */
1346                         Progress.ProgDesc = 3;  /* 1 = Not end-to-end ISDN */
1347                         gen->ProgInd = Q931AppendIE((L3UCHAR *)gen, (L3UCHAR *)&Progress);
1348 
1349                         /*
1350                          * Display IE
1351                          */
1352                         if (!(isdn_data->opts & FTDM_ISDN_OPT_OMIT_DISPLAY_IE)) {
1353                                 Q931InitIEDisplay(&Display);
1354                                 Display.Size = Display.Size + (unsigned char)strlen(ftdmchan->caller_data.cid_name);
1355                                 gen->Display = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &Display);
1356                                 ptrDisplay = Q931GetIEPtr(gen->Display, gen->buf);
1357                                 ftdm_copy_string((char *)ptrDisplay->Display, ftdmchan->caller_data.cid_name, strlen(ftdmchan->caller_data.cid_name)+1);
1358                         }
1359 
1360                         /*
1361                          * CallingNum IE
1362                          */ 
1363                         Q931InitIECallingNum(&CallingNum);
1364                         CallingNum.TypNum    = ftdmchan->caller_data.ani.type;
1365                         CallingNum.NumPlanID = Q931_NUMPLAN_E164;
1366                         CallingNum.PresInd   = Q931_PRES_ALLOWED;
1367                         CallingNum.ScreenInd = Q931_SCREEN_USER_NOT_SCREENED;
1368                         CallingNum.Size = CallingNum.Size + (unsigned char)strlen(ftdmchan->caller_data.cid_num.digits);
1369                         gen->CallingNum = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &CallingNum);
1370                         ptrCallingNum = Q931GetIEPtr(gen->CallingNum, gen->buf);
1371                         ftdm_copy_string((char *)ptrCallingNum->Digit, ftdmchan->caller_data.cid_num.digits, strlen(ftdmchan->caller_data.cid_num.digits)+1);
1372 
1373                         /*
1374                          * CalledNum IE
1375                          */
1376                         Q931InitIECalledNum(&CalledNum);
1377                         CalledNum.TypNum    = ftdmchan->caller_data.dnis.type;
1378                         CalledNum.NumPlanID = Q931_NUMPLAN_E164;
1379                         CalledNum.Size = CalledNum.Size + (unsigned char)strlen(ftdmchan->caller_data.dnis.digits);
1380                         gen->CalledNum = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &CalledNum);
1381                         ptrCalledNum = Q931GetIEPtr(gen->CalledNum, gen->buf);
1382                         ftdm_copy_string((char *)ptrCalledNum->Digit, ftdmchan->caller_data.dnis.digits, strlen(ftdmchan->caller_data.dnis.digits)+1);
1383 
1384                         /*
1385                          * High-Layer Compatibility IE   (Note: Required for AVM FritzBox)
1386                          */
1387                         Q931InitIEHLComp(&HLComp);
1388                         HLComp.CodStand  = Q931_CODING_ITU;     /* ITU */
1389                         HLComp.Interpret = 4;   /* only possible value */
1390                         HLComp.PresMeth  = 1;   /* High-layer protocol profile */
1391                         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 */
1392                         gen->HLComp = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &HLComp);
1393 
1394                         Q931Rx43(&isdn_data->q931, (L3UCHAR *) gen, gen->Size);
1395                         isdn_data->channels_local_crv[gen->CRV] = ftdmchan;
1396                 }
1397                 break;
1398         case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
1399                 {
1400                         /* reply RELEASE with RELEASE_COMPLETE message */
1401                         if(ftdmchan->last_state == FTDM_CHANNEL_STATE_HANGUP) {
1402                                 gen->MesType = Q931mes_RELEASE_COMPLETE;
1403 
1404                                 Q931Rx43(&isdn_data->q931, (L3UCHAR *) gen, gen->Size);
1405                         }
1406                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
1407                 }
1408                 break;
1409         case FTDM_CHANNEL_STATE_HANGUP:
1410                 {
1411                         Q931ie_Cause cause;
1412 
1413                         ftdm_log(FTDM_LOG_DEBUG, "Hangup: Direction %s\n", ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) ? "Outbound" : "Inbound");
1414 
1415                         gen->CRVFlag = ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) ? 0 : 1;
1416 
1417                         cause.IEId = Q931ie_CAUSE;
1418                         cause.Size = sizeof(Q931ie_Cause);
1419                         cause.CodStand = Q931_CODING_ITU;       /* ITU */
1420                         cause.Location = 1;     /* private network */
1421                         cause.Recom    = 1;     /* */
1422 
1423                         /*
1424                          * BRI PTMP needs special handling here...
1425                          * TODO: cleanup / refine (see above)
1426                          */
1427                         if (ftdmchan->last_state == FTDM_CHANNEL_STATE_RING) {
1428                                 /*
1429                                  * inbound call [was: number unknown (= not found in routing state)]
1430                                  * (in Q.931 spec terms: Reject request)
1431                                  */
1432                                 gen->MesType = Q931mes_RELEASE_COMPLETE;
1433 
1434                                 //cause.Value = (unsigned char) FTDM_CAUSE_UNALLOCATED;
1435                                 cause.Value = (unsigned char) ftdmchan->caller_data.hangup_cause;
1436                                 *cause.Diag = '\0';
1437                                 gen->Cause = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &cause);
1438                                 Q931Rx43(&isdn_data->q931, (L3UCHAR *) gen, gen->Size);
1439 
1440                                 /* we're done, release channel */
1441                                 //ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
1442                                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
1443                         }
1444                         else if (ftdmchan->last_state <= FTDM_CHANNEL_STATE_PROGRESS) {
1445                                 /*
1446                                  * just release all unanswered calls [was: inbound call, remote side hung up before we answered]
1447                                  */
1448                                 gen->MesType = Q931mes_RELEASE;
1449 
1450                                 cause.Value = (unsigned char) ftdmchan->caller_data.hangup_cause;
1451                                 *cause.Diag = '\0';
1452                                 gen->Cause = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &cause);
1453                                 Q931Rx43(&isdn_data->q931, (void *)gen, gen->Size);
1454 
1455                                 /* this will be triggered by the RELEASE_COMPLETE reply */
1456                                 /* ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); */
1457                         }
1458                         else {
1459                                 /*
1460                                  * call connected, hangup
1461                                  */
1462                                 gen->MesType = Q931mes_DISCONNECT;
1463 
1464                                 cause.Value = (unsigned char) ftdmchan->caller_data.hangup_cause;
1465                                 *cause.Diag = '\0';
1466                                 gen->Cause = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &cause);
1467                                 Q931Rx43(&isdn_data->q931, (L3UCHAR *) gen, gen->Size);
1468                         }
1469                 }
1470                 break;
1471         case FTDM_CHANNEL_STATE_TERMINATING:
1472                 {
1473                         ftdm_log(FTDM_LOG_DEBUG, "Terminating: Direction %s\n", ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) ? "Outbound" : "Inbound");
1474 
1475                         sig.event_id = FTDM_SIGEVENT_STOP;
1476                         status = ftdm_span_send_signal(ftdmchan->span, &sig);
1477                         gen->MesType = Q931mes_RELEASE;
1478                         gen->CRVFlag = ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND) ? 0 : 1;
1479                         Q931Rx43(&isdn_data->q931, (void *)gen, gen->Size);
1480                 }
1481         default:
1482                 break;
1483         }
1484 }
1485 
1486 /**
1487  * \brief Checks current state on a span
1488  * \param span Span to check status on
1489  */
1490 static __inline__ void check_state(ftdm_span_t *span)
1491 {
1492     if (ftdm_test_flag(span, FTDM_SPAN_STATE_CHANGE)) {
1493         uint32_t j;
1494         ftdm_clear_flag_locked(span, FTDM_SPAN_STATE_CHANGE);
1495         for(j = 1; j <= span->chan_count; j++) {
1496             if (ftdm_test_flag((span->channels[j]), FTDM_CHANNEL_STATE_CHANGE)) {
1497                                 ftdm_mutex_lock(span->channels[j]->mutex);
1498                 ftdm_clear_flag((span->channels[j]), FTDM_CHANNEL_STATE_CHANGE);
1499                 state_advance(span->channels[j]);
1500                 ftdm_channel_complete_state(span->channels[j]);
1501                                 ftdm_mutex_unlock(span->channels[j]->mutex);
1502             }
1503         }
1504     }
1505 }
1506 
1507 /**
1508  * \brief Processes FreeTDM event on a span
1509  * \param span Span to process event on
1510  * \param event Event to process
1511  * \return Success or failure
1512  */
1513 static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *event)
1514 {
1515         ftdm_log(FTDM_LOG_DEBUG, "EVENT [%s][%d:%d] STATE [%s]\n", 
1516                         ftdm_oob_event2str(event->enum_id), event->channel->span_id, event->channel->chan_id, ftdm_channel_state2str(event->channel->state));
1517 
1518         switch(event->enum_id) {
1519         case FTDM_OOB_ALARM_TRAP:
1520                 {
1521                         if (event->channel->state != FTDM_CHANNEL_STATE_DOWN) {
1522                                 if (event->channel->type == FTDM_CHAN_TYPE_B) {
1523                                         ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_RESTART);
1524                                 }
1525                         }
1526                         
1527 
1528                         ftdm_set_flag(event->channel, FTDM_CHANNEL_SUSPENDED);
1529 
1530                         
1531                         ftdm_channel_get_alarms(event->channel);
1532                         ftdm_log(FTDM_LOG_WARNING, "channel %d:%d (%d:%d) has alarms! [%s]\n", 
1533                                         event->channel->span_id, event->channel->chan_id, 
1534                                         event->channel->physical_span_id, event->channel->physical_chan_id, 
1535                                         event->channel->last_error);
1536                 }
1537                 break;
1538         case FTDM_OOB_ALARM_CLEAR:
1539                 {
1540                         
1541                         ftdm_log(FTDM_LOG_WARNING, "channel %d:%d (%d:%d) alarms Cleared!\n", event->channel->span_id, event->channel->chan_id,
1542                                         event->channel->physical_span_id, event->channel->physical_chan_id);
1543 
1544                         ftdm_clear_flag(event->channel, FTDM_CHANNEL_SUSPENDED);
1545                         ftdm_channel_get_alarms(event->channel);
1546                 }
1547                 break;
1548         }
1549 
1550         return FTDM_SUCCESS;
1551 }
1552 
1553 /**
1554  * \brief Checks for events on a span
1555  * \param span Span to check for events
1556  */
1557 static __inline__ void check_events(ftdm_span_t *span)
1558 {
1559         ftdm_status_t status;
1560 
1561         status = ftdm_span_poll_event(span, 5);
1562 
1563         switch(status) {
1564         case FTDM_SUCCESS:
1565                 {
1566                         ftdm_event_t *event;
1567                         while (ftdm_span_next_event(span, &event) == FTDM_SUCCESS) {
1568                                 if (event->enum_id == FTDM_OOB_NOOP) {
1569                                         continue;
1570                                 }
1571                                 if (process_event(span, event) != FTDM_SUCCESS) {
1572                                         break;
1573                                 }
1574                         }
1575                 }
1576                 break;
1577         case FTDM_FAIL:
1578                 {
1579                         ftdm_log(FTDM_LOG_DEBUG, "Event Failure! %d\n", ftdm_running());
1580                 }
1581                 break;
1582         default:
1583                 break;
1584         }
1585 }
1586 
1587 /**
1588  * \brief Retrieves tone generation output to be sent
1589  * \param ts Teletone generator
1590  * \param map Tone map
1591  * \return -1 on error, 0 on success
1592  */
1593 static int teletone_handler(teletone_generation_session_t *ts, teletone_tone_map_t *map)
1594 {
1595         ftdm_buffer_t *dt_buffer = ts->user_data;
1596         int wrote;
1597 
1598         if (!dt_buffer) {
1599                 return -1;
1600         }
1601         wrote = teletone_mux_tones(ts, map);
1602         ftdm_buffer_write(dt_buffer, ts->buffer, wrote * 2);
1603         return 0;
1604 }
1605 
1606 /**
1607  * \brief Main thread function for tone generation on a span
1608  * \param me Current thread
1609  * \param obj Span to generate tones on
1610  */
1611 static void *ftdm_isdn_tones_run(ftdm_thread_t *me, void *obj)
1612 {
1613         ftdm_span_t *span = (ftdm_span_t *) obj;
1614         ftdm_isdn_data_t *isdn_data = span->signal_data;
1615         ftdm_buffer_t *dt_buffer = NULL;
1616         teletone_generation_session_t ts = {{{{0}}}};
1617         unsigned char frame[1024];
1618         uint32_t x;
1619         int interval = 0;
1620         int offset = 0;
1621 
1622         ftdm_log(FTDM_LOG_DEBUG, "ISDN tones thread starting.\n");
1623         ftdm_set_flag(isdn_data, FTDM_ISDN_TONES_RUNNING);
1624 
1625         if (ftdm_buffer_create(&dt_buffer, 1024, 1024, 0) != FTDM_SUCCESS) {
1626                 snprintf(isdn_data->dchan->last_error, sizeof(isdn_data->dchan->last_error), "memory error!");
1627                 ftdm_log(FTDM_LOG_ERROR, "MEM ERROR\n");
1628                 goto done;
1629         }
1630         ftdm_buffer_set_loops(dt_buffer, -1);
1631 
1632         /* get a tone generation friendly interval to avoid distortions */
1633         for (x = 1; x <= span->chan_count; x++) {
1634                 if (span->channels[x]->type != FTDM_CHAN_TYPE_DQ921) {
1635                         ftdm_channel_command(span->channels[x], FTDM_COMMAND_GET_INTERVAL, &interval);
1636                         break;
1637                 }
1638         }
1639         if (!interval) {
1640                 interval = 20;
1641         }
1642         ftdm_log(FTDM_LOG_NOTICE, "Tone generating interval %d\n", interval);
1643 
1644         /* init teletone */
1645         teletone_init_session(&ts, 0, teletone_handler, dt_buffer);
1646         ts.rate     = 8000;
1647         ts.duration = ts.rate;
1648 
1649         /* main loop */
1650         while(ftdm_running() && ftdm_test_flag(isdn_data, FTDM_ISDN_TONES_RUNNING) && !ftdm_test_flag(isdn_data, FTDM_ISDN_STOP)) {
1651                 ftdm_wait_flag_t flags;
1652                 ftdm_status_t status;
1653                 int last_chan_state = 0;
1654                 int gated = 0;
1655                 L2ULONG now = ftdm_time_now();
1656 
1657                 /*
1658                  * check b-channel states and generate & send tones if neccessary
1659                  */
1660                 for (x = 1; x <= span->chan_count; x++) {
1661                         ftdm_channel_t *ftdmchan = span->channels[x];
1662                         ftdm_size_t len = sizeof(frame), rlen;
1663 
1664                         if (ftdmchan->type == FTDM_CHAN_TYPE_DQ921) {
1665                                 continue;
1666                         }
1667 
1668                         /*
1669                          * Generate tones based on current bchan state
1670                          * (Recycle buffer content if succeeding channels share the
1671                          *  same state, this saves some cpu cycles)
1672                          */
1673                         switch (ftdmchan->state) {
1674                         case FTDM_CHANNEL_STATE_DIALTONE:
1675                                 {
1676                                         ftdm_isdn_bchan_data_t *data = (ftdm_isdn_bchan_data_t *)ftdmchan->mod_data;
1677 
1678                                         /* check overlap dial timeout first before generating tone */
1679                                         if (data && data->digit_timeout && data->digit_timeout <= now) {
1680                                                 if (strlen(ftdmchan->caller_data.dnis.digits) > 0) {
1681                                                         ftdm_log(FTDM_LOG_DEBUG, "Overlap dial timeout, advancing to RING state\n");
1682                                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RING);
1683                                                 } else {
1684                                                         /* no digits received, hangup */
1685                                                         ftdm_log(FTDM_LOG_DEBUG, "Overlap dial timeout, no digits received, going to HANGUP state\n");
1686                                                         ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_RECOVERY_ON_TIMER_EXPIRE;       /* TODO: probably wrong cause value */
1687                                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
1688                                                 }
1689                                                 data->digit_timeout = 0;
1690                                                 continue;
1691                                         }
1692 
1693                                         if (last_chan_state != ftdmchan->state) {
1694                                                 ftdm_buffer_zero(dt_buffer);
1695                                                 teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_DIAL]);
1696                                                 last_chan_state = ftdmchan->state;
1697                                         }
1698                                 }
1699                                 break;
1700 
1701                         case FTDM_CHANNEL_STATE_RING:
1702                                 {
1703                                         if (last_chan_state != ftdmchan->state) {
1704                                                 ftdm_buffer_zero(dt_buffer);
1705                                                 teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_RING]);
1706                                                 last_chan_state = ftdmchan->state;
1707                                         }
1708                                 }
1709                                 break;
1710 
1711                         default:        /* Not in a tone generating state, go to next round */
1712                                 continue;
1713                         }
1714 
1715                         if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) {
1716                                 if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) {
1717                                         ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
1718                                         continue;
1719                                 }
1720                                 ftdm_log(FTDM_LOG_NOTICE, "Successfully opened channel %d:%d\n", ftdmchan->span_id, ftdmchan->chan_id);
1721                         }
1722 
1723                         flags = FTDM_READ;
1724 
1725                         status = ftdm_channel_wait(ftdmchan, &flags, (gated) ? 0 : interval);
1726                         switch(status) {
1727                         case FTDM_FAIL:
1728                                 continue;
1729 
1730                         case FTDM_TIMEOUT:
1731                                 gated = 1;
1732                                 continue;
1733 
1734                         default:
1735                                 if (!(flags & FTDM_READ)) {
1736                                         continue;
1737                                 }
1738                         }
1739                         gated = 1;
1740 
1741                         status = ftdm_channel_read(ftdmchan, frame, &len);
1742                         if (status != FTDM_SUCCESS || len <= 0) {
1743                                 continue;
1744                         }
1745 
1746                         if (ftdmchan->effective_codec != FTDM_CODEC_SLIN) {
1747                                 len *= 2;
1748                         }
1749 
1750                         /* seek to current offset */
1751                         ftdm_buffer_seek(dt_buffer, offset);
1752 
1753                         rlen = ftdm_buffer_read_loop(dt_buffer, frame, len);
1754 
1755                         if (ftdmchan->effective_codec != FTDM_CODEC_SLIN) {
1756                                 fio_codec_t codec_func = NULL;
1757 
1758                                 if (ftdmchan->native_codec == FTDM_CODEC_ULAW) {
1759                                         codec_func = fio_slin2ulaw;
1760                                 } else if (ftdmchan->native_codec == FTDM_CODEC_ALAW) {
1761                                         codec_func = fio_slin2alaw;
1762                                 }
1763 
1764                                 if (codec_func) {
1765                                         status = codec_func(frame, sizeof(frame), &rlen);
1766                                 } else {
1767                                         snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "codec error!");
1768                                         goto done;
1769                                 }
1770                         }
1771                         ftdm_channel_write(ftdmchan, frame, sizeof(frame), &rlen);
1772                 }
1773 
1774                 /*
1775                  * sleep a bit if there was nothing to do
1776                  */
1777                 if (!gated) {
1778                         ftdm_sleep(interval);
1779                 }
1780 
1781                 offset += (ts.rate / (1000 / interval)) << 1;
1782                 if (offset >= ts.rate) {
1783                         offset = 0;
1784                 }
1785         }
1786 
1787 done:
1788         if (ts.buffer) {
1789                 teletone_destroy_session(&ts);
1790         }
1791 
1792         if (dt_buffer) {
1793                 ftdm_buffer_destroy(&dt_buffer);
1794         }
1795 
1796         ftdm_log(FTDM_LOG_DEBUG, "ISDN tone thread ended.\n");
1797         ftdm_clear_flag(isdn_data, FTDM_ISDN_TONES_RUNNING);
1798 
1799         return NULL;
1800 }
1801 
1802 /**
1803  * \brief Main thread function for an ISDN span
1804  * \param me Current thread
1805  * \param obj Span to monitor
1806  */
1807 static void *ftdm_isdn_run(ftdm_thread_t *me, void *obj)
1808 {
1809         ftdm_span_t *span = (ftdm_span_t *) obj;
1810         ftdm_isdn_data_t *isdn_data = span->signal_data;
1811         unsigned char frame[1024];
1812         ftdm_size_t len = sizeof(frame);
1813         int errs = 0;
1814 
1815 #ifdef WIN32
1816     timeBeginPeriod(1);
1817 #endif
1818 
1819         ftdm_log(FTDM_LOG_DEBUG, "ISDN thread starting.\n");
1820         ftdm_set_flag(isdn_data, FTDM_ISDN_RUNNING);
1821 
1822         Q921Start(&isdn_data->q921);
1823 
1824         while(ftdm_running() && ftdm_test_flag(isdn_data, FTDM_ISDN_RUNNING) && !ftdm_test_flag(isdn_data, FTDM_ISDN_STOP)) {
1825                 ftdm_wait_flag_t flags = FTDM_READ;
1826                 ftdm_status_t status = ftdm_channel_wait(isdn_data->dchan, &flags, 100);
1827 
1828                 Q921TimerTick(&isdn_data->q921);
1829                 Q931TimerTick(&isdn_data->q931);
1830                 check_state(span);
1831                 check_events(span);
1832 
1833                 /*
1834                  *
1835                  */
1836                 switch(status) {
1837                 case FTDM_FAIL:
1838                         {
1839                                 ftdm_log(FTDM_LOG_ERROR, "D-Chan Read Error!\n");
1840                                 snprintf(span->last_error, sizeof(span->last_error), "D-Chan Read Error!");
1841                                 if (++errs == 10) {
1842                                         isdn_data->dchan->state = FTDM_CHANNEL_STATE_UP;
1843                                         goto done;
1844                                 }
1845                         }
1846                         break;
1847                 case FTDM_TIMEOUT:
1848                         {
1849                                 errs = 0;
1850                         }
1851                         break;
1852                 default:
1853                         {
1854                                 errs = 0;
1855                                 if (flags & FTDM_READ) {
1856 
1857                                         if (ftdm_test_flag(isdn_data->dchan, FTDM_CHANNEL_SUSPENDED)) {
1858                                                 ftdm_clear_flag_all(span, FTDM_CHANNEL_SUSPENDED);
1859                                         }
1860                                         len = sizeof(frame);
1861                                         if (ftdm_channel_read(isdn_data->dchan, frame, &len) == FTDM_SUCCESS) {
1862 #ifdef IODEBUG
1863                                                 char bb[4096] = "";
1864                                                 print_hex_bytes(frame, len, bb, sizeof(bb));
1865 
1866                                                 print_bits(frame, (int)len, bb, sizeof(bb), FTDM_ENDIAN_LITTLE, 0);
1867                                                 ftdm_log(FTDM_LOG_DEBUG, "READ %d\n%s\n%s\n\n", (int)len, LINE, bb);
1868 #endif
1869 
1870                                                 Q921QueueHDLCFrame(&isdn_data->q921, frame, (int)len);
1871                                                 Q921Rx12(&isdn_data->q921);
1872                                         }
1873                                 } else {
1874                                         ftdm_log(FTDM_LOG_DEBUG, "No Read FLAG!\n");
1875                                 }
1876                         }
1877                         break;
1878                 }
1879         }
1880         
1881  done:
1882         ftdm_channel_close(&isdn_data->dchans[0]);
1883         ftdm_channel_close(&isdn_data->dchans[1]);
1884         ftdm_clear_flag(isdn_data, FTDM_ISDN_RUNNING);
1885 
1886 #ifdef WIN32
1887     timeEndPeriod(1);
1888 #endif
1889 
1890         ftdm_log(FTDM_LOG_DEBUG, "ISDN thread ended.\n");
1891         return NULL;
1892 }
1893 
1894 /**
1895  * \brief FreeTDM ISDN signaling module initialisation
1896  * \return Success
1897  */
1898 static FIO_SIG_LOAD_FUNCTION(ftdm_isdn_init)
1899 {
1900         Q931Initialize();
1901 
1902         Q921SetGetTimeCB(ftdm_time_now);
1903         Q931SetGetTimeCB(ftdm_time_now);
1904 
1905         return FTDM_SUCCESS;
1906 }
1907 
1908 /**
1909  * \brief Receives a Q931 indication message
1910  * \param pvt Span were message is coming from
1911  * \param ind Q931 indication
1912  * \param tei Terminal Endpoint Identifier
1913  * \param msg Message string
1914  * \param mlen Message string length
1915  * \return 0 on success
1916  */
1917 static int q931_rx_32(void *pvt, Q921DLMsg_t ind, L3UCHAR tei, L3UCHAR *msg, L3INT mlen)
1918 {
1919         int offset = 4;
1920         char bb[4096] = "";
1921 
1922         switch(ind) {
1923         case Q921_DL_UNIT_DATA:
1924                 offset = 3;
1925 
1926         case Q921_DL_DATA:
1927                 print_hex_bytes(msg + offset, mlen - offset, bb, sizeof(bb));
1928 #ifdef HAVE_LIBPCAP
1929                 /*Q931ToPcap*/
1930                 if(do_q931ToPcap==1){
1931                         ftdm_span_t *span = (ftdm_span_t *) pvt;
1932                         if(writeQ931PacketToPcap(msg + offset, mlen - offset, span->span_id, 0) != FTDM_SUCCESS){
1933                                 ftdm_log(FTDM_LOG_WARNING, "Couldn't write Q931 buffer to pcap file!\n");       
1934                         }
1935                 }
1936                 /*Q931ToPcap done*/
1937 #endif
1938                 ftdm_log(FTDM_LOG_DEBUG, "WRITE %d\n%s\n%s\n\n", (int)mlen - offset, LINE, bb);
1939                 break;
1940 
1941         default:
1942                 break;
1943         }
1944 
1945         return Q921Rx32(pvt, ind, tei, msg, mlen);
1946 }
1947 
1948 /**
1949  * \brief Logs Q921 message
1950  * \param pvt Span were message is coming from
1951  * \param level Q921 log level
1952  * \param msg Message string
1953  * \param size Message string length
1954  * \return 0
1955  */
1956 static int ftdm_isdn_q921_log(void *pvt, Q921LogLevel_t level, char *msg, L2INT size)
1957 {
1958         ftdm_span_t *span = (ftdm_span_t *) pvt;
1959 
1960         ftdm_log("Span", "Q.921", span->span_id, (int)level, "%s", msg);
1961         return 0;
1962 }
1963 
1964 /**
1965  * \brief Logs Q931 message
1966  * \param pvt Span were message is coming from
1967  * \param level Q931 log level
1968  * \param msg Message string
1969  * \param size Message string length
1970  * \return 0
1971  */
1972 static L3INT ftdm_isdn_q931_log(void *pvt, Q931LogLevel_t level, char *msg, L3INT size)
1973 {
1974         ftdm_span_t *span = (ftdm_span_t *) pvt;
1975 
1976         ftdm_log("Span", "Q.931", span->span_id, (int)level, "%s", msg);
1977         return 0;
1978 }
1979 /**
1980  * \brief ISDN state map
1981  */
1982 static ftdm_state_map_t isdn_state_map = {
1983         {
1984                 {
1985                         ZSD_OUTBOUND,
1986                         ZSM_UNACCEPTABLE,
1987                         {FTDM_ANY_STATE},
1988                         {FTDM_CHANNEL_STATE_RESTART, FTDM_END}
1989                 },
1990                 {
1991                         ZSD_OUTBOUND,
1992                         ZSM_UNACCEPTABLE,
1993                         {FTDM_CHANNEL_STATE_RESTART, FTDM_END},
1994                         {FTDM_CHANNEL_STATE_DOWN, FTDM_END}
1995                 },
1996                 {
1997                         ZSD_OUTBOUND,
1998                         ZSM_UNACCEPTABLE,
1999                         {FTDM_CHANNEL_STATE_DOWN, FTDM_END},
2000                         {FTDM_CHANNEL_STATE_DIALING, FTDM_END}
2001                 },
2002                 {
2003                         ZSD_OUTBOUND,
2004                         ZSM_UNACCEPTABLE,
2005                         {FTDM_CHANNEL_STATE_DIALING, FTDM_END},
2006                         {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_UP, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}
2007                 },
2008                 {
2009                         ZSD_OUTBOUND,
2010                         ZSM_UNACCEPTABLE,
2011                         {FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_PROGRESS, FTDM_END},
2012                         {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_UP, FTDM_END}
2013                 },
2014                 {
2015                         ZSD_OUTBOUND,
2016                         ZSM_UNACCEPTABLE,
2017                         {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END},
2018                         {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_DOWN, FTDM_END}
2019                 },
2020                 {
2021                         ZSD_OUTBOUND,
2022                         ZSM_UNACCEPTABLE,
2023                         {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END},
2024                         {FTDM_CHANNEL_STATE_DOWN, FTDM_END},
2025                 },
2026                 {
2027                         ZSD_OUTBOUND,
2028                         ZSM_UNACCEPTABLE,
2029                         {FTDM_CHANNEL_STATE_UP, FTDM_END},
2030                         {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}
2031                 },
2032 
2033                 /****************************************/
2034                 {
2035                         ZSD_INBOUND,
2036                         ZSM_UNACCEPTABLE,
2037                         {FTDM_ANY_STATE},
2038                         {FTDM_CHANNEL_STATE_RESTART, FTDM_END}
2039                 },
2040                 {
2041                         ZSD_INBOUND,
2042                         ZSM_UNACCEPTABLE,
2043                         {FTDM_CHANNEL_STATE_RESTART, FTDM_END},
2044                         {FTDM_CHANNEL_STATE_DOWN, FTDM_END}
2045                 },
2046                 {
2047                         ZSD_INBOUND,
2048                         ZSM_UNACCEPTABLE,
2049                         {FTDM_CHANNEL_STATE_DOWN, FTDM_END},
2050                         {FTDM_CHANNEL_STATE_DIALTONE, FTDM_CHANNEL_STATE_RING, FTDM_END}
2051                 },
2052                 {
2053                         ZSD_INBOUND,
2054                         ZSM_UNACCEPTABLE,
2055                         {FTDM_CHANNEL_STATE_DIALTONE, FTDM_END},
2056                         {FTDM_CHANNEL_STATE_RING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}
2057                 },
2058                 {
2059                         ZSD_INBOUND,
2060                         ZSM_UNACCEPTABLE,
2061                         {FTDM_CHANNEL_STATE_RING, FTDM_END},
2062                         {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END}
2063                 },
2064                 {
2065                         ZSD_INBOUND,
2066                         ZSM_UNACCEPTABLE,
2067                         {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END},
2068                         {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_DOWN, FTDM_END},
2069                 },
2070                 {
2071                         ZSD_INBOUND,
2072                         ZSM_UNACCEPTABLE,
2073                         {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END},
2074                         {FTDM_CHANNEL_STATE_DOWN, FTDM_END},
2075                 },
2076                 {
2077                         ZSD_INBOUND,
2078                         ZSM_UNACCEPTABLE,
2079                         {FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_END},
2080                         {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, 
2081                          FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_UP, FTDM_END},
2082                 },
2083                 {
2084                         ZSD_INBOUND,
2085                         ZSM_UNACCEPTABLE,
2086                         {FTDM_CHANNEL_STATE_UP, FTDM_END},
2087                         {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END},
2088                 },
2089                 
2090 
2091         }
2092 };
2093 
2094 /**
2095  * \brief Stops an ISDN span
2096  * \param span Span to halt
2097  * \return Success
2098  *
2099  * Sets a stop flag and waits for the threads to end
2100  */
2101 static ftdm_status_t ftdm_isdn_stop(ftdm_span_t *span)
2102 {
2103         ftdm_isdn_data_t *isdn_data = span->signal_data;
2104 
2105         if (!ftdm_test_flag(isdn_data, FTDM_ISDN_RUNNING)) {
2106                 return FTDM_FAIL;
2107         }
2108                 
2109         ftdm_set_flag(isdn_data, FTDM_ISDN_STOP);
2110         
2111         while(ftdm_test_flag(isdn_data, FTDM_ISDN_RUNNING)) {
2112                 ftdm_sleep(100);
2113         }
2114 
2115         while(ftdm_test_flag(isdn_data, FTDM_ISDN_TONES_RUNNING)) {
2116                 ftdm_sleep(100);
2117         }
2118 
2119         return FTDM_SUCCESS;
2120         
2121 }
2122 
2123 /**
2124  * \brief Starts an ISDN span
2125  * \param span Span to halt
2126  * \return Success or failure
2127  *
2128  * Launches a thread to monitor the span and a thread to generate tones on the span
2129  */
2130 static ftdm_status_t ftdm_isdn_start(ftdm_span_t *span)
2131 {
2132         ftdm_status_t ret;
2133         ftdm_isdn_data_t *isdn_data = span->signal_data;
2134 
2135         if (ftdm_test_flag(isdn_data, FTDM_ISDN_RUNNING)) {
2136                 return FTDM_FAIL;
2137         }
2138 
2139         ftdm_clear_flag(isdn_data, FTDM_ISDN_STOP);
2140         ret = ftdm_thread_create_detached(ftdm_isdn_run, span);
2141 
2142         if (ret != FTDM_SUCCESS) {
2143                 return ret;
2144         }
2145 
2146         if (FTDM_SPAN_IS_NT(span) && !(isdn_data->opts & FTDM_ISDN_OPT_DISABLE_TONES)) {
2147                 ret = ftdm_thread_create_detached(ftdm_isdn_tones_run, span);
2148         }
2149         return ret;
2150 }
2151 
2152 /**
2153  * \brief Parses an option string to flags
2154  * \param in String to parse for configuration options
2155  * \return Flags
2156  */
2157 static uint32_t parse_opts(const char *in)
2158 {
2159         uint32_t flags = 0;
2160         
2161         if (!in) {
2162                 return 0;
2163         }
2164         
2165         if (strstr(in, "suggest_channel")) {
2166                 flags |= FTDM_ISDN_OPT_SUGGEST_CHANNEL;
2167         }
2168 
2169         if (strstr(in, "omit_display")) {
2170                 flags |= FTDM_ISDN_OPT_OMIT_DISPLAY_IE;
2171         }
2172 
2173         if (strstr(in, "disable_tones")) {
2174                 flags |= FTDM_ISDN_OPT_DISABLE_TONES;
2175         }
2176 
2177         return flags;
2178 }
2179 
2180 /**
2181  * \brief Initialises an ISDN span from configuration variables
2182  * \param span Span to configure
2183  * \param sig_cb Callback function for event signals
2184  * \param ap List of configuration variables
2185  * \return Success or failure
2186  */
2187 static FIO_SIG_CONFIGURE_FUNCTION(ftdm_isdn_configure_span)
2188 {
2189         uint32_t i, x = 0;
2190         ftdm_channel_t *dchans[2] = {0};
2191         ftdm_isdn_data_t *isdn_data;
2192         const char *tonemap = "us";
2193         char *var, *val;
2194         Q931Dialect_t dialect = Q931_Dialect_National;
2195         int32_t digit_timeout = 0;
2196         int q921loglevel = -1;
2197         int q931loglevel = -1;
2198 #ifdef HAVE_LIBPCAP
2199         int q931topcap   = -1;  /*Q931ToPcap*/
2200         int openPcap = 0;       /*Flag: open Pcap file please*/
2201 #endif
2202 
2203         if (span->signal_type) {
2204 #ifdef HAVE_LIBPCAP
2205                 /*Q931ToPcap: Get the content of the q931topcap and pcapfilename args given by mod_freetdm */
2206                 while((var = va_arg(ap, char *))) {
2207                         if (!strcasecmp(var, "q931topcap")) {
2208                                 q931topcap = va_arg(ap, int);
2209                                 if(q931topcap==1) {
2210                                         /*PCAP on*/;
2211                                         openPcap=1;
2212                                 } else if (q931topcap==0) {
2213                                         /*PCAP off*/
2214                                         if (closePcapFile() != FTDM_SUCCESS) return FTDM_FAIL;
2215                                         do_q931ToPcap=0;
2216                                         return FTDM_SUCCESS;
2217                                 }
2218                         }
2219                         if (!strcasecmp(var, "pcapfilename")) {
2220                                 /*Put filename into global var*/
2221                                 pcapfn = va_arg(ap, char*);
2222                         }
2223                 }
2224                 /*We know now, that user wants to enable Q931ToPcap and what file name he wants, so open it please*/
2225                 if(openPcap==1){
2226                         if(openPcapFile() != FTDM_SUCCESS) return FTDM_FAIL;
2227                         do_q931ToPcap=1;
2228                         return FTDM_SUCCESS;
2229                 }
2230                 /*Q931ToPcap done*/
2231 #endif
2232                 snprintf(span->last_error, sizeof(span->last_error), "Span is already configured for signalling [%d].", span->signal_type);
2233                 return FTDM_FAIL;
2234         }
2235 
2236         if (span->trunk_type >= FTDM_TRUNK_NONE) {
2237                 ftdm_log(FTDM_LOG_WARNING, "Invalid trunk type '%s' defaulting to T1.\n", ftdm_trunk_type2str(span->trunk_type));
2238                 span->trunk_type = FTDM_TRUNK_T1;
2239         }
2240         
2241         for(i = 1; i <= span->chan_count; i++) {
2242                 if (span->channels[i]->type == FTDM_CHAN_TYPE_DQ921) {
2243                         if (x > 1) {
2244                                 snprintf(span->last_error, sizeof(span->last_error), "Span has more than 2 D-Channels!");
2245                                 return FTDM_FAIL;
2246                         } else {
2247                                 if (ftdm_channel_open(span->span_id, i, &dchans[x]) == FTDM_SUCCESS) {
2248                                         ftdm_log(FTDM_LOG_DEBUG, "opening d-channel #%d %d:%d\n", x, dchans[x]->span_id, dchans[x]->chan_id);
2249                                         dchans[x]->state = FTDM_CHANNEL_STATE_UP;
2250                                         x++;
2251                                 }
2252                         }
2253                 }
2254         }
2255 
2256         if (!x) {
2257                 snprintf(span->last_error, sizeof(span->last_error), "Span has no D-Channels!");
2258                 return FTDM_FAIL;
2259         }
2260 
2261         isdn_data = ftdm_malloc(sizeof(*isdn_data));
2262         assert(isdn_data != NULL);
2263         memset(isdn_data, 0, sizeof(*isdn_data));
2264         
2265         isdn_data->mode = Q931_TE;
2266         dialect = Q931_Dialect_National;
2267         
2268         while((var = va_arg(ap, char *))) {
2269                 if (!strcasecmp(var, "mode")) {
2270                         if (!(val = va_arg(ap, char *))) {
2271                                 break;
2272                         }
2273                         isdn_data->mode = strcasecmp(val, "net") ? Q931_TE : Q931_NT;
2274                 } else if (!strcasecmp(var, "dialect")) {
2275                         if (!(val = va_arg(ap, char *))) {
2276                                 break;
2277                         }
2278                         dialect = q931_str2Q931Dialect_type(val);
2279                         if (dialect == Q931_Dialect_Count) {
2280                                 return FTDM_FAIL;
2281                         }
2282                 } else if (!strcasecmp(var, "opts")) {
2283                         if (!(val = va_arg(ap, char *))) {
2284                                 break;
2285                         }
2286                         isdn_data->opts = parse_opts(val);
2287                 } else if (!strcasecmp(var, "tonemap")) {
2288                         if (!(val = va_arg(ap, char *))) {
2289                                 break;
2290                         }
2291                         tonemap = (const char *)val;
2292                 } else if (!strcasecmp(var, "digit_timeout")) {
2293                         int *optp;
2294                         if (!(optp = va_arg(ap, int *))) {
2295                                 break;
2296                         }
2297                         digit_timeout = *optp;
2298                 } else if (!strcasecmp(var, "q921loglevel")) {
2299                         q921loglevel = va_arg(ap, int);
2300                         if (q921loglevel < Q921_LOG_NONE) {
2301                                 q921loglevel = Q921_LOG_NONE;
2302                         } else if (q921loglevel > Q921_LOG_DEBUG) {
2303                                 q921loglevel = Q921_LOG_DEBUG;
2304                         }
2305                 } else if (!strcasecmp(var, "q931loglevel")) {
2306                         q931loglevel = va_arg(ap, int);
2307                         if (q931loglevel < Q931_LOG_NONE) {
2308                                 q931loglevel = Q931_LOG_NONE;
2309                         } else if (q931loglevel > Q931_LOG_DEBUG) {
2310                                 q931loglevel = Q931_LOG_DEBUG;
2311                         }
2312                 } else {
2313                         snprintf(span->last_error, sizeof(span->last_error), "Unknown parameter [%s]", var);
2314                         return FTDM_FAIL;
2315                 }
2316         }
2317 
2318 
2319         if (!digit_timeout) {
2320                 digit_timeout = DEFAULT_DIGIT_TIMEOUT;
2321         }
2322         else if (digit_timeout < 3000 || digit_timeout > 30000) {
2323                 ftdm_log(FTDM_LOG_WARNING, "Digit timeout %d ms outside of range (3000 - 30000 ms), using default (10000 ms)\n", digit_timeout);
2324                 digit_timeout = DEFAULT_DIGIT_TIMEOUT;
2325         }
2326 
2327         /* allocate per b-chan data */
2328         if (isdn_data->mode == Q931_NT) {
2329                 ftdm_isdn_bchan_data_t *data;
2330 
2331                 data = ftdm_malloc((span->chan_count - 1) * sizeof(ftdm_isdn_bchan_data_t));
2332                 if (!data) {
2333                         return FTDM_FAIL;
2334                 }
2335 
2336                 for (i = 1; i <= span->chan_count; i++, data++) {
2337                         if (span->channels[i]->type == FTDM_CHAN_TYPE_B) {
2338                                 span->channels[i]->mod_data = data;
2339                                 memset(data, 0, sizeof(ftdm_isdn_bchan_data_t));
2340                         }
2341                 }
2342         }
2343                                         
2344         span->start = ftdm_isdn_start;
2345         span->stop = ftdm_isdn_stop;
2346         span->signal_cb = sig_cb;
2347         isdn_data->dchans[0] = dchans[0];
2348         isdn_data->dchans[1] = dchans[1];
2349         isdn_data->dchan = isdn_data->dchans[0];
2350         isdn_data->digit_timeout = digit_timeout;
2351         
2352         Q921_InitTrunk(&isdn_data->q921,
2353                                    0,
2354                                    0,
2355                                    isdn_data->mode,
2356                                    span->trunk_type == FTDM_TRUNK_BRI_PTMP ? Q921_PTMP : Q921_PTP,
2357                                    0,
2358                                    ftdm_isdn_921_21,
2359                                    (Q921Tx23CB_t)ftdm_isdn_921_23,
2360                                    span,
2361                                    &isdn_data->q931);
2362 
2363         Q921SetLogCB(&isdn_data->q921, &ftdm_isdn_q921_log, isdn_data);
2364         Q921SetLogLevel(&isdn_data->q921, (Q921LogLevel_t)q921loglevel);
2365         
2366         Q931Api_InitTrunk(&isdn_data->q931,
2367                                           dialect,
2368                                           isdn_data->mode,
2369                                           span->trunk_type,
2370                                           ftdm_isdn_931_34,
2371                                           (Q931Tx32CB_t)q931_rx_32,
2372                                           ftdm_isdn_931_err,
2373                                           &isdn_data->q921,
2374                                           span);
2375 
2376         Q931SetLogCB(&isdn_data->q931, &ftdm_isdn_q931_log, isdn_data);
2377         Q931SetLogLevel(&isdn_data->q931, (Q931LogLevel_t)q931loglevel);
2378 
2379         isdn_data->q931.autoRestartAck = 1;
2380         isdn_data->q931.autoConnectAck = 0;
2381         isdn_data->q931.autoServiceAck = 1;
2382         span->signal_data = isdn_data;
2383         span->signal_type = FTDM_SIGTYPE_ISDN;
2384         span->outgoing_call = isdn_outgoing_call;
2385 
2386         if ((isdn_data->opts & FTDM_ISDN_OPT_SUGGEST_CHANNEL)) {
2387                 span->channel_request = isdn_channel_request;
2388                 ftdm_set_flag(span, FTDM_SPAN_SUGGEST_CHAN_ID);
2389         }
2390         span->state_map = &isdn_state_map;
2391 
2392         ftdm_span_load_tones(span, tonemap);
2393 
2394         return FTDM_SUCCESS;
2395 }
2396 
2397 /**
2398  * \brief FreeTDM ISDN signaling module definition
2399  */
2400 EX_DECLARE_DATA ftdm_module_t ftdm_module = {
2401         "isdn",
2402         NULL,
2403         close_pcap,
2404         ftdm_isdn_init,
2405         ftdm_isdn_configure_span,
2406         NULL
2407 };
2408 
2409 
2410 
2411 /* For Emacs:
2412  * Local Variables:
2413  * mode:c
2414  * indent-tabs-mode:t
2415  * tab-width:4
2416  * c-basic-offset:4
2417  * End:
2418  * For VIM:
2419  * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
2420  */

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