FUNCTION_BLOCK SatelEthernet
VAR_INPUT
xOpen_Client: BOOL; (* uaktywnij polaczenie do modulu ETHM-1 *)
IP: STRING; (* adres IP modulu ETHM-1 *)
Port: WORD; (* port integracji modulu ETHM-1 *)
END_VAR
VAR_OUTPUT
czujki: ARRAY [1..64] OF BOOL; (* tablica zawierajaca stany czujek od 1 do 64, TRUE - czujka aktywna *)
strefy: ARRAY [1..32] OF BOOL; (* tablica zawierajaca stany stref od 1 do 32, TRUE - strefa uzbrojona *)
wyjscia: ARRAY [1..64] OF BOOL; (* tablica zawierajaca stany wyjsc od 1 do 64, TRUE - wyjscie aktywne *)
xCLIENT_OPEN: BOOL; (* polaczenie do modulu ETHM-1 aktywne *)
wSOCKET: WORD; (* numer wtyczki *)
END_VAR
VAR
Protocol : SEL_PROTOCOL := IPPROTO_TCP; (* wybrany protokol transmisji - TCP *)
ProtocolType : SEL_TYPE := SOCK_STREAM; (* wybrany typ trasmisji - stream *)
MyEthernetOpen : ETHERNET_CLIENT_OPEN;
MyEthernetClose : ETHERNET_CLIENT_CLOSE;
MyEthernetWrite : ETHERNET_WRITE;
MyEthernetRead : ETHERNET_READ;
Read00 : BOOL := TRUE; (* zadanie wyslania polecenia 00 - odczyt stanu czujek*)
Read0A : BOOL := TRUE; (*zadanie wyslania polecenia 0A - odczyt stanu uzbrojenia alarmu *)
Read17 : BOOL := TRUE; (* zadanie wyslania polecenia 00 - odczyt stanu wyjsc*)
fi: INT; (* pierwszy indeks ramki *)
fin: INT; (* drugi indeks ramki *)
buf_len: WORD; (* dlugosc danych w buforze *)
znacznik: BYTE := 1; (* znacznik uzywany do operacji bitowych *)
pt: POINTER TO ARRAY [1..1500] OF BYTE; (* wskaznik do tablicy - uzywany przy przkazywaniu tablicy do funkcji *)
frame_rcv: ARRAY [1..1500] OF BYTE; (* tablica danych odebranych *)
frame_snd: ARRAY [1..1500] OF BYTE; (* tablica danych wysylanych *)
Status: WORD := 0; (* status transmisji: 0 - inicjalizacja, 1 - sprawdzenie stosu TCP/IP 4 - inicjalizacja otwarcia polaczenia, 5 - oczekiwanie na otwarcie polaczenia, 10 -wyslanie danych do serwera, 20 - oczekiwanie na odbior danych, 30 - interpretacja otrzymanych danych, 40 - zamykanie polaczenia *)
GetConfig: ETHERNET_GET_NETWORK_CONFIG;
utERROR: ETH_ERROR;
closeState: INT; (* status zamykania polaczenia *)
Timeout: TOF_1 := (PT:=T#2s, IN:=TRUE, RST:= FALSE); (* maksymalny czas oczekiwania na odpowiedz ze sterownika *)
END_VAR
IF xOpen_Client THEN
CASE Status OF
0
*Initialize functionblocks*)
GetConfig(EN:=FALSE );
GetConfig(EN:=TRUE );
status:=1;
utERROR:=0;
wSocket:=0;
closeState:=0;
xCLIENT_OPEN:=FALSE;
1
*check ethernet stack*)
GetConfig(EN:=TRUE );
IF GetConfig.ENO THEN
IF GetConfig.IP_ADR<>0 THEN
status:=4;(*stack initialized*)
ELSE
status:=0;(*try again*)
END_IF
END_IF
4
*open connection*)
MyEthernetRead( EN:= 0, SOCKET:=0 , DATA:=frame_rcv );
MyEthernetClose(EN:= 0);
MyEthernetOpen(EN:=0);
MyEthernetOpen(EN:=1 , TYP:=ProtocolType , PROTO:=Protocol , IP_ADR:= IP_ADDRESS(IP), PORT:=Port );
status:=5;
5
*wait for server response according to client request to open the connection*)
MyEthernetOpen(EN:=1, TYP:=ProtocolType, PROTO:=Protocol, IP_ADR:= IP_ADDRESS(IP), PORT:=Port );
IF MyEthernetOpen.ENO = 1 THEN
IF MyEthernetOpen.ERROR = 0 THEN
Status := 10; (*socket available*)
xCLIENT_OPEN:=TRUE;
wSOCKET :=MyEthernetOpen.socket;
MyEthernetWrite( EN:= 0 , DATA:=frame_snd );
ELSE
Status := 0; (*no socket available, try it again *)
END_IF;
utERROR:=MyEthernetOpen.ERROR;
END_IF
10
* Write data to server*)
frame_snd[1]:=16#FE;
frame_snd[2]:=16#FE;
IF Read00 THEN
frame_snd[3]:=16#00; (* zapytanie o stan czujek *)
ELSIF Read0A THEN
frame_snd[3]:=16#0A; (* zapytanie o stan uzbrojenia alarmu *)
ELSIF Read17 THEN
frame_snd[3]:=16#17; (* zapytanie o stan wyjsc *)
ELSE
frame_snd[3]:=16#7F; (* zapytanie o zmiane stanu *)
END_IF
pt:=ADR(frame_snd);
frame_snd[4]:=WORD_TO_BYTE(SHR(SatelCRC(pt,3,3),8)); (* obliczenie CRC.H *)
frame_snd[5]:=WORD_TO_BYTE(SatelCRC(pt,3,3)); (* obliczenie CRC.L *)
frame_snd[6]:=16#FE;
frame_snd[7]:=16#0D;
MyEthernetWrite(EN:= 1,SOCKET:= MyEthernetOpen.SOCKET, LEN_IN:=7,DATA:=frame_snd); (* wyslanie ramki *)
IF MyEthernetWrite.eno THEN
IF(MyEthernetWrite.ERROR <>0) THEN
Status:=40; (* Error writing to the socket, close it *)
ELSE
Status:=20; (* Write complete, read data *)
END_IF;
utERROR:=MyEthernetWrite.ERROR;
END_IF
Timeout (IN := FALSE);
20: (* Read data*)
MyEthernetRead( EN:= 1, SOCKET:=MyEthernetOpen.SOCKET , DATA:=frame_rcv );
MyEthernetRead( EN:= 0, SOCKET:=0 , DATA:=frame_rcv );
Timeout (IN := FALSE);
utERROR:=MyEthernetREAD.ERROR;
IF(MyEthernetRead.ERROR<>0) THEN (* Error reading the socket, close it *)
Status:=40;
ELSIF (MyEthernetRead.LEN_OUT <> 0) THEN (* Process the data received via the ethernet port *)
Timeout(IN := TRUE);
Status:=30;
ELSIF NOT Timeout.Q THEN
Timeout(IN := TRUE);
Status:=10; (* uplynal czas oczeiwania na odpowiedz, zerowanie licznika i ponowne wyslanie zapytania *)
END_IF
30: (* Process received data *)
buf_len:=MyEthernetRead.LEN_OUT;
FOR fi:=3 TO buf_len-4 DO (* sprawdzenie, czy bajt odebranej ramki nie zawiera kombinacji FE F0; w takim przypadku wyrzuc F0 i skroc odebrane dane *)
IF frame_rcv[fi]=16#FE THEN
IF frame_rcv [fi+1]=16#F0 THEN
FOR fin:=fi+1 TO buf_len-2 DO
frame_rcv[fin]:= frame_rcv[fin+1];
END_FOR
buf_len:=buf_len-1;
END_IF;
END_IF;
END_FOR;
pt:=ADR(frame_rcv); (* przekazanie adresu znacznika danych odebranych - potrzebne do przekazania danych do obliczenia CRC *)
IF frame_rcv[buf_len-3]=WORD_TO_BYTE(SHR(SatelCRC(pt,3,buf_len-4),8)) AND frame_rcv[buf_len-2]=WORD_TO_BYTE(SatelCRC(pt,3,buf_len-4)) THEN (* sprawdzenie poprawnosci CRC otrzymanych danych *)
IF frame_rcv[3]=16#7F THEN (* jesli otrzymano ramke zapytania o zmiane stanu *)
(*Com7FReceived:=Com7FReceived+1;*)
IF (frame_rcv[4] AND znacznik) >0 THEN (* sprawdzenie czy bit 0 pierwszego bajtu danych jest 1, czyli stan czujek ulegl zmianie *)
Read00:=TRUE; (* jesli tak, nastepnym razem zapytaj o stan czujek *)
END_IF;
IF (frame_rcv[5] AND ROL(znacznik,2)) >0 THEN (* sprawdzenie czy bit 2 drugiego bajtu danych jest 1, czyli stan stref ulegl zmianie *)
Read0A:=TRUE; (* jesli tak, nastepnym razem zapytaj o stan stref*)
END_IF;
IF (frame_rcv[6] AND ROL(znacznik,7)) >0 THEN (* sprawdzenie czy bit 7 trzeciego bajtu danych jest 1, czyli stan wyjsc ulegl zmianie *)
Read17:=TRUE; (* jesli tak, nastepnym razem zapytaj o stan wyjsc*)
END_IF;
ELSIF frame_rcv[3] = 16#00 THEN (* jesli otrzymano ramke stanu czujek *)
(*Com00Received:=Com00Received+1;*)
znacznik:=1;
FOR fi:=4 TO buf_len-5 DO (* dla kazdego bajtu danych *)
FOR fin:=0 TO 7 DO (* dla kazdego bitu *)
IF (SHL(znacznik,fin) AND frame_rcv[fi]) >0 THEN (* sprawdz czy bit jest 1 *)
czujki[(fi-4)*8+fin+1]:=TRUE; (* jesli tak stan czujki = TRUE - aktywna *)
ELSE
czujki[(fi-4)*8+fin+1]:=FALSE; (* jesli nie = FALSE - nieaktywna *)
END_IF;
END_FOR;
END_FOR;
(*AktCzujek := TRUE;*)
Read00 := FALSE;; (* nastepnym razem nie pytaj o czujki *)
ELSIF frame_rcv[3] = 16#0A THEN
FOR fi:=4 TO buf_len-5 DO (* dla kazdego bajtu danych *)
FOR fin:=0 TO 7 DO (* dla kazdego bitu *)
IF (SHL(znacznik,fin) AND frame_rcv[fi]) >0 THEN (* sprawdz czy bit jest 1 *)
strefy[(fi-4)*8+fin+1]:=TRUE; (* jesli tak stan strefy = TRUE - uzbrojona *)
ELSE
strefy[(fi-4)*8+fin+1]:=FALSE; (* jesli nie = FALSE - rozbrojona *)
END_IF;
END_FOR;
END_FOR;
Read0A := FALSE; (* nastepnym razem nie pyatj o strefy *)
ELSIF frame_rcv[3] =16#17 THEN
FOR fi:=4 TO buf_len-5 DO (* dla kazdego bajtu danych *)
FOR fin:=0 TO 7 DO (* dla kazdego bitu *)
IF (SHL(znacznik,fin) AND frame_rcv[fi]) >0 THEN (* sprawdz czy bit jest 1 *)
wyjscia[(fi-4)*8+fin+1]:=TRUE; (* jesli tak stan wyjscia = TRUE - aktywne *)
ELSE
wyjscia[(fi-4)*8+fin+1]:=FALSE; (* jesli nie = FALSE - nieaktywne *)
END_IF;
END_FOR;
END_FOR;
Read17 := FALSE; (* nastepnym razem nie pyatj o wyjscia *)
END_IF;
END_IF;
Status:=10; (* przejdz do wysylania danych *)
MyEthernetWrite( EN:= 0 , DATA:=frame_snd ); (* przygotuj nadajnik do nadawania *)
40: (* Close the client *)
MyEthernetClose(EN:= 1, SOCKET:= MyEthernetOpen.SOCKET);
IF MyEthernetClose.eno THEN
MyEthernetClose(EN:= 0);
xCLIENT_OPEN:=FALSE;
Status := 0; (* Try to open the server again *)
END_IF
END_CASE;
ELSE
CASE CloseState OF
0:
MyEthernetClose(EN:= 0);
MyEthernetClose(EN:= 1, SOCKET:= MyEthernetOpen.SOCKET);
CloseState:=1;
1:
MyEthernetClose(EN:= 1, SOCKET:= MyEthernetOpen.SOCKET);
IF MyEthernetClose.eno THEN
MyEthernetClose(EN:= 0);
CloseState:=2;
END_IF
2:
Status := 0;
utERROR:=0;
xCLIENT_OPEN:=FALSE;
END_CASE
END_IF