Hívások

Fontos

Ez az oldal részletezi a Jami-fiókok alapelvét. SIP-fiókok esetén a SIP-protokollt használják.

Hívjuk Jami-t!

Rendszerfolyamatoldali

Amikor két társa között hívást készít, Jami főleg ismert protokollokat használ, mint például az ICE, a SIP vagy a TLS. Azonban, hogy eloszlatják, a hívás létrehozásának folyamata kissé más. Összefoglalva, amikor valaki kapcsolatba lép egy kapcsolattartójával, ezt teszik:

  1. Keresse meg a kapcsolattartó jelenlétét a DHT-hálózaton (további részletekért lásd: A kapcsolatkezelés).

  2. Miután megtalálta a kapcsolattartót, küldjön egy hívási kérelmet, amelyben közölje az ismert jelölteket (minden hálózati felület IP-címe + közvetítőcímek (TURN) + reflexív címek (UPnP, nyilvános).

  3. Várja meg a kapcsolattartó válaszát (az ismert címeire fog válaszolni).

  4. A csatorna egyeztetése ICE-rejtjelezéssel. Valójában két ICE-munkamenet kerül egyeztetésre. Egy (előnyben részesített) a TCP-protokollban, egy pedig az UDP-protokollban (tartalékként).

  5. A csatornát ezután TLS protokollal (TCP protokoll esetén) vagy DTLS protokollal (UDP protokoll esetén) titkosítják.

  6. A kapcsolattartó most már képes elfogadni vagy elutasítani a hívást. Amikor fogadja a hívást, egy ICE átviteli protokollon (egyelőre csak UDP) keresztül történik a hívás egyeztetése, amely 4 új csatornákat hoz létre a média számára (2 a hanghoz, 2 a videóhoz).

  7. A hívás most él!

A cseréjeICE jelöltek

Minden a jamiaccount.cpp (JamiAccount::startOutgoingCall) fájlban kezdődik. Amint mindkét ICE-objektum elkészült, és a kapcsolat megtalálható a DHT-hálózaton keresztül, létrejön a híváskérés a kapcsolathoz. Ez a kérés tartalmazza a távoli ICE-munkamenethez szükséges összes információt, amelyet a következők határoznak meg:

dht::IceCandidates(callvid,  blob)

ahol:

  • A callvid egy véletlenszerű szám, amely a hívás azonosítására szolgál, és

  • A blob két összefűzött ICE-üzenetet tartalmaz (IceTransport::packIceMsg az ice_transport.cpp fájlban), amelyek tartalmazzák a munkamenet jelszavát, az ufrag-ot és az ICE-jelölteket, mint például:

0d04b935
7c33834e7cf944bf0e367b42
H6e6ca382 1 UDP 2130706431 2607:fad8:4:6:9eb6:d0ff:dead:c0de 14133 typ host
H42c1g477 1 UDP 2130706431 fe80::9eb6:d0ff:fee7:1412 14133 typ host
Hc0a8027e 1 UDP 2130706431 192.168.0.123 34567 typ host
Sc0a8027e 1 UDP 1694498815 X.X.X.X 32589 typ srflx
0d04b932
7c33834e7cf944bf0e367b47
H6e6ca682 1 TCP 2130706431 2607:fad8:4:6:9eb6:d0ff:dead:c0de 50693 typ host tcptype passive
H6e6ca682 1 TCP 2130706431 2607:fad8:4:6:9eb6:d0ff:dead:c0de 9 typ host tcptype active
H42c1b577 1 TCP 2130706431 fe80::9eb6:d0ff:fee7:1412 50693 typ host tcptype passive
H42c1b577 1 TCP 2130706431 fe80::9eb6:d0ff:fee7:1412 9 typ host tcptype active
Hc0a8007e 1 TCP 2130706431 192.168.0.123 42751 typ host tcptype passive
Hc0a8007e 1 TCP 2130706431 192.168.0.123 9 typ host tcptype active
Sc0a8007e 1 TCP 1694498815 X.X.X.X 42751 typ srflx tcptype passive

és a DHT hálózaton keresztül titkosított üzenetben kerül elküldésre az eszköznek a hash(callto:xxxxxx) utasítással, ahol az xxxxxx az eszköz azonosítója. A társ pontosan ugyanazon a helyen (de a küldő eszköz számára titkosítva) válaszol a saját dht::IceCandidates'-ére. További részletekért lásd a JamiAccount::replyToIncomingIceMsg` leírást.

Az ICE-munkamenet mindkét oldalon létrejön, amikor az összes jelölt megvan (azaz a küldőnél, amikor a kapcsolattartótól megérkezik a válasz).

A JCE tárgyalása

Pending calls are managed by JamiAccount::handlePendingCallList(), which first wait for the TCP negotiation to finish (and if it fails, wait for the UDP one). The code for the ICE negotiation is mainly managed by pjproject but for Jami, the interesting part is located in ice_transport.cpp. Moreover, we add some important patches/features on top of pjproject not merged upstream for now (for example, ICE over TCP). These patches are present in contrib/src/pjproject.

Titkosítsd a vezérlőcsatornát

Once the socket is created and managed by an IceTransport instance, it is then wrapped in a SipTransport corresponding to a TlsIceTransport. The main code is located in JamiAccount::handlePendingCall() and the wrapping is done in SipTransportBroker::getTlsIceTransport. Finally, our session is managed by TlsSession in daemon/src/security/tls_session.cpp and uses the GnuTLS library.

So, the control socket will be a TLS (1.3 if you and your peer’s GnuTLS version supports it) if a TCP socket is negotiated. If a UDP socket is negotiated instead (due to firewall restrictions/problems in the negotiation/etc.), the socket will use DTLS (still managed by the same parts).

The control socket is used to transmit SIP packets, like invites, custom messages (Jami sends the vCard of your profile on this socket at the start of the call, or the rotation of the camera), and text messages.

Rendszeres:

A médiacsatornák

Media sockets are SRTP sockets where the key is negotiated through the TLS session previously created.

Figyelem

TEENDŐ: Ez a rész hiányos.

Építészet

Figyelem

TEENDŐ: Ez a rész hiányos.

Adatfolyamok

Since daemon version 13.3.0, multi-stream is fully supported. This feature allows users to share multiple videos during a call at the same time. In the following parts, we will describe all related changes.

PJSIP

The first part is to negotiate enough media streams. In fact, every media stream uses 2 UDP sockets. We consider three scenarios:

  1. If it’s the host of a conference who wants to add media, there is nothing more to negotiate, because we already mix the videos into one stream. So, we add the new media directly to the video mixer without negotiations.

  2. Ha 1:1-ban vagyunk, mostantól, mivel nincs konferencia információ, a multi-stream nem támogatott.

  3. Egyébként 2 új csatornát tárgyalnak az új média számára.

To make PJSIP able to generate more sockets per ICE session, PJ_ICE_COMP_BITS was modified to \(5\) (which corresponds to \(2^5\), so \(32\) streams).

Deprecate switchElet, támogatási kérésMediaChange

A daemonban a régi API switchInput most DEPRECATED; ugyanaz a switchSecondaryInput:

<method name="switchInput" tp:name-for-bindings="switchInput">
    <tp:docstring>
        Switch input for the specified call
    </tp:docstring>
    <arg type="s" name="accountId" direction="in"/>
    <arg type="s" name="callId" direction="in"/>
    <arg type="s" name="input" direction="in"/>
    <arg type="b" direction="out" />
</method>

<method name="switchSecondaryInput" tp:name-for-bindings="switchSecondaryInput">
    <tp:added version="11.0.0"/>
    <tp:docstring>
        Switch secondary input for the specified conference
    </tp:docstring>
    <arg type="s" name="accountId" direction="in" />
    <arg type="s" name="conferenceId" direction="in"/>
    <arg type="s" name="input" direction="in"/>
    <arg type="b" direction="out" />
</method>

requestMediaChange helyettesíti ezt mind a hívások, mind a konferenciák esetében:

<method name="requestMediaChange" tp:name-for-bindings="requestMediaChange">
    <tp:added version="11.0.0"/>
    <tp:docstring>
        <p>Request changes in the media of the specified call.</p>
    </tp:docstring>
    <arg type="s" name="accountId" direction="in" />
    <arg type="s" name="callId" direction="in">
        <tp:docstring>
        The ID of the call.
        </tp:docstring>
    </arg>
    <annotation name="org.qtproject.QtDBus.QtTypeName.In2" value="VectorMapStringString"/>
    <arg type="aa{ss}" name="mediaList" direction="in">
        <tp:docstring>
        A list of media attributes to apply.
        </tp:docstring>
    </arg>
    <arg type="b" name="requestMediaChangeSucceeded" direction="out"/>
</method>

Compatibility

If a call is done with a peer where the daemon’s version is < 13.3.0, multi-stream is not enabled, and the old behavior is used (1 video only).

Stream identification

Mivel most több stream is lehet, minden médiaáram azonosítója alapján azonosítható, és a formátum „_”; például: „audio_0”, „video_2”, stb.

Forgatás

Az XML frissült, hogy hozzáadja a kívánt áramot:

<?xml version="1.0" encoding="utf-8" ?>
<media_control>
  <vc_primitive>
    <stream_id>{}</stream_id>
    <to_encoder>
      <device_orientation>0</device_orientation>
    </to_encoder>
  </vc_primitive>
</media_control>

Főkerék

Az XML frissült, hogy hozzáadja a kívánt áramot:

<?xml version="1.0" encoding="utf-8" ?>
<media_control>
  <vc_primitive>
    <stream_id>{}</stream_id>
    <to_encoder><picture_fast_update/></to_encoder>
  </vc_primitive>
</media_control>

Hangtevékenység

The XML was updated to add the required stream:

<?xml version="1.0" encoding="utf-8" ?>
<media_control>
  <vc_primitive>
    <stream_id>{}</stream_id>
    <to_encoder>
      <voice_activity>true</voice_activity>
    </to_encoder>
  </vc_primitive>
</media_control>

Konferencia

A tükrözött változásokat itt dokumentáljuk.

Ügyfél

Even if the back-end supports up to 32 media at the same time, except for custom clients, we currently recommend only giving the ability to share one camera and one video at the same time. The camera is controlled via the camera button, and the other media via the „Share” button.

In client-qt, the interesting part is in AvAdapter (methods like isCapturing, shareAllScreens, stopSharing). In the library’s logic, addMedia and removeMedia in the callModel directly use the requestMediaChange, and can be used as a design reference.