3.3. Algorytm działania programu sender

Program sender przy starcie inicjalizuje tablicę SterInfo, w której dla każdego wysyłanego parametru znajdują się następujące informacje:

typedef struct _SterData {
	tMsgSetParam msg;       /* komunikat do wysłania */
	unsigned short srcaddr; /* adres (indeks IPC) wysyłanego parametru */
	unsigned char status;   /* stan transmisji parametru:
					MSG_SEND - do wysłania
					MSG_NOSEND - nie będzie wysyłany (brak
					danych)
					MSG_CONF - czekamy na potwierdzenie
				 */
       unsigned char avgkind;   /* rodzaj średniej do wysłania */
       unsigned char sendnodata;/* czy wysyłać wartości 'NO_DATA' */
} tSterData;

Struktura komunikatu do wysłania jest następująca:

typedef struct _MsgSetParam {
	long type;	/* typ wiadomości, wyliczany na podstawie
			numeru linii i jednostki */
	struct {
		ushort param;	/* numer parametru wyjściowego sterownika */
		short value;	/* wartość parametru */
		long rtype;	/* typ oczekiwanej odpowiedzi od demona,
				dla każdego parametru sendera inny */
		unsigned char retry;
				/* ilość powtórzeń przy nieudanym wysłaniu,
				niewykorzystywana w programie */
	} tSetParam;
} tMsgSetParam;

Wykorzystywane są dwie kolejki - jedna do wysyłania żądań ustawienia parametrów, druga dla odbierania odpowiedzi (potwierdzeń) od demonów.

W pętli program wykonuje następujące działania:

  1. Łączy się z parcookiem i dla każdego parametru oddzielnie podłącza się do segmentu pamięci dzielonej zależnego od pola avgkind (rodzaju średniej) dla parametru. Kopiuje wartość do pola value komunikatu, przy czym jeżeli wartość jest równa NO_DATA a nie mamy wysyłać pustych wartości, to status jest ustawiany na MSG_NOSEND. Jeżeli mamy wysyłać stałą, to oczywiście zostaje stała (wpisana przy inicjalizacji do pola value komunikatu).

  2. Dla każdego parametru który ma status MSG_SEND (do wysłania) próbuje wstawić do kolejki uprzednio przygotowany komunikat. Zapamiętuje jeżeli choć w jednym przypadku się to nie udało. Podobnie jak w innych miejscach w programie, operacje na kolejkach wykonywane są z flagą NO_WAIT - nieblokująco.

  3. Jeżeli w poprzednim kroku nie udało się wysłać wszystkich komunikatów, program zakłada, że kolejka jest zapchana i próbuje wyjąć z kolejki tyle komunikatów ile jest parametrów (a więc na pewno nie mniej niż włożył). Wykorzystywany jest typ komunikatu 0, oznaczający dowolny komunikat. Zapchanie kolejki nie jest takie proste - kolejka ma standardowo wielkość 16 KB, pojedynczy komunikat to około 24 bajty (może zależeć od kompilatora - sposobu pakowania pól w strukturze), a więc kolejka mieści ponad 680 komunikatów. Jeżeli wkładamy komunikaty co 10 sekund (i nikt ich nie wyjmuje), kolejka zacznie się zapychać po prawie dwóch godzinach...

  4. Jeżeli w kroku 1 nie udało się wysłać wszystkich komunikatów, powtórz kroki 2 i 3, a następnie przejdź do kroku 5.

  5. Czekaj 10 sekund (lub tyle sekund ile wynosi wartość parametru send_freq zdefiniowanego w pliku params.xml).

  6. Dla każdego parametru pobierz z kolejki odpowiedzi wszystkie komunikaty o oczekiwanym typie zwrotnym. Jeżeli odpowiedź dla danego parametru była oczekiwana (a więc pole status dla parametru miało wartość MSG_CONF), sprawdź czy pola param i value odebranego komunikatu są takie jak komunikatu wysyłanego (dla danego parametru). Jeżeli wszystko się zgadza, ustawiany jest status - MSG_NOREP jeżeli ilość pozostałych powtórzeń zgłoszona przez demona linii jest równa 0 lub MSG_OK w przeciwnym przypadku. Oznacza to także, że status MSG_NOREP (oznaczający błąd) jest ustawiany także w sytuacji, gdy po prostu w pliku konfiguracyjnym nie zażądaliśmy powtarzania. Status ten nie ma jednak żadnego wpływu na działanie sendera, wykorzystywany jest tylko do diagnostyki.

  7. Z kolejki odpowiedzi usuwane są wszystkie pozostałe tam komunikaty.

  8. Program przechodzi do kroku 1.

Należy zauważyć, że demony różnie podchodzą do współpracy z senderem. Najbardziej zaawansowany jest linedmn, który próbuje wysyłać potwierdzenia, co może skutkować poprawnym logowaniem przez sendera faktu dotarcia lub niedotarcia danych do sterownika (choć domyślnie logowanie jest wyłączone). Demon rsdmn wysyła potwierdzenia, ale z błędnym typem komunikatu, więc są one usuwane przez sendera z kolejki jako błędne. Demon mbrtudmn nie wysyła w ogóle potwierdzeń (co wydaje się najsensowniejszym rozwiązaniem). Pozostałe demony (w chwili pisanie tego rozdziału) nie współpracują w ogóle z senderem.