eGospodarka.pl
eGospodarka.pl poleca

eGospodarka.plGrupypl.misc.elektronika › Biblioteka MQTT i dziwny kod w C
Ilość wypowiedzi w tym wątku: 25

  • 11. Data: 2022-08-09 19:13:46
    Temat: Re: Biblioteka MQTT i dziwny kod w C
    Od: "J.F" <j...@p...onet.pl>

    On Tue, 9 Aug 2022 07:13:17 +0200, JDX wrote:
    > On 08.08.2022 19:14, Atlantis wrote:
    > [...]
    >> BYTE llen;
    >> WORD len= MQTTReadPacket(&llen);
    >>
    > Ewidentny błąd - pokazuje dlaczego należy kompilować z -Wall (oraz
    > ewentualnie -pedantic) i nie ignorować ostrzeżeń. Aczkolwiek w
    > przytoczonym kontekście nie ma znaczenia - zmienna llen ma zasięg
    > lokalny ograniczony do wnętrza if-a i poza wywołaniem MQTTReadPacket()
    > nigdzie nie jest tam później używana.

    Blad troche dziwaczny, bo w ogole nie widze definicji MQTTReadPacket
    z parametrem. Jak to zwykłe C, i parametr nie ma znaczenia,
    to nadal dziwaczne.
    Podejrzewam, ze cos tu przerabiali, i zrezygnowali z podawania adresu.

    Ale nawet tam, gdzie tak piszą, to nie widzę aby uzywali tego llen,
    czyli błąd w zasadzie bez znaczenia.
    Dane będą w MQTTBuffer ?

    A jak Atlantis zauwazyl - program bierze z rxBF, tylko juz tam nic nie
    zapisuje.

    Wyglada na to, jakby kod byl w połowie wiekszych przeróbek.

    >> Potem zawartość takiej zmiennej jest wykorzystywana w kodzie jako
    >> element indeksu tablicy MQTTBuffer - również w tych częściach kodu,
    >> które działały prawidłowo. Szybkie poszukiwania w internecie ujawniły,
    >> że możliwość zdeklarowania pustej listy argumentów to historyczna
    >> zaszłość. Wszyscy przestrzegają przed robieniem tego. Natomiast nigdzie
    >> nie mogę znaleźć informacji o tym, w jaki sposób to działa i co
    >> właściwie robią te kawałki kodu. Ktoś ma jakiś pomysł?
    > Nie jestem pewny co oznaczają ,,te kawałki kodu", ale w ramach testu
    > proponuję odnaleźć ten kontekst:
    >
    > if(MQTTAvailable()) {
    > BYTE llen;
    > WORD len = MQTTReadPacket(&llen);
    > WORD msgId = 0;
    > BYTE *payload;
    >
    > i zaraz po deklaracjach zmiennych dopisać llen = len.

    ale o co im by mialo chodzic? Czemu mieliby uzywac llen - len
    niedobre?

    > No i proponuję też zamienić
    > switch(rxBF[1]) { //MQTTBuffer
    > na
    > switch(MQTTBuffer[1]) { //MQTTBuffer

    J.


  • 12. Data: 2022-08-09 20:38:31
    Temat: Re: Biblioteka MQTT i dziwny kod w C
    Od: Atlantis <m...@w...pl>

    On 09.08.2022 19:13, J.F wrote:

    > Blad troche dziwaczny, bo w ogole nie widze definicji MQTTReadPacket
    > z parametrem. Jak to zwykłe C, i parametr nie ma znaczenia,
    > to nadal dziwaczne.

    To jest właśnie jakaś zaszłość historyczna, o której sam wcześniej nie
    miałem pojęcia. W C++ funkcja z pustą listą parametrów równa się funkcji
    z parametrem void. Jednak w C działa to inaczej - pusta lista parametrów
    oznacza niesprecyzowaną liczbę parametrów. Do takiej funkcji możemy
    przekazać albo nic, albo cokolwiek i taki kod się skompiluje, jednak z
    wnętrza funkcji do tych parametrów i tak nie będziemy mieć dostępu.
    Liczyłem na to, że może jakaś ezoteryka języka pozwala na niejawne
    przekazanie czegoś w ten sposób jednak wychodzi na to, że ktoś po prostu
    zmieniał tę funkcję i po prostu usunął parametry zamiast przerobić
    funkcję na void.


    > Ale nawet tam, gdzie tak piszą, to nie widzę aby uzywali tego llen,
    > czyli błąd w zasadzie bez znaczenia.
    > Dane będą w MQTTBuffer ?

    Dane powinny trafić do MQTTBuffer, jednak z tego co widzę funkcja
    MQTTReadPacket() w jej obecnej formie nie radzi sobie z wiadomością
    CONNACK. Odczytuje tylko dwa pierwsze bajty (nagłówek) ale już nie dwa
    kolejne, z czego nas interesuje ostatni - result code.


    > Wyglada na to, jakby kod byl w połowie wiekszych przeróbek.

    Na to wygląda. Udało mi się skontaktować z autorem wcześniejszej wersji
    tej biblioteki na PIC32. To znaczy wcześniejszej w stosunku do tego, co
    sam znalazłem na GitHubie. A i on prawdopodobnie opierał się na jakimś
    wcześniejszym kodzie. Przesłał mi jakąś swoją starą wersję kodu -
    nietestowaną i jak się okazało niedziałającą przez kilka bugów (m.in.
    powodujących zatrzaskiwanie się maszyny stanów albo błędy podczas
    czytania z socketa). Co jednak istotne, w tej wersji kodu funkcja
    MQTTReadPacket przyjmowała jeden parametr - wskaźnik na BYTE. Wychodzi
    się na to, że pusta lista parametrów powstała, gdy ktoś później
    przepisywał ten kod.

    Wychodzi na to, że trzeba będzie teraz przyjrzeć się tej funkcji i
    ustalić, czemu nie parsuje prawidłowo CONNACT.


    > ale o co im by mialo chodzic? Czemu mieliby uzywac llen - len
    > niedobre?

    Rozróżnienie na len i llen bierze się ze specyfiki MQTT. W podstawowych
    wiadomościach (np. kontrolnych) mamy niewielką wartość len. Jednak gdy
    trzeba np. załączyć większy payload, załącza się jeszcze dodatkową
    informację. Podejrzewam, że w takich sytuacjach obydwie wartości mogą
    być potrzebne do manipulowania do manipulowania buforem. Z drugiej
    strony obecna wersja MQTTReadPacket posiada lokalną, statyczną tablice o
    nazwie lengthLength, która może być właśnie do tego wykorzystywana.


  • 13. Data: 2022-08-10 00:06:33
    Temat: Re: Biblioteka MQTT i dziwny kod w C
    Od: Atlantis <m...@w...pl>

    Sprawa ciągle nie daje mi spokoju, wiec przyjrzałem się jeszcze raz
    trochę bliżej działaniu funkcji MQTTReadPacket(). Nadal nie wiem jak
    rozwiązać problem, ale sprawa przynajmniej się trochę wyjaśniła.

    W uproszczeniu korzystanie z tej funkcji wygląda następująco:

    case MQTT_CONNECT_ACK
    WORD len = MQTTReadPacket();
    if (len >= 2) {
    //Tutaj wykonują się główne operacje
    //Tylko tutaj może zostać zmieniony stan maszyny stanów
    }
    break;

    Funkcja może być wywołana w tym miejscu wielokrotnie i dalej przejdziemy
    dopiero wtedy, gdy zwróci ona dwa lub więcej (wartość ta oznacza liczbę
    bajtów zapisanych do bufora). Sama funkcja MQTTReadPacket również
    posiada swoją własną maszynę stanów, której wartość jest zapisywana w
    lokalnej zmiennej statycznej. Od stanu tej maszyny zależy co funkcja zwróci.

    Dopisałem do kodu kilka printf-ów, żeby zobaczyć co się tam dzieje.
    Wynik wygląda następująco:

    Tutaj wywolujemy MQTTReadPacket() w MQTT_CONNECT_ACK
    m_state=0 <- stan po wywołaniu funkcji w MQTT_CONNECT_ACK
    len=2 <- wartość zwrócona

    Tutaj wywołania w innych częściach programu
    m_state=2
    m_state=3
    m_state=0

    Tutaj wywolujemy MQTTReadPacket() w MQTT_CONNECT_ACK
    m_state=2 <- stan po wywołaniu funkcji w MQTT_CONNECT_ACK
    len=0 <- wartość zwrócona

    Tutaj wywolujemy MQTTReadPacket() w MQTT_CONNECT_ACK
    m_state=3 <- stan po wywołaniu funkcji w MQTT_CONNECT_ACK
    len=0 <- wartość zwrócona

    Tutaj wywolujemy MQTTReadPacket() w MQTT_CONNECT_ACK
    m_state=0 <- stan po wywołaniu funkcji w MQTT_CONNECT_ACK
    len=2 <- wartość zwrócona

    Tutaj wywołania w innych częściach programu
    m_state=2
    m_state=3
    m_state=0


    Jak widać maszyna stanów przy kolejnych wywołaniach funkcji
    MQTTReadPacket() posiada wartości 0, 2 albo 3.
    Jeśli funkcja zostanie wywołana gdy jej maszyna będzie w stanie 0, to
    zwrócona zostanie wartość 2 - spowoduje to, że będziemy mogli wejść do
    ifa i wykonać operacje przewidziane dla MQTT_CONNECT_ACK.
    Jeśli jednak w momencie wywołania funkcji jej maszyna stanów będzie
    ustawiona na 2 albo 3, zwrócone zostanie zero. If się nie wywoła, a wiec
    nie opuścimy MQTT_CONNECT_ACK i wrócimy do tego samego miejsca w
    kolejnym obiegu pętli.

    Co więcej - wywołania MQTTReadPacket w innych miejscach programu również
    biorą udział w tym cyklu.

    Kolejny wniosek jest taki, że "magiczne liczby" w switch/case wewnątrz
    MQTTReadPacket to tak naprawdę kolejne etapy pracy maszyny stanów tej
    funkcji.

    Więc główny problem polega teraz na tym, żeby w tym miejscu nie było
    zwracane 2, ale 4. Do MQTTBuffer powinny trafiać cztery bajty, a
    ostatnio z nich będzie kodem wyniku, przesyłanym w pakiecie CONNACK.
    Konieczna będzie dokładniejsza analiza tego, co właściwie ta funkcja
    robi. :)


  • 14. Data: 2022-08-10 00:13:41
    Temat: Re: Biblioteka MQTT i dziwny kod w C
    Od: JDX <j...@o...pl>

    On 09.08.2022 19:13, J.F wrote:
    [...]
    > Blad troche dziwaczny, bo w ogole nie widze definicji MQTTReadPacket
    > z parametrem. Jak to zwykłe C, i parametr nie ma znaczenia,
    > to nadal dziwaczne.
    Błąd człowieka, na który pozwala język C, w szczególności stare
    standardy. Od C11 (aka ISO/IEC 9899:2011) takie deklaracje zostały
    uznane za przestarzałe (chociaż nadal dopuszczalne).

    Tu masz to opisane razem z cytatami ze standardu/ów:

    https://stackoverflow.com/questions/13950642/why-doe
    s-a-function-with-no-parameters-compared-to-the-actu
    al-function-definiti

    https://stackoverflow.com/questions/18378993/c-and-d
    efining-a-function-prototype-with-no-parameters


  • 15. Data: 2022-08-10 09:52:16
    Temat: Re: Biblioteka MQTT i dziwny kod w C
    Od: "J.F" <j...@p...onet.pl>

    On Wed, 10 Aug 2022 00:13:41 +0200, JDX wrote:
    > On 09.08.2022 19:13, J.F wrote:
    > [...]
    >> Blad troche dziwaczny, bo w ogole nie widze definicji MQTTReadPacket
    >> z parametrem. Jak to zwykłe C, i parametr nie ma znaczenia,
    >> to nadal dziwaczne.
    > Błąd człowieka, na który pozwala język C, w szczególności stare
    > standardy. Od C11 (aka ISO/IEC 9899:2011) takie deklaracje zostały
    > uznane za przestarzałe (chociaż nadal dopuszczalne).
    >
    > Tu masz to opisane razem z cytatami ze standardu/ów:
    >
    > https://stackoverflow.com/questions/13950642/why-doe
    s-a-function-with-no-parameters-compared-to-the-actu
    al-function-definiti
    >
    > https://stackoverflow.com/questions/18378993/c-and-d
    efining-a-function-prototype-with-no-parameters

    Jest to moze i jakis błąd, ale jest szerszy - C pozwala na wywołanie
    funkcji z dowolną listą parametrow, bo inaczej printf nie moglby
    dzialac.

    Co prawda powinno to zostac zdefinioniowane z uzyciem "..."
    ... no to moze i jest jakis błąd kompilatora, ze nie zgłasza rożnic
    w prototypie, deklaracji i wywolaniach ...

    J.


  • 16. Data: 2022-08-10 09:59:20
    Temat: Re: Biblioteka MQTT i dziwny kod w C
    Od: "Grzegorz Niemirowski" <g...@g...net>

    J.F <j...@p...onet.pl> napisał(a):
    > Jest to moze i jakis błąd, ale jest szerszy - C pozwala na wywołanie
    > funkcji z dowolną listą parametrow, bo inaczej printf nie moglby
    > dzialac.

    Ale właśnie...

    > Co prawda powinno to zostac zdefinioniowane z uzyciem "..."
    > ... no to moze i jest jakis błąd kompilatora, ze nie zgłasza rożnic
    > w prototypie, deklaracji i wywolaniach ...
    > J.

    ...printf z tego nie korzysta. On ma taką deklarację:
    int printf ( const char * format, ... );
    Czyli przyjmuje jeden lub więcej parametrów i jest to po ludzku określone.
    Do niczego nie jest mu potrzebny ten dziwny mechanizm z pustą listą
    argumentów.

    --
    Grzegorz Niemirowski
    https://www.grzegorz.net/


  • 17. Data: 2022-08-10 19:25:51
    Temat: Re: Biblioteka MQTT i dziwny kod w C
    Od: Atlantis <m...@w...pl>

    Ok, posiedziałem nad tym jeszcze przez kilka godzin i udało mi się
    znaleźć przyczynę. W wielkim skrócie maszyna stanów w funkcji
    MQTTReadPacket była źle napisana. Jeden if nie wykonywał się wcale, a
    część kodu w dalszej części była pomijana zupełnie z uwagi "break"
    umieszczony w złym miejscu. Efekt był taki, że kod przechodził dalej już
    po odebraniu nagłówka pakietu i nie pobierał pozostałych dwóch bajtów.

    Biblioteka w takiej formie działała tylko dlatego, że w wyniku innego
    błędu kod zawsze zakładał, że autoryzacja przeszła poprawnie. ;)
    Z uwagi na wadliwość tej funkcji rzecz jasna nie miały szans działać
    jakiekolwiek inne funkcje związane z odbieraniem danych od brokera.
    Niewykluczone zresztą, że będę musiał przeprowadzić dodatkowe testy i
    poprawić jeszcze kilka błędów, zanim uda mi się uruchomić sprawdzanie
    wiadomości PUBLISHACK albo subskrybowanie tematu i odbieranie wiadomości
    przychodzących od brokera.

    Wireskark pokazuje także, że mam trochę retransmisji TCP na porcie MQTT,
    więc temu też jeszcze będę musiał się przyjrzeć.

    Na chwilę obecną działa jednak najważniejsze - wrzucanie danych na
    serwer. Jeśli ktoś byłby zainteresowany, to po posprzątaniu mogę się tym
    podzielić. O ile ktoś jeszcze używa PIC32 z bibliotekami MLA i będzie
    potrzebował obsługi MQTT. :)


  • 18. Data: 2022-08-10 20:41:36
    Temat: Re: Biblioteka MQTT i dziwny kod w C
    Od: heby <h...@p...onet.pl>

    On 10/08/2022 19:25, Atlantis wrote:
    > podzielić. O ile ktoś jeszcze używa PIC32 z bibliotekami MLA i będzie
    > potrzebował obsługi MQTT. :)

    Teraz, to się używa ESP8266/ESP32 do tego a nie jakieś PICe od migania
    ledami ;)


  • 19. Data: 2022-08-10 22:06:33
    Temat: Re: Biblioteka MQTT i dziwny kod w C
    Od: Marek <f...@f...com>

    On Wed, 10 Aug 2022 20:41:36 +0200, heby <h...@p...onet.pl> wrote:
    > Teraz, to się używa ESP8266/ESP32 do tego a nie jakieś PICe od
    > migania
    > ledami ;)

    Uu pic32 od migania ledami, mocne.

    --
    Marek


  • 20. Data: 2022-08-10 22:43:23
    Temat: Re: Biblioteka MQTT i dziwny kod w C
    Od: "Grzegorz Niemirowski" <g...@g...net>

    Atlantis <m...@w...pl> napisał(a):
    > Jeśli ktoś byłby zainteresowany, to po posprzątaniu mogę się tym
    > podzielić.

    Ja nie potrzebuję, ale może po prostu wrzuć na githuba, to ktoś spoza pme
    też skorzysta i nie będzie się musiał męczyć z tamtym kodem.

    --
    Grzegorz Niemirowski
    https://www.grzegorz.net/

strony : 1 . [ 2 ] . 3


Szukaj w grupach

Szukaj w grupach

Eksperci egospodarka.pl

1 1 1

Wpisz nazwę miasta, dla którego chcesz znaleźć jednostkę ZUS.

Wzory dokumentów

Bezpłatne wzory dokumentów i formularzy.
Wyszukaj i pobierz za darmo: