Przejdź do treści

Vemmio nRF Serial API

Wprowadzenie

Vemmio Smart Gateway, oprócz obecnego wsparcia dla sieci Z-Wave, powinien udostępniać możliwość obsługi urządzeń ZigBee oraz BLE. Aby zapewnić możliwość komunikacji urządzenia z otoczeniam z wykorzystaniem obu wskazanych protokołów, zdecydowano się na wykorzystanie mikrprocesorów z serii nRF52, dostarczanych przez firmę Nordic. Procesory nRF52 to seria układów opartych o rdzeń ARM Cortex M4 wspartych uniwersalnym układem komunikacyjnym, którego działanie można definiować programowo wykorzystując technologię SoftDevice opracowaną przez firmę Nordic. SoftDevice to prekompilowny stos komunikacyjny, definiujący działanie modulu komunikacyjnego. Do wybory mamy takie protokoły jak:
1. ZigBee 2. Bluetooth Low Energy 3. Bluetooth Mesh 4. NFC 5. ANT

To, jaki protokół będzie obsługiwany przez układ zależy od tego, jaki wsad SoftDevice został do niego wgrany obok aplikacji. Bardzo istotną cechą jest fakt, że możliwa jest pseudo-równoległa obsługa dwóch różnych protokołów, co wydaje się najważniejszą zaletą układów nRF w kontekście onieczności dodania obsługi BLE oraz ZigBee do Vemmio Smart Gateway.

Realizacja komunikacji Mediatek <-> nRF

Opis problemu

Początkowo najlepszym pomysłem wydawało się skorzystanie z dostarczanego przez Nordic rozwiązania o nazwie serializowany SoftDevice, polegający na udostępnieniu API komunikacyjnego (pozwalającego na konfiguracje i zarządzanie komunikacją) przez port szeregowy, dając w ten sposób możliwość realizacji warstwy aplikacji na innej platformie. Niestety przeprowadzny eksperyment pokazał, że ograniczenia techniczne, związane z dostępnością peryferiów w procesorze Mediatek, uniemożliwiają wykorzystanie tego rozwiązania bez konieczności wprowadzenia gruntownych zmian w wykorzystywanej platformie sprzętowej.

Proponowane rozwiązanie

W zaistniałej sytuacji podjęto decyzję, że zostanie napisana obsługa własnego protokołu Vemmio nRF Serial API. Rozwiązanie takie, mimo iż na pierwszy rzut oka kosztowniejsze (ze względu na konieczność zaimplementowania, a następnie testowania i utrzymania własnego rozwiązania), w dalszej perspektywie może przynieść znaczące korzyści, szczególnie w kontekście swobodnej rozbudowy czy też posiadania pełnej kontroli nad tym, co się dzieje za kulisami obsługi.
Dodatkowo, z myślą o jak największej elastyczności docelowego rozwiązania, chcąc jedncześnie w miarę możliwości jak najbardziej skrócić czas jego przygotowania, implementację API postanowiono oprzeć o gotową bibliotekę CLI (Command Line Interface) dostarczaną wraz z Nordic SDK. Nordic CLI Library jest uniwersalnym frameworkiem pozwalającym na definiowanie dowolnych komend, któe mogą być wysyłane do urządzenia za pośrednictwem portu szeregowego. Każda komenda posiada przypisany callback implementaujący obsługę danej komendy, który może wykonać dowolną operację i w razie potrzeby zwrócić odpowiedź, któa następnie może być odesłana spowrotem za pośrednictwem portu szeregowego.
Opierając swój własny protokół na tej bibliotece zyskujemy niemal nieograniczoną (jedynym ogranicznikiem są zasoby w postaci pamięci programu) dowolność rozbudowy API w przyszłości, a jednocześnie niesamowitą łatwość realizacji jego warstwy fizycznej, gdyż do sprawnej obsługi wystarczy nam magistrala UART o niskiej prędkości rzędu 9600bps, bez sprzętowej kontroli przepływu.

Składnia Vemmio nRF Serial API

Komenda

Interfejs Vemmio nRF Serial API będzie miał postać unix'owych poleceń z '\r' (\, 0x0D) jako znakiem końca linii, będącym jedocześnie sygnałem żądania wykonania komendy.
Składnia pojedynczej komendy to

command [arg1[ arg2[... [arg8]]]]\r

  gdzie:  
    command - jedna z opisanych w dalszej części komend tekstowych  
    arg1, arg2, ..., arg8 - maksymalnie 8 ciągów dowolnych ciągi znaków alfa-numerycznych oddzielone spacją (argumenty wielowyrazowe należy zamknąć w znaku cydzysłowia) o długości nie większej niż 32 znaki każdy

W reakcji na przyjętą komendę nRF w czasie nie dłuższym niż 1s wysyła odpowiedź. Nieuzyskanie odpowiedzi w/w czasie oznacza, że komenda nie została poprawnie obsłużona. W przypadku wystąpienia takie sytuacji trzy razy z rzędu należy przyjąć, że proces obsługujący Vemmio nRF Serial API się zawiesił i jedynym sposobem na prywrócenie poprawnej pracy jest wywołanie sprzętowego resetu.

Odpowiedź

Aby ułatwić obsługę interpretacji danych zwracanych jako rezultat wywołania komendy, składnia odpowiedzi będzie bazowała na formacie JSON.
Protokół Vemmio nRF Serial API definiuje trzy rodzaje ramek wysyłanych przez nRF do Mediatek'a:

  • ImmediateResponse (0)
    Jest to odpowiedź wysłana jako bezpośrednia reakcja na przyjętą przez nRF komendę. Zazwyczaj zawiera ona informację o statusie wykonania żądanej operacji lub obiekt z danymi, jeśli aplikacja jest w stanie dostarczyć je niezwłocznie.
    Przykładowa odpowiedź oraz standardowy przepływ danych:
{
    "type":0,
    "error":error,
    "data":
    {
        ...
    }
}

  gdzie:
    type  - zawsze wartość 0
    error - 0 jeśli operacja przebiegła pomyślnie lub kod błędu
    data  - dane zwrotne, jeśli komenda dostarcza danych

@startuml Mediatek -> nRF : Command nRF -> Mediatek : ImmediateResponse @enduml

  • DelayedResponse (1)
    Jest to odpowiedź wysyłana z opóźnieniem, w reakcji na wywołanie komendy, której czas obsługi przekracza maksymalny limit oczekiwania na odpowiedź. W takiej sytuacji w odpowiedzi na komendę najpierw wysyłana jest odpowiedź typu ImmediateResponse, zawierająca unikalny numer (callbackID) nadany obsłudze komendy, dzięki któremu będzie można powiązać wywołanie komendy z ramką typu DelayedResponse, która zostanie wysłana w późniejszym terminie, nie później niż 30 sekund od momentu wywołania. Jeżeli 30 seund nie wystarczy Przykładowa odpowiedź oraz standardowy przepływ danych:
{
    "type":1,
    "error": error,
    "callbackId":callbackId,
    "pending":flag,
    "data":
    {
        ...
    }
}

  gdzie:
    type         zawsze wartość 1
    error        0 jeśli operacja przebiegła pomyślnie lub kod błędu
    callbackId   unikalny numer nadany obsłudze komendy, dla której wygenerowano odpowiedź
    pending      1 jeżeli komenda wciąż nie zostałą obsłużona, 0 jeśli obiekt zawiera gotową odpowiedź
    data         dane zwrotne, jeśli dostępne

@startuml Mediatek -> nRF : Command nRF -> Mediatek : ImmediateResponse (w polu danych zawiera unikalny callbackId) ... alt dane nie są gotowe case nRF --> Mediatek : DelayedResponse (flaga pending ustawiona na 1) end ... nRF --> Mediatek : DelayedResponse (zawiera obiekt z odpowiedzią) @enduml

  • UnsolicitedMessage (2)
    Jest to typ wiadomości nie wysyłany w odpowiedzi na żadną komendę, a w celu poinformowania hosta o zaistnieniu jakiegoś zdarzenia, wymagającego obsługi ze strony aplikacji pracującej na Mediateku.
    Przykładowa odpowiedź oraz standardowy przepływ danych:
{
    "type":2,
    "actionId": actionId,
    "data":
    {
      ...
    }
}

  gdzie:
    type      zawsze wartość 2
    actionId  identyfikator akcji, którą należy podjąć
    data      obiekt opisujący akcję wraz z niezbędnymi argumentami

@startuml nRF --> Mediatek : UnsolicitedMessage @enduml

Lista komend

Aktywacja rozgłaszania

Przy pomocy tej komendy Mediatek informuje moduł nRF, że powinien uaktywnić tryb rozgłaszania w celu sparowania GW z aplikacja mobilną.

Komenda:

ble_advertise arg

gdzie:
  arg    on     włącz tryb rozgłaszania
         off    wyłącz tryb rozgłaszania 

Odpowiedź:

{
    "type":0,
    "error":errorCode,
    "data":""
}

gdzie:
  errorCode   0   operacja przebiegła pomyślnie
              1   stos nie jest zainicjalizowany

Udostępnienie listy widocznych sieci

Komenda ta służy do ustawienia listy identyfikatorów sieci WiFi, które należy udostępnić aplikacji mobilnej. Uwaga! Jednorazowo można przesłać 8 identyfikatorów, każdy nie dłuższy niż 31 znaków.

Komenda:

ble_set_wifi_networks arg

gdzie:
  arg    lista SSID oddzielonych spacją (max. 8)

Odpowiedź:

{
    "type":0,
    "error":errorCode,
    "data":""
}

gdzie:
  errorCode   0   operacja przebiegła pomyślnie
              2   błędy parametr (np. przekazanie pustej listy sieci)
              3   błąd aktualizacji wartości atrybutu
              4   błąd aktywowania notyfikacji atrybutu
              5   błąd stanu stosu (brak połączenia albo brak subskrypcji na notyfikację)

Informacja o zakończeniu przesyłania listy identyfikatoró SSID

Komenda ta służy do poinformowania o stanie skanowania sieci.

Komenda:

ble_set_networks_scanning_status arg

gdzie:
  arg    1   rozpoczęcie skanowania
         2   zakończenie skanowania
         x   dowolna inna wartość, jeśli tylko okaże sie przydatna w aplikacji mobilnej

Odpowiedź:

{
    "type":0,
    "error":errorCode,
    "data":""
}

gdzie:
  errorCode   0   operacja przebiegła pomyślnie
              4   błąd aktywowania notyfikacji atrybutu
              5   błąd stanu stosu (brak połączenia albo brak subskrypcji na notyfikację)

Informacja o rezultacie logowania do sieci WiFi

Komenda ta służy do poinformowania o rezultacie próby logowania do sieci. Może zostać użyta zarówno w procesie dodawania urządzenia do sieci WiFi przy pomocy aplikacji mobilnej, jak i w późniejszym czasie, aby poinformować aplikację mobilną, że zaistniał np. problem z dostępem do sieci.

Komenda:

ble_notify_login_result res

gdzie:
  res    1    rozpoczęcie zestawiania połączenia
         2    potwierdzenie zestawienia połączenia
         3    błąd zestawienia połączenia
        ...   ...

Odpowiedź:

{
    "type":0,
    "error":errorCode,
    "data":""
}

gdzie:
  errorCode   0   operacja przebiegła pomyślnie
              2   błędy parametr (np. przekazanie pustej listy sieci)
              3   błąd aktualizacji wartości atrybutu
              4   błąd aktywowania notyfikacji atrybutu
              5   błąd stanu stosu (brak połączenia albo brak subskrypcji na notyfikację)

Kody bledow

Nazwa Wartość Opis
NoError 0 Brak błędu
NotInitialized 1 Brak inicjalizacji modułu biorącego udział w obsłudze komendy
WrongParameter 2 Błędna wartość parametru wywołania
GattsSetError 3 Nie powiodło sie ustawienie wartości atrybutu
GattsNotifyError 4 Nie powiodło się wywołanie notyfikacji na atrybucie
WrongStateError 5 Stos znajduje się w stanie uniemożliwiającym podjęcie wybranej akcji

Lista UnsolicitedMessages

Żądanie wysłania listy sieci WiFi

Przy pomocy tej wiadomości nRF infomuje Mediatek, że aplikacja mobilna zażądała listy identyfikatorów sieci WiFi, które są widoczne dla urządzenia. W reakcji na tę wiadomość powinien wykonać komendę ble_set_wifi_networks.

{
    "type":2,
    "actionId":0,
    "data":{}
}

Żądanie zalogowania do sieci WiFi

Przy pomocy tej wiadomości nRF informuje Meditek, że aplikacja mobilna przeslała dane logowania do sieci. W reakcji na tę wiadomość Mediatek powinien spróbować zalogować się do wybranej sieci WiFi i za pomocą komendy ble_notify_login_result poinformować o rezultacie operacji.

{
    "type":2,
    "actionId":1,
    "data":
    {
        "ssid":name,
        "pass":pass,
        "mode":mode
    }
}

gdzie:
  name          identyfikator SSID sieci, dla której podano dane logowania
  pass          hasło dostępu do sieci WiFi (może być puste)
  mode     0    brak szyfrowania
           1    WEP
           2    WPA/WPA2