Uwagi
=====

* Za imlementację można zdobyć 7 punktów.

* Programy powinny realizować podany protokół, więc powinny umieć się
  dogadać z programami innych studentów.

* Aby uzyskać 5 punktów wystarczy zrealizowanie pełnej funkcjonalności bez
  grup i jakiejś jednej funkcjonalności z grupami. Np. nie musi sie dać
  odbierać i odwieszać połączeń, które przyszły/zostały zawieszone przez
  inną osobę w grupie. Jak ktoś do nas dzwoni lub zawiesiliśmy, to mówimy
  innym w grupie po prostu, że linia jest w stanie TALK, nie dając im
  możliwości odebrać. Wystarczy więc, że w obrębie grupy każdy będzie
  rozmawiał sobie sam, a wspólnie kontrolowana będzie jedynie zajętość ich
  linii. Dobrze by było, gdyby tak okrojone programy współpracowały z innymi
  programami, również w obrębie grupy (aczkolwiek w tym wypadku
  kompatybilność w ramach grupy nie jest bezwzględnie konieczna do uzyskania
  5 pkt).

* Ponieważ w "uwagach dodanych po ogłoszeniu treści zadania" napisane jest,
  że można założyć, że wszystkie telefony w grupie działają, to aby uzyskać
  7 (lub 5) punktów nie trzeba implementować części protokołu dotyczącej
  sytuacji, gdy tak nie jest. Widzę tu 3 możliwe podejścia:
  1) Działa wszystko.
  2) Zakładamy, że łączność z telefonami w grupie z jakichś magicznych
     powodów nie zaniknie i że nie zostaną one w brutalny sposób ubite. Nie
     robimy rozdziału "Konflikty", rozdziału "Kontrola WLT", reagowania na
     "WLT_RESET". Wszystko jednak działa dobrze, gdy część telefonów w
     grupie jest wyłączona (zakładając, że przed wyłączeniem się telefon
     zawsze zrobi "WLT_PUSH" na posiadanych liniach).
  3) Póki wszystkie telefony w grupie nie są włączone nie musi działać
     dzwonienie, odbieranie, itp. Pomijamy to co w 2 oraz obsługę "WLT_PUSH"
     oraz przy "WLT_POP" możemy założyć, że druga strona reaguje (jeśli
     jednak nie reaguje, to po upłynięciu jakiegoś timeoutu trzeba
     poinformować o błędzie i np. zakończyć program). Przy czym należy
     zwrócić uwagę, żeby dało się uruchomić telefony (gdy włączamy pierwszy
     telefon, to pozostałe są jeszcze wyłączone).
  Zatem wystarczy zrobić punkt 3, jednak zrobienie 2 lub 1 wpływa pozytywnie
  na ocenę w przypadku innych braków.

* Podobnie rozsyłanie i obsługa "WLT_PING" są tylko opcjonalne.

* Laboratorium zalicza uzyskanie w sumie co najmniej 6 pkt. Dodatkowe punkty
  dają bonus na egzaminie:
  Punkty z laboratorium   Dodatkowe punkty z egzaminu
  10p             ->      3p
  9p              ->      2p
  7-8p            ->      1p

* Ostateczny termin oddawania programów: do końca sesji, tj. do 30.06.2007.
  Polecam jednak wcześniejsze oddawanie.



Poniżej opis protokołu, który należy zrealizować:

Autor: Bartłomiej Romański


Opis protokołu do symulacji centralki telefonicznej na SIK
===========================================================


Cele protokołu
---------------

Protokół ma umożliwiać symulację działania centralki telefonicznej
zgodnie z opisem z treści zadania.




Uwagi ogólne
-------------

'Telefon' oznacza pojedyńczy program działający w ramach symulacji.

'Numer telefonu' oznacza parę adres IP (ew. host) i numer portu.

Wszystki użyte ponizej znaki cudzysłowu mają na celu jedynie
wyróżnienie fragmentu tekstu i nigdy nie są częścią komunikatu
 - nie są przesyłane!




Format komunikatów
--------------------

Typowy komunikat wygląda następująco:

"TYP PARAMETR1 PARAMETR2 PARAMETR\n"

Pojedyńczy komunikat to jedna linia tekstu w standardzie ASCII zakończona
"\n". Telefony powinny obsługiwać zarówno standard Unix jak i Windows.

Poszczególne składowe (typ i parametry) komunikatu oddzielone są pojedyńczą
spacją. Składowe nigdy nie zawierają spacji ani znaków o kodzie ASCII równym
10 lub 13, więc interpretacja komunikatów jest zawsze jednoznaczna.

Drobny wyjątek stanowi komunikat MSG (opisany dalej).

Liczby całkowite przesyłamy w postaci ich standardowego zapisu dziesiętnego,
bez nadmiarowych zer wiodących. Numery telefonów przesyłamy w postaci
"ADRES_IP:PORT" np. "192.168.0.1:80". Pola 'nieokreślone' przesyłamy w
postaci "-", np. "TYP P1 - P3\n".

Poniżej komunikaty opisuje już w formie skróconej.



Połączenia
-----------

Każdy z telefonów nasłuchuje na swoim porcie połączeń TCP-IP od innych
klientów. Telefon inicjujący połączenie zawsze jako pierwszy komunikat
przesyła 'HI' (opisany poniżej). Nie należy na niego odpowiadać.





Stan WLT
---------

WLT w ramach grupy ponumerowane są kolejnymi liczbami naturalnymi startując
od 1. W obrębie grupy będzie nie więcej niż 10000 WLT. WLT może być 'czyjeś'
(dowolnego telefonu w grupie) lub 'niczyje'. Każde WLT 'czyjeś' ma swój
'stan'. Na 'stan' składa się:

status     - jedna z wartości: "FREE", "RING", "CALL", "TALK", "L_SUSP" lub "R_SUSP"
remote_num - numer 'zdalnego' telefonu
remote_wlt - numer 'zdalnego' WLT

W przypadku statusu FREE pola remote_num i remote_wlt są 'nieokreślone',
wpp. określone (za połączenie zawsze odpowiada po jednym WLT i jednym
telefonie z każdej strony).

WLT niczyje domyślnie mają stan "FREE".

Statusy należy interpretować następująco:

FREE - linia jest wolna
RING - ktoś do nas dzwoni, jeszcze nikt nie odebrał
CALL - my do kogoś dzwonimy, jeszcze nikt nie odebrał
TALK - trwa rozmowa
L_SUSP - my zawiesiliśmy połączenie
R_SUSP - rozmówca zawiesił połączenie

Każdy telefon utrzymuje informacje o stanie każdej WLT oraz informacje o
'właścicielu' każdego WLT. Protokół dba o to, aby ta informacja była spójna.





Typy komunikatów (zarządzanie WLT)
-----------------------------------

Do zarządzania WLT w ramach grupy służy klika komunikatów-poleceń o nazwach
zaczynających się od "WLT_". Na każdy z nich należy odpowiedzieć dokładnie
jednym komunikatem-odpowiedzią. Komunikaty "WLT_" przesyłamy tylko wewnątrz
grupy. Aby skorzystać z komunikatów "WLT_" należy nawiązać nowe połączenie
TCP-IP, połączenie zrywa tylko strona inicjująca. W ramach jednego
połączenia można przesłać dowolnie wiele komunikatów-poleceń, jednak
komunikaty polecenia może przesyłać tylko strona inicująca. Połączeń użytych
do komunikatów "WLT_" nie wolno używać w innym celu! Nie zaleca się
utrzymywania tych połączeń dłużej niż jest to niezbędne, jednak nie wpływa
to na funkcjonowanie protokołu.

Oto możliwe komunikaty-polecenia:



WLT_WANT <wlt> <prio>
----------------------

Taki komunikat wysyłamy do wszystkich telefonów w grupie, jeśli
podejrzewamy, że WLT o numerze <wlt>. Jest 'niczyje' i chcemy aby było
'nasze'. Wartość <prio> jest losową liczbą naturalną z przedziału 1 do 2^30.
Możliwe odpowiedzi to: ""OK", "NO" lub "OWNER".

Szczegóły w opisie przejmowania WLT.




WLT_STATUS <wlt> <status> <remote_num> <remote_wlt>
----------------------------------------------------

Taki komunikat informuje o zmianie stanu WLT o numerze <wlt>. Autor tego
komunikatu jest aktualnym 'właścicielem' danego WLT (mógł się zmienić).
Możliwa odpowiedź to tylko "OK", jesteśmy zobowiązani zaktualizować nasze
informacje. Jeśli to my myśleliśmy, że 'mamy' to WLT oznacza to, że wystąpił
'konflikt' - rozsyłamy do wszystkich WLT_RESET (patrz opis).

Parametry:

<status>     - jedna z wartości: "FREE", "RING", "CALL", "TALK", "L_SUSP" lub "R_SUSP"
<remote_num> - numer 'zdalnego' telefonu
<remote_wlt> - numer 'zdalnego' WLT



WLT_PUSH <wlt>
---------------

Taki komunikat nakazuje odbiorcy 'przejęcie' danego WLT. Możliwe odpowiedzi
to "OK" lub "NO". Odpowiedź OK zobowiązuje nowego właściciela do rozesłania
komunikatów WLT_STATUS z informacją o zmianie. Raczej nie należy odpowiadać
"NO", jeśli nie mamy ważnego powodu - np. sami kończymy pracę. Bezpośrednio
przed WLT_PUSH należy wysłać WLT_STATUS, aby potwierdzić spójność informacji
o danym WLT!

Jeśli linia była w stanie RING lub L_SUSP oznacza to, że poprzedni
właściciel (nazwijmy go A) utrzymywał połączenie TCP-IP ze zdalnym telefonem
B. Przed odpowiedzią OK musimy, więc przygotować się na przejęcie tego
połączenia. Po otrzymaniu odpowiedzi telefon A wysyła do B komunikat SWITCH
nakazując mu rozłączenie bieżącego połączenia TCP-IP oraz nawiązanie
połączenia z nowym właścicielem (czyli z nami). Nowy właściciel powinien
oczekiwać połączenia od B zaczynającego się od odpowiedniego komunikatu
CONT. Jeśli nowy właściciel nie odebrał połączenia od B w przeciągu 3s od
otrzymania od A odpowiedzi OK powinien uznać, że linia przechodzi w stan
FREE. (wartość 3s może zostać zmieniona - nie wpływa to bezpośrednio na
działanie protokołu)

Przejęcie WLT zobowiązuje do rozesłania WLT_STATUS.



WLT_CHECK <wlt> 
----------------

Taki komunikat wysyłamy, jeśli chcemy sprawdzić stan danego WLT. Możliwe
odpowiedzi to:

"OK <status> <remote_num> <remote_wlt>"
"ASK <local_num>"

Jeśli jesteśmy właścicielem danego WLT w odpowiedzi OK zwracamy stan danej
linii. Jeśli nie w odpowiedzi ASK w parametrze <local_num> podajemy adres
właściciela danego WLT. (może być 'nieokreślony'!)

Z odpowiedzią na WLT_CHECK należy się wstrzymać, jeśli status linii jest
niejasny, tzn. jesteśmy w trakcie wykonywania jakiejść operacji (np.
wysłaliśmy WLT_PUSH lub WLT_POP i czekamy na odpowiedź).



WLT_POP <wlt> <status> <remote_num> <remote_wlt>
-------------------------------------------------

Taki komunikat wysyłamy do właściciela WLT, jeśli chcemy je przejąć.
Podajemy jego stan według nas, aby potwierdzić, że wiemy co przejmujemy.

Możliwe odpowiedzi to "MIS", "NO" lub "OK". Odpowiadamy MIS jeśli stan się
nie zgadza lub NO jeśli nie chcemy oddać naszej WLT, bo np. właśnie
zabieramy się do dzwonienia.

Można przejmować tylko linie w stanie FREE, RING lub L_SUSP.

Jeśli linia była w stanie RING lub L_SUSP oznacza to, że poprzedni
właściciel (nazwijmy go A) utrzymywał połączenie TCP-IP ze zdalnym telefonem
B. Przed wysłaniem WLT_POP musimy, więc przygotować się na przejęcie tego
połączenia. Po otrzymaniu WLT_POP telefon A wysyła do B komunikat SWITCH
nakazując mu rozłączenie bieżącego połączenia TCP-IP oraz nawiązanie
połączenia z nowym właścicielem. Nowy właściciel powinien oczekiwać
połączenia od B zaczynającego się od odpowiedniego komunikatu CONT.
Równolegle A wysyła odpowiedź OK do nowego właściciela. Jeśli nowy
właściciel nie odebrał połączenia od B w przeciągu 3s od otrzymania od A
odpowiedzi OK powinien uznać, że linia przechodzi w stan FREE. (wartość 3s
może zostać zmieniona - nie wpływa to bezpośrednio na działanie protokołu)

Z odpowiedzią na WLT_POP należy się wstrzymać, jeśli wysłaliśmy już
WLT_PUSH, a jeszcze nie dostaliśmy odpowiedzi.

Przejęcie WLT zobowiązuje do rozesłania WLT_STATUS.




WLT_RESET <wlt>
----------------

Otrzymanie takiego komunikatu zobowiązuje nas do uznania danego WLT za
'niczyje'. Jeśli było to 'nasze' WLT musimy rozłączyć ew. związane z nim
połączenie.

Komunikat jest rozysłany do wszystkich telefonów w grupie, jeśli ktoś
wykryje konflikt, czyli np. otrzyma WLT_STATUS od kogoś innego, jeśli sam
uważał się za właściciela.




Inicjacja WLT
--------------

Domyślnie wszystkie WLT są 'niczyje'. Telefon po uruchomieniu próbuje
nawiązać połączenie TCP-IP z dowolnym innym telefonem w grupie i ustalić
stan wszystkich WLT. (używa komunikatów WLT_CHECK).



Przejmowanie WLT
-----------------

Proces przejmowania 'niczyjego' WLT wygląda następująco.

Podejrzewamy, że dane WLT jest niczyje. Losujemy dla nas wartość 'prio'.
Odpytujemy wszystkie telefony w grupie komunikatami WTL_WANT. Jeśli
dostaniemy odpowiedź OWNER lub NO anulujemy przejmowanie. Jeśli w trakcie
przejmowania dostaniemy WTL_WANT z większym (lub równym) 'prio' odpowiadamy
OK i anulujemy przejmowanie. Jeśli dostaniemy WTL_WANT z mniejszym 'prio'
odpowiadamy 'NO'. Jeśli pozbieramy od wszystkich OK stajemy się
właścicielami WTL - rozsyłamy dumnie WTL_STATUS. Jeśli mamy nasze WLT i
dostaniemy WLT_WANT odpowiadamy OWNER. Jeśli nie jesteśmy właścicielami WTL
i nie jesteśmy w trakcie przejmowania na WTL_WANT odpowiadamy zawsze OK.

Jeśli w trakcie odpytywania komunikatów WLT_WANT niektóre telefony nie
odpowiadają (są wyłączone lub odłączone od sieci) uznajemy je za 'martwe',
traktujemy brak odpowiedzi jak OK.

Wartość 'prio' ma na celu roztrzyganie konfliktów przy próbie równoczesnego
przejęcia WTL przez wiele różnych telefonów. Wylosowanie identycznego 'prio'
choć mało prawdopodobne prowadzi do anulowania przejmowania przez obie
strony. WLT pozostanie niczyje, za jakiś czas ktoś może spróbować znowu je
przejąć.

Przejmowanie WTL potrzebne jest na starcie oraz w przypadku 'śmierci'
telefonu, który miał kilka WTL i nie zdążył ich oddać przed odłączeniem od
sieci.

Warto przejmować 'niczyje' WLT, gdyż odbieranie WLT komuś jest istotnie
szybsze niż proces przejmowania 'niczyjego' WLT. Telefony powinny zawsze
próbować przejąć WLT, które wyglądaja na niczyje.



Kontrola WLT
-------------

Każdy z aktywnych telefonów zobowiązany jest pamiętać stan wszystkich WLT w
grupie oraz czas ostatniej aktualizacji tej informacji. Jeśli czas ten jest
zbyt duży, a linia nie jest w stanie FREE, to telefon powienien wykonać
WTL_CHECK, aby upewnić się, że właściciel danego WLT ciągle żyje. Jeśli nie
odpowiada podejrzewamy daną WLT za niczyją i rozpoczynamy proces
przejmowania niczyjego WLT. Regularne odpytywanie właścicieli WLT zapobiega
sytuacjom kiedy telefon przejmie kilka WLT i utraci łączność z siecią.
Częstotliwość odpytywania nie wpływa na funkcjonowanie protokołu
- pojedyńcze telefony mogą odpytywać z różną częstotliwością. Zalecana jest wykonanie
WLT_CHECK co 10s. Na liniach o statusie FREE, których właściciel nie wydaje się martwy
z innych powodów, nie ma konieczności wykonywania WLT_CHECK (aby nie powodować ruchu 
w sieci, gdy nic się nie dzieje).

Telefon przed odłączeniem się od sieci powinien wykonać WLT_PUSH na
wszystkich swoich liniach, aby nie powodować konieczności wywoływania całej
procedury przejmowania WLT.

Aby ograczniczy konieczność częstego nawiązywania połączeń TCP-IP tylko w
celu kontroli danego WLT można zdefiniować komunikat wysyłany po UDP o
następującym formacie

"WLT_PING <who> <wlt1> <wlt2> ...\n"

Gdzie w polu <who> wpisujemy nasz numer telefonu, a następnie numery
wszystkich WLT, które posiadamy. Taki komunikat wysyłamy co 8s do wszystkich
telefonów w grupie po UDP o ile posiadamy chociaż jedną linię w stanie innym
niż FREE. Oznacza on, że podtrzymujemy, że jesteśmy właścicielami tych linii
i nadal żyjemy. Otrzymanie takiego komunikatu resetuje licznik czasu u
innych telefonów, dopiero jak nie dostaniemy takiego komunikatu telefon
powinien wywoływać WLT_CHECK. Na WLT_PING nie należy w żadne sposób
odpowiadać.

Telefony (nawet w ramach jednej grupy) mogą, ale nie muszą implementować
obsługę tego komunikatu. Nie powoduje to błędów w działaniu protokołu.




Konflikty
----------

W sytaucji gdy część grupy utraci łączność z pozostałymi obie podgrupy
uznają drugą połowę za telefony martwe i obie podgrupy uznają, że mają do
dyspozycji wszystkie WLT. Po odzyskaniu łączności może pojawić się konflikt
- jedno WLT wykorzystywane jest przez 2 telefony. Sytuacja taka może
utrzymywać się do czasu, aż któryś telefon wykryje konflikt (np. dostanie
WLT_STATUS/odpowiedź OK na WLT_CHECK, a sam myślał, że jest właścicielem tej
lini). W takiej sytuacji powinien zostać rozesłany WLT_RESET, a linia
przejść obowiązkowo w stan FREE i stać się 'niczyja' - później można ją
przejąć.

Jeśli konflikt zostanie wykryty za pomocą WLT_PING (tzn. otrzymamy WLT_PING
z numerem linii, którą myślimy, że my posiadamy), to nie wysyłamy od razu
WLT_RESET. Pytamy wtedy za pomocą WLT_CHECK niby-właściciela naszej linii i
dopiero jeśli tym sposobem konflikt potwierdzi się, to wysyłamy WLT_RESET.
Należy tak robić, gdyż komunikaty po UDP mogą rozsynchronizować się z innymi
i z tego powodu może się wydawać, że jest jakiś konflikt.




Typy komunikatów (połączenie)
-----------------------------


HI <local_num>
---------------

Komunikat wysyłamy zawsze po zainicjowaniu połączenia (wysyła tylko
inicjujący i tylko na początku). <local_num> oznacza nasz numer telefonu. Na
komunikat HI nie należy odpowiadać. Komunikat HI wysyłamy także przy
nawiązywaniu połączeń do komunikatów "WLT_"!


RING <wlt>
-----------

Oznacza chęć zadzwonienia, podajemy nr naszego lokalnego WLT z którego
chcemy zadzwonić. Można wysłać tylko bezpośrednio po HI.


BUSY
-----

Odpowiedź na RING - linia zajęta, po otrzymaniu tego komunikatu powinniśmy
przerwać powinniśmy zerwać łącze TCP-IP.


OK <wlt>
---------

Odpowiedź na RING - zwrócony zostaje nr lini WLT po stronie osoby do której
dzwonimy. Od tej pory telefon "dzwoni". Lnia zmienia status na CALL lub RING
(odpowiednio po każdej stronie).


ANS
----

Można wysłać tylko jeśli linia była w stanie RING lub L_SUSP. Oznacza
podniesienie słuchawki, odebranie dzwonka lub odwieszenie połączenia. Linia
przechodzi po obu stronach w stan TALK. Od tej pory można wysyłać komunikaty
MSG. ANS nie należy bezpośrednio potwierdzać.



MSG (specjalny!)
-----------------

Specjalny komunikat o formacie "MSG treść\n". Pierwsze 4 znaki to "MSG ", a
cała reszta lini (aż do "\n", wyłącznie) to treść wiadomości. Np.

"MSG How od you do?\n"

oznacza wiadomość "How do you do?". W treści wiadomości nie można przesyłać
znaków \10 ani \13. Maksymalna długość treści takiej wiadomości wynosi 10000
znaków (czyli razem z "MSG " jeszcze o 4 znaki więcej). Tak odebrana
wiadomość pojawia się w okienku chata. Nie należy jej w żaden sposób
potwierdzać. Można wysyłać tylko gdy linia jest w stanie TALK.

[ W przypadku użycia protokołu do komunikacji VOIP wydajniejsze może być
przesyłanie komunikatów MSG po UDP, lecz wtedy należy uzupełnić jego format
o dodatkowe informacje. Jednak do czata TCP-IP jest spoko. ]



SUSP 
-----

Wysłanie takiego komunikatu oznacza chęć zawieszenia połączenia. Odbiorca
powinien odpowiedzieć OK. Wtedy linia przechodzi w stan L_SUSP. (a po
drugiej stronie w R_SUSP)

Jeśli zamiast OK dostaniemy w odpowiedzi MSG wyświetlamy komunikat i czekamy
dalej.

Jeśli dostaniemy SUSP oznaczna to, że obie strony połączenia równolegle
wysłały SUSP. W takiej sytuacji uznajemy, że połączenia nie udało się
zawiesić. Nie powoduje to niespójność bo druga strona również na SUSP
dostanie odpowiedź SUSP - też uzna, że się nie udało. Można wyświetlić
odpowiedni komunikat użytkownikowi i/lub po losowym okresie czasu spróbować
ponownie.

SUSP można wysłać tylko jeśli linia jest w stanie TALK.



SWITCH <num>
-------------

Nakazuje odbiorcy tego komunikatu (telefon X) przerwanie aktualnego łącza
TCP-IP i nawiązanie łącza TCP-IP z telefonem o numerze <num>. Po nawiązaniu
tego połączenia telefon X powinien wysłać mu HI oraz CONT, a następnie
uznać, że połączenie trwa normalnie dalej - jakgdyby nigdy nic :)

SWITCH ma na celu umożliwienie zmiany telefonu odpowiedzialnego za
połączenie. Np. jeśli odebrać lub odwiesić chce ktoś inny z grupy lub jeśli
aktualny telefon chce się odłączyć od sieci.

Można wysłać tylko jeśli linia znajduje się w stanie RING lub L_SUSP!




CONT <wlt> 
-----------

Komunikat wysyłamy zaraz po HI jeśli na skutek otrzymania SWITCH musieliśmy
ustawić łącze TCP-IP z nowym telefonem. Podajemy numer naszego lokalnego
WLT. Nie należy tego komunikatu specjalnie potwierdzać. Po jego wysłaniu
uznajemy, że połączenie trwa nadal. Należy za pomocą WLT_STATUS zmienić
wartość <remote_num>.





Połączenia
-----------

Rozłączenie łącza TCP-IP (nie po SWITCH) lub nie nawiązanie nowego
połączenia przez odbiorcę komunikatu SWITCH w określonym czasie (3s)
traktowane jest jak odłożenie słuchawki - linia zmienia status na FREE.

W powyższym opisie komunikatów jednoznacznie zdefiniowany został przebieg
połączenia oraz prawidłowa reakcja na wszystkie komunikaty. Wątpliwości dot.
działania całości wyjaśnia poniższy przykład.



Przykład
---------


Przykładowy przebieg rozmowy wygląda następująco.
(telefon A w grupie ABC dzwoni do D w grupie DEF).


1. A znajduje sobie wolne WLT nr X i przejmuje je.

2. A łączy się przez TCP-IP z D, wysyła "HI A" oraz "RING X".

3. D szuka wolnego WLT.

4a. D nie znajduje wolnego WLT, odpowiada "BUSY", A rozłącza połączenie TCP-IP.
4b. D znajduje wolne WLT o numerze Y, przejmuje je, odpowiada "OK Y".

5. A i D zmieniają stan lini na odpowiednio CALL i RING.

6. Jakiś telefon w grupie DEF (np. E) decyduje się odebrać połączenie.

7. E wysyła do D: "WLT_POP ..."

8. D wysyła do A: "SWITCH E" i do E: "OK"

9. A rozłącza połączenie z D i inicjuje połączenie TCP-IP do E.

10. A wysyła "HI A" i "CONT Y", A rozsyła WLT_STATUS, bo zmienił się <remote_num>.

11. E wysyła do A: "ANS", od tej pory linie zmieniają status na TALK.

12. A i E wysyłają sobie komunikaty "MSG".

13. Któryś z rozmówców (np. A) nagle wysyła "SUSP" i dostaje odpowiedź "OK".

14. Teraz np. A stwierdza, że chce się wyłączyć.

15. A wysyła WLT_PUSH do B i dostaje odpowiedź OK.

16. A wysyła "SWITCH B" do E.

17. E rozłącza się i łączy z B, wysyła HI i CONT.

18. B wysyła ANS, gadają dalej B i E.

19. W dowolnym momencie połączenie TCP-IP zostaje przerwane,
    linia po obu stronach przechodzi w stan FREE.

Tutaj jeszcze wielokrotnie były wysyłane komunikaty WLT_STATUS (wszędzie,
gdzie zmienia się stan linii).

Nie ma konieczności wysyłania komunikatu SWITCH jeśli to D decyduje się na
odebranie połączenia. Ale z drugiej strony komunikatów SWITCH przed
odebraniem (lub w trakcie zawieszenia) może być więcej niż jeden.