root/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c

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

DEFINITIONS

This source file includes following definitions.
  1. SNGISDN_ENUM_NAMES
  2. clear_call_glare_data
  3. get_unique_suInstId
  4. get_ftdmchan_by_suInstId
  5. get_ftdmchan_by_spInstId
  6. sngisdn_set_chan_avail_rate
  7. sngisdn_set_span_avail_rate
  8. get_callref
  9. get_calling_num
  10. get_calling_num2
  11. get_called_num
  12. get_redir_num
  13. get_calling_name_from_display
  14. get_calling_name_from_usr_usr
  15. get_calling_subaddr
  16. get_facility_ie
  17. get_facility_ie_str
  18. get_prog_ind_ie
  19. set_calling_num
  20. set_calling_num2
  21. set_called_num
  22. set_redir_num
  23. set_calling_name
  24. set_calling_subaddr
  25. set_facility_ie
  26. set_facility_ie_str
  27. set_prog_ind_ie
  28. set_chan_id_ie
  29. set_bear_cap_ie
  30. set_restart_ind_ie
  31. sngisdn_t3_timeout
  32. sngisdn_delayed_setup
  33. sngisdn_delayed_release
  34. sngisdn_delayed_connect
  35. sngisdn_delayed_disconnect
  36. sngisdn_facility_timeout
  37. sngisdn_check_free_ids
  38. get_memory_info
  39. sngisdn_get_infoTranCap_from_user
  40. sngisdn_get_usrInfoLyr1Prot_from_user
  41. sngisdn_get_infoTranCap_from_stack
  42. sngisdn_get_usrInfoLyr1Prot_from_stack
  43. sngisdn_print_phy_stats
  44. sngisdn_print_span
  45. sngisdn_print_spans

   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 #define SNGISDN_Q931_FACILITY_IE_ID 0x1C
  37 
  38 /* ftmod_sangoma_isdn specific enum look-up functions */
  39 
  40 SNGISDN_ENUM_NAMES(SNGISDN_PROGIND_DESCR_NAMES, SNGISDN_PROGIND_DESCR_STRINGS)
  41 SNGISDN_STR2ENUM(ftdm_str2ftdm_sngisdn_progind_descr, ftdm_sngisdn_progind_descr2str, ftdm_sngisdn_progind_descr_t, SNGISDN_PROGIND_DESCR_NAMES, SNGISDN_PROGIND_DESCR_INVALID)
  42 
  43 SNGISDN_ENUM_NAMES(SNGISDN_PROGIND_LOC_NAMES, SNGISDN_PROGIND_LOC_STRINGS)
  44 SNGISDN_STR2ENUM(ftdm_str2ftdm_sngisdn_progind_loc, ftdm_sngisdn_progind_loc2str, ftdm_sngisdn_progind_loc_t, SNGISDN_PROGIND_LOC_NAMES, SNGISDN_PROGIND_LOC_INVALID)
  45 
  46 ftdm_status_t sngisdn_check_free_ids(void);
  47 
  48 extern ftdm_sngisdn_data_t      g_sngisdn_data;
  49 void get_memory_info(void);
  50 
  51 void clear_call_data(sngisdn_chan_data_t *sngisdn_info)
  52 {
  53         uint32_t cc_id = ((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->cc_id;
  54 
  55         ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_DEBUG, "Clearing call data (suId:%u suInstId:%u spInstId:%u)\n", cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
  56         ftdm_mutex_lock(g_sngisdn_data.ccs[cc_id].mutex);
  57         g_sngisdn_data.ccs[cc_id].active_spInstIds[sngisdn_info->spInstId]=NULL;
  58         g_sngisdn_data.ccs[cc_id].active_suInstIds[sngisdn_info->suInstId]=NULL;
  59         ftdm_mutex_unlock(g_sngisdn_data.ccs[cc_id].mutex);
  60         
  61         sngisdn_info->suInstId = 0;
  62         sngisdn_info->spInstId = 0;
  63         sngisdn_info->globalFlg = 0;
  64         sngisdn_info->flags = 0;
  65         return;
  66 }
  67 
  68 void clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info)
  69 {
  70         ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_DEBUG, "Clearing glare data (suId:%d suInstId:%u spInstId:%u actv-suInstId:%u  actv-spInstId:%u)\n",
  71                                                                                 sngisdn_info->glare.suId,
  72                                                                                 sngisdn_info->glare.suInstId, sngisdn_info->glare.spInstId,
  73                                                                                 sngisdn_info->suInstId, sngisdn_info->spInstId);
  74 
  75         ftdm_mutex_lock(g_sngisdn_data.ccs[sngisdn_info->glare.suId].mutex);    
  76         if (sngisdn_info->glare.spInstId != sngisdn_info->spInstId) {
  77                 g_sngisdn_data.ccs[sngisdn_info->glare.suId].active_spInstIds[sngisdn_info->glare.spInstId]=NULL;
  78         }
  79         g_sngisdn_data.ccs[sngisdn_info->glare.suId].active_suInstIds[sngisdn_info->glare.suInstId]=NULL;
  80         ftdm_mutex_unlock(g_sngisdn_data.ccs[sngisdn_info->glare.suId].mutex);
  81 
  82         ftdm_clear_flag(sngisdn_info, FLAG_GLARE);
  83         memset(&sngisdn_info->glare.setup, 0, sizeof(ConEvnt));
  84         sngisdn_info->glare.suId = 0;
  85         sngisdn_info->glare.suInstId = 0;
  86         sngisdn_info->glare.spInstId = 0;
  87         sngisdn_info->glare.dChan = 0;
  88         sngisdn_info->glare.ces = 0;
  89         return;
  90 }
  91 
  92 
  93 uint32_t get_unique_suInstId(int16_t cc_id)
  94 {
  95         uint32_t suInstId;
  96         ftdm_assert_return((cc_id > 0 && cc_id <=MAX_VARIANTS), FTDM_FAIL, "Invalid cc_id\n");
  97         ftdm_mutex_lock(g_sngisdn_data.ccs[cc_id].mutex);
  98         suInstId = g_sngisdn_data.ccs[cc_id].last_suInstId;
  99 
 100         while(1) {
 101                 if (++suInstId == MAX_INSTID) {
 102                         suInstId = 1;
 103                 }
 104                 if (g_sngisdn_data.ccs[cc_id].active_suInstIds[suInstId] == NULL) {
 105                         g_sngisdn_data.ccs[cc_id].last_suInstId = suInstId;
 106                         ftdm_mutex_unlock(g_sngisdn_data.ccs[cc_id].mutex);
 107                         return suInstId;
 108                 }
 109         }
 110         /* Should never reach here */
 111         ftdm_mutex_unlock(g_sngisdn_data.ccs[cc_id].mutex);
 112         return 0;
 113 }
 114 
 115 ftdm_status_t get_ftdmchan_by_suInstId(int16_t cc_id, uint32_t suInstId, sngisdn_chan_data_t **sngisdn_data)
 116 {
 117         ftdm_assert_return((cc_id > 0 && cc_id <=MAX_VARIANTS), FTDM_FAIL, "Invalid cc_id\n");
 118         ftdm_assert_return(g_sngisdn_data.ccs[cc_id].activation_done, FTDM_FAIL, "Trying to find call on unconfigured CC\n");
 119 
 120         if (g_sngisdn_data.ccs[cc_id].active_suInstIds[suInstId] == NULL) {
 121                 return FTDM_FAIL;
 122         }
 123         *sngisdn_data = g_sngisdn_data.ccs[cc_id].active_suInstIds[suInstId];   
 124         return FTDM_SUCCESS;
 125 }
 126 
 127 ftdm_status_t get_ftdmchan_by_spInstId(int16_t cc_id, uint32_t spInstId, sngisdn_chan_data_t **sngisdn_data)
 128 {
 129         ftdm_assert_return((cc_id > 0 && cc_id <=MAX_VARIANTS), FTDM_FAIL, "Invalid cc_id\n");
 130         ftdm_assert_return(g_sngisdn_data.ccs[cc_id].activation_done, FTDM_FAIL, "Trying to find call on unconfigured CC\n");
 131 
 132         if (g_sngisdn_data.ccs[cc_id].active_spInstIds[spInstId] == NULL) {
 133                 return FTDM_FAIL;
 134         }
 135         *sngisdn_data = g_sngisdn_data.ccs[cc_id].active_spInstIds[spInstId];
 136         return FTDM_SUCCESS;
 137 }
 138 
 139 ftdm_status_t sngisdn_set_chan_avail_rate(ftdm_channel_t *chan, sngisdn_avail_t avail)
 140 {
 141         if (FTDM_SPAN_IS_BRI(chan->span)) {
 142                 ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Setting availability rate to:%d\n", avail);
 143                 chan->availability_rate = avail;
 144         }
 145         return FTDM_SUCCESS;
 146 }
 147 
 148 ftdm_status_t sngisdn_set_span_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail)
 149 {
 150         if (FTDM_SPAN_IS_BRI(span)) {
 151                 ftdm_iterator_t *chaniter = NULL;
 152                 ftdm_iterator_t *curr = NULL;
 153 
 154                 chaniter = ftdm_span_get_chan_iterator(span, NULL);
 155                 for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
 156                         ftdm_log_chan(((ftdm_channel_t*)ftdm_iterator_current(curr)), FTDM_LOG_DEBUG, "Setting availability rate to:%d\n", avail);
 157                         sngisdn_set_chan_avail_rate(((ftdm_channel_t*)ftdm_iterator_current(curr)), avail);
 158                 }
 159                 ftdm_iterator_free(chaniter);
 160         }
 161         return FTDM_SUCCESS;
 162 }
 163 
 164 #ifdef NETBORDER_CALL_REF
 165 ftdm_status_t get_callref(ftdm_channel_t *ftdmchan, BCCallRef* callRef)
 166 {
 167         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
 168         sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data;
 169 
 170         if (signal_data->raw_trace_q931) {
 171                 if (callRef->eh.pres != PRSNT_NODEF || callRef->reference.pres != PRSNT_NODEF) {
 172                         /* Netborder only supports BRI, so we only care for BRI for now */
 173                         if (FTDM_SPAN_IS_BRI(ftdmchan->span) && !sngisdn_info->call_ref) {
 174                                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Failed to obtain call reference\n");
 175                         }
 176                         return FTDM_FAIL;
 177                 }               
 178                 if (FTDM_SPAN_IS_BRI(ftdmchan->span)) {
 179                         sngisdn_info->call_ref = 0x7F & callRef->reference.val;
 180                 } else {
 181                         sngisdn_info->call_ref = 0x7FFF & callRef->reference.val;
 182                 }
 183                 
 184                 ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Call reference:%04x\n", sngisdn_info->call_ref);
 185         }
 186         return FTDM_SUCCESS;
 187 }
 188 #endif
 189 
 190 ftdm_status_t get_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb)
 191 {
 192         ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
 193         if (cgPtyNmb->eh.pres != PRSNT_NODEF) {
 194                 return FTDM_FAIL;
 195         }
 196 
 197         if (cgPtyNmb->screenInd.pres == PRSNT_NODEF) {
 198                 caller_data->screen = cgPtyNmb->screenInd.val;
 199         }
 200 
 201         if (cgPtyNmb->presInd0.pres == PRSNT_NODEF) {
 202                 caller_data->pres = cgPtyNmb->presInd0.val;
 203         }
 204 
 205         if (cgPtyNmb->nmbPlanId.pres == PRSNT_NODEF) {
 206                 caller_data->cid_num.plan = cgPtyNmb->nmbPlanId.val;
 207         }
 208                 
 209         if (cgPtyNmb->typeNmb1.pres == PRSNT_NODEF) {
 210                 caller_data->cid_num.type = cgPtyNmb->typeNmb1.val;
 211         }
 212         
 213         if (cgPtyNmb->nmbDigits.pres == PRSNT_NODEF) {
 214                 ftdm_copy_string(caller_data->cid_num.digits, (const char*)cgPtyNmb->nmbDigits.val, cgPtyNmb->nmbDigits.len+1);
 215         }
 216         memcpy(&caller_data->ani, &caller_data->cid_num, sizeof(caller_data->ani));
 217         return FTDM_SUCCESS;
 218 }
 219 
 220 ftdm_status_t get_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb)
 221 {
 222         ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
 223         if (cgPtyNmb->eh.pres != PRSNT_NODEF) {
 224                 return FTDM_FAIL;
 225         }
 226 
 227         if (cgPtyNmb->screenInd.pres == PRSNT_NODEF) {
 228                 ftdm_call_add_var(caller_data, "isdn.cg_pty2.screen_ind", ftdm_screening2str(cgPtyNmb->screenInd.val));
 229         }
 230 
 231         if (cgPtyNmb->presInd0.pres == PRSNT_NODEF) {
 232                 ftdm_call_add_var(caller_data, "isdn.cg_pty2.presentation_ind", ftdm_presentation2str(cgPtyNmb->presInd0.val));
 233         }
 234 
 235         if (cgPtyNmb->nmbPlanId.pres == PRSNT_NODEF) {
 236                 ftdm_call_add_var(caller_data, "isdn.cg_pty2.npi", ftdm_npi2str(cgPtyNmb->nmbPlanId.val));
 237         }
 238                 
 239         if (cgPtyNmb->typeNmb1.pres == PRSNT_NODEF) {
 240                 ftdm_call_add_var(caller_data, "isdn.cg_pty2.ton", ftdm_ton2str(cgPtyNmb->typeNmb1.val));
 241         }
 242         
 243         if (cgPtyNmb->nmbDigits.pres == PRSNT_NODEF) {
 244                 char digits_string [32];
 245                 memcpy(digits_string, (const char*)cgPtyNmb->nmbDigits.val, cgPtyNmb->nmbDigits.len);
 246                 digits_string[cgPtyNmb->nmbDigits.len] = '\0';
 247                 ftdm_call_add_var(caller_data, "isdn.cg_pty2.digits", digits_string);
 248         }
 249         memcpy(&caller_data->ani, &caller_data->cid_num, sizeof(caller_data->ani));
 250         return FTDM_SUCCESS;
 251 }
 252 
 253 ftdm_status_t get_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb)
 254 {
 255         ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
 256         if (cdPtyNmb->eh.pres != PRSNT_NODEF) {
 257                 return FTDM_FAIL;
 258         }
 259 
 260         if (cdPtyNmb->nmbPlanId.pres == PRSNT_NODEF) {
 261                 caller_data->dnis.plan = cdPtyNmb->nmbPlanId.val;
 262         }
 263 
 264         if (cdPtyNmb->typeNmb0.pres == PRSNT_NODEF) {
 265                 caller_data->dnis.type = cdPtyNmb->typeNmb0.val;
 266         }
 267         
 268         if (cdPtyNmb->nmbDigits.pres == PRSNT_NODEF) {
 269                 /* In overlap receive mode, append the new digits to the existing dnis */
 270                 unsigned i = strlen(caller_data->dnis.digits);
 271                 
 272                 ftdm_copy_string(&caller_data->dnis.digits[i], (const char*)cdPtyNmb->nmbDigits.val, cdPtyNmb->nmbDigits.len+1);
 273         }
 274         return FTDM_SUCCESS;
 275 }
 276 
 277 ftdm_status_t get_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb)
 278 {
 279         ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
 280         if (redirNmb->eh.pres != PRSNT_NODEF) {
 281                 return FTDM_FAIL;
 282         }
 283 
 284         if (redirNmb->nmbPlanId.pres == PRSNT_NODEF) {
 285                 caller_data->rdnis.plan = redirNmb->nmbPlanId.val;
 286         }
 287 
 288         if (redirNmb->typeNmb.pres == PRSNT_NODEF) {
 289                 caller_data->rdnis.type = redirNmb->typeNmb.val;
 290         }
 291         
 292         if (redirNmb->nmbDigits.pres == PRSNT_NODEF) {
 293                 ftdm_copy_string(caller_data->rdnis.digits, (const char*)redirNmb->nmbDigits.val, redirNmb->nmbDigits.len+1);
 294         }
 295         return FTDM_SUCCESS;
 296 }
 297 
 298 ftdm_status_t get_calling_name_from_display(ftdm_channel_t *ftdmchan, Display *display)
 299 {
 300         ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
 301         if (display->eh.pres != PRSNT_NODEF) {
 302                 return FTDM_FAIL;
 303         }
 304         if (display->dispInfo.pres != PRSNT_NODEF) {
 305                 return FTDM_FAIL;
 306         }
 307         
 308         ftdm_copy_string(caller_data->cid_name, (const char*)display->dispInfo.val, display->dispInfo.len+1);
 309         return FTDM_SUCCESS;
 310 }
 311 
 312 ftdm_status_t get_calling_name_from_usr_usr(ftdm_channel_t *ftdmchan, UsrUsr *usrUsr)
 313 {
 314         ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
 315         if (usrUsr->eh.pres != PRSNT_NODEF) {
 316                 return FTDM_FAIL;
 317         }
 318         
 319         if (usrUsr->protocolDisc.val != PD_IA5) {
 320                 return FTDM_FAIL;
 321         }
 322                 
 323         if (usrUsr->usrInfo.pres != PRSNT_NODEF) {
 324                 return FTDM_FAIL;
 325         }
 326                 
 327         ftdm_copy_string(caller_data->cid_name, (const char*)usrUsr->usrInfo.val, usrUsr->usrInfo.len+1);
 328         return FTDM_SUCCESS;
 329 }
 330 
 331 ftdm_status_t get_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad)
 332 {
 333         char subaddress[100];
 334         
 335         if (cgPtySad->eh.pres != PRSNT_NODEF) {
 336                 return FTDM_FAIL;
 337         }
 338         memset(subaddress, 0, sizeof(subaddress));
 339         if(cgPtySad->sadInfo.len >= sizeof(subaddress)) {
 340                 ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Calling Party Subaddress exceeds local size limit (len:%d max:%d)\n", cgPtySad->sadInfo.len, sizeof(subaddress));
 341                 cgPtySad->sadInfo.len = sizeof(subaddress)-1;
 342         }
 343                 
 344         memcpy(subaddress, (char*)cgPtySad->sadInfo.val, cgPtySad->sadInfo.len);
 345         subaddress[cgPtySad->sadInfo.len] = '\0';
 346         ftdm_call_add_var(&ftdmchan->caller_data, "isdn.calling_subaddr", subaddress);
 347         return FTDM_SUCCESS;
 348 }
 349 
 350 ftdm_status_t get_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr)
 351 {
 352         if (!facilityStr->eh.pres) {
 353                 return FTDM_FAIL;
 354         }
 355 
 356         return get_facility_ie_str(ftdmchan, facilityStr->facilityStr.val, facilityStr->facilityStr.len);
 357 }
 358 
 359 ftdm_status_t get_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, uint8_t data_len)
 360 {
 361         ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
 362         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
 363         
 364         if (signal_data->facility_ie_decode == SNGISDN_OPT_FALSE) {
 365                 /* size of facilityStr->facilityStr.len is a uint8_t so no need to check
 366                 for overflow here as facilityStr->facilityStr.len will always be smaller
 367                 than sizeof(caller_data->raw_data) */
 368                 
 369                 memset(caller_data->raw_data, 0, sizeof(caller_data->raw_data));
 370                 /* Always include Facility IE identifier + len so this can be used as a sanity check by the user */
 371                 caller_data->raw_data[0] = SNGISDN_Q931_FACILITY_IE_ID;
 372                 caller_data->raw_data[1] = data_len;
 373         
 374                 memcpy(&caller_data->raw_data[2], data, data_len);
 375                 caller_data->raw_data_len = data_len+2;
 376                 ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Raw Facility IE copied available\n");
 377         } else {
 378                 /* Call libsng_isdn to process facility IE's here */
 379         }
 380         return FTDM_SUCCESS;
 381 }
 382 
 383 ftdm_status_t get_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd)
 384 {
 385         uint8_t val;    
 386         if (!progInd->eh.pres) {
 387                 return FTDM_FAIL;
 388         }
 389 
 390         if (progInd->progDesc.pres) {
 391                 switch (progInd->progDesc.val) {
 392                         case IN_PD_NOTETEISDN:
 393                                 val = SNGISDN_PROGIND_DESCR_NETE_ISDN;
 394                                 break;
 395                         case IN_PD_DSTNOTISDN:
 396                                 val = SNGISDN_PROGIND_DESCR_DEST_NISDN;
 397                                 break;
 398                         case IN_PD_ORGNOTISDN:
 399                                 val = SNGISDN_PROGIND_DESCR_ORIG_NISDN;
 400                                 break;
 401                         case IN_PD_CALLRET:
 402                                 val = SNGISDN_PROGIND_DESCR_RET_ISDN;
 403                                 break;
 404                         case IN_PD_DELRESP:
 405                                 val = SNGISDN_PROGIND_DESCR_SERV_CHANGE;
 406                                 break;
 407                         case IN_PD_IBAVAIL:
 408                                 val = SNGISDN_PROGIND_DESCR_IB_AVAIL;
 409                                 break;
 410                         default:
 411                                 ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Unknown Progress Indicator Description (%d)\n", progInd->progDesc.val);
 412                                 val = SNGISDN_PROGIND_DESCR_INVALID;
 413                                 break;
 414                 }
 415                 ftdm_call_add_var(&ftdmchan->caller_data, "isdn.prog_ind.descr", ftdm_sngisdn_progind_descr2str(val));
 416         }
 417         
 418         if (progInd->location.pres) {
 419                 switch (progInd->location.val) {
 420                         case IN_LOC_USER:
 421                                 val = SNGISDN_PROGIND_LOC_USER;
 422                                 break;
 423                         case IN_LOC_PRIVNETLU:
 424                                 val = SNGISDN_PROGIND_LOC_PRIV_NET_LOCAL_USR;
 425                                 break;
 426                         case IN_LOC_PUBNETLU:
 427                                 val = SNGISDN_PROGIND_LOC_PUB_NET_LOCAL_USR;
 428                                 break;
 429                         case IN_LOC_TRANNET:
 430                                 val = SNGISDN_PROGIND_LOC_TRANSIT_NET;
 431                                 break;
 432                         case IN_LOC_PUBNETRU:
 433                                 val = SNGISDN_PROGIND_LOC_PUB_NET_REMOTE_USR;
 434                                 break;
 435                         case IN_LOC_PRIVNETRU:
 436                                 val = SNGISDN_PROGIND_LOC_PRIV_NET_REMOTE_USR;
 437                                 break;
 438                         case IN_LOC_NETINTER:
 439                                 val = SNGISDN_PROGIND_LOC_NET_BEYOND_INTRW;
 440                                 break;
 441                         default:
 442                                 ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Unknown Progress Indicator Location (%d)", progInd->location.val);
 443                                 val = SNGISDN_PROGIND_LOC_INVALID;
 444                                 break;
 445                 }
 446                 ftdm_call_add_var(&ftdmchan->caller_data, "isdn.prog_ind.loc", ftdm_sngisdn_progind_loc2str(val));
 447         }       
 448         return FTDM_SUCCESS;
 449 }
 450 
 451 
 452 ftdm_status_t set_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb)
 453 {
 454         ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
 455         uint8_t len = strlen(caller_data->cid_num.digits);
 456         if (!len) {
 457                 return FTDM_SUCCESS;
 458         }
 459         cgPtyNmb->eh.pres                       = PRSNT_NODEF;
 460 
 461         cgPtyNmb->screenInd.pres        = PRSNT_NODEF;
 462         cgPtyNmb->screenInd.val         = caller_data->screen;
 463 
 464         cgPtyNmb->presInd0.pres     = PRSNT_NODEF;
 465         cgPtyNmb->presInd0.val      = caller_data->pres;
 466         
 467         cgPtyNmb->nmbPlanId.pres        = PRSNT_NODEF;
 468         if (caller_data->cid_num.plan >= FTDM_NPI_INVALID) {
 469                 cgPtyNmb->nmbPlanId.val         = FTDM_NPI_UNKNOWN;
 470         } else {
 471                 cgPtyNmb->nmbPlanId.val         = caller_data->cid_num.plan;
 472         }
 473 
 474         cgPtyNmb->typeNmb1.pres         = PRSNT_NODEF;
 475 
 476         if (caller_data->cid_num.type >= FTDM_TON_INVALID) {
 477                 cgPtyNmb->typeNmb1.val          = FTDM_TON_UNKNOWN;
 478         } else {
 479                 cgPtyNmb->typeNmb1.val          = caller_data->cid_num.type;
 480         }
 481 
 482         cgPtyNmb->nmbDigits.pres        = PRSNT_NODEF;
 483         cgPtyNmb->nmbDigits.len         = len;
 484 
 485         memcpy(cgPtyNmb->nmbDigits.val, caller_data->cid_num.digits, len);
 486 
 487         return FTDM_SUCCESS;
 488 }
 489 
 490 ftdm_status_t set_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb)
 491 {
 492         const char* string = NULL;
 493         uint8_t len,val;
 494         ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
 495         
 496         string = ftdm_call_get_var(caller_data, "isdn.cg_pty2.digits");
 497         if ((string == NULL) || !(*string)) {
 498                 return FTDM_FAIL;
 499         }
 500 
 501         cgPtyNmb->eh.pres                       = PRSNT_NODEF;
 502         
 503         len = strlen(string);
 504         cgPtyNmb->nmbDigits.len         = len;
 505 
 506         cgPtyNmb->nmbDigits.pres        = PRSNT_NODEF;
 507         memcpy(cgPtyNmb->nmbDigits.val, string, len);
 508 
 509         /* Screening Indicator */
 510         cgPtyNmb->screenInd.pres        = PRSNT_NODEF;
 511 
 512         val = FTDM_SCREENING_INVALID;
 513         string = ftdm_call_get_var(caller_data, "isdn.cg_pty2.screening_ind");
 514         if ((string != NULL) && (*string)) {
 515                 val = ftdm_str2ftdm_screening(string);
 516         }
 517 
 518         /* isdn.cg_pty2.screen_ind does not exist or we could not parse its value */
 519         if (val == FTDM_SCREENING_INVALID) {            
 520                 /* default to caller data screening ind */
 521                 cgPtyNmb->screenInd.val = caller_data->screen;
 522         } else {
 523                 cgPtyNmb->screenInd.val = val;
 524         }
 525 
 526         /* Presentation Indicator */
 527         cgPtyNmb->presInd0.pres = PRSNT_NODEF;
 528         
 529         val = FTDM_PRES_INVALID;
 530         string = ftdm_call_get_var(caller_data, "isdn.cg_pty2.presentation_ind");
 531         if ((string != NULL) && (*string)) {
 532                 val = ftdm_str2ftdm_presentation(string);
 533         }
 534 
 535         if (val == FTDM_PRES_INVALID) {
 536                 cgPtyNmb->presInd0.val = caller_data->pres;
 537         } else {
 538                 cgPtyNmb->presInd0.val = val;
 539         }
 540 
 541         /* Numbering Plan Indicator */
 542         cgPtyNmb->nmbPlanId.pres        = PRSNT_NODEF;
 543         
 544         val = FTDM_NPI_INVALID;
 545         string = ftdm_call_get_var(caller_data, "isdn.cg_pty2.npi");
 546         if ((string != NULL) && (*string)) {
 547                 val = ftdm_str2ftdm_npi(string);
 548         }
 549 
 550         if (val == FTDM_NPI_INVALID) {
 551                 cgPtyNmb->nmbPlanId.val = caller_data->cid_num.plan;
 552         } else {
 553                 cgPtyNmb->nmbPlanId.val = val;
 554         }
 555 
 556         cgPtyNmb->typeNmb1.pres         = PRSNT_NODEF;
 557 
 558         /* Type of Number */
 559         val = FTDM_TON_INVALID;
 560         string = ftdm_call_get_var(caller_data, "isdn.cg_pty2.ton");
 561         if ((string != NULL) && (*string)) {
 562                 val = ftdm_str2ftdm_ton(string);
 563         }
 564 
 565         if (val == FTDM_TON_INVALID) {
 566                 cgPtyNmb->typeNmb1.val = caller_data->cid_num.type;
 567         } else {
 568                 cgPtyNmb->typeNmb1.val = val;
 569         }
 570         return FTDM_SUCCESS;
 571 }
 572 
 573 ftdm_status_t set_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb)
 574 {
 575         ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
 576         uint8_t len = strlen(caller_data->dnis.digits);
 577         
 578         if (!len) {
 579                 return FTDM_SUCCESS;
 580         }
 581         cdPtyNmb->eh.pres           = PRSNT_NODEF;
 582 
 583         cdPtyNmb->nmbPlanId.pres      = PRSNT_NODEF;
 584         if (caller_data->dnis.plan >= FTDM_NPI_INVALID) {
 585                 cdPtyNmb->nmbPlanId.val       = FTDM_NPI_UNKNOWN;
 586         } else {
 587                 cdPtyNmb->nmbPlanId.val       = caller_data->dnis.plan;
 588         }
 589         
 590         cdPtyNmb->typeNmb0.pres       = PRSNT_NODEF;
 591         if (caller_data->dnis.type >= FTDM_TON_INVALID) {
 592                 cdPtyNmb->typeNmb0.val        = FTDM_TON_UNKNOWN;
 593         } else {
 594                 cdPtyNmb->typeNmb0.val        = caller_data->dnis.type;
 595         }
 596 
 597         cdPtyNmb->nmbDigits.pres = PRSNT_NODEF;
 598         cdPtyNmb->nmbDigits.len = len;
 599 
 600         
 601         memcpy(cdPtyNmb->nmbDigits.val, caller_data->dnis.digits, len);
 602     return FTDM_SUCCESS;
 603 }
 604 
 605 ftdm_status_t set_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb)
 606 {
 607         ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
 608         uint8_t len = strlen(caller_data->rdnis.digits);
 609         if (!len) {
 610                 return FTDM_SUCCESS;
 611         }
 612 
 613         redirNmb->eh.pres       = PRSNT_NODEF;
 614 
 615         redirNmb->nmbPlanId.pres        = PRSNT_NODEF;
 616         if (caller_data->rdnis.plan >= FTDM_NPI_INVALID) {
 617                 redirNmb->nmbPlanId.val = FTDM_NPI_UNKNOWN;
 618         } else {
 619                 redirNmb->nmbPlanId.val = caller_data->rdnis.plan;
 620         }
 621 
 622         redirNmb->typeNmb.pres          = PRSNT_NODEF;
 623         if (caller_data->rdnis.type >= FTDM_TON_INVALID) {
 624                 redirNmb->typeNmb.val           = FTDM_TON_UNKNOWN;
 625         } else {
 626                 redirNmb->typeNmb.val           = caller_data->rdnis.type;
 627         }
 628 
 629         redirNmb->nmbDigits.pres = PRSNT_NODEF;
 630         redirNmb->nmbDigits.len = len;
 631 
 632         memcpy(redirNmb->nmbDigits.val, caller_data->rdnis.digits, len);
 633 
 634         return FTDM_SUCCESS;
 635 }
 636 
 637 
 638 ftdm_status_t set_calling_name(ftdm_channel_t *ftdmchan, ConEvnt *conEvnt)
 639 {
 640         uint8_t len;
 641         ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
 642         /* sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data; */
 643         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
 644 
 645         len = strlen(caller_data->cid_name);
 646         if (!len) {
 647                 return FTDM_SUCCESS;
 648         }
 649 
 650         if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI ||
 651                 ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
 652 
 653                 conEvnt->usrUsr.eh.pres = PRSNT_NODEF;
 654                 conEvnt->usrUsr.protocolDisc.pres = PRSNT_NODEF;
 655                 conEvnt->usrUsr.protocolDisc.val = PD_IA5; /* IA5 chars */
 656                 conEvnt->usrUsr.usrInfo.pres = PRSNT_NODEF;
 657                 conEvnt->usrUsr.usrInfo.len = len;
 658                 /* in sangoma_brid we used to send usr-usr info as <cid_name>!<calling_number>,
 659                 change to previous style if current one does not work */
 660                 memcpy(conEvnt->usrUsr.usrInfo.val, caller_data->cid_name, len);
 661         } else {
 662                 switch (signal_data->switchtype) {
 663                 case SNGISDN_SWITCH_NI2:
 664                         /* TODO: Need to send the caller ID as a facility IE */
 665 
 666                         break;
 667                 case SNGISDN_SWITCH_EUROISDN:
 668                         if (signal_data->signalling != SNGISDN_SIGNALING_NET) {
 669                         break;
 670                         }
 671                         /* follow through */
 672                 case SNGISDN_SWITCH_5ESS:
 673                 case SNGISDN_SWITCH_4ESS:
 674                 case SNGISDN_SWITCH_DMS100:
 675                         conEvnt->display.eh.pres = PRSNT_NODEF;
 676                         conEvnt->display.dispInfo.pres = PRSNT_NODEF;
 677                         conEvnt->display.dispInfo.len = len;
 678                         memcpy(conEvnt->display.dispInfo.val, caller_data->cid_name, len);
 679                         break;
 680                 case SNGISDN_SWITCH_QSIG:
 681                         /* It seems like QSIG does not support Caller ID Name */
 682                         break;
 683                 case SNGISDN_SWITCH_INSNET:
 684                         /* Don't know how to transmit caller ID name on INSNET */
 685                         break;
 686                 }
 687         }
 688         return FTDM_SUCCESS;
 689 }
 690 
 691 ftdm_status_t set_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad)
 692 {
 693         const char* clg_subaddr = NULL;
 694         clg_subaddr = ftdm_call_get_var(&ftdmchan->caller_data, "isdn.calling_subaddr");
 695         if ((clg_subaddr != NULL) && (*clg_subaddr)) {
 696                 unsigned len = strlen (clg_subaddr);
 697                 cgPtySad->eh.pres = PRSNT_NODEF;
 698                 cgPtySad->typeSad.pres = 1;
 699                 cgPtySad->typeSad.val = 0; /* NSAP */
 700                 cgPtySad->oddEvenInd.pres = 1;
 701                 cgPtySad->oddEvenInd.val = 0;
 702 
 703                 ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending Calling Party Subaddress:%s\n", clg_subaddr);
 704                 cgPtySad->sadInfo.pres = 1;
 705                 cgPtySad->sadInfo.len = len;
 706                 memcpy(cgPtySad->sadInfo.val, clg_subaddr, len);
 707         }
 708         return FTDM_SUCCESS;
 709 }
 710 
 711 ftdm_status_t set_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr)
 712 {
 713         ftdm_status_t status;
 714         status = set_facility_ie_str(ftdmchan, facilityStr->facilityStr.val, (uint8_t*)&(facilityStr->facilityStr.len));
 715         if (status == FTDM_SUCCESS) {
 716                 facilityStr->eh.pres = PRSNT_NODEF;
 717                 facilityStr->facilityStr.pres = PRSNT_NODEF;
 718         }
 719         return status;
 720 }
 721 
 722 ftdm_status_t set_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, uint8_t *data_len)
 723 {
 724         int len;
 725         ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
 726         if (caller_data->raw_data_len > 0 && caller_data->raw_data[0] == SNGISDN_Q931_FACILITY_IE_ID) {
 727                 len = caller_data->raw_data[1];
 728                 memcpy(data, &caller_data->raw_data[2], len);
 729                 *data_len = len;
 730                 return FTDM_SUCCESS;
 731         }       
 732         return FTDM_FAIL;
 733 }
 734 
 735 ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_sngisdn_progind_t prog_ind)
 736 {
 737         const char *str = NULL;
 738         int descr = prog_ind.descr;
 739         int loc = prog_ind.loc;
 740         
 741         str = ftdm_call_get_var(&ftdmchan->caller_data, "isdn.prog_ind.descr");
 742         if (str && *str) {
 743                 /* User wants to override progress indicator */
 744                 descr = ftdm_str2ftdm_sngisdn_progind_descr(str);
 745         }
 746 
 747         if (descr == SNGISDN_PROGIND_DESCR_INVALID) {
 748                 /* User does not want to send progress indicator */
 749                 return FTDM_SUCCESS;
 750         }
 751 
 752         str = ftdm_call_get_var(&ftdmchan->caller_data, "isdn.prog_ind.loc");
 753         if (str && *str) {
 754                 loc = ftdm_str2ftdm_sngisdn_progind_loc(str);
 755         }
 756         if (loc == SNGISDN_PROGIND_LOC_INVALID) {
 757                 loc = SNGISDN_PROGIND_LOC_USER;
 758         }
 759 
 760         progInd->eh.pres = PRSNT_NODEF; 
 761         progInd->codeStand0.pres = PRSNT_NODEF;
 762         progInd->codeStand0.val = IN_CSTD_CCITT;
 763         
 764         progInd->progDesc.pres = PRSNT_NODEF;
 765         switch(descr) {
 766                 case SNGISDN_PROGIND_DESCR_NETE_ISDN:
 767                         progInd->progDesc.val = IN_PD_NOTETEISDN;
 768                         break;
 769                 case SNGISDN_PROGIND_DESCR_DEST_NISDN:
 770                         progInd->progDesc.val = IN_PD_DSTNOTISDN;
 771                         break;
 772                 case SNGISDN_PROGIND_DESCR_ORIG_NISDN:
 773                         progInd->progDesc.val = IN_PD_ORGNOTISDN;
 774                         break;
 775                 case SNGISDN_PROGIND_DESCR_RET_ISDN:
 776                         progInd->progDesc.val = IN_PD_CALLRET;
 777                         break;
 778                 case SNGISDN_PROGIND_DESCR_SERV_CHANGE:
 779                         /* Trillium defines do not match ITU-T Q931 Progress descriptions,
 780                         indicate a delayed response for now */
 781                         progInd->progDesc.val = IN_PD_DELRESP;
 782                         break;
 783                 case SNGISDN_PROGIND_DESCR_IB_AVAIL:
 784                         progInd->progDesc.val = IN_PD_IBAVAIL;
 785                         break;
 786                 default:
 787                         ftdm_log(FTDM_LOG_WARNING, "Invalid prog_ind description:%d\n", descr);
 788                         progInd->progDesc.val = IN_PD_NOTETEISDN;
 789                         break;
 790         }
 791 
 792         progInd->location.pres = PRSNT_NODEF;
 793         switch (loc) {
 794                 case SNGISDN_PROGIND_LOC_USER:
 795                         progInd->location.val = IN_LOC_USER;
 796                         break;
 797                 case SNGISDN_PROGIND_LOC_PRIV_NET_LOCAL_USR:
 798                         progInd->location.val = IN_LOC_PRIVNETLU;
 799                         break;
 800                 case SNGISDN_PROGIND_LOC_PUB_NET_LOCAL_USR:
 801                         progInd->location.val = IN_LOC_PUBNETLU;
 802                         break;
 803                 case SNGISDN_PROGIND_LOC_TRANSIT_NET:
 804                         progInd->location.val = IN_LOC_TRANNET;
 805                         break;
 806                 case SNGISDN_PROGIND_LOC_PUB_NET_REMOTE_USR:
 807                         progInd->location.val = IN_LOC_PUBNETRU;
 808                         break;
 809                 case SNGISDN_PROGIND_LOC_PRIV_NET_REMOTE_USR:
 810                         progInd->location.val = IN_LOC_PRIVNETRU;
 811                         break;
 812                 case SNGISDN_PROGIND_LOC_NET_BEYOND_INTRW:
 813                         progInd->location.val = IN_LOC_NETINTER;
 814                         break;
 815                 default:
 816                         ftdm_log(FTDM_LOG_WARNING, "Invalid prog_ind location:%d\n", loc);
 817                         progInd->location.val = IN_LOC_USER;
 818         }
 819         return FTDM_SUCCESS;
 820 }
 821 
 822 ftdm_status_t set_chan_id_ie(ftdm_channel_t *ftdmchan, ChanId *chanId)
 823 {
 824         if (!ftdmchan) {
 825                 return FTDM_SUCCESS;
 826         }
 827         chanId->eh.pres = PRSNT_NODEF;
 828         chanId->prefExc.pres = PRSNT_NODEF;
 829         chanId->prefExc.val = IN_PE_EXCLSVE;
 830         chanId->dChanInd.pres = PRSNT_NODEF;
 831         chanId->dChanInd.val = IN_DSI_NOTDCHAN;
 832         chanId->intIdentPres.pres = PRSNT_NODEF;
 833         chanId->intIdentPres.val = IN_IIP_IMPLICIT;
 834 
 835         if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI ||
 836                    ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
 837 
 838                 /* BRI only params */
 839                 chanId->intType.pres = PRSNT_NODEF;
 840                 chanId->intType.val = IN_IT_BASIC;
 841                 chanId->infoChanSel.pres = PRSNT_NODEF;
 842                 chanId->infoChanSel.val = ftdmchan->physical_chan_id;
 843         } else {
 844                 chanId->intType.pres = PRSNT_NODEF;
 845                 chanId->intType.val = IN_IT_OTHER;
 846                 chanId->infoChanSel.pres = PRSNT_NODEF;
 847                 chanId->infoChanSel.val = IN_ICS_B1CHAN;
 848                 chanId->chanMapType.pres = PRSNT_NODEF;
 849                 chanId->chanMapType.val = IN_CMT_BCHAN;
 850                 chanId->nmbMap.pres = PRSNT_NODEF;
 851                 chanId->nmbMap.val = IN_NM_CHNNMB;
 852                 chanId->codeStand1.pres = PRSNT_NODEF;
 853                 chanId->codeStand1.val = IN_CSTD_CCITT;
 854                 chanId->chanNmbSlotMap.pres = PRSNT_NODEF;
 855                 chanId->chanNmbSlotMap.len = 1;
 856                 chanId->chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
 857         }
 858         return FTDM_SUCCESS;
 859 }
 860 
 861 ftdm_status_t set_bear_cap_ie(ftdm_channel_t *ftdmchan, BearCap *bearCap)
 862 {
 863         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
 864         
 865         bearCap->eh.pres = PRSNT_NODEF;
 866         bearCap->infoTranCap.pres = PRSNT_NODEF;
 867         bearCap->infoTranCap.val = sngisdn_get_infoTranCap_from_user(ftdmchan->caller_data.bearer_capability);
 868 
 869         bearCap->codeStand0.pres = PRSNT_NODEF;
 870         bearCap->codeStand0.val = IN_CSTD_CCITT;
 871         bearCap->infoTranRate0.pres = PRSNT_NODEF;
 872         bearCap->infoTranRate0.val = IN_ITR_64KBIT;
 873         bearCap->tranMode.pres = PRSNT_NODEF;
 874         bearCap->tranMode.val = IN_TM_CIRCUIT;
 875 
 876         if (!FTDM_SPAN_IS_BRI(ftdmchan->span)) {
 877                 /* Trillium stack rejests lyr1Ident on BRI, but Netbricks always sends it.
 878                 Check with Trillium if this ever causes calls to fail in the field */
 879 
 880                 /* PRI only params */
 881                 bearCap->usrInfoLyr1Prot.pres = PRSNT_NODEF;
 882                 bearCap->usrInfoLyr1Prot.val = sngisdn_get_usrInfoLyr1Prot_from_user(ftdmchan->caller_data.bearer_layer1);
 883 
 884                 if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN &&
 885                         bearCap->usrInfoLyr1Prot.val == IN_UIL1_G711ULAW) {
 886 
 887                         /* We are bridging a call from T1 */
 888                         bearCap->usrInfoLyr1Prot.val = IN_UIL1_G711ALAW;
 889 
 890                 } else if (bearCap->usrInfoLyr1Prot.val == IN_UIL1_G711ALAW) {
 891 
 892                         /* We are bridging a call from E1 */
 893                         bearCap->usrInfoLyr1Prot.val = IN_UIL1_G711ULAW;
 894                 }
 895 
 896                 bearCap->lyr1Ident.pres = PRSNT_NODEF;
 897                 bearCap->lyr1Ident.val = IN_L1_IDENT;
 898         }
 899         return FTDM_SUCCESS;
 900 }
 901 
 902 ftdm_status_t set_restart_ind_ie(ftdm_channel_t *ftdmchan, RstInd *rstInd)
 903 {
 904         rstInd->eh.pres = PRSNT_NODEF;
 905         rstInd->rstClass.pres = PRSNT_NODEF;
 906         rstInd->rstClass.val = IN_CL_INDCHAN;
 907         return FTDM_SUCCESS;
 908 }
 909 
 910 void sngisdn_t3_timeout(void* p_sngisdn_info)
 911 {
 912         sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info;
 913         ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
 914         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
 915 
 916         ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Timer T3 expired (suId:%d suInstId:%u spInstId:%u)\n",
 917                                   signal_data->cc_id, sngisdn_info->glare.spInstId, sngisdn_info->glare.suInstId);
 918         ftdm_mutex_lock(ftdmchan->mutex);
 919         if (ftdm_test_flag(sngisdn_info, FLAG_ACTIVATING)){
 920                 /* PHY layer timed-out, need to clear the call */
 921                 ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Failed to Wake-Up line (suId:%d suInstId:%u spInstId:%u)\n",
 922                                           signal_data->cc_id, sngisdn_info->glare.spInstId, sngisdn_info->glare.suInstId);
 923 
 924                 ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NO_ROUTE_DESTINATION;
 925                 ftdm_clear_flag(sngisdn_info, FLAG_ACTIVATING);
 926                 ftdm_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
 927                 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
 928         }       
 929         ftdm_mutex_unlock(ftdmchan->mutex);
 930 }
 931 
 932 void sngisdn_delayed_setup(void* p_sngisdn_info)
 933 {
 934         sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info;
 935         ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
 936 
 937         ftdm_mutex_lock(ftdmchan->mutex);
 938         sngisdn_snd_setup(ftdmchan);
 939         ftdm_mutex_unlock(ftdmchan->mutex);
 940         return;
 941 }
 942 
 943 void sngisdn_delayed_release(void* p_sngisdn_info)
 944 {
 945         sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info;       
 946         ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
 947         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;  
 948 
 949         ftdm_mutex_lock(ftdmchan->mutex);
 950         
 951         if (ftdm_test_flag(sngisdn_info, FLAG_DELAYED_REL)) {
 952                 ftdm_clear_flag(sngisdn_info, FLAG_DELAYED_REL);
 953                 ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending delayed RELEASE (suId:%d suInstId:%u spInstId:%u)\n",
 954                                                                 signal_data->cc_id, sngisdn_info->glare.spInstId, sngisdn_info->glare.suInstId);
 955 
 956                 sngisdn_snd_release(ftdmchan, 1);
 957                 clear_call_glare_data(sngisdn_info);
 958         } else {
 959                 ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Call was already released (suId:%d suInstId:%u spInstId:%u)\n",
 960                                                                 signal_data->cc_id, sngisdn_info->glare.spInstId, sngisdn_info->glare.suInstId);
 961         }
 962         ftdm_mutex_unlock(ftdmchan->mutex);
 963         return;
 964 }
 965 
 966 void sngisdn_delayed_connect(void* p_sngisdn_info)
 967 {
 968         sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info;       
 969         ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
 970         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;  
 971 
 972         ftdm_mutex_lock(ftdmchan->mutex);
 973         ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending delayed CONNECT (suId:%d suInstId:%u spInstId:%u)\n",
 974                                                                 signal_data->cc_id, sngisdn_info->glare.spInstId, sngisdn_info->glare.suInstId);
 975 
 976         sngisdn_snd_connect(ftdmchan);
 977         ftdm_mutex_unlock(ftdmchan->mutex);
 978         return;
 979 }
 980 
 981 void sngisdn_delayed_disconnect(void* p_sngisdn_info)
 982 {
 983         sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info;       
 984         ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
 985         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;  
 986 
 987         ftdm_mutex_lock(ftdmchan->mutex);
 988         if (ftdmchan->caller_data.hangup_cause == IN_CCNORTTODEST || ftdmchan->state != FTDM_CHANNEL_STATE_DOWN) {
 989                 ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending delayed DISCONNECT (suId:%d suInstId:%u spInstId:%u)\n",
 990                                                                         signal_data->cc_id, sngisdn_info->glare.spInstId, sngisdn_info->glare.suInstId);
 991 
 992                 sngisdn_snd_disconnect(ftdmchan);
 993                 if (ftdmchan->caller_data.hangup_cause == IN_CCNORTTODEST) {
 994                         ftdm_channel_t *close_chan = ftdmchan;
 995                         ftdm_channel_close(&close_chan);
 996                 }
 997         }
 998 
 999         ftdm_mutex_unlock(ftdmchan->mutex);
1000         return;
1001 }
1002 
1003 void sngisdn_facility_timeout(void* p_sngisdn_info)
1004 {
1005         sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info;
1006         ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
1007         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;  
1008 
1009         ftdm_mutex_lock(ftdmchan->mutex);
1010         if (ftdmchan->state == FTDM_CHANNEL_STATE_GET_CALLERID) {
1011                 ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Facility timeout reached proceeding with call (suId:%d suInstId:%u spInstId:%u)\n",
1012                                           signal_data->cc_id, sngisdn_info->spInstId, sngisdn_info->suInstId);
1013                 
1014                 ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
1015         }
1016         
1017         ftdm_mutex_unlock(ftdmchan->mutex);
1018         return;
1019 }
1020 
1021 ftdm_status_t sngisdn_check_free_ids(void)
1022 {
1023         unsigned i;
1024         unsigned j;
1025         ftdm_log(FTDM_LOG_INFO, "Checking suInstId's\n");
1026         for(j=1;j<=MAX_VARIANTS;j++) {
1027                 if (g_sngisdn_data.ccs[j].config_done) {
1028                         for(i=1;i<MAX_INSTID;i++) {
1029                                 if (g_sngisdn_data.ccs[j].active_suInstIds[i] != NULL) {
1030                                         ftdm_log(FTDM_LOG_INFO, "suId:%u suInstId:%u is not free\n", j, i);
1031                                         
1032 
1033                                 }
1034                         }
1035                 }
1036         }
1037 
1038         ftdm_log(FTDM_LOG_INFO, "Checking spInstId's\n");
1039         for(j=1;j<=MAX_VARIANTS;j++) {
1040                 if (g_sngisdn_data.ccs[j].config_done) {
1041                         for(i=1;i<MAX_INSTID;i++) {
1042                                 if (g_sngisdn_data.ccs[j].active_spInstIds[i] != NULL) {
1043                                         ftdm_log(FTDM_LOG_INFO, "suId:%u spInstId:%u is not free\n", j, i);
1044                                         
1045 
1046                                 }
1047                         }
1048                 }
1049         }
1050         ftdm_log(FTDM_LOG_INFO, "Checking ID's done\n");
1051         return FTDM_SUCCESS;
1052 }
1053 
1054 void get_memory_info(void)
1055 {
1056         U32 availmen = 0;
1057         SRegInfoShow(S_REG, &availmen);
1058         return;
1059 }
1060 
1061 uint8_t sngisdn_get_infoTranCap_from_user(ftdm_bearer_cap_t bearer_capability)
1062 {
1063         switch(bearer_capability) {
1064         case FTDM_BEARER_CAP_SPEECH:
1065                 return IN_ITC_SPEECH;
1066         case FTDM_BEARER_CAP_64K_UNRESTRICTED:
1067                 return IN_ITC_UNRDIG;
1068         case FTDM_BEARER_CAP_3_1KHZ_AUDIO:
1069                 return IN_ITC_A31KHZ;
1070         case FTDM_BEARER_CAP_INVALID:
1071                 return IN_ITC_SPEECH;
1072                 /* Do not put a default case here, so we can see compile warnings if we have unhandled cases */
1073         }
1074         return FTDM_BEARER_CAP_SPEECH;
1075 }
1076 
1077 uint8_t sngisdn_get_usrInfoLyr1Prot_from_user(ftdm_user_layer1_prot_t layer1_prot)
1078 {
1079         switch(layer1_prot) {
1080         case FTDM_USER_LAYER1_PROT_V110:
1081                 return IN_UIL1_CCITTV110;
1082         case FTDM_USER_LAYER1_PROT_ULAW:
1083                 return IN_UIL1_G711ULAW;
1084         case FTDM_USER_LAYER1_PROT_ALAW:
1085                 return IN_UIL1_G711ALAW;
1086         case FTDM_USER_LAYER1_PROT_INVALID:
1087                 return IN_UIL1_G711ULAW;
1088         /* Do not put a default case here, so we can see compile warnings if we have unhandled cases */
1089         }
1090         return IN_UIL1_G711ULAW;
1091 }
1092 
1093 ftdm_bearer_cap_t sngisdn_get_infoTranCap_from_stack(uint8_t bearer_capability)
1094 {
1095         switch(bearer_capability) {
1096         case IN_ITC_SPEECH:
1097                 return FTDM_BEARER_CAP_SPEECH;          
1098         case IN_ITC_UNRDIG:
1099                 return FTDM_BEARER_CAP_64K_UNRESTRICTED;                
1100         case IN_ITC_A31KHZ:
1101                 return FTDM_BEARER_CAP_3_1KHZ_AUDIO;
1102         default:
1103                 return FTDM_BEARER_CAP_SPEECH;
1104         }
1105         return FTDM_BEARER_CAP_SPEECH;
1106 }
1107 
1108 ftdm_user_layer1_prot_t sngisdn_get_usrInfoLyr1Prot_from_stack(uint8_t layer1_prot)
1109 {
1110         switch(layer1_prot) {
1111         case IN_UIL1_CCITTV110:
1112                 return FTDM_USER_LAYER1_PROT_V110;
1113         case IN_UIL1_G711ULAW:
1114                 return FTDM_USER_LAYER1_PROT_ULAW;
1115         case IN_UIL1_G711ALAW:
1116                 return IN_UIL1_G711ALAW;
1117         default:
1118                 return FTDM_USER_LAYER1_PROT_ULAW;
1119         }
1120         return FTDM_USER_LAYER1_PROT_ULAW;
1121 }
1122 
1123 void sngisdn_print_phy_stats(ftdm_stream_handle_t *stream, ftdm_span_t *span)
1124 {
1125         L1Mngmt sts;
1126         sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
1127 
1128         memset(&sts, 0, sizeof(sts));
1129         sng_isdn_phy_stats(signal_data->link_id , &sts);
1130 
1131         stream->write_function(stream, "\n---------------------------------------------------------------------\n");
1132         stream->write_function(stream, "   Span:%s", span->name);
1133         stream->write_function(stream, "\n---------------------------------------------------------------------\n");
1134         stream->write_function(stream, "   Performance Counters");
1135         stream->write_function(stream, "\n---------------------------------------------------------------------\n");
1136         stream->write_function(stream, "RX Packets:\t%u\tTX Packets:\t%u\tEvents:%u\n", sts.t.sts.rx_packets, sts.t.sts.tx_packets, sts.t.sts.rx_events);
1137         stream->write_function(stream, "RX Bytes:\t%u\tTX Bytes:\t%u\n\n", sts.t.sts.rx_bytes, sts.t.sts.tx_bytes);
1138         stream->write_function(stream, "TX Queue:\t%u/%u\tRX Queue:\t%u/%u\tEvents Queue:\t%u/%u\n",
1139                                                         sts.t.sts.num_frames_in_tx_queue,sts.t.sts.tx_queue_len,
1140                                                         sts.t.sts.num_frames_in_rx_queue, sts.t.sts.rx_queue_len,
1141                                                         sts.t.sts.rx_events_in_queue, sts.t.sts.event_queue_len);
1142         
1143         stream->write_function(stream, "\n---------------------------------------------------------------------\n");
1144         stream->write_function(stream, "   Errors");
1145         stream->write_function(stream, "\n---------------------------------------------------------------------\n");
1146         stream->write_function(stream, "RX Errors:\t%u\tTX Errors:\t%u\n", sts.t.sts.rx_errors, sts.t.sts.tx_errors);
1147         stream->write_function(stream, "RX Dropped:\t%u\tTX Dropped:\t%u\tEvents Dropped:\t%u\n", sts.t.sts.rx_dropped, sts.t.sts.tx_dropped,sts.t.sts.rx_events_dropped);
1148 
1149 
1150         stream->write_function(stream, "\n---------------------------------------------------------------------\n");
1151         stream->write_function(stream, "   RX Errors Details");
1152         stream->write_function(stream, "\n---------------------------------------------------------------------\n");
1153         stream->write_function(stream, "CRC:\t\t%u\tFrame:\t\t%u\tOverruns:\t%u\n", sts.t.sts.rx_crc_errors, sts.t.sts.rx_frame_errors, sts.t.sts.rx_over_errors);
1154         stream->write_function(stream, "Fifo:\t\t%u\tAborts:\t\t%u\tMissed:\t\t%u\n", sts.t.sts.rx_fifo_errors, sts.t.sts.rx_hdlc_abort_counter, sts.t.sts.rx_missed_errors);
1155         stream->write_function(stream, "Length:\t\t%u\n", sts.t.sts.rx_length_errors);
1156 
1157         stream->write_function(stream, "\n---------------------------------------------------------------------\n");
1158         stream->write_function(stream, "   TX Errors Details");
1159         stream->write_function(stream, "\n---------------------------------------------------------------------\n");
1160         stream->write_function(stream, "Aborted:\t%u\tFifo:\t\t%u\tCarrier:\t%u\n", sts.t.sts.tx_aborted_errors, sts.t.sts.tx_fifo_errors, sts.t.sts.tx_carrier_errors);
1161         return;
1162 }
1163 
1164 
1165 void sngisdn_print_span(ftdm_stream_handle_t *stream, ftdm_span_t *span)
1166 {
1167         ftdm_signaling_status_t sigstatus;
1168         ftdm_alarm_flag_t alarmbits;
1169         ftdm_channel_t *fchan;
1170         alarmbits = FTDM_ALARM_NONE;
1171         fchan = ftdm_span_get_channel(span, 1);
1172         if (fchan) {
1173                 ftdm_channel_get_alarms(fchan, &alarmbits);
1174         }
1175                         
1176         ftdm_span_get_sig_status(span, &sigstatus);
1177         stream->write_function(stream, "span:%s physical:%s signalling:%s\n",
1178                                                                                 span->name, alarmbits ? "ALARMED" : "OK",
1179                                                                                 ftdm_signaling_status2str(sigstatus));
1180         return;
1181 }
1182 
1183 void sngisdn_print_spans(ftdm_stream_handle_t *stream)
1184 {
1185         int i;  
1186         for(i=1;i<=MAX_L1_LINKS;i++) {          
1187                 if (g_sngisdn_data.spans[i]) {
1188                         sngisdn_print_span(stream, g_sngisdn_data.spans[i]->ftdm_span);
1189                 }
1190         }
1191         return;
1192 }
1193 
1194 /* For Emacs:
1195  * Local Variables:
1196  * mode:c
1197  * indent-tabs-mode:t
1198  * tab-width:4
1199  * c-basic-offset:4
1200  * End:
1201  * For VIM:
1202  * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
1203  */
1204 
1205 /******************************************************************************/

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