If end user is indicated as known in received ACM interpret it as progress or ringing indication.
Added generic mechanism to set protocol specific parameters in messages. git-svn-id: http://yate.null.ro/svn/yate/trunk@2484 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
parent
570511346a
commit
335d0d57a0
|
@ -106,6 +106,10 @@
|
|||
; Defaults to user-provided if missing or incorrect
|
||||
;screening=user-provided
|
||||
|
||||
; earlyacm: boolean: Convert received early ACM user state into progress or ringing
|
||||
; Defaults to enable
|
||||
;earlyacm=enable
|
||||
|
||||
; format: string: Default data format for outgoing calls. Values: alaw, mulaw, g721
|
||||
; Defaults to alaw if missing or incorrect
|
||||
; alaw is used commonly in Europe while mulaw is used commonly in US and Japan.
|
||||
|
|
|
@ -128,6 +128,9 @@ static const SignallingFlags s_flags_paramcompat[] = {
|
|||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
// Backward call indicators to be copied
|
||||
static const String s_copyBkInd("BackwardCallIndicators,OptionalBackwardCallIndicators");
|
||||
|
||||
// Default decoder, dumps raw octets
|
||||
static bool decodeRaw(const SS7ISUP* isup, NamedList& list, const IsupParam* param,
|
||||
const unsigned char* buf, unsigned int len, const String& prefix)
|
||||
|
@ -1630,6 +1633,8 @@ bool SS7ISUPCall::sendEvent(SignallingEvent* event)
|
|||
SS7MsgISUP* m = new SS7MsgISUP(SS7MsgISUP::CPR,id());
|
||||
m->params().addParam("EventInformation",
|
||||
event->type() == SignallingEvent::Ringing ? "ringing": "progress");
|
||||
if (event->message())
|
||||
m->params().copyParams(event->message()->params(),s_copyBkInd);
|
||||
m_state = Ringing;
|
||||
result = transmitMessage(m);
|
||||
}
|
||||
|
@ -1638,8 +1643,7 @@ bool SS7ISUPCall::sendEvent(SignallingEvent* event)
|
|||
if (validMsgState(true,SS7MsgISUP::ACM)) {
|
||||
SS7MsgISUP* m = new SS7MsgISUP(SS7MsgISUP::ACM,id());
|
||||
if (event->message())
|
||||
m->params().addParam("BackwardCallIndicators",
|
||||
event->message()->params().getValue("BackwardCallIndicators"));
|
||||
m->params().copyParams(event->message()->params(),s_copyBkInd);
|
||||
m_state = Accepted;
|
||||
result = transmitMessage(m);
|
||||
}
|
||||
|
@ -1647,6 +1651,8 @@ bool SS7ISUPCall::sendEvent(SignallingEvent* event)
|
|||
case SignallingEvent::Answer:
|
||||
if (validMsgState(true,SS7MsgISUP::ANM)) {
|
||||
SS7MsgISUP* m = new SS7MsgISUP(SS7MsgISUP::ANM,id());
|
||||
if (event->message())
|
||||
m->params().copyParams(event->message()->params(),s_copyBkInd);
|
||||
m_state = Answered;
|
||||
result = transmitMessage(m);
|
||||
}
|
||||
|
@ -1942,11 +1948,33 @@ SignallingEvent* SS7ISUPCall::processSegmented(SS7MsgISUP* sgm, bool timeout)
|
|||
break;
|
||||
case SS7MsgISUP::ACM:
|
||||
m_state = Accepted;
|
||||
m_lastEvent = new SignallingEvent(SignallingEvent::Accept,m_sgmMsg,this);
|
||||
{
|
||||
m_lastEvent = 0;
|
||||
bool inband = SignallingUtils::hasFlag(m_sgmMsg->params(),"OptionalBackwardCallIndicators","inband");
|
||||
if (isup() && isup()->m_earlyAcm) {
|
||||
// If the called party is known free report ringing
|
||||
// If it may become free or there is inband audio report progress
|
||||
bool ring = SignallingUtils::hasFlag(m_sgmMsg->params(),"BackwardCallIndicators","called-free");
|
||||
if (inband || ring || SignallingUtils::hasFlag(m_sgmMsg->params(),"BackwardCallIndicators","called-conn")) {
|
||||
m_sgmMsg->params().setParam("earlymedia",String::boolText(inband));
|
||||
m_lastEvent = new SignallingEvent(ring ? SignallingEvent::Ringing : SignallingEvent::Progress,m_sgmMsg,this);
|
||||
}
|
||||
}
|
||||
if (!m_lastEvent) {
|
||||
if (inband)
|
||||
m_sgmMsg->params().setParam("earlymedia",String::boolText(true));
|
||||
m_lastEvent = new SignallingEvent(SignallingEvent::Accept,m_sgmMsg,this);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SS7MsgISUP::CPR:
|
||||
m_state = Ringing;
|
||||
m_lastEvent = new SignallingEvent(SignallingEvent::Ringing,m_sgmMsg,this);
|
||||
{
|
||||
bool ring = SignallingUtils::hasFlag(m_sgmMsg->params(),"EventInformation","ringing");
|
||||
if (!ring && SignallingUtils::hasFlag(m_sgmMsg->params(),"EventInformation","inband"))
|
||||
m_sgmMsg->params().setParam("earlymedia",String::boolText(true));
|
||||
m_lastEvent = new SignallingEvent(ring ? SignallingEvent::Ringing : SignallingEvent::Progress,m_sgmMsg,this);
|
||||
}
|
||||
break;
|
||||
case SS7MsgISUP::ANM:
|
||||
case SS7MsgISUP::CON:
|
||||
|
@ -1957,8 +1985,7 @@ SignallingEvent* SS7ISUPCall::processSegmented(SS7MsgISUP* sgm, bool timeout)
|
|||
Debug(isup(),DebugStub,"Call(%u). Segment waiting message is '%s' [%p]",
|
||||
id(),m_sgmMsg->name(),this);
|
||||
}
|
||||
m_sgmMsg->deref();
|
||||
m_sgmMsg = 0;
|
||||
TelEngine::destruct(m_sgmMsg);
|
||||
return m_lastEvent;
|
||||
}
|
||||
|
||||
|
@ -1995,6 +2022,7 @@ SS7ISUP::SS7ISUP(const NamedList& params)
|
|||
m_remotePoint(0),
|
||||
m_priossf(0),
|
||||
m_sls(255),
|
||||
m_earlyAcm(true),
|
||||
m_inn(false),
|
||||
m_l3LinkUp(false),
|
||||
m_uptTimer(0),
|
||||
|
@ -2033,6 +2061,7 @@ SS7ISUP::SS7ISUP(const NamedList& params)
|
|||
m_priossf |= SS7MSU::getPriority(params.getValue("priority"),SS7MSU::Regular);
|
||||
m_priossf |= SS7MSU::getNetIndicator(params.getValue("netindicator"),SS7MSU::National);
|
||||
|
||||
m_earlyAcm = params.getBoolValue("earlyacm",m_earlyAcm);
|
||||
m_inn = params.getBoolValue("inn",m_inn);
|
||||
m_numPlan = params.getValue("numplan");
|
||||
if (-1 == lookup(m_numPlan,s_dict_numPlan,-1))
|
||||
|
|
|
@ -5688,6 +5688,7 @@ private:
|
|||
SS7PointCode* m_remotePoint; // Default remote point code for outgoing calls and maintenance
|
||||
unsigned char m_priossf; // MSU priority + Subservice field
|
||||
unsigned char m_sls; // Last known valid SLS
|
||||
bool m_earlyAcm; // Accept progress/ringing in early ACM
|
||||
bool m_inn; // Routing to internal network number flag
|
||||
String m_numPlan; // Numbering plan
|
||||
String m_numType; // Number type
|
||||
|
|
|
@ -93,6 +93,8 @@ private:
|
|||
void evAccept(SignallingEvent* event);
|
||||
void evAnswer(SignallingEvent* event);
|
||||
void evRinging(SignallingEvent* event);
|
||||
// Update circuit and format in source, optionally in consumer too
|
||||
void updateCircuitFormat(SignallingEvent* event, bool consumer);
|
||||
// Open or update format source/consumer
|
||||
// Set force to true to change source/consumer pointer/format
|
||||
bool updateConsumer(const char* format, bool force);
|
||||
|
@ -142,6 +144,8 @@ public:
|
|||
// event call controller's prefix
|
||||
void copySigMsgParams(NamedList& dest, SignallingEvent* event,
|
||||
const String* params = 0);
|
||||
// Copy outgoing message parameters
|
||||
void copySigMsgParams(SignallingEvent* event, const NamedList& params);
|
||||
private:
|
||||
// Handle command complete requests
|
||||
virtual bool commandComplete(Message& msg, const String& partLine,
|
||||
|
@ -500,6 +504,7 @@ public:
|
|||
static SigDriver plugin;
|
||||
static Configuration s_cfg;
|
||||
static Configuration s_cfgData;
|
||||
static const String s_noPrefixParams = "format,earlymedia";
|
||||
|
||||
static const char s_miniHelp[] = "sigdump component [filename]";
|
||||
static const char s_fullHelp[] = "Command to dump signalling data to a file";
|
||||
|
@ -699,6 +704,7 @@ bool SigChannel::msgProgress(Message& msg)
|
|||
SignallingEvent* event = new SignallingEvent(SignallingEvent::Progress,sm,m_call);
|
||||
TelEngine::destruct(sm);
|
||||
lock.drop();
|
||||
plugin.copySigMsgParams(event,msg);
|
||||
event->sendEvent();
|
||||
return true;
|
||||
}
|
||||
|
@ -719,6 +725,7 @@ bool SigChannel::msgRinging(Message& msg)
|
|||
SignallingEvent* event = new SignallingEvent(SignallingEvent::Ringing,sm,m_call);
|
||||
TelEngine::destruct(sm);
|
||||
lock.drop();
|
||||
plugin.copySigMsgParams(event,msg);
|
||||
event->sendEvent();
|
||||
return true;
|
||||
}
|
||||
|
@ -745,6 +752,7 @@ bool SigChannel::msgAnswered(Message& msg)
|
|||
SignallingEvent* event = new SignallingEvent(SignallingEvent::Answer,sm,m_call);
|
||||
TelEngine::destruct(sm);
|
||||
lock.drop();
|
||||
plugin.copySigMsgParams(event,msg);
|
||||
event->sendEvent();
|
||||
return true;
|
||||
}
|
||||
|
@ -772,6 +780,7 @@ bool SigChannel::msgTone(Message& msg, const char* tone)
|
|||
SignallingEvent* event = new SignallingEvent(SignallingEvent::Info,sm,m_call);
|
||||
TelEngine::destruct(sm);
|
||||
lock.drop();
|
||||
plugin.copySigMsgParams(event,msg);
|
||||
event->sendEvent();
|
||||
return true;
|
||||
}
|
||||
|
@ -787,6 +796,7 @@ bool SigChannel::msgText(Message& msg, const char* text)
|
|||
SignallingEvent* event = new SignallingEvent(SignallingEvent::Message,sm,m_call);
|
||||
TelEngine::destruct(sm);
|
||||
lock.drop();
|
||||
plugin.copySigMsgParams(event,msg);
|
||||
event->sendEvent();
|
||||
return true;
|
||||
}
|
||||
|
@ -805,6 +815,7 @@ bool SigChannel::msgTransfer(Message& msg)
|
|||
return true;
|
||||
SignallingEvent* event = new SignallingEvent(SignallingEvent::Transfer,0,m_call);
|
||||
lock.drop();
|
||||
plugin.copySigMsgParams(event,msg);
|
||||
return event->sendEvent();
|
||||
}
|
||||
|
||||
|
@ -839,8 +850,10 @@ void SigChannel::callAccept(Message& msg)
|
|||
}
|
||||
setState("accepted",false);
|
||||
lock.drop();
|
||||
if (event)
|
||||
if (event) {
|
||||
plugin.copySigMsgParams(event,msg);
|
||||
event->sendEvent();
|
||||
}
|
||||
Channel::callAccept(msg);
|
||||
}
|
||||
|
||||
|
@ -947,8 +960,9 @@ void SigChannel::evInfo(SignallingEvent* event)
|
|||
void SigChannel::evProgress(SignallingEvent* event)
|
||||
{
|
||||
setState("progressing");
|
||||
updateCircuitFormat(event,false);
|
||||
Message* msg = message("call.progress");
|
||||
plugin.copySigMsgParams(*msg,event);
|
||||
plugin.copySigMsgParams(*msg,event,&s_noPrefixParams);
|
||||
Engine::enqueue(msg);
|
||||
}
|
||||
|
||||
|
@ -964,28 +978,13 @@ void SigChannel::evRelease(SignallingEvent* event)
|
|||
void SigChannel::evAccept(SignallingEvent* event)
|
||||
{
|
||||
setState("accepted",false,false);
|
||||
const char* format = 0;
|
||||
bool cicChange = false;
|
||||
if (event->message()) {
|
||||
format = event->message()->params().getValue("format");
|
||||
cicChange = event->message()->params().getBoolValue("circuit-change",false);
|
||||
}
|
||||
updateSource(format,cicChange);
|
||||
updateConsumer(0,cicChange);
|
||||
updateCircuitFormat(event,true);
|
||||
}
|
||||
|
||||
void SigChannel::evAnswer(SignallingEvent* event)
|
||||
{
|
||||
static String params = "format";
|
||||
setState("answered");
|
||||
const char* format = 0;
|
||||
bool cicChange = false;
|
||||
if (event->message()) {
|
||||
format = event->message()->params().getValue("format");
|
||||
cicChange = event->message()->params().getBoolValue("circuit-change",false);
|
||||
}
|
||||
updateSource(format,cicChange);
|
||||
updateConsumer(0,cicChange);
|
||||
updateCircuitFormat(event,true);
|
||||
// Start echo training
|
||||
SignallingCircuit* cic = getCircuit();
|
||||
if (cic) {
|
||||
|
@ -993,24 +992,32 @@ void SigChannel::evAnswer(SignallingEvent* event)
|
|||
cic->setParam("echotrain",value);
|
||||
}
|
||||
Message* msg = message("call.answered",false,true);
|
||||
plugin.copySigMsgParams(*msg,event,¶ms);
|
||||
plugin.copySigMsgParams(*msg,event,&s_noPrefixParams);
|
||||
msg->clearParam("earlymedia");
|
||||
Engine::enqueue(msg);
|
||||
}
|
||||
|
||||
void SigChannel::evRinging(SignallingEvent* event)
|
||||
{
|
||||
static String params = "format";
|
||||
setState("ringing");
|
||||
updateCircuitFormat(event,false);
|
||||
Message* msg = message("call.ringing",false,true);
|
||||
plugin.copySigMsgParams(*msg,event,&s_noPrefixParams);
|
||||
Engine::enqueue(msg);
|
||||
}
|
||||
|
||||
void SigChannel::updateCircuitFormat(SignallingEvent* event, bool consumer)
|
||||
{
|
||||
const char* format = 0;
|
||||
bool cicChange = false;
|
||||
if (event->message()) {
|
||||
format = event->message()->params().getValue("format");
|
||||
cicChange = event->message()->params().getBoolValue("circuit-change",false);
|
||||
}
|
||||
DDebug(this,DebugInfo,"Updating format to '%s'%s",format,cicChange ? ", circuit changed" : "");
|
||||
updateSource(format,cicChange);
|
||||
Message* msg = message("call.ringing",false,true);
|
||||
plugin.copySigMsgParams(*msg,event,¶ms);
|
||||
Engine::enqueue(msg);
|
||||
if (consumer)
|
||||
updateConsumer(0,cicChange);
|
||||
}
|
||||
|
||||
bool SigChannel::updateConsumer(const char* format, bool force)
|
||||
|
@ -1365,6 +1372,28 @@ void SigDriver::copySigMsgParams(NamedList& dest, SignallingEvent* event,
|
|||
dest.clearParam("message-prefix");
|
||||
}
|
||||
|
||||
// Copy outgoing message parameters
|
||||
void SigDriver::copySigMsgParams(SignallingEvent* event, const NamedList& params)
|
||||
{
|
||||
if (!(event && event->message() && event->controller()))
|
||||
return;
|
||||
String prefix = event->controller()->msgPrefix();
|
||||
if (prefix)
|
||||
prefix = "o" + prefix;
|
||||
prefix = params.getValue("message-oprefix",prefix);
|
||||
if (prefix.null())
|
||||
return;
|
||||
unsigned int n = params.length();
|
||||
for (unsigned int i = 0; i < n; i++) {
|
||||
NamedString* param = params.getParam(i);
|
||||
if (!param)
|
||||
continue;
|
||||
String name = param->name();
|
||||
if (name.startSkip(prefix,false))
|
||||
event->message()->params().addParam(name,*param);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle command complete requests
|
||||
bool SigDriver::commandComplete(Message& msg, const String& partLine,
|
||||
const String& partWord)
|
||||
|
|
Loading…
Reference in New Issue