[[mncc]]
== MNCC for External Call Control

The 3GPP GSM specifications define an interface point (service access
point) inside the MSC between the call-control part and the rest of the
system.  This service access point is called the MNCC-SAP.  It is
described in _3GPP TS 24.007_ <<3gpp-ts-24-007>> Chapter 7.1.

However, like for all internal interfaces, 3GPP does not give any
specific encoding for the primitives passed at this SAP.

The MNCC protocol has been created by the Osmocom community
and allows to control the call handling and audio processing by an
external application. The interface is currently exposed using Unix
Domain Sockets. The protocol is defined in the `mncc.h` header file.

It is exposed by the Osmocom MSC layer (both in the old OsmoNITB as well as the
new OsmoMSC.

{program-name} can run in two different modes:

. with internal MNCC handler
. with external MNCC handler

=== Internal MNCC handler

When the internal MNCC handler is enabled, {program-name} will switch voice
calls between GSM subscribers internally and automatically based on the
the subscribers _extension_ number.  No external software is required.

NOTE: Internal MNCC is the default behavior.

==== Internal MNCC Configuration

The internal MNCC handler offers some configuration parameters under the
`mncc-int` VTY configuration node.

===== `default-codec tch-f (fr|efr|amr)`

Using this command, you can configure the default voice codec to be used
by voice calls on TCH/F channels.

===== `default-codec tch-h (hr|amr)`

Using this command, you can configure the default voice codec to be used
by voice calls on TCH/H channels.

[[mncc-external]]
=== External MNCC handler

When the external MNCC handler is enabled, {program-name} will not perform
any internal call switching, but delegate all call-control handling towards the
external MNCC program connected via the MNCC socket.

If you intend to operate {program-name} with external MNCC handler, you have
to disable the internal MNCC handler and specify the MNCC socket path in
the configuration file.

At the time of this writing, there are only two known open source applications implementing the
MNCC interface compatible with the Osmocom MNCC socket:

* historically `lcr`, the Linux Call Router (support for modern MNCC protocol versions may be missing)
* `osmo-sip-connector`, the more up-to-date integration of external call routing by translating MNCC into a SIP trunk towards an external SIP PBX / switch.


=== DTMF considerations

In mobile networks, the signaling of DTMF tones is implemented differently,
depending on the signaling direction. A mobile originated DTMF tone is
signaled using START/STOP DTMF messages which are hauled through various
protocols upwards into the core network.

Contrary to that, a mobile terminated DTMF tone is not transferred as an out of
band message. Instead, in-band signaling is used, which means a tone is injected
early inside a PBX or MGW.

When using {program-name} with its built in MNCC functionality a mobile
originated DTMF message will not be translated into an in-band tone. Therefore,
sending DTMF will not work when internal MNCC is used.

For external MNCC, the network integrator must make sure that the back-end
components are configured properly in order to handle the two different
signaling schemes depending on the signaling direction.

NOTE: osmo-sip-connector will translate MNCC DTMF signaling into sip-info
messages. DTMF signaling in the opposite direction is not possible.
osmo-sip-connector will reject sip-info messages that attempt to signal
a DTMF tone.


=== MNCC protocol description

The protocol follows the primitives specified in 3GPP TS 04.07 Chapter 7.1.
The encoding of the primitives is provided in the `mncc.h` header file in
{program-name}'s source tree, which uses some common definitions from
`osmocom/gsm/mncc.h` (part of libosmocore.git).

However, Osmocom's MNCC specifies a number of additional primitives beyond
those listed in the 3GPP specification.

The different calls in the network are distinguished by their callref
(call reference), which is a unique unsigned 32bit integer.

==== MNCC_HOLD_IND

Direction: {program-name} -> Handler

A 'CC HOLD' message was received from the MS.

==== MNCC_HOLD_CNF

Direction: Handler -> {program-name}

Acknowledge a previously-received 'CC HOLD' message, causes the
transmission of a 'CC HOLD ACK' message to the MS.

==== MNCC_HOLD_REJ

Direction: Handler -> {program-name}

Reject a previously-received 'CC HOLD' message, causes the
transmission of a 'CC HOLD REJ' message to the MS.

==== MNCC_RETRIEVE_IND

Direction: {program-name} -> Handler

A 'CC RETRIEVE' message was received from the MS.

==== MNCC_RETRIEVE_CNF

Direction: Handler -> {program-name}

Acknowledge a previously-received 'CC RETRIEVE' message, causes the
transmission of a 'CC RETRIEVE ACK' message to the MS.

==== MNCC_RETRIEVE_REJ

Direction: Handler -> {program-name}

Reject a previously-received 'CC RETRIEVE' message, causes the
transmission of a 'CC RETRIEVE REJ' message to the MS.

==== MNCC_USERINFO_REQ

Direction: {program-name} -> Handler

Causes a 'CC USER INFO' message to be sent to the MS.

==== MNCC_USERINFO_IND

Direction: {program-name} -> Handler

Indicates that a 'CC USER-USER' message has been received from the MS.

==== MNCC_BRIDGE

Direction: Handler -> {program-name}

Requests that the TCH (voice) channels of two calls shall be
inter-connected.   This is the old-fashioned way of using MNCC,
historically required for circuit-switched BTSs whose TRAU frames are
received via an E1 interface card, and works only when the TCH channel types
match.

NOTE: Internal MNCC uses MNCC_BRIDGE to connect calls directly between
connected BTSs or RNCs, in effect disallowing calls between mismatching TCH
types and forcing all BTSs to be configured with exactly one TCH type and
codec. This is a limitation that will probably remain for the old OsmoNITB. For
the new OsmoMSC, the MNCC_BRIDGE command will instruct the separate OsmoMGW to
bridge calls, which will be able to handle transcoding between different TCH as
well as 3G (IuUP) payloads (but note: not yet implemented at the time of
writing this). Hence an external MNCC may decide to bridge calls directly
between BTSs or RNCs that both are internal to the OsmoMSC, for optimization
reasons.

==== MNCC_FRAME_RECV

Direction: Handler -> {program-name}

Enable the forwarding of TCH voice frames via the MNCC interface in
{program-name}->Handler direction for the specified call.

==== MNCC_FRAME_DROP

Direction: Handler -> {program-name}

Disable the forwarding of TCH voice frames via the MNCC interface in
{program-name}->Handler direction for the specified call.

==== MNCC_LCHAN_MODIFY

Direction: Handler -> {program-name}

Modify the current dedicated radio channel from signalling to voice, or
if it is a signalling-only channel (SDCCH), assign a TCH to the MS.

==== MNCC_RTP_CREATE

Direction: Handler -> {program-name}

Create a RTP socket for this call at the BTS/TRAU that serves this BTS.

==== MNCC_RTP_CONNECT

Direction: Handler -> {program-name}

Connect the RTP socket of this call to the given remote IP address and
port.

==== MNCC_RTP_FREE

Direction: Handler -> {program-name}

Release a RTP connection for one given call.

==== GSM_TCHF_FRAME

Direction: both

Transfer the payload of a GSM Full-Rate (FR) voice frame between the
{program-name} and an external MNCC handler.

==== GSM_TCHF_FRAME_EFR

Direction: both

Transfer the payload of a GSM Enhanced Full-Rate (EFR) voice frame
between the {program-name} and an external MNCC handler.

==== GSM_TCHH_FRAME

Direction: both

Transfer the payload of a GSM Half-Rate (HR) voice frame between the
{program-name} and an external MNCC handler.

==== GSM_TCH_FRAE_AMR

Direction: both

Transfer the payload of a GSM Adaptive-Multi-Rate (AMR) voice frame
between the {program-name} and an external MNCC handler.

==== GSM_BAD_FRAME

Direction: {program-name} -> Handler

Indicate that no valid voice frame, but a 'bad frame' was received over
the radio link from the MS.

==== MNCC_START_DTMF_IND

Direction: {program-name} -> Handler

Indicate the beginning of a DTMF tone playback.

==== MNCC_START_DTMF_RSP

Direction: Handler -> {program-name}

Acknowledge that the DTMF tone playback has been started.

==== MNCC_START_DTMF_REJ

Direction: both

Indicate that starting a DTMF tone playback was not possible.

==== MNCC_STOP_DTMF_IND

Direction: {program-name} -> Handler

Indicate the ending of a DTMF tone playback.

==== MNCC_STOP_DTMF_RSP

Direction: Handler -> {program-name}

Acknowledge that the DTMF tone playback has been stopped.
