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_fac_req
  9. sngisdn_snd_info_req
  10. sngisdn_snd_status_enq
  11. sngisdn_snd_disconnect
  12. sngisdn_snd_release
  13. sngisdn_snd_restart
  14. sngisdn_snd_data
  15. sngisdn_snd_event

   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 void sngisdn_snd_setup(ftdm_channel_t *ftdmchan)
  38 {
  39         ConEvnt conEvnt;        
  40         sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data;
  41         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
  42         ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_INVALID};
  43 
  44         ftdm_assert((!sngisdn_info->suInstId && !sngisdn_info->spInstId), "Trying to call out, but call data was not cleared\n");
  45         
  46         sngisdn_info->suInstId = get_unique_suInstId(signal_data->cc_id);
  47         sngisdn_info->spInstId = 0;
  48 
  49         ftdm_mutex_lock(g_sngisdn_data.ccs[signal_data->cc_id].mutex);
  50         g_sngisdn_data.ccs[signal_data->cc_id].active_suInstIds[sngisdn_info->suInstId] = sngisdn_info;
  51         ftdm_mutex_unlock(g_sngisdn_data.ccs[signal_data->cc_id].mutex);
  52 
  53         memset(&conEvnt, 0, sizeof(conEvnt));
  54         if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN) {
  55                 conEvnt.sndCmplt.eh.pres = PRSNT_NODEF;
  56         }
  57         if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP &&
  58                 signal_data->signalling == SNGISDN_SIGNALING_NET) {
  59                 sngisdn_info->ces = CES_MNGMNT;
  60         }
  61         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);
  62 
  63         set_chan_id_ie(ftdmchan, &conEvnt.chanId);
  64         set_bear_cap_ie(ftdmchan, &conEvnt.bearCap[0]);
  65         set_called_num(ftdmchan, &conEvnt.cdPtyNmb);
  66         set_calling_num(ftdmchan, &conEvnt.cgPtyNmb);
  67         set_calling_num2(ftdmchan, &conEvnt.cgPtyNmb2);
  68         set_calling_subaddr(ftdmchan, &conEvnt.cgPtySad);
  69         set_redir_num(ftdmchan, &conEvnt.redirNmb);
  70         set_calling_name(ftdmchan, &conEvnt);
  71         set_facility_ie(ftdmchan, &conEvnt.facilityStr);
  72         set_prog_ind_ie(ftdmchan, &conEvnt.progInd, prog_ind);
  73 
  74         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);
  75 
  76         if (sng_isdn_con_request(signal_data->cc_id, sngisdn_info->suInstId, &conEvnt, signal_data->dchan_id, sngisdn_info->ces)) {
  77                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused SETUP request\n");
  78         }
  79 
  80         return;
  81 }
  82 
  83 /* Unsed only for overlap receive */
  84 void sngisdn_snd_setup_ack(ftdm_channel_t *ftdmchan)
  85 {
  86         CnStEvnt cnStEvnt;
  87         
  88         sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
  89         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
  90 
  91         if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
  92                 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);
  93                 sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
  94                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
  95                 return;
  96         }
  97         
  98         memset(&cnStEvnt, 0, sizeof(cnStEvnt)); 
  99 
 100 
 101 
 102         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);
 103 
 104         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)) {
 105                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT,      "stack refused SETUP ACK request\n");
 106         }
 107         return;
 108 }
 109 
 110 
 111 /* Used only for BRI PTMP - This function is used when the NT side makes a call out,
 112         and one or multiple TE's reply, then NT assigns the call by sending a con_complete*/
 113 void sngisdn_snd_con_complete(ftdm_channel_t *ftdmchan)
 114 {
 115         CnStEvnt cnStEvnt;
 116         
 117         sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
 118         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
 119 
 120         if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
 121                 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);
 122                 sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
 123                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
 124                 return;
 125         }
 126         
 127         memset(&cnStEvnt, 0, sizeof(cnStEvnt));
 128         
 129         set_chan_id_ie(ftdmchan, &cnStEvnt.chanId);
 130 
 131         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);
 132 
 133         if(sng_isdn_con_comp(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, signal_data->dchan_id, sngisdn_info->ces)) {
 134                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT,      "stack refused CONNECT ACK request\n");
 135         }
 136         return;
 137 }
 138 
 139 
 140 void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind)
 141 {
 142         CnStEvnt cnStEvnt;
 143         sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
 144         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
 145 
 146         if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
 147                 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);
 148                 sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
 149                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
 150                 return;
 151         }
 152         
 153         memset(&cnStEvnt, 0, sizeof(cnStEvnt));
 154 
 155         set_chan_id_ie(ftdmchan, &cnStEvnt.chanId);
 156         set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind);
 157         set_facility_ie(ftdmchan, &cnStEvnt.facilityStr);
 158         
 159         ftdm_call_clear_data(&ftdmchan->caller_data);
 160 
 161         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);
 162 
 163         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)) {
 164                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT,      "stack refused PROCEED request\n");
 165         }
 166         return;
 167 }
 168 
 169 void sngisdn_snd_progress(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind)
 170 {
 171         CnStEvnt cnStEvnt;
 172         
 173         sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
 174         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
 175 
 176         if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
 177                 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);
 178                 sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
 179                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
 180                 return;
 181         }       
 182         
 183         if (signal_data->switchtype == SNGISDN_SWITCH_INSNET) {
 184                 /* Trillium Q931 layer complains of invalid event when receiving PROGRESS in
 185                         INSNET variant, so PROGRESS event is probably invalid */
 186                 return;
 187         }
 188 
 189         memset(&cnStEvnt, 0, sizeof(cnStEvnt)); 
 190         set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind);
 191         set_facility_ie(ftdmchan, &cnStEvnt.facilityStr);
 192         ftdm_call_clear_data(&ftdmchan->caller_data);
 193 
 194         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);
 195         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)) {
 196                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT,      "stack refused PROGRESS request\n");
 197         }
 198         return;
 199 }
 200 
 201 void sngisdn_snd_alert(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_ind)
 202 {
 203         CnStEvnt cnStEvnt;
 204         
 205         sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
 206         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
 207 
 208         if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
 209                 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);
 210                 sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
 211                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
 212                 return;
 213         }       
 214 
 215         memset(&cnStEvnt, 0, sizeof(cnStEvnt));
 216 
 217         set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind);
 218         set_facility_ie(ftdmchan, &cnStEvnt.facilityStr);
 219         ftdm_call_clear_data(&ftdmchan->caller_data);
 220 
 221         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);
 222 
 223         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)) {
 224                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT,      "stack refused ALERT request\n");
 225         }
 226         return;
 227 }
 228 
 229 void sngisdn_snd_connect(ftdm_channel_t *ftdmchan)
 230 {
 231         CnStEvnt cnStEvnt;      
 232         sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
 233         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
 234         ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN};
 235 
 236         if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
 237                 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);
 238                 sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
 239                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
 240                 return;
 241         }
 242         
 243         memset(&cnStEvnt, 0, sizeof(cnStEvnt));
 244         
 245         set_chan_id_ie(ftdmchan, &cnStEvnt.chanId);
 246         set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind);
 247         set_facility_ie(ftdmchan, &cnStEvnt.facilityStr);
 248         ftdm_call_clear_data(&ftdmchan->caller_data);
 249 
 250         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);
 251         if (sng_isdn_con_response(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, signal_data->dchan_id, sngisdn_info->ces)) {
 252                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused CONNECT request\n");
 253         }
 254         return;
 255 }
 256 
 257 void sngisdn_snd_fac_req(ftdm_channel_t *ftdmchan)
 258 {
 259         FacEvnt facEvnt;
 260         
 261         sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
 262         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
 263 
 264         if (!sngisdn_info->suInstId) {
 265                 ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending FACILITY, but no call data, ignoring (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
 266                 return;
 267         }
 268                 
 269         memset(&facEvnt, 0, sizeof(facEvnt));
 270         
 271         if (set_facility_ie_str(ftdmchan, &facEvnt.facElmt.facStr.val[2], (uint8_t*)&facEvnt.facElmt.facStr.len) != FTDM_SUCCESS) {
 272                 /* No point in sending a FACILITY message if there is no Facility IE to transmit */
 273                 return;
 274         }
 275         ftdm_call_clear_data(&ftdmchan->caller_data);
 276         
 277         facEvnt.facElmt.eh.pres = PRSNT_NODEF;
 278         facEvnt.facElmt.facStr.pres = PRSNT_NODEF;
 279         facEvnt.facElmt.facStr.val[0] = 0x1C;
 280         facEvnt.facElmt.facStr.val[1] = (uint8_t)facEvnt.facElmt.facStr.len;
 281         facEvnt.facElmt.facStr.len +=2; /* Need to include the size of identifier + len */
 282         
 283         ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending FACILITY (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);
 284 
 285         if (sng_isdn_facility_request(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &facEvnt, MI_FACIL, signal_data->dchan_id, sngisdn_info->ces)) {
 286                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT,      "stack refused FACILITY request\n");
 287         }
 288         return;
 289 }
 290 
 291 void sngisdn_snd_info_req(ftdm_channel_t *ftdmchan)
 292 {
 293         CnStEvnt cnStEvnt;
 294         
 295         sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
 296         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
 297 
 298         if (ftdmchan->span->trunk_type != FTDM_TRUNK_BRI &&
 299                 ftdmchan->span->trunk_type != FTDM_TRUNK_BRI_PTMP) {
 300 
 301                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring INFO REQ on non-BRI channel\n");
 302                 return;
 303         }
 304 
 305         memset(&cnStEvnt, 0, sizeof(cnStEvnt));
 306         //ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Sending INFO REQ\n");
 307 
 308 
 309         ftdm_call_clear_data(&ftdmchan->caller_data);
 310         
 311         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);
 312 
 313         if (sng_isdn_con_status(signal_data->cc_id, 0, 0, &cnStEvnt, MI_INFO, signal_data->dchan_id, sngisdn_info->ces)) {
 314                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT,      "stack refused INFO request\n");
 315         }
 316         return;
 317 }
 318 
 319 
 320 void sngisdn_snd_status_enq(ftdm_channel_t *ftdmchan)
 321 {
 322         StaEvnt staEvnt;
 323 
 324         sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
 325         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
 326 
 327         //ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Sending STATUS ENQ\n");
 328 
 329         memset(&staEvnt, 0, sizeof(StaEvnt));
 330 
 331         ftdm_call_clear_data(&ftdmchan->caller_data);
 332         
 333         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);
 334         if (sng_isdn_status_request(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &staEvnt, MI_STATENQ)) {
 335                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT,      "stack refused Status ENQ request\n");
 336         }
 337         return;
 338 }
 339 
 340 
 341 void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan)
 342 {       
 343         DiscEvnt discEvnt;
 344 
 345         sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
 346         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
 347 
 348         if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
 349                 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);
 350 
 351                 sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
 352                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
 353                 return;
 354         }
 355         
 356         memset(&discEvnt, 0, sizeof(discEvnt));
 357         
 358         /* Fill discEvnt here */
 359         /* TODO move this to set_cause_ie function */
 360         discEvnt.causeDgn[0].eh.pres = PRSNT_NODEF;
 361         discEvnt.causeDgn[0].location.pres = PRSNT_NODEF;
 362         discEvnt.causeDgn[0].location.val = IN_LOC_PRIVNETLU;
 363         discEvnt.causeDgn[0].codeStand3.pres = PRSNT_NODEF;
 364         discEvnt.causeDgn[0].codeStand3.val = IN_CSTD_CCITT;
 365         discEvnt.causeDgn[0].causeVal.pres = PRSNT_NODEF;
 366         discEvnt.causeDgn[0].causeVal.val = ftdmchan->caller_data.hangup_cause;
 367         discEvnt.causeDgn[0].recommend.pres = NOTPRSNT;
 368         discEvnt.causeDgn[0].dgnVal.pres = NOTPRSNT;
 369 
 370         set_facility_ie(ftdmchan, &discEvnt.facilityStr);
 371         ftdm_call_clear_data(&ftdmchan->caller_data);
 372 
 373         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);
 374         if (sng_isdn_disc_request(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &discEvnt)) {
 375                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused DISCONNECT request\n");
 376         }
 377         return;
 378 }
 379 
 380 void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare)
 381 {
 382         RelEvnt relEvnt;
 383         uint32_t suInstId, spInstId;
 384 
 385         sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
 386         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
 387 
 388         if (!sngisdn_info->suInstId) {
 389                 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);
 390 
 391                 sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
 392                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
 393                 return;
 394         }
 395         
 396         memset(&relEvnt, 0, sizeof(relEvnt));
 397         
 398         /* Fill relEvnt here */
 399         relEvnt.causeDgn[0].eh.pres = PRSNT_NODEF;
 400         relEvnt.causeDgn[0].location.pres = PRSNT_NODEF;
 401         relEvnt.causeDgn[0].location.val = IN_LOC_PRIVNETLU;
 402         relEvnt.causeDgn[0].codeStand3.pres = PRSNT_NODEF;
 403         relEvnt.causeDgn[0].codeStand3.val = IN_CSTD_CCITT;
 404 
 405         relEvnt.causeDgn[0].causeVal.pres = PRSNT_NODEF;
 406         relEvnt.causeDgn[0].causeVal.val = ftdmchan->caller_data.hangup_cause;
 407         relEvnt.causeDgn[0].recommend.pres = NOTPRSNT;
 408         relEvnt.causeDgn[0].dgnVal.pres = NOTPRSNT;
 409 
 410         if (glare) {
 411                 suInstId = sngisdn_info->glare.suInstId;
 412                 spInstId = sngisdn_info->glare.spInstId;
 413         } else {
 414                 suInstId = sngisdn_info->suInstId;
 415                 spInstId = sngisdn_info->spInstId;
 416         }
 417 
 418         set_facility_ie(ftdmchan, &relEvnt.facilityStr);
 419         ftdm_call_clear_data(&ftdmchan->caller_data);
 420         
 421         ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending RELEASE/RELEASE COMPLETE (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, suInstId, spInstId);
 422 
 423         if (glare) {
 424                 if (sng_isdn_release_request(signal_data->cc_id, suInstId, spInstId, &relEvnt)) {
 425                         ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused RELEASE/RELEASE COMPLETE request\n");
 426                 }
 427         } else {        
 428                 if (sng_isdn_release_request(signal_data->cc_id, suInstId, spInstId, &relEvnt)) {
 429                         ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused RELEASE/RELEASE COMPLETE request\n");
 430                 }
 431         }       
 432         return;
 433 }
 434 
 435 void sngisdn_snd_restart(ftdm_channel_t *ftdmchan)
 436 {
 437         Rst rstEvnt;
 438         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
 439 
 440         memset(&rstEvnt, 0, sizeof(rstEvnt));
 441 
 442         set_chan_id_ie(ftdmchan, &rstEvnt.chanId);
 443         set_restart_ind_ie(ftdmchan, &rstEvnt.rstInd);
 444         
 445         ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending RESTART (suId:%d dchan:%d ces:%d)\n", signal_data->cc_id, signal_data->dchan_id, CES_MNGMNT);
 446 
 447         if (sng_isdn_restart_request(signal_data->cc_id, &rstEvnt, signal_data->dchan_id, CES_MNGMNT, IN_SND_RST)) {
 448                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused RESTART request\n");
 449         }
 450         return;
 451 }
 452 
 453 
 454 /* We received an incoming frame on the d-channel, send data to the stack */
 455 void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len)
 456 {
 457         sng_l1_frame_t l1_frame;
 458         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) dchan->span->signal_data;
 459 
 460         memset(&l1_frame, 0, sizeof(l1_frame));
 461         l1_frame.len = len;
 462 
 463         memcpy(&l1_frame.data, data, len);
 464 
 465         if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_CRC)) {
 466                 l1_frame.flags |= SNG_L1FRAME_ERROR_CRC;
 467         }
 468 
 469         if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_FRAME)) {
 470                 l1_frame.flags |= SNG_L1FRAME_ERROR_FRAME;
 471         }
 472         
 473         if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_ABORT)) {
 474                 l1_frame.flags |= SNG_L1FRAME_ERROR_ABORT;
 475         }
 476 
 477         if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_FIFO)) {
 478                 l1_frame.flags |= SNG_L1FRAME_ERROR_FIFO;
 479         }
 480 
 481         if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_DMA)) {
 482                 l1_frame.flags |= SNG_L1FRAME_ERROR_DMA;
 483         }
 484 
 485         if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES)) {
 486                 /* Should we trigger congestion here? */                
 487                 l1_frame.flags |= SNG_L1FRAME_QUEUE_THRES;
 488         }
 489 
 490         if (ftdm_test_flag(&(dchan->iostats.rx), FTDM_IOSTATS_ERROR_QUEUE_FULL)) {
 491                 /* Should we trigger congestion here? */
 492                 l1_frame.flags |= SNG_L1FRAME_QUEUE_FULL;
 493         }
 494 
 495         sng_isdn_data_ind(signal_data->dchan_id, &l1_frame);
 496 }
 497 
 498 void sngisdn_snd_event(ftdm_channel_t *dchan, ftdm_oob_event_t event)
 499 {
 500         sng_l1_event_t l1_event;
 501         sngisdn_span_data_t *signal_data = NULL;
 502         memset(&l1_event, 0, sizeof(l1_event));
 503         
 504         
 505         signal_data = (sngisdn_span_data_t*) dchan->span->signal_data;
 506         switch(event) {
 507                 case FTDM_OOB_ALARM_CLEAR:
 508                         l1_event.type = SNG_L1EVENT_ALARM_OFF;
 509                         sng_isdn_event_ind(signal_data->dchan_id, &l1_event);
 510                         break;
 511                 case FTDM_OOB_ALARM_TRAP:
 512                         l1_event.type = SNG_L1EVENT_ALARM_ON;
 513                         sng_isdn_event_ind(signal_data->dchan_id, &l1_event);
 514                         break;
 515                 default:
 516                         /* We do not care about the other OOB events for now */
 517                         return;
 518         }
 519         return;
 520 }
 521 
 522 
 523 /* For Emacs:
 524  * Local Variables:
 525  * mode:c
 526  * indent-tabs-mode:t
 527  * tab-width:4
 528  * c-basic-offset:4
 529  * End:
 530  * For VIM:
 531  * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
 532  */
 533 
 534 /******************************************************************************/

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