|
//-----------------------------------------------------------------------------
// LEDmanager.vpl, created 2020-02-19 15:58
//
// This program demonstrates communication between two RTCU devices, where one
// is the manager (trap listener) and the other a client (publishing agent).
//
// To visualize the communication, the LEDs of both devices are manipulated
// by each other. The manager initiates by setting a pablished integer variable
// on the client, which then updates it's LEDs according to the value written,
// and then sends a trap to the manager, that updates it's LEDs accordingly and
// writes the next value to the other LED on the client, which again responds
// with a trap, which the manager uses to update it's LEDs with and so on.
//-----------------------------------------------------------------------------
INCLUDE rtcu.inc
// Use LAN1
#DEFINE SNMP_INTERFACE 2
// Exchange this with your real enterprise OID base.
#DEFINE ENTERPRISE_OID "1.3.6.1.4.1.65500."
// Put the actual IP address and port of the client here.
#DEFINE SNMP_CLIENT_IP "192.168.1.20" // example IP
#DEFINE SNMP_CLIENT_PORT 161
#DEFINE rwusername "roed"
#DEFINE sysUpTime "1.3.6.1.2.1.1.3.0"
#DEFINE usmStatsUnknownEngineIDs "1.3.6.1.6.3.15.1.1.4.0"
VAR_OUTPUT
ledAgreen : BOOL;
ledAred : BOOL;
ledBgreen : BOOL;
ledBred : BOOL;
END_VAR;
VAR
netInfo : netGetInformation;
snmpvar : snmpVariable;
iface : SINT := SNMP_INTERFACE;
ledA : INT; // 0=off, 1=green, 2=red, 3=yellow
ledB : INT; // 0=off, 1=green, 2=red, 3=yellow
END_VAR;
FUNCTION printNetInfo
netInfo(iface:=iface);
DebugFmt(message:="Network interface \1:", v1:=iface);
CASE netInfo.status OF
0 : DebugMsg(message:="Interface is not present.");
1 : DebugMsg(message:="Interface is not opened.");
2 : DebugMsg(message:="Interface is not clientconected.");
3 : DebugMsg(message:="Interface is clientconected.");
4 : DebugMsg(message:="Interface link is up and waiting for IP configuration.");
ELSE
DebugFmt(message:="Illegal net status? (\1)", v1:=netInfo.status);
END_CASE;
IF netInfo.status > 1 THEN
DebugMsg(message:=" Phy addr " + netInfo.phy_addr);
IF netInfo.dhcp THEN
DebugMsg(message:=" Dynamic IP address");
ELSE
DebugMsg(message:=" Static IP address");
END_IF;
DebugMsg(message:=" IP addr " + sockIPToName(ip := netInfo.ip));
DebugMsg(message:=" Mask " + sockIPToName(ip := netInfo.subnetMask));
DebugMsg(message:=" Gateway " + sockIPToName(ip := netInfo.gateway));
IF netInfo.AutoDNS THEN
DebugMsg(message:=" Automatic DNS");
ELSE
DebugMsg(message:=" Manual DNS");
END_IF;
DebugMsg(message:=" DNS1 " + sockIPToName(ip := netInfo.DNS1));
DebugMsg(message:=" DNS2 " + sockIPToName(ip := netInfo.DNS2));
END_IF;
END_FUNCTION;
FUNCTION updateLeds;
VAR_INPUT
ledA : INT;
ledB : INT;
END_VAR;
CASE ledA OF
0:
ledAgreen := OFF;
ledAred := OFF;
1:
ledAgreen := ON;
ledAred := OFF;
2:
ledAgreen := OFF;
ledAred := ON;
3:
ledAgreen := ON;
ledAred := ON;
END_CASE;
CASE ledB OF
0:
ledBgreen := OFF;
ledBred := OFF;
1:
ledBgreen := ON;
ledBred := OFF;
2:
ledBgreen := OFF;
ledBred := ON;
3:
ledBgreen := ON;
ledBred := ON;
END_CASE;
UPDATEIO;
END_FUNCTION;
PROGRAM LEDmanager;
VAR
deleteuser : snmpUser;
rwuser : snmpUser;
trapd : SYSHANDLE;
clientcon : SYSHANDLE;
str : STRING;
val : DINT;
rc : INT;
oid : STRING;
vars : INT;
ix : SINT;
event : USINT;
x : DINT;
END_VAR;
ledA := 0;
ledB := 0;
updateLeds(ledA:=ledA, ledB:=ledB);
rc := netOpen(iface:=iface);
DebugFmt(Message:="netOpen (rc=\1)", v1:=rc);
WHILE NOT netConnected(iface:=iface) DO
Sleep(Delay:=2000);
END_WHILE;
// Output network information
printNetInfo();
// Preemptively delete persistent users.
deleteuser.username := "";
FOR ix:=1 TO 25 DO
snmpUserSet(index:=ix, user:=deleteuser);
END_FOR;
// Configure read-write user
rwuser.username := rwusername;
rwuser.password := "deor1234";
rwuser.cryptkey := "a0b3d543";
rwuser.authentication := _SNMP_USM_MD5;
rwuser.encryption := _SNMP_USM_AES;
rwuser.level := _SNMP_SEC_ENC;
rwuser.engineid := "12345678900001030507";
// Set USM users
rc := snmpUserSet(index:=1, user:=rwuser);
IF rc <> 1 THEN
DebugFmt(message:="Failed to set snmp user (rc=\1)", v1:=rc);
END_IF;
// Start the trap listener
rc := snmpStartListen(
handle := trapd,
version:= _SNMP_VER_3
);
DebugFmt(message:="snmpStartListen (rc=\1)", v1:=rc);
// Register traps to listen for
rc := snmpRegisterTrap(oid:=ENTERPRISE_OID + "100");
DebugFmt(message:="snmpRegisterTrap (rc=\1)", v1:=rc);
rc := snmpRegisterTrap(oid:=ENTERPRISE_OID + "101");
DebugFmt(message:="snmpRegisterTrap (rc=\1)", v1:=rc);
// Setup connection to the client
rc := snmpConnect(
host := SNMP_CLIENT_IP,
port := SNMP_CLIENT_PORT,
version := _SNMP_VER_3,
usmuser := ADDR(rwuser),
handle := clientcon
);
DebugFmt(message:="snmpConnect (rc=\1)", v1:=rc);
// Start the test by setting a variable on the client
snmpSetInteger(handle:=clientcon, OID:=ENTERPRISE_OID + "1.1.0", v:=1);
IF rc <> 1 THEN
DebugFmt(message:="Failed to set variable! snmpSetInteger (rc=\1)", v1:=rc);
END_IF;
BEGIN
// Handle events
rc := snmpWaitEvent(timeout:=-1, event:=event, oid:=oid, vars:=vars);
CASE event OF
_SNMP_EVENT_NOEVENT :
CASE rc OF
0: DebugMsg(message:="ERROR: The function is not supported!");
-2: DebugMsg(message:="ERROR: Invalid input");
-5: DebugMsg(message:="WARNING: Event buffer overflow.");
ELSE
DebugFmt(message:="ERROR: unknown return code from snmpReadEvent (rc=\1)", v1:=rc);
END_CASE;
_SNMP_EVENT_TIMEOUT :
DebugMsg(message:="snmpWaitEvent: Timeout!");
_SNMP_EVENT_TRAP :
DebugMsg(message:="Trap received!");
DebugMsg(message:="Trap oid is: " + oid);
DebugFmt(message:="Vars to read : \1", v1:=vars);
_SNMP_EVENT_SET :
DebugMsg(message:="Set request received on OID " + oid);
ELSE
DebugFmt(message:="ERROR: snmpWaitEvent - unknown event type \1!", v1:=event);
END_CASE;
rc := 0;
WHILE NOT(rc = -11) DO
rc := snmpGetNextVar(data:=snmpvar);
CASE rc OF
0: DebugMsg(message:="snmpGetNextVar: Function not implemented!");
-2: DebugMsg(message:="Invalid parameter.");
-9: DebugFmt(message:="Invalid variable type \1", v1:=snmpvar.type);
-11:
1:
CASE snmpvar.type OF
1: DebugFmt(message:="TimeTicks received = \4", v4:=snmpvar.time_value);
2: DebugFmt(message:="INTEGER received = \4", v4:=snmpvar.int_value);
3: DebugFmt(message:="UNSIGNED INTEGER received = \4", v4:=snmpvar.uint_value);
4: DebugFmt(message:="STRING received = " + snmpvar.str_value);
5: DebugFmt(message:="Hex STRING received = " + snmpvar.hex_value);
6: DebugFmt(message:="OID received = " + snmpvar.oid_value);
7: DebugFmt(message:="IP Address received = " + snmpvar.ip_value);
8: DebugFmt(message:="FLOAT received = " + floatToStr(v:=snmpvar.float_value) );
9: DebugFmt(message:="DOUBLE received = " + doubleToStr(v:=snmpvar.double_value) );
ELSE
DebugFmt(message:="Unknown var type received : \1", v1:=snmpvar.type);
END_CASE;
IF strCompare(str1:=snmpvar.oid, str2:="." + ENTERPRISE_OID + "100.1") = 0 THEN
ledA := INT(snmpvar.int_value);
updateleds(ledA:=ledA, ledB:=ledB);
snmpGetString(handle:=clientcon, OID:=ENTERPRISE_OID + "2.1.0", v:=str);
DebugMsg(message:="Client LED " + str);
x := (snmpvar.int_value + 1) MOD 4;
snmpSetInteger(handle:=clientcon, OID:=ENTERPRISE_OID + "1.2.0", v:=x);
END_IF;
IF strCompare(str1:=snmpvar.oid, str2:="." + ENTERPRISE_OID + "100.2") = 0 THEN
ledB := INT(snmpvar.int_value);
updateleds(ledA:=ledA, ledB:=ledB);
snmpGetString(handle:=clientcon, OID:=ENTERPRISE_OID + "2.2.0", v:=str);
DebugMsg(message:="Client LED "+str);
x := (snmpvar.int_value + 1) MOD 4;
snmpSetInteger(handle:=clientcon, OID:=ENTERPRISE_OID + "1.1.0", v:=x);
END_IF;
DebugMsg(message:="Variable OID was : " + snmpvar.oid);
ELSE
DebugFmt(Message:="snmpGetNextVar (rc=\1)", v1:=rc);
END_CASE;
END_WHILE;
END;
END_PROGRAM;
|