root/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c

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

DEFINITIONS

This source file includes following definitions.
  1. sngisdn_snd_setup
  2. sngisdn_snd_setup_ack
  3. sngisdn_snd_con_complete
  4. sngisdn_snd_proceed
  5. sngisdn_snd_progress
  6. sngisdn_snd_alert
  7. sngisdn_snd_connect
  8. sngisdn_snd_info_req
  9. sngisdn_snd_status_enq
  10. sngisdn_snd_disconnect
  11. sngisdn_snd_release

   1 /*
   2  * Copyright (c) 2010, Sangoma Technologies
   3  * David Yat Sin <davidy@sangoma.com>
   4  * All rights reserved.
   5  *
   6  * Redistribution and use in source and binary forms, with or without
   7  * modification, are permitted provided that the following conditions
   8  * are met:
   9  *
  10  * * Redistributions of source code must retain the above copyright
  11  * notice, this list of conditions and the following disclaimer.
  12  *
  13  * * Redistributions in binary form must reproduce the above copyright
  14  * notice, this list of conditions and the following disclaimer in the
  15  * documentation and/or other materials provided with the distribution.
  16  *
  17  * * Neither the name of the original author; nor the names of any contributors
  18  * may be used to endorse or promote products derived from this software
  19  * without specific prior written permission.
  20  *
  21  *
  22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  25  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
  26  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  27  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  28  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  29  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  30  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  31  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  32  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  33  */
  34 
  35 #include "ftmod_sangoma_isdn.h"
  36 
  37 extern ftdm_status_t cpy_calling_num_from_user(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *ftdm);
  38 extern ftdm_status_t cpy_called_num_from_user(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *ftdm);
  39 extern ftdm_status_t cpy_calling_name_from_user(ConEvnt *conEvnt, ftdm_channel_t *ftdmchan);
  40 
  41 void sngisdn_snd_setup(ftdm_channel_t *ftdmchan);
  42 void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan);
  43 void sngisdn_snd_progress(ftdm_channel_t *ftdmchan);
  44 void sngisdn_snd_connect(ftdm_channel_t *ftdmchan);
  45 void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan);
  46 void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare);
  47 
  48 
  49 void sngisdn_snd_setup(ftdm_channel_t *ftdmchan)
  50 {
  51         ConEvnt conEvnt;
  52         sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data;
  53         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;  
  54 
  55         ftdm_assert((!sngisdn_info->suInstId && !sngisdn_info->spInstId), "Trying to call out, but call data was not cleared\n");
  56         
  57         sngisdn_info->suInstId = get_unique_suInstId(signal_data->cc_id);
  58         sngisdn_info->spInstId = 0;
  59 
  60         ftdm_mutex_lock(g_sngisdn_data.ccs[signal_data->cc_id].mutex);
  61         g_sngisdn_data.ccs[signal_data->cc_id].active_suInstIds[sngisdn_info->suInstId] = sngisdn_info;
  62         ftdm_mutex_unlock(g_sngisdn_data.ccs[signal_data->cc_id].mutex);
  63 
  64         memset(&conEvnt, 0, sizeof(conEvnt));
  65 
  66         conEvnt.bearCap[0].eh.pres = PRSNT_NODEF;
  67         conEvnt.bearCap[0].infoTranCap.pres = PRSNT_NODEF;
  68         conEvnt.bearCap[0].infoTranCap.val = sngisdn_get_infoTranCap_from_user(ftdmchan->caller_data.bearer_capability);
  69 
  70         conEvnt.bearCap[0].codeStand0.pres = PRSNT_NODEF;
  71         conEvnt.bearCap[0].codeStand0.val = IN_CSTD_CCITT;
  72         conEvnt.bearCap[0].infoTranRate0.pres = PRSNT_NODEF;
  73         conEvnt.bearCap[0].infoTranRate0.val = IN_ITR_64KBIT;
  74         conEvnt.bearCap[0].tranMode.pres = PRSNT_NODEF;
  75         conEvnt.bearCap[0].tranMode.val = IN_TM_CIRCUIT;
  76 
  77         conEvnt.chanId.eh.pres = PRSNT_NODEF;
  78         conEvnt.chanId.prefExc.pres = PRSNT_NODEF;
  79         conEvnt.chanId.prefExc.val = IN_PE_EXCLSVE;
  80         conEvnt.chanId.dChanInd.pres = PRSNT_NODEF;
  81         conEvnt.chanId.dChanInd.val = IN_DSI_NOTDCHAN;
  82         conEvnt.chanId.intIdentPres.pres = PRSNT_NODEF;
  83         conEvnt.chanId.intIdentPres.val = IN_IIP_IMPLICIT;
  84         conEvnt.chanId.intIdent.pres = NOTPRSNT;
  85 
  86         if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI ||
  87                 ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
  88                 /* Trillium stack rejests lyr1Ident on BRI, but Netbricks always sends it.
  89                 Check with Trillium if this ever causes calls to fail in the field */
  90 
  91                 /* BRI only params */
  92                 conEvnt.chanId.intType.pres = PRSNT_NODEF;
  93                 conEvnt.chanId.intType.val = IN_IT_BASIC;
  94                 conEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
  95                 conEvnt.chanId.infoChanSel.val = ftdmchan->physical_chan_id;
  96         } else {
  97                 /* PRI only params */
  98                 conEvnt.bearCap[0].usrInfoLyr1Prot.pres = PRSNT_NODEF;
  99                 conEvnt.bearCap[0].usrInfoLyr1Prot.val = sngisdn_get_usrInfoLyr1Prot_from_user(ftdmchan->caller_data.bearer_layer1);
 100                 
 101                 if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN &&
 102                         conEvnt.bearCap[0].usrInfoLyr1Prot.val == IN_UIL1_G711ULAW) {
 103                         
 104                         /* We are bridging a call from T1 */
 105                         conEvnt.bearCap[0].usrInfoLyr1Prot.val = IN_UIL1_G711ALAW;
 106                         
 107                 } else if (conEvnt.bearCap[0].usrInfoLyr1Prot.val == IN_UIL1_G711ALAW) {
 108                         
 109                         /* We are bridging a call from E1 */
 110                         conEvnt.bearCap[0].usrInfoLyr1Prot.val = IN_UIL1_G711ULAW;
 111                 }
 112                 
 113                 conEvnt.bearCap[0].lyr1Ident.pres = PRSNT_NODEF;
 114                 conEvnt.bearCap[0].lyr1Ident.val = IN_L1_IDENT;
 115 
 116                 conEvnt.chanId.intType.pres = PRSNT_NODEF;
 117                 conEvnt.chanId.intType.val = IN_IT_OTHER;
 118                 conEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
 119                 conEvnt.chanId.infoChanSel.val = IN_ICS_B1CHAN;
 120                 conEvnt.chanId.chanMapType.pres = PRSNT_NODEF;
 121                 conEvnt.chanId.chanMapType.val = IN_CMT_BCHAN;
 122                 conEvnt.chanId.nmbMap.pres = PRSNT_NODEF;
 123                 conEvnt.chanId.nmbMap.val = IN_NM_CHNNMB;
 124                 conEvnt.chanId.codeStand1.pres = PRSNT_NODEF;
 125                 conEvnt.chanId.codeStand1.val = IN_CSTD_CCITT;
 126                 conEvnt.chanId.chanNmbSlotMap.pres = PRSNT_NODEF;
 127                 conEvnt.chanId.chanNmbSlotMap.len = 1;
 128                 conEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
 129         }
 130 
 131         conEvnt.progInd.eh.pres = PRSNT_NODEF;
 132         conEvnt.progInd.location.pres = PRSNT_NODEF;
 133         conEvnt.progInd.location.val = IN_LOC_USER;
 134         conEvnt.progInd.codeStand0.pres = PRSNT_NODEF;
 135         conEvnt.progInd.codeStand0.val = IN_CSTD_CCITT;
 136         conEvnt.progInd.progDesc.pres = PRSNT_NODEF;
 137         conEvnt.progInd.progDesc.val = IN_PD_NOTETEISDN; /* Not end-to-end ISDN */
 138 
 139         if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN) {
 140                 conEvnt.sndCmplt.eh.pres = PRSNT_NODEF;
 141         }
 142         if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP &&
 143                 signal_data->signalling == SNGISDN_SIGNALING_NET) {
 144                 sngisdn_info->ces = CES_MNGMNT;
 145         }
 146         ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Outgoing call: Called No:[%s] Calling No:[%s]\n", ftdmchan->caller_data.dnis.digits, ftdmchan->caller_data.cid_num.digits);
 147 
 148         cpy_called_num_from_user(&conEvnt.cdPtyNmb, &ftdmchan->caller_data);
 149         cpy_calling_num_from_user(&conEvnt.cgPtyNmb, &ftdmchan->caller_data);
 150         cpy_calling_name_from_user(&conEvnt, ftdmchan);
 151 
 152         ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending SETUP (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
 153 
 154         if (sng_isdn_con_request(signal_data->cc_id, sngisdn_info->suInstId, &conEvnt, signal_data->dchan_id, sngisdn_info->ces)) {
 155                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused SETUP request\n");
 156         }
 157 
 158         return;
 159 }
 160 
 161 /* Unsed only for overlap receive */
 162 void sngisdn_snd_setup_ack(ftdm_channel_t *ftdmchan)
 163 {
 164         CnStEvnt cnStEvnt;
 165         
 166         sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
 167         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
 168 
 169         if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
 170                 ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending SETUP ACK , but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
 171                 sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
 172                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
 173                 return;
 174         }
 175         
 176         memset(&cnStEvnt, 0, sizeof(cnStEvnt)); 
 177 
 178         cnStEvnt.chanId.eh.pres = PRSNT_NODEF;
 179         cnStEvnt.chanId.prefExc.pres = PRSNT_NODEF;
 180         cnStEvnt.chanId.prefExc.val = IN_PE_EXCLSVE;
 181         cnStEvnt.chanId.dChanInd.pres = PRSNT_NODEF;
 182         cnStEvnt.chanId.dChanInd.val = IN_DSI_NOTDCHAN;
 183         cnStEvnt.chanId.intIdentPres.pres = PRSNT_NODEF;
 184         cnStEvnt.chanId.intIdentPres.val = IN_IIP_IMPLICIT;
 185 
 186         
 187         if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI ||
 188                 ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
 189 
 190                 /* BRI only params */
 191                 cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
 192                 cnStEvnt.chanId.intType.val = IN_IT_BASIC;
 193                 cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
 194                 cnStEvnt.chanId.infoChanSel.val = ftdmchan->physical_chan_id;
 195         } else {
 196                 cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
 197                 cnStEvnt.chanId.intType.val = IN_IT_OTHER;
 198                 cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
 199                 cnStEvnt.chanId.infoChanSel.val = IN_ICS_B1CHAN;
 200                 cnStEvnt.chanId.chanMapType.pres = PRSNT_NODEF;
 201                 cnStEvnt.chanId.chanMapType.val = IN_CMT_BCHAN;
 202                 cnStEvnt.chanId.nmbMap.pres = PRSNT_NODEF;
 203                 cnStEvnt.chanId.nmbMap.val = IN_NM_CHNNMB;
 204                 cnStEvnt.chanId.codeStand1.pres = PRSNT_NODEF;
 205                 cnStEvnt.chanId.codeStand1.val = IN_CSTD_CCITT;
 206                 cnStEvnt.chanId.chanNmbSlotMap.pres = PRSNT_NODEF;
 207                 cnStEvnt.chanId.chanNmbSlotMap.len = 1;
 208                 cnStEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
 209         }
 210 
 211         ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending SETUP ACK (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
 212 
 213         if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, MI_SETUPACK, signal_data->dchan_id, sngisdn_info->ces)) {
 214                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT,      "stack refused SETUP ACK request\n");
 215         }
 216         return;
 217 }
 218 
 219 
 220 /* Used only for BRI PTMP - This function is used when the NT side makes a call out,
 221         and one or multiple TE's reply, then NT assigns the call by sending a con_complete*/
 222 void sngisdn_snd_con_complete(ftdm_channel_t *ftdmchan)
 223 {
 224         CnStEvnt cnStEvnt;
 225         
 226         sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
 227         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
 228 
 229         if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
 230                 ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending CONNECT COMPL , but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
 231                 sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
 232                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
 233                 return;
 234         }
 235         
 236         memset(&cnStEvnt, 0, sizeof(cnStEvnt));
 237         
 238         cnStEvnt.chanId.eh.pres = PRSNT_NODEF;
 239         cnStEvnt.chanId.prefExc.pres = PRSNT_NODEF;
 240         cnStEvnt.chanId.prefExc.val = IN_PE_EXCLSVE;
 241         cnStEvnt.chanId.dChanInd.pres = PRSNT_NODEF;
 242         cnStEvnt.chanId.dChanInd.val = IN_DSI_NOTDCHAN;
 243         cnStEvnt.chanId.intIdentPres.pres = PRSNT_NODEF;
 244         cnStEvnt.chanId.intIdentPres.val = IN_IIP_IMPLICIT;
 245         
 246         if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI ||
 247                 ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
 248 
 249                 /* BRI only params */
 250                 cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
 251                 cnStEvnt.chanId.intType.val = IN_IT_BASIC;
 252                 cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
 253                 cnStEvnt.chanId.infoChanSel.val = ftdmchan->physical_chan_id;
 254         } else {
 255                 cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
 256                 cnStEvnt.chanId.intType.val = IN_IT_OTHER;
 257                 cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
 258                 cnStEvnt.chanId.infoChanSel.val = IN_ICS_B1CHAN;
 259                 cnStEvnt.chanId.chanMapType.pres = PRSNT_NODEF;
 260                 cnStEvnt.chanId.chanMapType.val = IN_CMT_BCHAN;
 261                 cnStEvnt.chanId.nmbMap.pres = PRSNT_NODEF;
 262                 cnStEvnt.chanId.nmbMap.val = IN_NM_CHNNMB;
 263                 cnStEvnt.chanId.codeStand1.pres = PRSNT_NODEF;
 264                 cnStEvnt.chanId.codeStand1.val = IN_CSTD_CCITT;
 265                 cnStEvnt.chanId.chanNmbSlotMap.pres = PRSNT_NODEF;
 266                 cnStEvnt.chanId.chanNmbSlotMap.len = 1;
 267                 cnStEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
 268         }
 269 
 270 
 271         ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending CONNECT COMPL (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
 272 
 273         if(sng_isdn_con_comp(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, signal_data->dchan_id, sngisdn_info->ces)) {
 274                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT,      "stack refused CONNECT ACK request\n");
 275         }
 276         return;
 277 }
 278 
 279 
 280 void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan)
 281 {
 282         CnStEvnt cnStEvnt;
 283         
 284         sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
 285         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
 286 
 287         if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
 288                 ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending PROGRESS, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
 289                 sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
 290                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
 291                 return;
 292         }
 293         
 294         memset(&cnStEvnt, 0, sizeof(cnStEvnt));
 295         
 296         cnStEvnt.chanId.eh.pres = PRSNT_NODEF;
 297         cnStEvnt.chanId.prefExc.pres = PRSNT_NODEF;
 298         cnStEvnt.chanId.prefExc.val = IN_PE_EXCLSVE;
 299         cnStEvnt.chanId.dChanInd.pres = PRSNT_NODEF;
 300         cnStEvnt.chanId.dChanInd.val = IN_DSI_NOTDCHAN;
 301         cnStEvnt.chanId.intIdentPres.pres = PRSNT_NODEF;
 302         cnStEvnt.chanId.intIdentPres.val = IN_IIP_IMPLICIT;
 303         
 304         if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI ||
 305                 ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
 306 
 307                 /* BRI only params */
 308                 cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
 309                 cnStEvnt.chanId.intType.val = IN_IT_BASIC;
 310                 cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
 311                 cnStEvnt.chanId.infoChanSel.val = ftdmchan->physical_chan_id;
 312         } else {
 313                 cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
 314                 cnStEvnt.chanId.intType.val = IN_IT_OTHER;
 315                 cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
 316                 cnStEvnt.chanId.infoChanSel.val = IN_ICS_B1CHAN;
 317                 cnStEvnt.chanId.chanMapType.pres = PRSNT_NODEF;
 318                 cnStEvnt.chanId.chanMapType.val = IN_CMT_BCHAN;
 319                 cnStEvnt.chanId.nmbMap.pres = PRSNT_NODEF;
 320                 cnStEvnt.chanId.nmbMap.val = IN_NM_CHNNMB;
 321                 cnStEvnt.chanId.codeStand1.pres = PRSNT_NODEF;
 322                 cnStEvnt.chanId.codeStand1.val = IN_CSTD_CCITT;
 323                 cnStEvnt.chanId.chanNmbSlotMap.pres = PRSNT_NODEF;
 324                 cnStEvnt.chanId.chanNmbSlotMap.len = 1;
 325                 cnStEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
 326         }
 327 
 328 
 329         ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending PROCEED (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
 330 
 331         if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, MI_CALLPROC, signal_data->dchan_id, sngisdn_info->ces)) {
 332                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT,      "stack refused PROCEED request\n");
 333         }
 334         return;
 335 }
 336 
 337 void sngisdn_snd_progress(ftdm_channel_t *ftdmchan)
 338 {
 339         CnStEvnt cnStEvnt;
 340         
 341         sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
 342         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
 343 
 344  if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
 345                 ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending PROGRESS, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
 346                 sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
 347                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
 348                 return;
 349         }       
 350         
 351         if (signal_data->switchtype == SNGISDN_SWITCH_INSNET) {
 352                 /* Trillium Q931 layer complains of invalid event when receiving PROGRESS in
 353                         INSNET variant, so PROGRESS event is probably invalid */
 354                 return;
 355         }
 356 
 357         memset(&cnStEvnt, 0, sizeof(cnStEvnt)); 
 358 
 359         cnStEvnt.progInd.eh.pres = PRSNT_NODEF;
 360         cnStEvnt.progInd.location.pres = PRSNT_NODEF;
 361         cnStEvnt.progInd.location.val = IN_LOC_USER;
 362         cnStEvnt.progInd.codeStand0.pres = PRSNT_NODEF;
 363         cnStEvnt.progInd.codeStand0.val = IN_CSTD_CCITT;
 364         cnStEvnt.progInd.progDesc.pres = PRSNT_NODEF;
 365         cnStEvnt.progInd.progDesc.val = IN_PD_IBAVAIL;
 366 
 367         ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending PROGRESS (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
 368         if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId,&cnStEvnt, MI_PROGRESS, signal_data->dchan_id, sngisdn_info->ces)) {
 369                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT,      "stack refused PROGRESS request\n");
 370         }
 371         return;
 372 }
 373 
 374 void sngisdn_snd_alert(ftdm_channel_t *ftdmchan)
 375 {
 376         CnStEvnt cnStEvnt;
 377         
 378         sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
 379         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
 380 
 381  if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
 382                 ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending ALERT, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
 383                 sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
 384                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
 385                 return;
 386         }       
 387 
 388         memset(&cnStEvnt, 0, sizeof(cnStEvnt));
 389 
 390         cnStEvnt.progInd.eh.pres = PRSNT_NODEF;
 391         cnStEvnt.progInd.location.pres = PRSNT_NODEF;
 392         cnStEvnt.progInd.location.val = IN_LOC_USER;
 393         cnStEvnt.progInd.codeStand0.pres = PRSNT_NODEF;
 394         cnStEvnt.progInd.codeStand0.val = IN_CSTD_CCITT;
 395         cnStEvnt.progInd.progDesc.pres = PRSNT_NODEF;
 396         cnStEvnt.progInd.progDesc.val = IN_PD_NOTETEISDN;
 397 
 398         ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending ALERT (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
 399 
 400         if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId,&cnStEvnt, MI_ALERTING, signal_data->dchan_id, sngisdn_info->ces)) {
 401                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT,      "stack refused ALERT request\n");
 402         }
 403         return;
 404 }
 405 
 406 void sngisdn_snd_connect(ftdm_channel_t *ftdmchan)
 407 {
 408         CnStEvnt cnStEvnt;
 409         
 410         sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
 411         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
 412 
 413         if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
 414                 ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending CONNECT, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
 415                 sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
 416                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
 417                 return;
 418         }
 419         
 420         memset(&cnStEvnt, 0, sizeof(cnStEvnt));
 421 
 422 
 423         cnStEvnt.chanId.eh.pres = PRSNT_NODEF;
 424         cnStEvnt.chanId.prefExc.pres = PRSNT_NODEF;
 425         cnStEvnt.chanId.prefExc.val = IN_PE_EXCLSVE;
 426         cnStEvnt.chanId.dChanInd.pres = PRSNT_NODEF;
 427         cnStEvnt.chanId.dChanInd.val = IN_DSI_NOTDCHAN;
 428         cnStEvnt.chanId.intIdentPres.pres = PRSNT_NODEF;
 429         cnStEvnt.chanId.intIdentPres.val = IN_IIP_IMPLICIT;
 430         
 431         if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI ||
 432                 ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
 433 
 434                 /* BRI only params */
 435                 cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
 436                 cnStEvnt.chanId.intType.val = IN_IT_BASIC;
 437                 cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
 438                 cnStEvnt.chanId.infoChanSel.val = ftdmchan->physical_chan_id;
 439         } else {
 440                 cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
 441                 cnStEvnt.chanId.intType.val = IN_IT_OTHER;
 442                 cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
 443                 cnStEvnt.chanId.infoChanSel.val = IN_ICS_B1CHAN;
 444                 cnStEvnt.chanId.chanMapType.pres = PRSNT_NODEF;
 445                 cnStEvnt.chanId.chanMapType.val = IN_CMT_BCHAN;
 446                 cnStEvnt.chanId.nmbMap.pres = PRSNT_NODEF;
 447                 cnStEvnt.chanId.nmbMap.val = IN_NM_CHNNMB;
 448                 cnStEvnt.chanId.codeStand1.pres = PRSNT_NODEF;
 449                 cnStEvnt.chanId.codeStand1.val = IN_CSTD_CCITT;
 450                 cnStEvnt.chanId.chanNmbSlotMap.pres = PRSNT_NODEF;
 451                 cnStEvnt.chanId.chanNmbSlotMap.len = 1;
 452                 cnStEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
 453         }
 454         
 455         cnStEvnt.progInd.eh.pres = PRSNT_NODEF;
 456         cnStEvnt.progInd.location.pres = PRSNT_NODEF;
 457         cnStEvnt.progInd.location.val = IN_LOC_USER;
 458         cnStEvnt.progInd.codeStand0.pres = PRSNT_NODEF;
 459         cnStEvnt.progInd.codeStand0.val = IN_CSTD_CCITT;
 460         cnStEvnt.progInd.progDesc.pres = PRSNT_NODEF;
 461         cnStEvnt.progInd.progDesc.val = IN_PD_NOTETEISDN; /* Not end-to-end ISDN */
 462 
 463         ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending CONNECT (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
 464         if (sng_isdn_con_response(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, signal_data->dchan_id, sngisdn_info->ces)) {
 465                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused CONNECT request\n");
 466         }
 467         return;
 468 }
 469 
 470 
 471 void sngisdn_snd_info_req(ftdm_channel_t *ftdmchan)
 472 {
 473         CnStEvnt cnStEvnt;
 474         
 475         sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
 476         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
 477 
 478         if (ftdmchan->span->trunk_type != FTDM_TRUNK_BRI &&
 479                 ftdmchan->span->trunk_type != FTDM_TRUNK_BRI_PTMP) {
 480 
 481                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring INFO REQ on non-BRI channel\n");
 482                 return;
 483         }
 484 
 485         memset(&cnStEvnt, 0, sizeof(cnStEvnt));
 486         //ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Sending INFO REQ\n");
 487 
 488 
 489         ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending INFO REQ (suId:%d dchan:%d ces:%d)\n", signal_data->cc_id, signal_data->dchan_id, sngisdn_info->ces);
 490 
 491         if (sng_isdn_con_status(signal_data->cc_id, 0, 0, &cnStEvnt, MI_INFO, signal_data->dchan_id, sngisdn_info->ces)) {
 492                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT,      "stack refused INFO request\n");
 493         }
 494         return;
 495 }
 496 
 497 
 498 void sngisdn_snd_status_enq(ftdm_channel_t *ftdmchan)
 499 {
 500         StaEvnt staEvnt;
 501 
 502         sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
 503         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
 504 
 505         //ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Sending STATUS ENQ\n");
 506 
 507         memset(&staEvnt, 0, sizeof(StaEvnt));
 508 
 509         ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending Status ENQ on suId:%d suInstId:%u spInstId:%d dchan:%d ces:%d\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
 510         if (sng_isdn_status_request(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &staEvnt, MI_STATENQ)) {
 511                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT,      "stack refused Status ENQ request\n");
 512         }
 513         return;
 514 }
 515 
 516 
 517 void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan)
 518 {       
 519         DiscEvnt discEvnt;
 520 
 521         sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
 522         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
 523 
 524  if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
 525                 ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending DISCONNECT, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
 526 
 527                 sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
 528                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
 529                 return;
 530         }
 531         
 532         memset(&discEvnt, 0, sizeof(discEvnt));
 533         
 534         /* Fill discEvnt here */        
 535         discEvnt.causeDgn[0].eh.pres = PRSNT_NODEF;
 536         discEvnt.causeDgn[0].location.pres = PRSNT_NODEF;
 537         discEvnt.causeDgn[0].location.val = IN_LOC_PRIVNETLU;
 538         discEvnt.causeDgn[0].codeStand3.pres = PRSNT_NODEF;
 539         discEvnt.causeDgn[0].codeStand3.val = IN_CSTD_CCITT;
 540         discEvnt.causeDgn[0].causeVal.pres = PRSNT_NODEF;
 541         discEvnt.causeDgn[0].causeVal.val = ftdmchan->caller_data.hangup_cause;
 542         discEvnt.causeDgn[0].recommend.pres = NOTPRSNT;
 543         discEvnt.causeDgn[0].dgnVal.pres = NOTPRSNT;
 544 
 545         ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending DISCONNECT (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
 546         if (sng_isdn_disc_request(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &discEvnt)) {
 547                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused DISCONNECT request\n");
 548         }
 549         return;
 550 }
 551 void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare)
 552 {
 553         RelEvnt relEvnt;
 554         uint32_t suInstId, spInstId;
 555 
 556         sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
 557         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
 558 
 559         if (!sngisdn_info->suInstId) {
 560                 ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending RELEASE, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
 561 
 562                 sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
 563                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
 564                 return;
 565         }
 566         
 567         memset(&relEvnt, 0, sizeof(relEvnt));
 568         
 569         /* Fill discEvnt here */        
 570         relEvnt.causeDgn[0].eh.pres = PRSNT_NODEF;
 571         relEvnt.causeDgn[0].location.pres = PRSNT_NODEF;
 572         relEvnt.causeDgn[0].location.val = IN_LOC_PRIVNETLU;
 573         relEvnt.causeDgn[0].codeStand3.pres = PRSNT_NODEF;
 574         relEvnt.causeDgn[0].codeStand3.val = IN_CSTD_CCITT;
 575 
 576         relEvnt.causeDgn[0].causeVal.pres = PRSNT_NODEF;
 577         relEvnt.causeDgn[0].causeVal.val = ftdmchan->caller_data.hangup_cause;
 578         relEvnt.causeDgn[0].recommend.pres = NOTPRSNT;
 579         relEvnt.causeDgn[0].dgnVal.pres = NOTPRSNT;
 580 
 581         if (glare) {
 582                 suInstId = sngisdn_info->glare.suInstId;
 583                 spInstId = sngisdn_info->glare.spInstId;
 584         } else {
 585                 suInstId = sngisdn_info->suInstId;
 586                 spInstId = sngisdn_info->spInstId;
 587         }
 588 
 589         ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending RELEASE/RELEASE COMPLETE (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, suInstId, spInstId);
 590 
 591         if (glare) {
 592                 if (sng_isdn_release_request(signal_data->cc_id, suInstId, spInstId, &relEvnt)) {
 593                         ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused RELEASE/RELEASE COMPLETE request\n");
 594                 }
 595         } else {        
 596                 if (sng_isdn_release_request(signal_data->cc_id, suInstId, spInstId, &relEvnt)) {
 597                         ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused RELEASE/RELEASE COMPLETE request\n");
 598                 }
 599         }       
 600         return;
 601 }
 602 
 603 
 604 
 605 /* For Emacs:
 606  * Local Variables:
 607  * mode:c
 608  * indent-tabs-mode:t
 609  * tab-width:4
 610  * c-basic-offset:4
 611  * End:
 612  * For VIM:
 613  * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
 614  */
 615 
 616 /******************************************************************************/

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