1053 lines
34 KiB
C
1053 lines
34 KiB
C
/*
|
|
* Copyright (c) 2009, Konrad Hammel <konrad@sangoma.com>
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
*
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* * Neither the name of the original author; nor the names of any contributors
|
|
* may be used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
*
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
|
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
/* INCLUDE ********************************************************************/
|
|
#include "ftmod_sangoma_ss7_main.h"
|
|
/******************************************************************************/
|
|
|
|
/* DEFINES ********************************************************************/
|
|
#define SNGSS7_EVNTINFO_IND_INBAND_AVAIL 0x03
|
|
/******************************************************************************/
|
|
|
|
/* GLOBALS ********************************************************************/
|
|
|
|
/* FUNCTIONS ******************************************************************/
|
|
void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
|
|
{
|
|
const char *var = NULL;
|
|
SiConEvnt iam;
|
|
ftdm_bool_t native_going_up = FTDM_FALSE;
|
|
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;;
|
|
sngss7_event_data_t *event_clone = NULL;
|
|
|
|
SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__);
|
|
|
|
sngss7_info->suInstId = get_unique_id ();
|
|
sngss7_info->spInstId = 0;
|
|
sngss7_info->spId = 1;
|
|
|
|
memset (&iam, 0x0, sizeof (iam));
|
|
|
|
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE)) {
|
|
ftdm_span_t *peer_span = NULL;
|
|
ftdm_channel_t *peer_chan = NULL;
|
|
sngss7_chan_data_t *peer_info = NULL;
|
|
|
|
var = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "sigbridge_peer");
|
|
ftdm_get_channel_from_string(var, &peer_span, &peer_chan);
|
|
if (!peer_chan) {
|
|
SS7_ERROR_CHAN(ftdmchan, "Failed to find sigbridge peer from string '%s'\n", var);
|
|
} else {
|
|
if (peer_span->signal_type != FTDM_SIGTYPE_SS7) {
|
|
SS7_ERROR_CHAN(ftdmchan, "Peer channel '%s' has different signaling type %d'\n",
|
|
var, peer_span->signal_type);
|
|
} else {
|
|
peer_info = peer_chan->call_data;
|
|
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Starting native bridge with peer CIC %d\n",
|
|
sngss7_info->circuit->cic, peer_info->circuit->cic);
|
|
|
|
/* retrieve only first message from the others guys queue (must be IAM) */
|
|
event_clone = ftdm_queue_dequeue(peer_info->event_queue);
|
|
|
|
/* make each one of us aware of the native bridge */
|
|
peer_info->peer_data = sngss7_info;
|
|
sngss7_info->peer_data = peer_info;
|
|
|
|
/* Go to up until release comes, note that state processing is done different and much simpler when there is a peer,
|
|
We can't go to UP state right away yet though, so do not set the state to UP here, wait until the end of this function
|
|
because moving from one state to another causes the ftdmchan->usrmsg structure to be wiped
|
|
and we still need those variables for further IAM processing */
|
|
native_going_up = FTDM_TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE)) {
|
|
if (!event_clone) {
|
|
SS7_ERROR_CHAN(ftdmchan, "No IAM event clone in peer queue!%s\n", "");
|
|
} else if (event_clone->event_id != SNGSS7_CON_IND_EVENT) {
|
|
/* first message in the queue should ALWAYS be an IAM */
|
|
SS7_ERROR_CHAN(ftdmchan, "Invalid initial peer message type '%d'\n", event_clone->event_id);
|
|
} else {
|
|
ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
|
|
|
|
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged, dialing %s)\n", sngss7_info->circuit->cic, caller_data->dnis.digits);
|
|
|
|
/* copy original incoming IAM */
|
|
memcpy(&iam, &event_clone->event.siConEvnt, sizeof(iam));
|
|
|
|
/* Change DNIS to whatever was specified, do not change NADI or anything else! */
|
|
copy_tknStr_to_sngss7(caller_data->dnis.digits, &iam.cdPtyNum.addrSig, &iam.cdPtyNum.oddEven);
|
|
|
|
/* SPIROU certification hack
|
|
If the IAM already contain RDINF, just increment the count and set the RDNIS digits
|
|
otherwise, honor RDNIS and RDINF stuff coming from the user */
|
|
if (iam.redirInfo.eh.pres == PRSNT_NODEF) {
|
|
const char *val = NULL;
|
|
if (iam.redirInfo.redirCnt.pres) {
|
|
iam.redirInfo.redirCnt.val++;
|
|
SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged), redirect count incremented = %d\n", sngss7_info->circuit->cic, iam.redirInfo.redirCnt.val);
|
|
}
|
|
val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rdnis_digits");
|
|
if (!ftdm_strlen_zero(val)) {
|
|
SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged), found user supplied RDNIS digits = %s\n", sngss7_info->circuit->cic, val);
|
|
copy_tknStr_to_sngss7((char*)val, &iam.redirgNum.addrSig, &iam.redirgNum.oddEven);
|
|
} else {
|
|
SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged), not found user supplied RDNIS digits\n", sngss7_info->circuit->cic);
|
|
}
|
|
} else {
|
|
SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged), redirect info not present, attempting to copy user supplied values\n", sngss7_info->circuit->cic);
|
|
/* Redirecting Number */
|
|
copy_redirgNum_to_sngss7(ftdmchan, &iam.redirgNum);
|
|
|
|
/* Redirecting Information */
|
|
copy_redirgInfo_to_sngss7(ftdmchan, &iam.redirInfo);
|
|
}
|
|
|
|
if (iam.origCdNum.eh.pres != PRSNT_NODEF) {
|
|
/* Original Called Number */
|
|
copy_ocn_to_sngss7(ftdmchan, &iam.origCdNum);
|
|
}
|
|
copy_access_transport_to_sngss7(ftdmchan, &iam.accTrnspt);
|
|
}
|
|
} else if (sngss7_info->circuit->transparent_iam &&
|
|
sngss7_retrieve_iam(ftdmchan, &iam) == FTDM_SUCCESS) {
|
|
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Transparent)\n", sngss7_info->circuit->cic);
|
|
|
|
/* Called Number information */
|
|
copy_cdPtyNum_to_sngss7(ftdmchan, &iam.cdPtyNum);
|
|
|
|
/* Redirecting Number */
|
|
copy_redirgNum_to_sngss7(ftdmchan, &iam.redirgNum);
|
|
|
|
/* Redirecting Information */
|
|
copy_redirgInfo_to_sngss7(ftdmchan, &iam.redirInfo);
|
|
|
|
/* Location Number information */
|
|
copy_locPtyNum_to_sngss7(ftdmchan, &iam.cgPtyNum1);
|
|
|
|
/* Forward Call Indicators */
|
|
copy_fwdCallInd_to_sngss7(ftdmchan, &iam.fwdCallInd);
|
|
|
|
/* Original Called Number */
|
|
copy_ocn_to_sngss7(ftdmchan, &iam.origCdNum);
|
|
|
|
copy_access_transport_to_sngss7(ftdmchan, &iam.accTrnspt);
|
|
|
|
copy_NatureOfConnection_to_sngss7(ftdmchan, &iam.natConInd);
|
|
} else {
|
|
/* Nature of Connection Indicators */
|
|
copy_natConInd_to_sngss7(ftdmchan, &iam.natConInd);
|
|
|
|
/* Forward Call Indicators */
|
|
copy_fwdCallInd_to_sngss7(ftdmchan, &iam.fwdCallInd);
|
|
|
|
/* Transmission medium requirements */
|
|
copy_txMedReq_to_sngss7(ftdmchan, &iam.txMedReq);
|
|
|
|
if (SNGSS7_SWITCHTYPE_ANSI(g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType)) {
|
|
/* User Service Info A */
|
|
copy_usrServInfoA_to_sngss7(ftdmchan, &iam.usrServInfoA);
|
|
}
|
|
|
|
/* Called Number information */
|
|
copy_cdPtyNum_to_sngss7(ftdmchan, &iam.cdPtyNum);
|
|
|
|
/* Calling Number information */
|
|
copy_cgPtyNum_to_sngss7(ftdmchan, &iam.cgPtyNum);
|
|
|
|
/* Location Number information */
|
|
copy_locPtyNum_to_sngss7(ftdmchan, &iam.cgPtyNum1);
|
|
|
|
/* Generic Number information */
|
|
copy_genNmb_to_sngss7(ftdmchan, &iam.genNmb);
|
|
|
|
/* Calling Party's Category */
|
|
copy_cgPtyCat_to_sngss7(ftdmchan, &iam.cgPtyCat);
|
|
|
|
/* Redirecting Number */
|
|
copy_redirgNum_to_sngss7(ftdmchan, &iam.redirgNum);
|
|
|
|
/* Redirecting Information */
|
|
copy_redirgInfo_to_sngss7(ftdmchan, &iam.redirInfo);
|
|
|
|
/* Original Called Number */
|
|
copy_ocn_to_sngss7(ftdmchan, &iam.origCdNum);
|
|
|
|
/* Access Transport - old implementation, taking from channel variable of ss7_clg_subaddr */
|
|
copy_accTrnspt_to_sngss7(ftdmchan, &iam.accTrnspt);
|
|
|
|
/* Access Transport - taking from channel variable of ss7_access_transport_urlenc.
|
|
This will overwirte the IE value set be above old implementation.
|
|
*/
|
|
copy_access_transport_to_sngss7(ftdmchan, &iam.accTrnspt);
|
|
|
|
copy_NatureOfConnection_to_sngss7(ftdmchan, &iam.natConInd);
|
|
|
|
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM clg = \"%s\" (NADI=%d), cld = \"%s\" (NADI=%d), loc = %s (NADI=%d)\n",
|
|
sngss7_info->circuit->cic,
|
|
ftdmchan->caller_data.cid_num.digits,
|
|
iam.cgPtyNum.natAddrInd.val,
|
|
ftdmchan->caller_data.dnis.digits,
|
|
iam.cdPtyNum.natAddrInd.val,
|
|
ftdmchan->caller_data.loc.digits,
|
|
iam.cgPtyNum1.natAddrInd.val);
|
|
}
|
|
|
|
sng_cc_con_request (sngss7_info->spId,
|
|
sngss7_info->suInstId,
|
|
sngss7_info->spInstId,
|
|
sngss7_info->circuit->id,
|
|
&iam,
|
|
0);
|
|
|
|
if (native_going_up) {
|
|
/*
|
|
Note that this function (ft_to_sngss7_iam) is run within the main SS7 processing loop in
|
|
response to the DIALING state handler, we can set the state to UP here and that will
|
|
implicitly complete the DIALING state, but we *MUST* also advance the state handler
|
|
right away for a native bridge, otherwise, the processing state function (ftdm_sangoma_ss7_process_state_change)
|
|
will complete the state without having executed the handler for FTDM_CHANNEL_STATE_UP, and we won't notify
|
|
the user sending FTDM_SIGEVENT_UP which can cause the application to misbehave (ie, no audio) */
|
|
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP);
|
|
ftdm_channel_advance_states(ftdmchan);
|
|
}
|
|
|
|
ftdm_safe_free(event_clone);
|
|
|
|
SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__);
|
|
return;
|
|
}
|
|
|
|
void ft_to_sngss7_inf(ftdm_channel_t *ftdmchan, SiCnStEvnt *inr)
|
|
{
|
|
SiCnStEvnt evnt;
|
|
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
|
|
|
memset (&evnt, 0x0, sizeof (evnt));
|
|
|
|
evnt.infoInd.eh.pres = PRSNT_NODEF;
|
|
evnt.infoInd.cgPtyAddrRespInd.pres = PRSNT_NODEF;
|
|
evnt.infoInd.cgPtyCatRespInd.pres = PRSNT_NODEF;
|
|
|
|
evnt.infoInd.chrgInfoRespInd.pres = PRSNT_NODEF;
|
|
evnt.infoInd.chrgInfoRespInd.val = 0;
|
|
evnt.infoInd.solInfoInd.pres = PRSNT_NODEF;
|
|
evnt.infoInd.solInfoInd.val = 0;
|
|
evnt.infoInd.holdProvInd.pres = PRSNT_NODEF;
|
|
evnt.infoInd.holdProvInd.val = 0;
|
|
evnt.infoInd.spare.pres = PRSNT_NODEF;
|
|
evnt.infoInd.spare.val = 0;
|
|
|
|
if (inr->infoReqInd.eh.pres == PRSNT_NODEF) {
|
|
if ((inr->infoReqInd.holdingInd.pres == PRSNT_NODEF) && (inr->infoReqInd.holdingInd.val == HOLD_REQ)) {
|
|
SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Received INR requesting holding information. Holding is not supported in INF.\n", sngss7_info->circuit->cic);
|
|
}
|
|
if ((inr->infoReqInd.chrgInfoReqInd.pres == PRSNT_NODEF) && (inr->infoReqInd.chrgInfoReqInd.val == CHRGINFO_REQ)) {
|
|
SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Received INR requesting charging information. Charging is not supported in INF.\n", sngss7_info->circuit->cic);
|
|
}
|
|
if ((inr->infoReqInd.malCaIdReqInd.pres == PRSNT_NODEF) && (inr->infoReqInd.malCaIdReqInd.val == CHRGINFO_REQ)) {
|
|
SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Received INR requesting malicious call id. Malicious call id is not supported in INF.\n", sngss7_info->circuit->cic);
|
|
}
|
|
|
|
if ((inr->infoReqInd.cgPtyAdReqInd.pres == PRSNT_NODEF) && (inr->infoReqInd.cgPtyAdReqInd.val == CGPRTYADDREQ_REQ)) {
|
|
evnt.infoInd.cgPtyAddrRespInd.val=CGPRTYADDRESP_INCL;
|
|
copy_cgPtyNum_to_sngss7 (ftdmchan, &evnt.cgPtyNum);
|
|
} else {
|
|
evnt.infoInd.cgPtyAddrRespInd.val=CGPRTYADDRESP_NOTINCL;
|
|
}
|
|
|
|
if ((inr->infoReqInd.cgPtyCatReqInd.pres == PRSNT_NODEF) && (inr->infoReqInd.cgPtyCatReqInd.val == CGPRTYCATREQ_REQ)) {
|
|
evnt.infoInd.cgPtyCatRespInd.val = CGPRTYCATRESP_INCL;
|
|
copy_cgPtyCat_to_sngss7 (ftdmchan, &evnt.cgPtyCat);
|
|
} else {
|
|
evnt.infoInd.cgPtyCatRespInd.val = CGPRTYCATRESP_NOTINCL;
|
|
}
|
|
}
|
|
else {
|
|
SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Received INR with no information request. Sending back default INF.\n", sngss7_info->circuit->cic);
|
|
}
|
|
|
|
sng_cc_inf(1,
|
|
sngss7_info->suInstId,
|
|
sngss7_info->spInstId,
|
|
sngss7_info->circuit->id,
|
|
&evnt,
|
|
INFORMATION);
|
|
|
|
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx INF\n", sngss7_info->circuit->cic);
|
|
|
|
}
|
|
|
|
void ft_to_sngss7_inr(ftdm_channel_t *ftdmchan)
|
|
{
|
|
SiCnStEvnt evnt;
|
|
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
|
|
|
memset (&evnt, 0x0, sizeof (evnt));
|
|
|
|
evnt.infoReqInd.eh.pres = PRSNT_NODEF;
|
|
evnt.infoReqInd.cgPtyAdReqInd.pres = PRSNT_NODEF;
|
|
evnt.infoReqInd.cgPtyAdReqInd.val=CGPRTYADDREQ_REQ;
|
|
|
|
evnt.infoReqInd.holdingInd.pres = PRSNT_NODEF;
|
|
evnt.infoReqInd.holdingInd.val = HOLD_REQ;
|
|
|
|
evnt.infoReqInd.cgPtyCatReqInd.pres = PRSNT_NODEF;
|
|
evnt.infoReqInd.cgPtyCatReqInd.val = CGPRTYCATREQ_REQ;
|
|
|
|
evnt.infoReqInd.chrgInfoReqInd.pres = PRSNT_NODEF;
|
|
evnt.infoReqInd.chrgInfoReqInd.val = CHRGINFO_REQ;
|
|
|
|
evnt.infoReqInd.malCaIdReqInd.pres = PRSNT_NODEF;
|
|
evnt.infoReqInd.malCaIdReqInd.val = MLBG_INFOREQ;
|
|
|
|
sng_cc_inr(1,
|
|
sngss7_info->suInstId,
|
|
sngss7_info->spInstId,
|
|
sngss7_info->circuit->id,
|
|
&evnt,
|
|
INFORMATREQ);
|
|
|
|
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx INR\n", sngss7_info->circuit->cic);
|
|
}
|
|
|
|
void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan)
|
|
{
|
|
SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__);
|
|
|
|
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
|
SiCnStEvnt acm;
|
|
const char *backwardInd = NULL;
|
|
|
|
memset (&acm, 0x0, sizeof (acm));
|
|
|
|
/* fill in the needed information for the ACM */
|
|
acm.bckCallInd.eh.pres = PRSNT_NODEF;
|
|
acm.bckCallInd.chrgInd.pres = PRSNT_NODEF;
|
|
acm.bckCallInd.chrgInd.val = CHRG_CHRG;
|
|
acm.bckCallInd.cadPtyStatInd.pres = PRSNT_NODEF;
|
|
acm.bckCallInd.cadPtyStatInd.val = 0x01;
|
|
acm.bckCallInd.cadPtyCatInd.pres = PRSNT_NODEF;
|
|
acm.bckCallInd.cadPtyCatInd.val = CADCAT_ORDSUBS;
|
|
acm.bckCallInd.end2EndMethInd.pres = PRSNT_NODEF;
|
|
acm.bckCallInd.end2EndMethInd.val = E2EMTH_NOMETH;
|
|
acm.bckCallInd.intInd.pres = PRSNT_NODEF;
|
|
acm.bckCallInd.intInd.val = INTIND_NOINTW;
|
|
acm.bckCallInd.end2EndInfoInd.pres = PRSNT_NODEF;
|
|
acm.bckCallInd.end2EndInfoInd.val = E2EINF_NOINFO;
|
|
|
|
acm.bckCallInd.isdnUsrPrtInd.pres = PRSNT_NODEF;
|
|
acm.bckCallInd.isdnUsrPrtInd.val = ISUP_NOTUSED;
|
|
backwardInd = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "acm_bi_iup");
|
|
if (!ftdm_strlen_zero(backwardInd)) {
|
|
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied backward indicator ISDN user part indicator ACM, value \"%s\"\n", backwardInd);
|
|
if (atoi(backwardInd) != 0 ) {
|
|
acm.bckCallInd.isdnUsrPrtInd.val = ISUP_USED;
|
|
}
|
|
}
|
|
acm.bckCallInd.holdInd.pres = PRSNT_NODEF;
|
|
acm.bckCallInd.holdInd.val = HOLD_NOTREQD;
|
|
acm.bckCallInd.isdnAccInd.pres = PRSNT_NODEF;
|
|
acm.bckCallInd.isdnAccInd.val = ISDNACC_NONISDN;
|
|
acm.bckCallInd.echoCtrlDevInd.pres = PRSNT_NODEF;
|
|
switch (ftdmchan->caller_data.bearer_capability) {
|
|
/**********************************************************************/
|
|
case (FTDM_BEARER_CAP_SPEECH):
|
|
acm.bckCallInd.echoCtrlDevInd.val = 0x1;
|
|
break;
|
|
/**********************************************************************/
|
|
case (FTDM_BEARER_CAP_UNRESTRICTED):
|
|
acm.bckCallInd.echoCtrlDevInd.val = 0x0;
|
|
break;
|
|
/**********************************************************************/
|
|
case (FTDM_BEARER_CAP_3_1KHZ_AUDIO):
|
|
acm.bckCallInd.echoCtrlDevInd.val = 0x1;
|
|
break;
|
|
/**********************************************************************/
|
|
default:
|
|
SS7_ERROR_CHAN(ftdmchan, "Unknown Bearer capability falling back to speech%s\n", " ");
|
|
acm.bckCallInd.echoCtrlDevInd.val = 0x1;
|
|
break;
|
|
/**********************************************************************/
|
|
} /* switch (ftdmchan->caller_data.bearer_capability) */
|
|
acm.bckCallInd.sccpMethInd.pres = PRSNT_NODEF;
|
|
acm.bckCallInd.sccpMethInd.val = SCCPMTH_NOIND;
|
|
|
|
/* fill in any optional parameters */
|
|
if (sngss7_test_options(&g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id], SNGSS7_ACM_OBCI_BITA)) {
|
|
SS7_DEBUG_CHAN(ftdmchan, "Found ACM_OBCI_BITA flag:0x%X\n", g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].options);
|
|
acm.optBckCalInd.eh.pres = PRSNT_NODEF;
|
|
acm.optBckCalInd.inbndInfoInd.pres = PRSNT_NODEF;
|
|
acm.optBckCalInd.inbndInfoInd.val = 0x1;
|
|
acm.optBckCalInd.caFwdMayOcc.pres = PRSNT_DEF;
|
|
acm.optBckCalInd.simpleSegmInd.pres = PRSNT_DEF;
|
|
acm.optBckCalInd.mlppUserInd.pres = PRSNT_DEF;
|
|
acm.optBckCalInd.usrNetIneractInd.pres = PRSNT_DEF;
|
|
acm.optBckCalInd.netExcDelInd.pres = PRSNT_DEF;
|
|
} /* if (sngss7_test_options(isup_intf, SNGSS7_ACM_OBCI_BITA)) */
|
|
|
|
/* send the ACM request to LibSngSS7 */
|
|
sng_cc_con_status (1,
|
|
sngss7_info->suInstId,
|
|
sngss7_info->spInstId,
|
|
sngss7_info->circuit->id,
|
|
&acm,
|
|
ADDRCMPLT);
|
|
|
|
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx ACM\n", sngss7_info->circuit->cic);
|
|
|
|
SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__);
|
|
return;
|
|
}
|
|
|
|
void ft_to_sngss7_cpg (ftdm_channel_t *ftdmchan)
|
|
{
|
|
SiCnStEvnt cpg;
|
|
SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__);
|
|
|
|
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
|
|
|
|
|
memset (&cpg, 0, sizeof (cpg));
|
|
|
|
cpg.evntInfo.eh.pres = PRSNT_NODEF;
|
|
|
|
cpg.evntInfo.evntInd.pres = PRSNT_NODEF;
|
|
cpg.evntInfo.evntInd.val = SNGSS7_EVNTINFO_IND_INBAND_AVAIL; /* Event Indicator = In-band info is now available */
|
|
|
|
cpg.evntInfo.evntPresResInd.pres = PRSNT_NODEF;
|
|
cpg.evntInfo.evntPresResInd.val = 0; /* Event presentation restricted indicator = no indication */
|
|
|
|
/* send the CPG request to LibSngSS7 */
|
|
sng_cc_con_status (1, sngss7_info->suInstId, sngss7_info->spInstId, sngss7_info->circuit->id, &cpg, PROGRESS);
|
|
|
|
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "[CIC:%d]Tx CPG\n", sngss7_info->circuit->cic);
|
|
SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__);
|
|
return;
|
|
}
|
|
void ft_to_sngss7_anm (ftdm_channel_t * ftdmchan)
|
|
{
|
|
SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__);
|
|
|
|
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
|
SiConEvnt anm;
|
|
|
|
memset (&anm, 0x0, sizeof (anm));
|
|
|
|
/* send the ANM request to LibSngSS7 */
|
|
sng_cc_con_response(1,
|
|
sngss7_info->suInstId,
|
|
sngss7_info->spInstId,
|
|
sngss7_info->circuit->id,
|
|
&anm,
|
|
5);
|
|
|
|
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx ANM\n", sngss7_info->circuit->cic);
|
|
|
|
SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__);
|
|
return;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
void ft_to_sngss7_rel (ftdm_channel_t * ftdmchan)
|
|
{
|
|
const char *loc_ind = NULL;
|
|
SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__);
|
|
|
|
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
|
SiRelEvnt rel;
|
|
|
|
memset (&rel, 0x0, sizeof (rel));
|
|
|
|
rel.causeDgn.eh.pres = PRSNT_NODEF;
|
|
rel.causeDgn.location.pres = PRSNT_NODEF;
|
|
|
|
loc_ind = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rel_loc");
|
|
if (!ftdm_strlen_zero(loc_ind)) {
|
|
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied location indicator in REL, value \"%s\"\n", loc_ind);
|
|
rel.causeDgn.location.val = atoi(loc_ind);
|
|
} else {
|
|
rel.causeDgn.location.val = 0x01;
|
|
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "No user supplied location indicator in REL, using 0x01\"%s\"\n", "");
|
|
}
|
|
rel.causeDgn.cdeStand.pres = PRSNT_NODEF;
|
|
rel.causeDgn.cdeStand.val = 0x00;
|
|
rel.causeDgn.recommend.pres = NOTPRSNT;
|
|
rel.causeDgn.causeVal.pres = PRSNT_NODEF;
|
|
rel.causeDgn.causeVal.val = (uint8_t) ftdmchan->caller_data.hangup_cause;
|
|
rel.causeDgn.dgnVal.pres = NOTPRSNT;
|
|
|
|
/* send the REL request to LibSngSS7 */
|
|
sng_cc_rel_request (1,
|
|
sngss7_info->suInstId,
|
|
sngss7_info->spInstId,
|
|
sngss7_info->circuit->id,
|
|
&rel);
|
|
|
|
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx REL cause=%d \n",
|
|
sngss7_info->circuit->cic,
|
|
ftdmchan->caller_data.hangup_cause );
|
|
|
|
SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__);
|
|
return;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
void ft_to_sngss7_rlc (ftdm_channel_t * ftdmchan)
|
|
{
|
|
SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__);
|
|
|
|
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
|
SiRelEvnt rlc;
|
|
|
|
memset (&rlc, 0x0, sizeof (rlc));
|
|
|
|
/* send the RLC request to LibSngSS7 */
|
|
sng_cc_rel_response (1,
|
|
sngss7_info->suInstId,
|
|
sngss7_info->spInstId,
|
|
sngss7_info->circuit->id,
|
|
&rlc);
|
|
|
|
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx RLC\n", sngss7_info->circuit->cic);
|
|
|
|
SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__);
|
|
return;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
void ft_to_sngss7_rsc (ftdm_channel_t * ftdmchan)
|
|
{
|
|
SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__);
|
|
|
|
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
|
|
|
sng_cc_sta_request (1,
|
|
sngss7_info->suInstId,
|
|
sngss7_info->spInstId,
|
|
sngss7_info->circuit->id,
|
|
sngss7_info->globalFlg,
|
|
SIT_STA_CIRRESREQ,
|
|
NULL);
|
|
|
|
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx RSC\n", sngss7_info->circuit->cic);
|
|
|
|
SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__);
|
|
return;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
void ft_to_sngss7_rsca (ftdm_channel_t * ftdmchan)
|
|
{
|
|
SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__);
|
|
|
|
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
|
|
|
sng_cc_sta_request (1,
|
|
sngss7_info->suInstId,
|
|
sngss7_info->spInstId,
|
|
sngss7_info->circuit->id,
|
|
sngss7_info->globalFlg,
|
|
SIT_STA_CIRRESRSP,
|
|
NULL);
|
|
|
|
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx RSC-RLC\n", sngss7_info->circuit->cic);
|
|
|
|
SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__);
|
|
return;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
void ft_to_sngss7_blo (ftdm_channel_t * ftdmchan)
|
|
{
|
|
SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__);
|
|
|
|
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
|
|
|
sng_cc_sta_request (1,
|
|
0,
|
|
0,
|
|
sngss7_info->circuit->id,
|
|
sngss7_info->globalFlg,
|
|
SIT_STA_CIRBLOREQ,
|
|
NULL);
|
|
|
|
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx BLO\n", sngss7_info->circuit->cic);
|
|
|
|
SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__);
|
|
return;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
void ft_to_sngss7_bla (ftdm_channel_t * ftdmchan)
|
|
{
|
|
SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__);
|
|
|
|
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
|
|
|
sng_cc_sta_request (1,
|
|
0,
|
|
0,
|
|
sngss7_info->circuit->id,
|
|
sngss7_info->globalFlg,
|
|
SIT_STA_CIRBLORSP,
|
|
NULL);
|
|
|
|
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx BLA\n", sngss7_info->circuit->cic);
|
|
|
|
SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__);
|
|
return;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
void
|
|
ft_to_sngss7_ubl (ftdm_channel_t * ftdmchan)
|
|
{
|
|
SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__);
|
|
|
|
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
|
|
|
sng_cc_sta_request (1,
|
|
0,
|
|
0,
|
|
sngss7_info->circuit->id,
|
|
sngss7_info->globalFlg,
|
|
SIT_STA_CIRUBLREQ,
|
|
NULL);
|
|
|
|
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx UBL\n", sngss7_info->circuit->cic);
|
|
|
|
SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__);
|
|
return;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
void ft_to_sngss7_uba (ftdm_channel_t * ftdmchan)
|
|
{
|
|
SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__);
|
|
|
|
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
|
|
|
sng_cc_sta_request (1,
|
|
0,
|
|
0,
|
|
sngss7_info->circuit->id,
|
|
sngss7_info->globalFlg,
|
|
SIT_STA_CIRUBLRSP,
|
|
NULL);
|
|
|
|
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx UBA\n", sngss7_info->circuit->cic);
|
|
|
|
SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__);
|
|
return;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
void ft_to_sngss7_lpa (ftdm_channel_t * ftdmchan)
|
|
{
|
|
SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__);
|
|
|
|
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
|
|
|
sng_cc_sta_request (1,
|
|
sngss7_info->suInstId,
|
|
sngss7_info->spInstId,
|
|
sngss7_info->circuit->id,
|
|
sngss7_info->globalFlg,
|
|
SIT_STA_LOOPBACKACK,
|
|
NULL);
|
|
|
|
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx LPA\n", sngss7_info->circuit->cic);
|
|
|
|
SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__);
|
|
return;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
void ft_to_sngss7_gra (ftdm_channel_t * ftdmchan)
|
|
{
|
|
SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__);
|
|
|
|
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
|
SiStaEvnt gra;
|
|
|
|
/* clean out the gra struct */
|
|
memset (&gra, 0x0, sizeof (gra));
|
|
|
|
gra.rangStat.eh.pres = PRSNT_NODEF;
|
|
|
|
/* fill in the range */
|
|
gra.rangStat.range.pres = PRSNT_NODEF;
|
|
gra.rangStat.range.val = sngss7_info->rx_grs.range;
|
|
|
|
/* fill in the status */
|
|
gra.rangStat.status.pres = PRSNT_NODEF;
|
|
gra.rangStat.status.len = ((sngss7_info->rx_grs.range + 1) >> 3) + (((sngss7_info->rx_grs.range + 1) & 0x07) ? 1 : 0);
|
|
|
|
/* the status field should be 1 if blocked for maintenace reasons
|
|
* and 0 is not blocked....since we memset the struct nothing to do
|
|
*/
|
|
|
|
/* send the GRA to LibSng-SS7 */
|
|
sng_cc_sta_request (1,
|
|
0,
|
|
0,
|
|
sngss7_info->rx_grs.circuit,
|
|
0,
|
|
SIT_STA_GRSRSP,
|
|
&gra);
|
|
|
|
SS7_INFO_CHAN(ftdmchan, "[CIC:%d]Tx GRA (%d:%d)\n",
|
|
sngss7_info->circuit->cic,
|
|
sngss7_info->circuit->cic,
|
|
(sngss7_info->circuit->cic + sngss7_info->rx_grs.range));
|
|
|
|
|
|
SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__);
|
|
return;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
void ft_to_sngss7_grs (ftdm_channel_t *fchan)
|
|
{
|
|
SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__);
|
|
|
|
sngss7_chan_data_t *cinfo = fchan->call_data;
|
|
|
|
SiStaEvnt grs;
|
|
|
|
ftdm_assert(sngss7_test_ckt_flag(cinfo, FLAG_GRP_RESET_TX) &&
|
|
!sngss7_test_ckt_flag(cinfo, FLAG_GRP_RESET_SENT), "Incorrect flags\n");
|
|
|
|
memset (&grs, 0x0, sizeof(grs));
|
|
grs.rangStat.eh.pres = PRSNT_NODEF;
|
|
grs.rangStat.range.pres = PRSNT_NODEF;
|
|
grs.rangStat.range.val = cinfo->tx_grs.range;
|
|
|
|
sng_cc_sta_request (1,
|
|
0,
|
|
0,
|
|
cinfo->tx_grs.circuit,
|
|
0,
|
|
SIT_STA_GRSREQ,
|
|
&grs);
|
|
|
|
SS7_INFO_CHAN(fchan, "[CIC:%d]Tx GRS (%d:%d)\n",
|
|
cinfo->circuit->cic,
|
|
cinfo->circuit->cic,
|
|
(cinfo->circuit->cic + cinfo->tx_grs.range));
|
|
|
|
sngss7_set_ckt_flag(cinfo, FLAG_GRP_RESET_SENT);
|
|
|
|
SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__);
|
|
}
|
|
|
|
/******************************************************************************/
|
|
void ft_to_sngss7_cgba(ftdm_channel_t * ftdmchan)
|
|
{
|
|
SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__);
|
|
|
|
sngss7_span_data_t *sngss7_span = ftdmchan->span->signal_data;
|
|
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
|
int x = 0;
|
|
|
|
SiStaEvnt cgba;
|
|
|
|
memset (&cgba, 0x0, sizeof(cgba));
|
|
|
|
/* fill in the circuit group supervisory message */
|
|
cgba.cgsmti.eh.pres = PRSNT_NODEF;
|
|
cgba.cgsmti.typeInd.pres = PRSNT_NODEF;
|
|
cgba.cgsmti.typeInd.val = sngss7_span->rx_cgb.type;
|
|
|
|
cgba.rangStat.eh.pres = PRSNT_NODEF;
|
|
/* fill in the range */
|
|
cgba.rangStat.range.pres = PRSNT_NODEF;
|
|
cgba.rangStat.range.val = sngss7_span->rx_cgb.range;
|
|
/* fill in the status */
|
|
cgba.rangStat.status.pres = PRSNT_NODEF;
|
|
cgba.rangStat.status.len = ((sngss7_span->rx_cgb.range + 1) >> 3) + (((sngss7_span->rx_cgb.range + 1) & 0x07) ? 1 : 0);
|
|
for(x = 0; x < cgba.rangStat.status.len; x++){
|
|
cgba.rangStat.status.val[x] = sngss7_span->rx_cgb.status[x];
|
|
}
|
|
|
|
sng_cc_sta_request (1,
|
|
0,
|
|
0,
|
|
sngss7_span->rx_cgb.circuit,
|
|
0,
|
|
SIT_STA_CGBRSP,
|
|
&cgba);
|
|
|
|
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx CGBA (%d:%d)\n",
|
|
sngss7_info->circuit->cic,
|
|
sngss7_info->circuit->cic,
|
|
(sngss7_info->circuit->cic + sngss7_span->rx_cgb.range));
|
|
|
|
/* clean out the saved data */
|
|
memset(&sngss7_span->rx_cgb, 0x0, sizeof(sngss7_group_data_t));
|
|
|
|
SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__);
|
|
return;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
void ft_to_sngss7_cgua(ftdm_channel_t * ftdmchan)
|
|
{
|
|
SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__);
|
|
|
|
sngss7_span_data_t *sngss7_span = ftdmchan->span->signal_data;
|
|
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
|
int x = 0;
|
|
|
|
SiStaEvnt cgua;
|
|
|
|
memset (&cgua, 0x0, sizeof(cgua));
|
|
|
|
/* fill in the circuit group supervisory message */
|
|
cgua.cgsmti.eh.pres = PRSNT_NODEF;
|
|
cgua.cgsmti.typeInd.pres = PRSNT_NODEF;
|
|
cgua.cgsmti.typeInd.val = sngss7_span->rx_cgu.type;
|
|
|
|
cgua.rangStat.eh.pres = PRSNT_NODEF;
|
|
/* fill in the range */
|
|
cgua.rangStat.range.pres = PRSNT_NODEF;
|
|
cgua.rangStat.range.val = sngss7_span->rx_cgu.range;
|
|
/* fill in the status */
|
|
cgua.rangStat.status.pres = PRSNT_NODEF;
|
|
cgua.rangStat.status.len = ((sngss7_span->rx_cgu.range + 1) >> 3) + (((sngss7_span->rx_cgu.range + 1) & 0x07) ? 1 : 0);
|
|
for(x = 0; x < cgua.rangStat.status.len; x++){
|
|
cgua.rangStat.status.val[x] = sngss7_span->rx_cgu.status[x];
|
|
}
|
|
|
|
sng_cc_sta_request (1,
|
|
0,
|
|
0,
|
|
sngss7_span->rx_cgu.circuit,
|
|
0,
|
|
SIT_STA_CGURSP,
|
|
&cgua);
|
|
|
|
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx CGUA (%d:%d)\n",
|
|
sngss7_info->circuit->cic,
|
|
sngss7_info->circuit->cic,
|
|
(sngss7_info->circuit->cic + sngss7_span->rx_cgu.range));
|
|
|
|
/* clean out the saved data */
|
|
memset(&sngss7_span->rx_cgu, 0x0, sizeof(sngss7_group_data_t));
|
|
|
|
|
|
SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__);
|
|
return;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
void ft_to_sngss7_cgb(ftdm_channel_t * ftdmchan)
|
|
{
|
|
SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__);
|
|
|
|
sngss7_span_data_t *sngss7_span = ftdmchan->span->signal_data;
|
|
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
|
SiStaEvnt cgb;
|
|
int x = 0;
|
|
|
|
|
|
memset (&cgb, 0x0, sizeof(cgb));
|
|
|
|
/* fill in the circuit group supervisory message */
|
|
cgb.cgsmti.eh.pres = PRSNT_NODEF;
|
|
cgb.cgsmti.typeInd.pres = PRSNT_NODEF;
|
|
cgb.cgsmti.typeInd.val = sngss7_span->tx_cgb.type;
|
|
|
|
/* fill in the range */
|
|
cgb.rangStat.eh.pres = PRSNT_NODEF;
|
|
cgb.rangStat.range.pres = PRSNT_NODEF;
|
|
cgb.rangStat.range.val = sngss7_span->tx_cgb.range;
|
|
|
|
/* fill in the status */
|
|
cgb.rangStat.status.pres = PRSNT_NODEF;
|
|
cgb.rangStat.status.len = ((sngss7_span->tx_cgb.range + 1) >> 3) + (((sngss7_span->tx_cgb.range + 1) & 0x07) ? 1 : 0);
|
|
for(x = 0; x < cgb.rangStat.status.len; x++){
|
|
cgb.rangStat.status.val[x] = sngss7_span->tx_cgb.status[x];
|
|
}
|
|
|
|
sng_cc_sta_request (1,
|
|
0,
|
|
0,
|
|
sngss7_span->tx_cgb.circuit,
|
|
0,
|
|
SIT_STA_CGBREQ,
|
|
&cgb);
|
|
|
|
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx CGB (%d:%d)\n",
|
|
sngss7_info->circuit->cic,
|
|
sngss7_info->circuit->cic,
|
|
(sngss7_info->circuit->cic + sngss7_span->tx_cgb.range));
|
|
|
|
/* clean out the saved data */
|
|
memset(&sngss7_span->tx_cgb, 0x0, sizeof(sngss7_group_data_t));
|
|
|
|
|
|
SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__);
|
|
return;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
void ft_to_sngss7_cgu(ftdm_channel_t * ftdmchan)
|
|
{
|
|
SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__);
|
|
|
|
sngss7_span_data_t *sngss7_span = ftdmchan->span->signal_data;
|
|
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
|
SiStaEvnt cgu;
|
|
int x = 0;
|
|
|
|
|
|
memset (&cgu, 0x0, sizeof(cgu));
|
|
|
|
/* fill in the circuit group supervisory message */
|
|
cgu.cgsmti.eh.pres = PRSNT_NODEF;
|
|
cgu.cgsmti.typeInd.pres = PRSNT_NODEF;
|
|
cgu.cgsmti.typeInd.val = sngss7_span->tx_cgu.type;
|
|
|
|
/* fill in the range */
|
|
cgu.rangStat.eh.pres = PRSNT_NODEF;
|
|
cgu.rangStat.range.pres = PRSNT_NODEF;
|
|
cgu.rangStat.range.val = sngss7_span->tx_cgu.range;
|
|
|
|
/* fill in the status */
|
|
cgu.rangStat.status.pres = PRSNT_NODEF;
|
|
cgu.rangStat.status.len = ((sngss7_span->tx_cgu.range + 1) >> 3) + (((sngss7_span->tx_cgu.range + 1) & 0x07) ? 1 : 0);
|
|
for(x = 0; x < cgu.rangStat.status.len; x++){
|
|
cgu.rangStat.status.val[x] = sngss7_span->tx_cgu.status[x];
|
|
}
|
|
|
|
sng_cc_sta_request (1,
|
|
0,
|
|
0,
|
|
sngss7_span->tx_cgu.circuit,
|
|
0,
|
|
SIT_STA_CGUREQ,
|
|
&cgu);
|
|
|
|
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx CGU (%d:%d)\n",
|
|
sngss7_info->circuit->cic,
|
|
sngss7_info->circuit->cic,
|
|
(sngss7_info->circuit->cic + sngss7_span->tx_cgu.range));
|
|
|
|
/* clean out the saved data */
|
|
memset(&sngss7_span->tx_cgu, 0x0, sizeof(sngss7_group_data_t));
|
|
|
|
|
|
SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__);
|
|
return;
|
|
}
|
|
|
|
/* French SPIROU send Charge Unit */
|
|
/* No one calls this function yet, but it has been implemented to complement TXA messages */
|
|
void ft_to_sngss7_itx (ftdm_channel_t * ftdmchan)
|
|
{
|
|
#ifndef SANGOMA_SPIROU
|
|
SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__);
|
|
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "ITX message not supported!, please update your libsng_ss7\n");
|
|
#else
|
|
const char* var = NULL;
|
|
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
|
SiCnStEvnt itx;
|
|
|
|
SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__);
|
|
|
|
memset (&itx, 0x0, sizeof (itx));
|
|
|
|
itx.msgNum.eh.pres = PRSNT_NODEF;
|
|
itx.msgNum.msgNum.pres = PRSNT_NODEF;
|
|
var = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_itx_msg_num");
|
|
if (!ftdm_strlen_zero(var)) {
|
|
itx.msgNum.msgNum.val = atoi(var);
|
|
} else {
|
|
itx.msgNum.msgNum.val = 0x1;
|
|
}
|
|
|
|
itx.chargUnitNum.eh.pres = PRSNT_NODEF;
|
|
itx.chargUnitNum.chargUnitNum.pres = PRSNT_NODEF;
|
|
var = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_itx_charge_unit");
|
|
if (!ftdm_strlen_zero(var)) {
|
|
itx.chargUnitNum.chargUnitNum.val = atoi(var);
|
|
} else {
|
|
itx.chargUnitNum.chargUnitNum.val = 0x1;
|
|
}
|
|
|
|
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "ITX Charging Unit:%d Msg Num:%d\n", itx.chargUnitNum.chargUnitNum.val, itx.msgNum.msgNum.val);
|
|
sng_cc_con_status (1, sngss7_info->suInstId, sngss7_info->spInstId, sngss7_info->circuit->id, &itx, CHARGE_UNIT);
|
|
|
|
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx ITX\n", sngss7_info->circuit->cic);
|
|
#endif
|
|
SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__);
|
|
return;
|
|
}
|
|
|
|
/* French SPIROU send Charging Acknowledgement */
|
|
void ft_to_sngss7_txa (ftdm_channel_t * ftdmchan)
|
|
{
|
|
#ifndef SANGOMA_SPIROU
|
|
SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__);
|
|
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "TXA message not supported!, please update your libsng_ss7\n");
|
|
#else
|
|
SiCnStEvnt txa;
|
|
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
|
SS7_FUNC_TRACE_ENTER (__FTDM_FUNC__);
|
|
|
|
memset (&txa, 0x0, sizeof(txa));
|
|
|
|
sng_cc_con_status(1, sngss7_info->suInstId, sngss7_info->spInstId, sngss7_info->circuit->id, &txa, CHARGE_ACK);
|
|
|
|
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx TXA\n", sngss7_info->circuit->cic);
|
|
#endif
|
|
SS7_FUNC_TRACE_EXIT (__FTDM_FUNC__);
|
|
return;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
/* For Emacs:
|
|
* Local Variables:
|
|
* mode:c
|
|
* indent-tabs-mode:t
|
|
* tab-width:4
|
|
* c-basic-offset:4
|
|
* End:
|
|
* For VIM:
|
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
|
|
*/
|
|
/******************************************************************************/
|