# Cviceni: Thread a CoAP na ESP32-C6 Tento projekt je pripraven jako kostra pro pocitacove cviceni. Cilem je: 1. nastavit uzel do site `Thread` pomoci aktivniho datasetu, 2. vytvorit CoAP `POST` pozadavek, 3. odeslat simulovana senzorova data ve formatu JSON. V projektu jsou nektere casti jiz hotove a nektere jsou pripraveny jako `TODO` pro doplneni. ## Co je Thread Thread je sitovy protokol pro zarizeni nad IEEE 802.15.4. Umoznuje IPv6 komunikaci mezi uzly s malou rezii a nizkou spotrebou. V siti se mohou objevit napriklad role: - `leader` - `router` - `child` Aby se uzel pripojil do konkretni site, musi znat parametry aktivniho datasetu: - `Network Name` - `Channel` - `PAN ID` - `Network Key` - `Extended PAN ID` - `Mesh-Local Prefix` Tyto hodnoty se v projektu vyplnuji do [src/thread_dataset.h](src/thread_dataset.h). ## Co je CoAP CoAP je lehky aplikacni protokol pro vestavene systemy. Bezi nad UDP a pripomina zjednodusene HTTP. V tomto cviceni budeme pouzivat: - metodu `POST` - URI cestu `/sensor` - payload ve formatu JSON Server, na ktery bude klient odesilat data, ma adresu: ```text coap://[fd11:2233:4455:6677::1]:5683/sensor ``` Parsovani teto URL je v projektu jiz hotove. Studenti implementuji jen vytvoreni JSON payloadu a sestaveni CoAP zpravy. ## Postup cviceni ### 1. Doplneni Thread datasetu Otevri [src/thread_dataset.h](src/thread_dataset.h). V souboru jsou placeholdery, ktere je potreba nahradit hodnotami ze zadani. Vypln: - `THREAD_NETWORK_NAME = "OpenThread-ESP"` - `THREAD_CHANNEL = 15` - `THREAD_PANID = 0x1234` - `THREAD_MESH_LOCAL_PREFIX_STRING = "fd11:2233:4455:6677"` - `THREAD_GATEWAY_STATIC_ADDR = "fd11:2233:4455:6677::1"` - `THREAD_NODE_STATIC_ADDR = "fd11:2233:4455:6677::10"` - `THREAD_GATEWAY_COAP_URL = "coap://[fd11:2233:4455:6677::1]:5683/sensor"` `Network Key`: ```c { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, } ``` `Extended PAN ID`: ```c { 0xde, 0xad, 0x00, 0xbe, 0xef, 0x00, 0xca, 0xfe, } ``` `Mesh-Local Prefix` jako pole bajtu: ```c { 0xfd, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, } ``` Po doplneni by mel byt uzel schopny se pripojit do site Thread. ### 2. Sestaveni JSON payloadu Otevri [src/coap_client.c](src/coap_client.c) a dopln funkci `coap_client_build_json_payload()`. Tato funkce ma: - vzit hodnoty ze struktury `sensor_data_t` - vytvorit z nich textovy JSON - ulozit vysledek do bufferu `payload` - vratit `true`, pokud se payload podarilo vytvorit Ocekavany format: ```json {"node_id":"node_1","temp":23.4,"humidity":48,"button":1} ``` K tomu je vhodne pouzit funkci `snprintf()`. `snprintf()`: - zapisuje formatovany text do bufferu - hlida maximalni velikost bufferu - vraci pocet znaku, ktere by byly zapsany Co je potreba zkontrolovat: - navratova hodnota neni zaporna - vysledny text se vesel do `payload_size` ### 3. Vytvoreni CoAP POST zpravy Ve stejnem souboru dopln funkci `coap_client_create_post_request()`. Tato funkce ma z vytvoreneho JSON payloadu pripravit CoAP zpravu pro OpenThread. Postup: 1. vytvorit zpravu 2. nastavit typ zpravy 3. nastavit kod `POST` 4. pridat URI path 5. pridat informaci, ze payload je `JSON` 6. pridat samotny payload Pouzij tyto OpenThread funkce: - `otCoapNewMessage()` Vytvori novou CoAP zpravu. - `otCoapMessageInit()` Nastavi typ a kod zpravy. Zde pouzij `OT_COAP_TYPE_CONFIRMABLE` a `OT_COAP_CODE_POST`. - `otCoapMessageGenerateToken()` Vygeneruje token, podle ktereho lze sparovat odpoved. - `otCoapMessageAppendUriPathOptions()` Prida URI cestu, napriklad `sensor`. - `otCoapMessageAppendContentFormatOption()` Nastavi format obsahu. Zde pouzij `OT_COAP_OPTION_CONTENT_FORMAT_JSON`. - `otCoapMessageSetPayloadMarker()` Oddeli CoAP options od samotneho payloadu. - `otMessageAppend()` Prida do zpravy data payloadu. Pokud nektery krok selze: - uvolni zpravu pomoci `otMessageFree(message)` - vrat `NULL` ### 4. Prepinani intervalu pomoci D1 Na kitu je pripojen pin `D1`, ktery bude slouzit pro prepinani periody odesilani. V [src/main.c](src/main.c) je pripraveno: - inicializovani vstupu pro tlacitko na `D1` - funkce `application_get_send_interval_ms()`, kterou je potreba doplnit Student ma dopsat logiku: - pokud je tlacitko stisknute, pouzij rychly interval `1000 ms` - pokud tlacitko stisknute neni, pouzij pomaly interval `5000 ms` Napoveda: - pro cteni vstupu lze pouzit `gpio_get_level()` - pri zapnutem `pull-up` byva stisk tlacitka casto reprezentovan hodnotou `0` ### 5. Otestovani Po doplneni sleduj log na seriove lince. Zajimaji te hlavne: - zmena role uzlu v Thread siti - informace o inicializaci CoAP klienta - vypis odesilaneho payloadu - zmena intervalu po stisku tlacitka `D1` - pripadna odpoved od CoAP serveru ## Co uz je hotove V projektu je jiz pripraveno: - spusteni OpenThread stacku v [src/main.c](src/main.c) - nacitani datasetu a start site v [src/main.c](src/main.c) - parsovani CoAP URL v [src/coap_client.c](src/coap_client.c) - volani `coap_send_data()` a odesilani periodickych dat ## Poznamka V [src/thread_dataset.h](src/thread_dataset.h) jsou zamerne placeholdery. Projekt se zkompiluje, ale bez spravnych hodnot se uzel nepripoji do pozadovane Thread site.