FULL-C: snmp functions
Tato stránka popisuje programovací jazyk FULL-C, který je dostupný na vybraných zařízeních SDS. Některá zařízení používají SDS-C, pro který máme návody jinde na této WiKi.
Síťové funkce: odesílání SNMP TRAP zpráv
Zařízení SDS umožňuje odeslat SNMP TRAP zprávu, na základě logiky uvnitř vašeho FULL-C programu.
Za tímto účelem jsou k dispozici tyto dvě funkce:
void snmp_send_trap(unsigned int IP0, unsigned int IP1, unsigned int IP2, unsigned int IP3, unsigned int PDUspecificType, unsigned int tableIndex); unsigned int snmp_send_trap_status(void);
Proměnné IP0 až IP3 skládají (po částech) dohromady konkrétní IP adresu (IP0.IP1.IP2.IP3), na kterou je SNMP TRAP odeslán.
Princip
SNMP protokol, který je podporován všemi zařízeními SDS, poskytuje i možnost odeslání tzv. TRAP zprávy ze zařízení SDS. Tato zpráva se typicky odesílá, pokud je splněna nějaká uživatelem určená podmínka (příklad: teplota čidla překročí X stupňů).
Funkce snmp_send_trap má jako parametry cílovou IP adresu, "PDU Specific" hodnotu (toto je namapováno na konkrétní OID) a index do tabulky, pokud je potřebný (pokud OID představuje řádek MIB tabulky).
Každé zařízení SDS podporuje různý seznam TRAP zpráv (závisí to na hardwarové konfiguraci zařízení).
Každá TRAP zpráva obsahuje v sobě tyto položky:
- "Enterprises" - výchozí OID určující zařízení SDS (konstanta) (určuje výrobce)
- "PDU Specific" číslo (někde taky jako "TRAP INDEX") - toto je mapováno na konkrétní OID položky (úplný seznam viz tabulka OID).
- "Table Index" číslo - pro položky v SNMP tabulce, kde je stejný výchozí OID, ale tabulkový index (řádek) se liší
- Identifikace odesílatele (konkrétní zařízení SDS - tj. IP adresa)
- Aktuální hodnotu (např. teplota čidla) - tato hodnota je vyplněna přímo zařízením SDS, v okamžiku odeslání TRAPu
Aktuální hodnota je zvolena podle vybraného OID (tj. OID které je v TRAP zprávě), a formát aktuální hodnoty odpovídá přesně tomu, co by vrátilo SNMP GET.
Tyto položky jsou vyhodnoceny na straně příjemce, a následně je vyvolána specifická akce (to už je na vás).
Postup
Postup odeslání TRAP zprávy:
1. FULL-C program vyhodnotí podmínky a rozhodne se odeslat TRAP zprávu 2. FULL-C program zjistí, zda-li není právě odesílána jiná TRAP zpráva (pomocí snmp_send_trap_status), pokud ano tak se musí čekat... 3. FULL-C program zavolá funkci snmp_send_trap() přičemž správně vyplní parametry funkce (cílovou IP adresu a TRAP INDEX) 4. SDS sestaví TRAP zprávu, přičemž podle vybraného "PDU Specific" a "Table Index", do zprávy vyplní hodnotu platnou v tomto okamžiku 5. SDS se pokusí odeslat TRAP zprávu (pokud není ARP záznam, odeslání je odloženo, a místo toho se pošle ARP dotaz) 6. Příjemce přijme TRAP zprávu a zpracuje ji. 7. FULL-C program kontroluje stav (povedlo / nepovedlo) a případně opakuje odesílání
Hodnoty
Všechny TRAP položky jsou přímo svázány s aktuální hodnotou, kterou lzezískat SNMP dotazem na konkrétní OID. Např. TRAP pro stav optického vstupu, v sobě nese hodnotu proměnné, kterou by stejný OID přesně v okamžiku odeslání TRAPu poskytl při svém přečtení (SNMP GET).
Speciální TRAP je položka "sdsCustomVarTrap1", který předává proměnnou, kterou lze předtím nastavit pomocí FULL-C funkce SDS_set_u(140, val); (tzn. zápis na index 140 nastavuje tuto hodnotu). Viz příklad dále.
Příklad
Nejprve je potřeba vědět, jaký vůbec TRAP chceme odeslat.
Pro tento příklad použijeme SDS-BIG a vybereme si teplotu z druhého teplotního čidla připojeného na 1-WIRE sběrnici.
V OID tabulce si najdeme správný řádek:
Full OID | TRAP INDEX | OID Type | MIB Name | Description |
.... | .... | .... | .... | .... |
.1.3.6.1.4.1.33283.1.30.6.1.4.2 | 304 [2] | Integer | sdsOneWireFullValIDX0.2 | (RO) First value received from 1-WIRE device. |
.... | .... | .... | .... | .... |
A pro sdsOneWireFullValIDX0.2 je odpovídající TRAP INDEX (PDU SPECIFIC) = 304 (hodnota před hranatými závorkami) a TRAP TABLE INDEX = 2 (hodnota v hranatých závorkách). Tyto údaje lze také zjistit z MIB souboru pro dané zařízení.
Program v SDS-C tak zavolá funkci s těmito parametry:
unsigned int status; unsigned int PDUspecificType, tableIndex; unsigned char ip0, ip1, ip2, ip3; // PRO NÁŠ PŘÍKLAD: // ip1, ip2, ip3, ip4 => jednotlivé části IP adresy cílového stroje (TRAP RECEIVER) tzn.: ip1.ip2.ip3.ip4 (a.b.c.d) // PDU SPECIFIC (TRAP INDEX) = 304 // TABLE INDEX = 2 ip0 = a; ip1 = b; ip2 = c; ip3 = d; PDUspecificType = 304; tableIndex = 2; // --- // musíme začít s hodnotou 4 (požadavek na opakované odeslání) status = 4; // smyčka (dokud se to nepovede odeslat) while (status == 4) { // požádáme SDS o odeslání TRAP snmp_send_trap(ip0, ip1, ip2, ip3, PDUspecificType , tableIndex ); // takže . . . status = snmp_send_trap_status(); // okamžitý test, zda-li se nesnažíme odeslat TRAP dříve, než se dokončilo předchozí odesílání if (status == 5) { // v tomto případě, stále nebyla odeslána předchozí TRAP zpráva, // musíme proto chvíli počkat, a pak to zkusit znovu wait(250); // tady je škoda čekat, když by program mohl dělat něco jiného - to už je na vás // a zkusíme to znovu (lehkým trikem) status = 4; continue; }; // takže odesílání TRAPu probíhá, takže: // počkáme, dokud není zpráva odeslána while (status == 1) { status = snmp_send_trap_status(); // wait(100}; // dělej něco jiného, zatímco se čeká . . . } // v tuto chvíli je 'status' vyplněn finální hodnotou // pokud místo TRAP odešel ARP, musíme odeslat TRAP znovu if (status == 4) continue; // jiná chyba if ((status == 3)||(status == 6)) { // byly použity špatné parametry (3) - zkuste použít správné hodnoty // nebo není dostatek paměti (6) - zkuste nějakou uvolnit printf("Chyba. TRAP neodeslan.\n"); // nepokračuj break; } // jinak zřejmě hotovo: printf("Hotovo, výsledek = %d\n", status); break; }
Samozřejmě tato funkce se musí zavolat jen jednou pro odeslání TRAPu. Logika chování je už na programátorovi konkrétního FULL-C programu.
Některé položky mají TABLE INDEX = 0. To znamená, že se jedná o SNMP OID položku která není v tabulce, tj. která existuje jen jako jediná pro daný OID. V tomto případě použijte číslo nula na pozici TABLE INDEX.
Příklad pro speciální TRAP (kde lze nastavit proměnnou v SNMP TRAP paketu pomocí FULL-C):
... // nastav promennou kterou specialni TRAP prenese na server SDS_set_u(140, trapValue); // odesli trap [specialni TRAP => 401, 0] snmp_send_trap(ip0, ip1, ip2, ip3, 401, 0);
Stavové hodnoty
Program musí použít volání funkce snmp_send_trap_status pro zjištění okamžitého stavu - a to vždy před pokusem odeslat SNMP TRAP (aby se ověřilo, že se odesílání dá provést), a potom lze funkci snmp_send_trap_status využít pro ověření, že se odeslání skutečně povedlo (ne vždy se to povede, z různých důvodů). Pokud program zjistí, že se odeslání nepovedlo, měl by se to pokusit zopakovat znovu za nějakou chvíli.
snmp_send_trap_status() význam -------------------------+----------------------------------------------------------------------- 0 | klid, můžete odeslat TRAP 1 | pracuje (pokouší se odeslat TRAP), čekejte 2 | provedeno 3 | byly zadány neplatné parametry - zpráva neodeslána 4 | místo TRAP zprávy byl odeslán ARP, takže musíte zopakovat odesílání 5 | nebylo dokončeno odesílání předchozího TRAP, čekejte a zkuste znovu 6 | nedostatek HEAP paměťi pro odeslání TRAP - zpráva neodeslána
Pokud funkce snmp_send_trap_status vrátí hodnotu 2, je vše jak má být (OK). Jiné hodnoty (mimo 0 a 1) znamenají určitou situaci, kterou je potřeba řešit - ne vždy je to jednoznačně chyba, může stačit chvíli počkat a zkusit TRAP odeslat znovu.