FULL-C: MQTT functions

FULL-C

Síťové funkce: komunikace MQTT (klient) ve FULL-C

Zařízení SDS umožňuje komunikovat s MQTT brokerem, tedy SDS lze provozovat jako MQTT klienta.

Za tímto účelem jsou k dispozici tyto funkce:

.
         void mqtt_connect(unsigned int IP0, unsigned int IP1, unsigned int IP2, unsigned int IP3, unsigned int TCPport, char *ClientID, char *username, char *password, unsigned int KeepAliveSec);
         void mqtt_disconnect(void);
         void mqtt_publish(char *FullTopicName, char *Value);
         void mqtt_subscribe(unsigned int TableIndex, char *FullTopicName);
         void mqtt_unsubscribe_index(unsigned int TableIndex);
         void mqtt_unsubscribe_name(char *FullTopicName);

Proměnné IP0 až IP3 skládají (po částech) dohromady konkrétní IP adresu (IP0.IP1.IP2.IP3), ke které se SDS (MQTT klient) připojí.


Princip

Veškerý popis využití MQTT je na této stránce (odkaz je zde).

Implementace ve FULL-C odpovídá implementaci v SDS-C, jediný rozdíl je popsán zde:


Příklady

Základní připojení k brokeru, publikování položky a odpojení:

. 
 // *** CONNECT
 
 // connect on start
 printf("connecting to MQTT broker...\n");
 
 //           ip   ip   ip ip   port  client-id          username   password    reserved
 mqtt_connect(192, 168, 1, 253, 1883, "sds-client-1234", "sds1234", "password", 0);
 
 // now wait for a complete connection:
 
 // done - connected ?
 while (SDS_get_i32(12200) != 4) 
 {
   // any error - did it fail ?
   if (SDS_get_i32(12200) < 0) goto mqtt_conn_fail;
 }
 
 // OK, done, so now:
 // test the CONNACK result - see "3.2.2.3 Connect Return code"
 
 if (SDS_get_i32(12201) != 0) goto mqtt_conn_fail;
 
 // CONNECTED OK ! (result is 0x00)
 
 printf("connected to broker OK, result in 12200=%d\n", SDS_get_i32(12200));
 
 
 // *** PUBLISH
 
 printf("publishing...");
 
 mqtt_publish("sds/temps/value1", "123456");
 
 // wait until done
 while (SDS_get_i32(12202) == 1)
 {
   // disconnected ?
   if (SDS_get_i32(12200) < 0) goto mqtt_conn_fail;    
 }
  
 // was it success ?
 if (SDS_get_i32(12202) != 2)
 { 
   // it FAILED
   printf("publish error = %d\n", SDS_get_i32(12202)); 
 };
 
 printf("OK\n");
 
 
 // *** DISCONNECT
 
 mqtt_disconnect();
 
 // todo: wait for disconnection result !!!
 
 ...
 
 return;
 
 //
 mqtt_conn_fail:
 
  printf("connection to broker - FAILED \n");

Samozřejmě si z příkladu vyberete jednotlivé části tak, jak zapadají do vašeho programu. Připojení je potřeba provést "jen jednou" na začátku, a SDS automaticky udržuje spojení (MQTT PING, tedy formou protokolového keep alive). Pokud by došlo ke ztrátě spojení (což se může stát), je toto předáno formou chybového hlášení (čtení patřičného indexu pomoci SDS_get funkce).

Je-li SDS připojeno, lze provádět neomezené publikování hodnot, a také se lze přihlásit k odběru (subscribe).

SDS nabízí možnost využít svou tabulku přihlášení (subscribe table), kam si vložíte položky které vás zajímají (každou pod jiným indexem) a SDS bude pro tyto položky trvale udržovat jejich aktuální hodnoty (values), tak jak je bude broker do SDS posílat. Váš program se pak kdykoliv do tabulky může podívat a přečíst si aktuální stav. Samozřejmě použití tabulky není nutnost, ale bez ní můžete přijít o aktualizaci, pokud ji svým programem nezachytíte.

Příklad přihlášení k odběru:

 
 // note. SDS shall be connected to a broker, at this point
 
 // *** let us subscribe to a topic:
 
 printf("subscribing...");
 
 // for this example, we choose index '1':
 mqtt_subscribe(1, "ha/output/q1/state");
 
 // wait for result
 while (SDS_get_i32(12202) == 4)
 {
   // disconnected ?
   if (SDS_get_i32(12200) < 0) goto mqtt_conn_fail;
 }
 
 // success ?
 if (SDS_get_i32(12202) != 8)
 { 
   // failed...
   printf("sub error = %d\n", SDS_get_i32(12202)); 
 };
 
 // OK we ARE subscribed !
 
 printf("OK\n");
 
 
 // *** example: watch for updates coming from broker, and print it to console
 
 unsigned int last1;
 char tn[32+1];
 char tv[32+1];
 
 last1 = 0;
 
 while(1)
 {
 
   // any change ? (any new message from broker, processed by SDS ?)
   if (last1 != SDS_get_u32(12291))  // 12291 is a timestamp for index #1
   {
      // store so we can compare it later, again
      last1 = SDS_get_u32(12291);
 
      // read Topic Name (tn) and the new Value (tv)
      SDS_get_a(12211, &tn, 32);
      SDS_get_a(12251, &tv, 32);
 
      // print to console
      printf("TOPIC #1: %s update to: %s \n", tn, tv);
  };
 
  // always check the connection state
  if (SDS_get_i32(12200) < 0)
  {  
    // disconnected
    printf("disconn\n"); break;
  }
 
 // continue loop
 }
 
 
 ...
 
 // *** unsubscribe
 mqtt_unsubscribe_index(1);
 
 // todo: wait for result !
 

Další příklady budou eventuálně doplněny, požadavky na ně předejte přes forum.


Hodnoty v systémových indexech

Významy údajů vrácených funkcí SDS_get_i32() pro MQTT klienta:

SDS_get_i32(12200)    stav průběhu mqtt_connect()
--------------------------------------------------------------------------------------------------------------------------------------------
                  -7 = obdrželi jsme CONNACK, ale negativní = nepřipojeno ( výsledek viz 12201 )
                  -6 = timeout při čekání na připojení, nepřipojeno
                  -5 = nespravne parametry (hodnoty např. IP, port), nepřipojeno
                  -4 = nespravne parametry (počet parametrů), nepřipojeno
                  -3 = funkce zavolána dříve (nebo opakovaně) než bylo dokončeno předchozí volání funkce, takže toto volání je ignorováno
                  -2 = pokus o TCP připojení selhal
                  -1 = nepoužito
                   0 = klid, nic se neprovádí, ODPOJENO ! (lze se začít připojovat)
                   1 = bylo zahájeno připojování (otevírá se TCP spojení)
                   2 = TCP připojeno a odeslán CONNECT požadavek
                   4 = obdrželi jsme CONNACK, připojeno ( výsledek viz 12201 )
                   8 = probíhá odpojování, čekáme na výsledek (na odpojení)
SDS_get_i32(12201)    výsledek mqtt_connect() = hodnota "CONNACK Connect Return"
--------------------------------------------------------------------------------------------------------------------------------------------
                  -7 = nepoužito
                  -6 = timeout při čekání na CONNACK, nepřipojeno
                  -5 = nepoužito
                  -4 = nepoužito
                  -3 = nepoužito
                  -2 = probíhá připojování, čekáme na CONNACK (zatím nepřišel)
                  -1 = idle, nepřipojeno
                   0 = (výsledek:) MQTT 0x00: broker akceptoval připojení - LZE POKRAČOVAT (provádět Publish, Subscribe)
                   1 = MQTT 0x01: Connection Refused, unacceptable protocol version
                   2 = MQTT 0x02: Connection Refused, identifier rejected
                   3 = MQTT 0x03: Connection Refused, Server unavailable
                   4 = MQTT 0x04: Connection Refused, bad user name or password
                   5 = MQTT 0x05: Connection Refused, not authorized
SDS_get_i32(12202)    výsledek pro tyto funkce: mqtt_publish(), mqtt_subscribe(), mqtt_unsubscribe_index(), mqtt_unsubscribe_name()
--------------------------------------------------------------------------------------------------------------------------------------------
                  -8 = SUBACK dorazil z Broker ale s indikovanou chybou (Failure Bit), můžete volat další funkci
                  -7 = vybraná položka (řádek) subscribe tabulky je prázdná, není co odhlašovat
                  -6 = timeout (možnosti: publish neprovedeno, nebo: SUBACK vůbec nedorazil, nebo: UNSUBACK vůbec nedorazil), můžete volat další funkci
                  -5 = nespravne parametry (hodnoty, např. index) např. jejich celková délka se nevleze do paketu
                  -4 = nespravne parametry (počet parametrů), nepřipojeno
                  -3 = funkce zavolána dříve (nebo opakovaně) než bylo dokončeno předchozí volání funkce, takže toto volání je ignorováno
                  -2 = SDS není připojeno k brokeru (buď právě ještě probíhá připojování, nebo není vůbec připojeno)
                  -1 = bez aktivity
                   0 = nepoužito
                   1 = mqtt_publish() probíhá
                   2 = mqtt_publish() hotovo (OK - obdržen TCP ACK), můžete volat další funkci
                   4 = mqtt_subscribe() probíhá - čekám na SUBACK
                   8 = SUBACK dorazil z Broker, bez chyby (OK), můžete volat další funkci
                  16 = čekám na UNSUBACK (pouze pro unsubscribe funkce)
                  32 = UNSUBACK dorazil z Brokera, můžete volat další funkce
SDS_get_i32(12203)    počet chyb v přijatých datech MQTT protokolu (data z Brokeru) (chyba způsobí zavření spojení)
--------------------------------------------------------------------------------------------------------------------------------------------

Konec stránky.