Zadanie zaliczeniowe na laboratorium z sieci komputerowych

1. Cel zadania

Należy zaprojektować i zaimplementować protokół sterujący połączeniami
telefonicznymi w sieci IP. Protokół ma umożliwiać imitację działania
typowej biurowej centralki telefonicznej. Przy czym będziemy się zajmować
głównie wymianą informacji, które umożliwiają realizację takich połączeń
głosowych i ewentualnie symulować przesyłanie głosu. Sterowanie ma być
rozproszone, bez centralnego serwera.

2. Podstawowe pojęcia

W dalszej części tego opisu *protokołem* nazywamy projektowany protokół służący
do sterowania połączeniami telefonicznymi w sieci IP.

Połączenie telefoniczne nazywamy dalej *połączeniem*. Połączenie składa się z
dwóch logicznych kanałów: *sterującego* i *głosowego*. Oba kanały są
dwukierunkowe. Kanał sterujący służy do wymiany informacji sterujących
połączeniem. Kanał głosowy służy do transmisji głosu. Kanał sterujący i
głosowy mogą używać tego samego lub różnych mechanizmów transportowych.
Jeżeli kanał sterujący i głosowy używają tego samego mechanizmu
transportowego, to mogą używać dwóch niezależnych kanałów transportowych lub
być multipleksowane w jednym kanale transportowym.

Proces budowania połączenia (kanału) nazywamy *zestawianiem*. Proces kończenia
istnienia połączenia (kanału) nazywamy *rozłączaniem*. Ofertę zestawienia
połączenia nazywamy *wywołaniem*. Zestawianie połączenia rozpoczyna się
wywołaniem, a kończy zestawieniem kanału głosowego lub rozłączeniem, gdy nie
dojdzie do zestawienia kanału głosowego. Rozłączenie połączenia oznacza
rozłączenie wszystkich zestawionych w tym połączeniu kanałów.

*Abonentem* nazywamy użytkownika instancji protokołu. *Identyfikatorem*
abonenta i zarazem instancji protokołu jest adres IP (lub nazwa hosta) i numer
portu. Każdy abonent posiada zadaną z góry i stałą liczbę wirtualnych linii
telefonicznych, w skrócie WLT. Każda WLT umożliwia prowadzenie jednego
połączenia. WLT jest *wolna*, jeśli nie uczestniczy w żadnej aktywności
związanej z zestawianiem, prowadzeniem lub rozłączaniem połączenia. WLT jest
*zajęta*, jeśli nie jest wolna. Abonent jest *wolny*, jeśli posiada co najmniej
jedną wolną WLT. Abonent jest *zajęty*, gdy wszystkie jego WLT są zajęte.

Abonenta inicjującego połączenie nazywamy abonentem *wywołującym*. Abonenta, do
którego kierowane jest połączenie, nazywamy abonentem *wywoływanym*. Mówimy, że
dwaj abonenci są *połączeni*, gdy doszło do zestawienia między nimi kanału
głosowego.

3. Opis funkcjonalności, którą powinien realizować protokół

Zadaniem protokołu jest obsługa połączeń. Protokół musi kanałem sterującym
wymieniać informacje niezbędne do zestawiania i rozłączania kanału głosowego.
Protokół nie zajmuje się zawartością kanału głosowego.

3.A. Zestawianie połączenia

W celu zestawienia połączenia wolny abonent wywołujący wybiera jedną ze swoich
wolnych WLT i wprowadza identyfikator abonenta wywoływanego. Jeśli abonent
wywoływany jest zajęty, to jest to sygnalizowane abonentowi wywołującemu, a
wywołanie zostaje zakończone. Jeśli abonent wywoływany jest wolny, to jest to
sygnalizowane abonentowi wywołującemu na wybranej przez niego WLT, a abonentowi
wywoływanemu jest to sygnalizowane na jednej z jego wolnych WLT.

Abonent wywoływany może odrzucić lub odebrać sygnalizowane mu wywołanie.
Odrzucenie wywołania jest sygnalizowane abonentowi wywołującemu i prowadzi do
zakończenia wywołania. Jeśli abonent wywoływany odbierze wywołanie, to zostaje
utworzony kanał głosowy - abonenci zostają połączeni.

Abonent wywołujący może zrezygnować zanim abonent wywoływany odbierze
wywołanie, co skutkuje zakończeniem wywołania. Należy zwrócić uwagę na
możliwość równoczesnego odebrania wywołania przez abonenta wywoływanego i
rezygnacji z wywołania przez abonenta wywołującego.

3.B. Rozłączanie połączenia

Gdy abonenci są połączeni, to obaj abonenci wywołujący i wywoływany mogą
zainicjować rozłączanie połączenia. Rozłączenie jest sygnalizowane obu
abonentom i prowadzi do zakończenia połączenia oraz zwolnienia obu WLT
biorących udział w połączeniu. Należy zwrócić uwagę na możliwość
równoczesnego zainicjowania rozłączania przez obu abonentów.

3.C. Zawieszanie i odwieszanie połączenia

Gdy abonenci są połączeni, to dowolny z nich może zawiesić połączenie.
Zawieszenie połączenia oznacza rozłączenie kanału głosowego (abonenci przestają
się słyszeć). Zawieszone połączenie może być odwieszone przez abonenta, który
je zawiesił lub rozłączone przez abonenta, który go nie zawiesił. Odwieszenie
powoduje ponowne zestawienie kanału głosowego. Zawieszenie połączenia nie
powoduje zwolnienia WLT. Należy zwrócić uwagę na możliwość równoczesnego
zainicjowania odwieszania i rozłączania.

3.D. Grupy abonentów

Kilku abonentów może tworzyć grupę. Grupa abonentów posiada wspólne wszystkie
WLT. Wywołanie grupy następuje przez wywołanie dowolnego abonenta należącego
do tej grupy. Wywołania sygnalizowane jest wszystkim abonentom w grupie.
Odbieranie i odrzucanie wywołania skierowanego do grupy dokonuje się na
zasadzie "kto pierwszy ten lepszy". Wywoływanie innych abonentów i rozłączanie
połaczeń przez abonenta będącego w grupie odbywa się identycznie jak przez
abonenta niebędącego w grupie. Połączenie zawieszone przez jednego z abonentów
w grupie może zostać odwieszone (przejęte) przez innego abonenta z tej samej
grupy. Zmiany stanu poszczególnych WLT są sygnalizowane u wszystkich abonentów
w grupie. Protokół nie ma służyć do konfigurowania grup. Przynależność do grupy
ma być konfigurowana w warstwie aplikacji i zakładamy, że zawsze jest spójna.

Należy zwrócić szczególną uwagę na rozstrzyganie konfliktów powstających przy
próbie równoczesnego wykonania operacji na tej samej WLT przez dwóch abonentów
z tej samej grupy. Należy też zwrócić uwagę, że abonent będący w grupie może
wywołać innego abonenta w tej samej grupie.

4. Uwagi odnośnie wykonania zadania

Projekt protokołu ma być wykonany zgodnie z zasadami opisanymi w dokumencie
opis-protokolow.txt. Trzeba też zaprojektować sposób realizacji (mechanizm
transportowy) kanałów sterującego i głosowego. Przy projektowaniu protokołu
trzeba mieć na uwadze, że druga strona komunikacji może nigdy nie odpowiedzieć
na wysłaną wiadomość. Trzeba więc przewidzieć mechanizm przekraczania
dopuszczalnego czasu oczekiwania na odpowiedź (ang. timeout). W niektórych
sytuacjach, np. oczekiwanie na odebranie połączenia, można takiego mechanizmu
nie projektować i zdać się na cierpliwość abonenta.

Należy napisać prostą aplikację używającą zaprojektowanego protokołu.
Implementacja protokołu powinna być wykonana jako oddzielny moduł.
Aplikacja powinna mieć prosty i intuicyjny interfejs użytkownika oraz
umożliwiać testowanie działania protokołu, w szczególności wyświetlać
informacje o wymienianych komunikatach. Aplikacja powinna zestawiać kanał
głosowy i dla celów testowych przesyłać nim napisy wpisywane z klawiatury.

Zalecane jest, aby aplikacja była konfigurowana za pomocą pliku zawierającego:
- liczbę WLT abonenta,
- fakt przynależności do grupy wraz z listą identyfikatorów abonentów w grupie,
- książkę telefoniczną - listę identyfikatorów innych abonentów.

5. Uwagi dodane po ogłoszeniu treści zadania

Można dzwonić do samego siebie, o ile posiada się co najmniej dwie WLT. Jedna z
tych linii służy do wykonania wywołania, a druga do odebrania wywołania. Na
tej samej zasadzie można zadzwonić do abonenta będącego w tej samej grupie.

Abonenci w grupie mają wszystkie WLT wspólne. Stan poszczególnych WLT jest
sygnalizowany u wszystkich abonentów w grupie. W szczególności jeśli abonent
należący do grupy używa WLT do wywołania innego abonenta, to jest to
odpowiednio sygnalizowane (WLT jest zajęta) u innych abonentów z tej grupy.

Trzeba założyć, że wszystkie komputery w grupie działają, bo problem
uzgadniania (konsensusu), gdy komputery nagle przestają działać jest
bardzo trudny algorytmicznie. Jedyne co być może warto wymusić, to że są
jakieś timeouty. Tzn. jeśli się wyśle komunikat do komputera, a on np.
nie działa, to nie czekamy na potwierdznie w nieskończoność, tylko
informujemy użytkownika, że coś jest źle i resetujemy stan protokołu,
zwalniamy zasoby itd. Można oczywiście zaprojektować protokół nie używający
potwierdzeń, ale są sytuacje, w których potwierdzenie jest konieczne, np.:
komunikacja za pomocą UDP, negocjowanie WLT w grupie, przejmowanie połączenia
w grupie.