freetdmvar = switch_channel_get_variable(channel, "freetdm_bearer_capability");
if (freetdmvar) {
caller_data.bearer_capability = (uint8_t)atoi(freetdmvar);
+ } else {
+ caller_data.bearer_capability = FTDM_INVALID_INT_PARM;
}
freetdmvar = switch_channel_get_variable(channel, "freetdm_bearer_layer1");
if (freetdmvar) {
caller_data.bearer_layer1 = (uint8_t)atoi(freetdmvar);
+ } else {
+ caller_data.bearer_layer1 = FTDM_INVALID_INT_PARM;
}
}
return FTDM_SUCCESS;
}
+FT_DECLARE(ftdm_status_t) ftdm_span_set_bearer_capability(const char *bc_string, ftdm_bearer_cap_t *target)
+{
+ if (!strcasecmp(bc_string, "speech")) {
+ *target = FTDM_BEARER_CAP_SPEECH;
+ } else if (!strcasecmp(bc_string, "unrestricted-digital")) {
+ *target = FTDM_BEARER_CAP_64K_UNRESTRICTED;
+ } else if (!strcasecmp(bc_string, "3.1Khz")) {
+ *target = FTDM_BEARER_CAP_3_1KHZ_AUDIO;
+ } else {
+ ftdm_log(FTDM_LOG_WARNING, "Unsupported Bearer Capability value (%s)\n", bc_string);
+ return FTDM_FAIL;
+ }
+ return FTDM_SUCCESS;
+}
+
+FT_DECLARE(ftdm_status_t) ftdm_span_set_bearer_layer1(const char *bc_string, ftdm_user_layer1_prot_t *target)
+{
+ if (!strcasecmp(bc_string, "v110")) {
+ *target = FTDM_USER_LAYER1_PROT_V110;
+ } else if (!strcasecmp(bc_string, "ulaw")) {
+ *target = FTDM_USER_LAYER1_PROT_ULAW;
+ } else if (!strcasecmp(bc_string, "alaw")) {
+ *target =FTDM_USER_LAYER1_PROT_ALAW ;
+ } else {
+ ftdm_log(FTDM_LOG_WARNING, "Unsupported Bearer Layer1 Prot value (%s)\n", bc_string);
+ return FTDM_FAIL;
+ }
+ return FTDM_SUCCESS;
+}
+
+
FT_DECLARE(ftdm_status_t) ftdm_is_number(char *number)
{
if (!number) {
caller_data->rdnis.type = span->default_caller_data.rdnis.type;
}
+ if (caller_data->bearer_capability == FTDM_INVALID_INT_PARM) {
+ caller_data->bearer_capability = span->default_caller_data.bearer_capability;
+ }
+
+ if (caller_data->bearer_layer1 == FTDM_INVALID_INT_PARM) {
+ caller_data->bearer_layer1 = span->default_caller_data.bearer_layer1;
+ }
+
if (FTDM_FAIL == ftdm_is_number(caller_data->cid_num.digits)) {
ftdm_log(FTDM_LOG_DEBUG, "dropping caller id number %s since we only accept digits\n", caller_data->cid_num.digits);
caller_data->cid_num.digits[0] = '\0';
void sngisdn_rcv_sng_log(uint8_t level, char *fmt,...);
void sngisdn_rcv_sng_assert(char *message);
+uint8_t sngisdn_get_infoTranCap_from_stack(ftdm_bearer_cap_t bearer_capability);
+uint8_t sngisdn_get_usrInfoLyr1Prot_from_stack(ftdm_user_layer1_prot_t layer1_prot);
+ftdm_bearer_cap_t sngisdn_get_infoTranCap_from_user(uint8_t bearer_capability);
+ftdm_user_layer1_prot_t sngisdn_get_usrInfoLyr1Prot_from_user(uint8_t layer1_prot);
+
static __inline__ uint32_t sngisdn_test_flag(sngisdn_chan_data_t *sngisdn_info, sngisdn_flag_t flag)
{
return (uint32_t) sngisdn_info->flags & flag;
signal_data->overlap_dial = SNGISDN_OPT_DEFAULT;
signal_data->setup_arb = SNGISDN_OPT_DEFAULT;
+ span->default_caller_data.bearer_capability = IN_ITC_SPEECH;
+
+ /* Cannot set default bearer_layer1 yet, as we do not know the switchtype */
+ span->default_caller_data.bearer_layer1 = FTDM_INVALID_INT_PARM;
+
if (span->trunk_type == FTDM_TRUNK_BRI ||
span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
ftdm_span_set_ton(val, &span->default_caller_data.rdnis.type);
} else if (!strcasecmp(var, "outbound-rdnis-npi")) {
ftdm_span_set_npi(val, &span->default_caller_data.rdnis.plan);
+ } else if (!strcasecmp(var, "outbound-bearer_cap")) {
+ ftdm_span_set_bearer_capability(val, &span->default_caller_data.bearer_capability);
+ } else if (!strcasecmp(var, "outbound-bearer_layer1")) {
+ ftdm_span_set_bearer_layer1(val, &span->default_caller_data.bearer_layer1);
} else {
ftdm_log(FTDM_LOG_WARNING, "Ignoring unknown parameter %s\n", ftdm_parameters[paramindex].var);
}
ftdm_log(FTDM_LOG_ERROR, "%s: signalling not specified", span->name);
return FTDM_FAIL;
}
+
+ if (span->default_caller_data.bearer_layer1 == FTDM_INVALID_INT_PARM) {
+ if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN) {
+ span->default_caller_data.bearer_layer1 = IN_UIL1_G711ULAW;
+ } else {
+ span->default_caller_data.bearer_layer1 = IN_UIL1_G711ALAW;
+ }
+ }
return FTDM_SUCCESS;
}
#include "ftmod_sangoma_isdn.h"
-extern ftdm_status_t cpy_calling_num_from_sngisdn(ftdm_caller_data_t *ftdm, CgPtyNmb *cgPtyNmb);
-extern ftdm_status_t cpy_called_num_from_sngisdn(ftdm_caller_data_t *ftdm, CdPtyNmb *cdPtyNmb);
-extern ftdm_status_t cpy_redir_num_from_sngisdn(ftdm_caller_data_t *ftdm, RedirNmb *redirNmb);
-extern ftdm_status_t cpy_calling_name_from_sngisdn(ftdm_caller_data_t *ftdm, Display *display);
+extern ftdm_status_t cpy_calling_num_from_stack(ftdm_caller_data_t *ftdm, CgPtyNmb *cgPtyNmb);
+extern ftdm_status_t cpy_called_num_from_stack(ftdm_caller_data_t *ftdm, CdPtyNmb *cdPtyNmb);
+extern ftdm_status_t cpy_redir_num_from_stack(ftdm_caller_data_t *ftdm, RedirNmb *redirNmb);
+extern ftdm_status_t cpy_calling_name_from_stack(ftdm_caller_data_t *ftdm, Display *display);
/* Remote side transmit a SETUP */
void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
break;
}
/* Fill in call information */
- cpy_calling_num_from_sngisdn(&ftdmchan->caller_data, &conEvnt->cgPtyNmb);
- cpy_called_num_from_sngisdn(&ftdmchan->caller_data, &conEvnt->cdPtyNmb);
- cpy_calling_name_from_sngisdn(&ftdmchan->caller_data, &conEvnt->display);
+ cpy_calling_num_from_stack(&ftdmchan->caller_data, &conEvnt->cgPtyNmb);
+ cpy_called_num_from_stack(&ftdmchan->caller_data, &conEvnt->cdPtyNmb);
+ cpy_calling_name_from_stack(&ftdmchan->caller_data, &conEvnt->display);
+ if (conEvnt->bearCap[0].eh.pres) {
+ ftdmchan->caller_data.bearer_layer1 = sngisdn_get_infoTranCap_from_stack(conEvnt->bearCap[0].usrInfoLyr1Prot.val);
+ ftdmchan->caller_data.bearer_capability = sngisdn_get_infoTranCap_from_stack(conEvnt->bearCap[0].infoTranCap.val);
+ }
if (signal_data->switchtype == SNGISDN_SWITCH_NI2) {
if (conEvnt->shift11.eh.pres && conEvnt->ni2OctStr.eh.pres) {
ftdm_size_t min_digits = ((sngisdn_span_data_t*)ftdmchan->span->signal_data)->min_digits;
ftdm_size_t num_digits;
- cpy_called_num_from_sngisdn(&ftdmchan->caller_data, &cnStEvnt->cdPtyNmb);
+ cpy_called_num_from_stack(&ftdmchan->caller_data, &cnStEvnt->cdPtyNmb);
num_digits = strlen(ftdmchan->caller_data.dnis.digits);
if (cnStEvnt->sndCmplt.eh.pres || num_digits >= min_digits) {
switch (ftdmchan->state) {
case FTDM_CHANNEL_STATE_GET_CALLERID:
/* Update the caller ID Name */
-#if 1
if (facEvnt->facElmt.facStr.pres) {
uint8_t facility_str[255];
memcpy(facility_str, (uint8_t*)&facEvnt->facElmt.facStr.val, facEvnt->facElmt.facStr.len);
if (sng_isdn_retrieve_facility_caller_name(facility_str, facEvnt->facElmt.facStr.len, retrieved_str) != FTDM_SUCCESS) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Failed to retrieve Caller Name from Facility IE\n");
}
- ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "DYDBG Name is:%s\n", retrieved_str);
}
-#endif
-
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
break;
default:
#include "ftmod_sangoma_isdn.h"
-extern ftdm_status_t cpy_calling_num_to_sngisdn(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *ftdm);
-extern ftdm_status_t cpy_called_num_to_sngisdn(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *ftdm);
-extern ftdm_status_t cpy_calling_name_to_sngisdn(ConEvnt *conEvnt, ftdm_channel_t *ftdmchan);
+extern ftdm_status_t cpy_calling_num_from_user(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *ftdm);
+extern ftdm_status_t cpy_called_num_from_user(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *ftdm);
+extern ftdm_status_t cpy_calling_name_from_user(ConEvnt *conEvnt, ftdm_channel_t *ftdmchan);
void sngisdn_snd_setup(ftdm_channel_t *ftdmchan);
void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan);
ftdm_mutex_unlock(g_sngisdn_data.ccs[signal_data->cc_id].mutex);
memset(&conEvnt, 0, sizeof(conEvnt));
-
+
conEvnt.bearCap[0].eh.pres = PRSNT_NODEF;
conEvnt.bearCap[0].infoTranCap.pres = PRSNT_NODEF;
-
- conEvnt.bearCap[0].infoTranCap.val = IN_ITC_SPEECH;
+ conEvnt.bearCap[0].infoTranCap.val = sngisdn_get_infoTranCap_from_user(ftdmchan->caller_data.bearer_capability);
conEvnt.bearCap[0].codeStand0.pres = PRSNT_NODEF;
conEvnt.bearCap[0].codeStand0.val = IN_CSTD_CCITT;
conEvnt.chanId.infoChanSel.val = ftdmchan->physical_chan_id;
} else {
/* PRI only params */
-
- if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN) {
- conEvnt.bearCap[0].usrInfoLyr1Prot.pres = PRSNT_NODEF;
+ conEvnt.bearCap[0].usrInfoLyr1Prot.pres = PRSNT_NODEF;
+ conEvnt.bearCap[0].usrInfoLyr1Prot.val = sngisdn_get_usrInfoLyr1Prot_from_user(ftdmchan->caller_data.bearer_layer1);
+
+ if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN &&
+ conEvnt.bearCap[0].usrInfoLyr1Prot.val == IN_UIL1_G711ULAW) {
+
+ /* We are bridging a call from T1 */
conEvnt.bearCap[0].usrInfoLyr1Prot.val = IN_UIL1_G711ALAW;
- } else {
- conEvnt.bearCap[0].usrInfoLyr1Prot.pres = PRSNT_NODEF;
+
+ } else if (conEvnt.bearCap[0].usrInfoLyr1Prot.val == IN_UIL1_G711ALAW) {
+
+ /* We are bridging a call from E1 */
conEvnt.bearCap[0].usrInfoLyr1Prot.val = IN_UIL1_G711ULAW;
}
+
conEvnt.bearCap[0].lyr1Ident.pres = PRSNT_NODEF;
conEvnt.bearCap[0].lyr1Ident.val = IN_L1_IDENT;
sngisdn_info->ces = CES_MNGMNT;
}
- cpy_called_num_to_sngisdn(&conEvnt.cdPtyNmb, &ftdmchan->caller_data);
- cpy_calling_num_to_sngisdn(&conEvnt.cgPtyNmb, &ftdmchan->caller_data);
- cpy_calling_name_to_sngisdn(&conEvnt, ftdmchan);
+ cpy_called_num_from_user(&conEvnt.cdPtyNmb, &ftdmchan->caller_data);
+ cpy_calling_num_from_user(&conEvnt.cgPtyNmb, &ftdmchan->caller_data);
+ cpy_calling_name_from_user(&conEvnt, ftdmchan);
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);
#include "ftmod_sangoma_isdn.h"
-ftdm_status_t cpy_calling_num_from_sngisdn(ftdm_caller_data_t *ftdm, CgPtyNmb *cgPtyNmb);
-ftdm_status_t cpy_called_num_from_sngisdn(ftdm_caller_data_t *ftdm, CdPtyNmb *cdPtyNmb);
-ftdm_status_t cpy_redir_num_from_sngisdn(ftdm_caller_data_t *ftdm, RedirNmb *redirNmb);
-ftdm_status_t cpy_calling_name_from_sngisdn(ftdm_caller_data_t *ftdm, Display *display);
+ftdm_status_t cpy_calling_num_from_stack(ftdm_caller_data_t *ftdm, CgPtyNmb *cgPtyNmb);
+ftdm_status_t cpy_called_num_from_stack(ftdm_caller_data_t *ftdm, CdPtyNmb *cdPtyNmb);
+ftdm_status_t cpy_redir_num_from_stack(ftdm_caller_data_t *ftdm, RedirNmb *redirNmb);
+ftdm_status_t cpy_calling_name_from_stack(ftdm_caller_data_t *ftdm, Display *display);
-ftdm_status_t cpy_calling_num_to_sngisdn(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *ftdm);
-ftdm_status_t cpy_called_num_to_sngisdn(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *ftdm);
-ftdm_status_t cpy_redir_num_to_sngisdn(RedirNmb *redirNmb, ftdm_caller_data_t *ftdm);
-ftdm_status_t cpy_calling_name_to_sngisdn(ConEvnt *conEvnt, ftdm_channel_t *ftdmchan);
+ftdm_status_t cpy_calling_num_from_user(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *ftdm);
+ftdm_status_t cpy_called_num_from_user(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *ftdm);
+ftdm_status_t cpy_redir_num_from_user(RedirNmb *redirNmb, ftdm_caller_data_t *ftdm);
+ftdm_status_t cpy_calling_name_from_user(ConEvnt *conEvnt, ftdm_channel_t *ftdmchan);
ftdm_status_t sngisdn_check_free_ids(void);
return FTDM_SUCCESS;
}
-ftdm_status_t cpy_calling_num_from_sngisdn(ftdm_caller_data_t *ftdm, CgPtyNmb *cgPtyNmb)
+ftdm_status_t cpy_calling_num_from_stack(ftdm_caller_data_t *ftdm, CgPtyNmb *cgPtyNmb)
{
if (cgPtyNmb->eh.pres != PRSNT_NODEF) {
return FTDM_FAIL;
return FTDM_SUCCESS;
}
-ftdm_status_t cpy_called_num_from_sngisdn(ftdm_caller_data_t *ftdm, CdPtyNmb *cdPtyNmb)
+ftdm_status_t cpy_called_num_from_stack(ftdm_caller_data_t *ftdm, CdPtyNmb *cdPtyNmb)
{
if (cdPtyNmb->eh.pres != PRSNT_NODEF) {
return FTDM_FAIL;
return FTDM_SUCCESS;
}
-ftdm_status_t cpy_redir_num_from_sngisdn(ftdm_caller_data_t *ftdm, RedirNmb *redirNmb)
+ftdm_status_t cpy_redir_num_from_stack(ftdm_caller_data_t *ftdm, RedirNmb *redirNmb)
{
if (redirNmb->eh.pres != PRSNT_NODEF) {
return FTDM_FAIL;
return FTDM_SUCCESS;
}
-ftdm_status_t cpy_calling_name_from_sngisdn(ftdm_caller_data_t *ftdm, Display *display)
+ftdm_status_t cpy_calling_name_from_stack(ftdm_caller_data_t *ftdm, Display *display)
{
if (display->eh.pres != PRSNT_NODEF) {
return FTDM_FAIL;
return FTDM_SUCCESS;
}
-ftdm_status_t cpy_calling_num_to_sngisdn(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *ftdm)
+ftdm_status_t cpy_calling_num_from_user(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *ftdm)
{
uint8_t len = strlen(ftdm->cid_num.digits);
if (!len) {
return FTDM_SUCCESS;
}
-ftdm_status_t cpy_called_num_to_sngisdn(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *ftdm)
+ftdm_status_t cpy_called_num_from_user(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *ftdm)
{
uint8_t len = strlen(ftdm->dnis.digits);
if (!len) {
return FTDM_SUCCESS;
}
-ftdm_status_t cpy_redir_num_to_sngisdn(RedirNmb *redirNmb, ftdm_caller_data_t *ftdm)
+ftdm_status_t cpy_redir_num_from_user(RedirNmb *redirNmb, ftdm_caller_data_t *ftdm)
{
uint8_t len = strlen(ftdm->rdnis.digits);
if (!len) {
}
-ftdm_status_t cpy_calling_name_to_sngisdn(ConEvnt *conEvnt, ftdm_channel_t *ftdmchan)
+ftdm_status_t cpy_calling_name_from_user(ConEvnt *conEvnt, ftdm_channel_t *ftdmchan)
{
uint8_t len;
ftdm_caller_data_t *ftdm = &ftdmchan->caller_data;
signal_data->cc_id, sngisdn_info->glare.spInstId, sngisdn_info->glare.suInstId);
sngisdn_snd_release(ftdmchan, 1);
-#if 1 /* TODO: Confirm this */
clear_call_glare_data(sngisdn_info);
-#else
- g_sngisdn_data.ccs[signal_data->cc_id].active_spInstIds[sngisdn_info->glare.spInstId] = NULL;
- g_sngisdn_data.ccs[signal_data->cc_id].active_suInstIds[sngisdn_info->glare.suInstId] = NULL;
-#endif
-
} else {
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Call was already released (suId:%d suInstId:%u spInstId:%u)\n",
signal_data->cc_id, sngisdn_info->glare.spInstId, sngisdn_info->glare.suInstId);
return;
}
+uint8_t sngisdn_get_infoTranCap_from_stack(ftdm_bearer_cap_t bearer_capability)
+{
+ switch(bearer_capability) {
+ case FTDM_BEARER_CAP_SPEECH:
+ return IN_ITC_SPEECH;
+
+ case FTDM_BEARER_CAP_64K_UNRESTRICTED:
+ return IN_ITC_UNRDIG;
+
+ case FTDM_BEARER_CAP_3_1KHZ_AUDIO:
+ return IN_ITC_A31KHZ;
+
+ /* Do not put a default case here, so we can see compile warnings if we have unhandled cases */
+ }
+ return FTDM_BEARER_CAP_SPEECH;
+}
+
+uint8_t sngisdn_get_usrInfoLyr1Prot_from_stack(ftdm_user_layer1_prot_t layer1_prot)
+{
+ switch(layer1_prot) {
+ case FTDM_USER_LAYER1_PROT_V110:
+ return IN_UIL1_CCITTV110;
+
+ case FTDM_USER_LAYER1_PROT_ULAW:
+ return IN_UIL1_G711ULAW;
+
+ case FTDM_USER_LAYER1_PROT_ALAW:
+ return IN_UIL1_G711ALAW;
+
+ /* Do not put a default case here, so we can see compile warnings if we have unhandled cases */
+ }
+ return IN_UIL1_G711ULAW;
+}
+
+ftdm_bearer_cap_t sngisdn_get_infoTranCap_from_user(uint8_t bearer_capability)
+{
+ switch(bearer_capability) {
+ case IN_ITC_SPEECH:
+ return FTDM_BEARER_CAP_SPEECH;
+
+ case IN_ITC_UNRDIG:
+ return FTDM_BEARER_CAP_64K_UNRESTRICTED;
+
+ case IN_ITC_A31KHZ:
+ return FTDM_BEARER_CAP_3_1KHZ_AUDIO;
+
+ default:
+ return FTDM_BEARER_CAP_SPEECH;
+ }
+ return FTDM_BEARER_CAP_SPEECH;
+}
+
+ftdm_user_layer1_prot_t sngisdn_get_usrInfoLyr1Prot_from_user(uint8_t layer1_prot)
+{
+ switch(layer1_prot) {
+ case IN_UIL1_CCITTV110:
+ return FTDM_USER_LAYER1_PROT_V110;
+ case IN_UIL1_G711ULAW:
+ return FTDM_USER_LAYER1_PROT_ULAW;
+ case IN_UIL1_G711ALAW:
+ return IN_UIL1_G711ALAW;
+ default:
+ return FTDM_USER_LAYER1_PROT_ULAW;
+ }
+ return FTDM_USER_LAYER1_PROT_ULAW;
+}
/* For Emacs:
* Local Variables:
/*! \brief Max number of groups */
#define FTDM_MAX_GROUPS_INTERFACE FTDM_MAX_SPANS_INTERFACE
+#define FTDM_INVALID_INT_PARM 0xFF
+
/*! \brief FreeTDM APIs possible return codes */
typedef enum {
FTDM_SUCCESS, /*!< Success */
ftdm_queue_destroy_func_t destroy;
} ftdm_queue_handler_t;
+
/*! \brief Type Of Number (TON) */
typedef enum {
FTDM_TON_UNKNOWN = 0,
FT_DECLARE(ftdm_status_t) ftdm_span_set_npi(const char *npi_string, uint8_t *target);
FT_DECLARE(ftdm_status_t) ftdm_span_set_ton(const char *ton_string, uint8_t *target);
+FT_DECLARE(ftdm_status_t) ftdm_span_set_bearer_capability(const char *bc_string, ftdm_bearer_cap_t *target);
+FT_DECLARE(ftdm_status_t) ftdm_span_set_bearer_layer1(const char *bc_string, ftdm_user_layer1_prot_t *target);
FT_DECLARE(ftdm_status_t) ftdm_is_number(char *number);
#endif /* __FTDM_CALL_UTILS_H__ */