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.