Author Topic: Yate MGCP not signalling disconnect on called party disconnect  (Read 13826 times)

andrew867

  • Newbie
  • *
  • Posts: 10
    • View Profile
Hi!

I have an Adit CMG router card configured and working with Yate via MGCPCA (FXS ports are connected locally and through T1 to another channel bank). Using the overlapped.php script I can dial out through the FXS ports but when the called party disconnects Yate does not send a disconnect to the MGCP gateway, it holds the line active and plays 'tone/congestion'.

Is there something I can add to regex route so it will send a disconnect to MGCP instead of holding the line active and playing tones?

Edit:

I think it has something to do with call-ended-target in analog.conf, but I'm unsure how I can change the parameters to allow it to signal a disconnect to the underlying channel driver from the analog module.
« Last Edit: June 19, 2018, 12:33:59 PM by andrew867 »

marian

  • Hero Member
  • *****
  • Posts: 513
    • View Profile
Re: Yate MGCP not signalling disconnect on called party disconnect
« Reply #1 on: June 20, 2018, 01:15:47 AM »
Please post a log with message sniffer enabled.
Please make sure analog channel debug level is 10.

andrew867

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Yate MGCP not signalling disconnect on called party disconnect
« Reply #2 on: June 20, 2018, 02:48:38 PM »
I mis-dialed at first, but the second attempt was successful. It looks like the mgcpca never gets a disconnect from analog to signal the FXS port to drop voltage on disconnect.



andrew867

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Yate MGCP not signalling disconnect on called party disconnect
« Reply #3 on: June 20, 2018, 03:21:10 PM »
Yate should send a Notify with 'osi' as the contents on a far-end disconnect, as per the RFC:

https://tools.ietf.org/html/rfc3660#section-2.4

Other additions that would be great is to signal via MGCP ringback signal (Notify rg) instead of using generated tones, as well as off hook tone (Notify ot) when the line is out-of-service.

marian

  • Hero Member
  • *****
  • Posts: 513
    • View Profile
Re: Yate MGCP not signalling disconnect on called party disconnect
« Reply #4 on: June 21, 2018, 01:59:28 AM »
Yate does send a DLCX when the call is terminated.
I'm not sure what the gateway should do. I suppose it should terminate the connection.
The gateway already notified the line on hook event.

Ringback may be set by driver if not provided by called party.
Just set ringback=yes in the line group section.

There is no support in the analog module for disconnect notification.

andrew867

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Yate MGCP not signalling disconnect on called party disconnect
« Reply #5 on: June 21, 2018, 05:32:32 AM »
Where would be the best place to hack in support to send an osi Notify along with the DLCX?

marian

  • Hero Member
  • *****
  • Posts: 513
    • View Profile
Re: Yate MGCP not signalling disconnect on called party disconnect
« Reply #6 on: June 21, 2018, 06:00:09 AM »
This is just a suggestion:
analog.cpp
void AnalogChannel::detachLine():
Call:
m_line->setCirctuitParam("SOME_STR","SOME_OPTIONAL_VALUE");

mgcpca.cpp:
bool MGCPCircuit::setParam(const String& param, const String& value)
{
....
    if (param == YSTRING("SOME_STR")) {
        // Send NTFY now or mark to send it before/in DLCX?
       // See all places where DLCX is sent
   }
}

andrew867

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Yate MGCP not signalling disconnect on called party disconnect
« Reply #7 on: June 21, 2018, 07:09:36 AM »
When the foreign end (called party) disconnects the analog driver never signals to the underlying driver that the call disconnected. Looks like I need to add something to:

void AnalogChannel::hangup(bool local, const char* status, const char* reason)

And create a new SignallingCircuitEvent to send to the underlying driver (mgcpca in my case) that the call disconnected and to do something if required. I've created a sendNTFY function in the MGCPWrapper which should work, I just need to get the signalling event sent to mgcpca to call that function.


Also ringback= has no affect as the mgcpca driver doesn't implement Notify for ringback. I actually can't even get analog channel internally generated tones to play (there's no log messages indicating it is trying to play tone/ring).

andrew867

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Yate MGCP not signalling disconnect on called party disconnect
« Reply #8 on: June 21, 2018, 04:44:03 PM »
So I have it working now :) I will clean up my code and attempt to create a patch. Ideally it should be a configuration option to turn on and off. Also other channel drivers can be updated to take advantage of the new NetworkDisconnect event.

andrew867

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Yate MGCP not signalling disconnect on called party disconnect
« Reply #9 on: June 22, 2018, 05:53:29 AM »
I've never done this before, please let me know how I can improve!

Code: [Select]
*** yate/libs/ysig/yatesig.h    2018-06-22 09:16:52.781426453 -0230
--- yate-andrew/libs/ysig/yatesig.h     2018-06-21 20:10:01.514867348 -0230
***************
*** 1565,1570 ****
--- 1565,1571 ----
        OffHook      = 21,               // The hook is up
        RingBegin    = 22,               // Start ringing
        RingEnd      = 23,               // Stop ringing
+         NetworkDisconnect = 24,          // OSI - Open Switch Interval to signal call end on FXS
        RingerOn     = 30,               // An FXS started the FXO's ringer
        RingerOff    = 31,               // An FXS stopped the FXO's ringer
        Wink         = 32,               // On hook momentarily

*** yate/modules/server/mgcpca.cpp      2018-06-22 09:17:09.213459432 -0230
--- yate-andrew/modules/server/mgcpca.cpp       2018-06-22 09:19:49.669782522 -0230
***************
*** 1993,1998 ****
--- 1993,2000 ----
                    return sendRequest("D/" + *tone);
            }
            break;
+         case SignallingCircuitEvent::NetworkDisconnect:
+             return fxs() && sendRequest("L/osi(to=500)"); //MGCP default is 900ms
        case SignallingCircuitEvent::GenericTone:
            if (params) {
                const String* tone = params->getParam(YSTRING("tone"));


*** yate/modules/server/analog.cpp      2018-06-22 09:17:09.197459399 -0230
--- yate-andrew/modules/server/analog.cpp       2018-06-21 20:43:42.843357095 -0230
***************
*** 1711,1716 ****
--- 1712,1719 ----
      if (m_callEndedTimer.interval()) {
        m_callEndedTimer.start();
        m_line->changeState(AnalogLine::CallEnded);
+         Debug(this,DebugAll,"Call ended. Sending OSI via sendEvent(SignallingCircuitEvent::NetworkDisconnected) [%p]",this);
+         m_line->sendEvent(SignallingCircuitEvent::NetworkDisconnect);
        if (!setAnnouncement("call-ended",m_callEndedTarget))
            ref();
      }

marian

  • Hero Member
  • *****
  • Posts: 513
    • View Profile
Re: Yate MGCP not signalling disconnect on called party disconnect
« Reply #10 on: June 22, 2018, 06:17:26 AM »
It may be suitable to configure the interval per MGCPSpan and check it when sending the event.
You may allow it to be overridden in event's params.

MGCPSpan::init()
Initialize m_osiInterval from params

sendEvent:
if (fxs()) {
    String s = "L/osi";
    int interval = params ? params->getIntValue(YSTRING("interval"),mySpan->osiInterval(),0) : mySpan->osiInterval();
    if (interval)
        s << "(to=" << interval << ")":
    sendRequest(s);
}
return false;

andrew867

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: Yate MGCP not signalling disconnect on called party disconnect
« Reply #11 on: June 22, 2018, 08:45:48 AM »
Thanks! If I have time I'll add that in there, for now it works exactly how I need it to. :)

It may be suitable to configure the interval per MGCPSpan and check it when sending the event.
You may allow it to be overridden in event's params.

MGCPSpan::init()
Initialize m_osiInterval from params

sendEvent:
if (fxs()) {
    String s = "L/osi";
    int interval = params ? params->getIntValue(YSTRING("interval"),mySpan->osiInterval(),0) : mySpan->osiInterval();
    if (interval)
        s << "(to=" << interval << ")":
    sendRequest(s);
}
return false;