SUDP protocol

Z onlinetechnology.cz

Přejít na: navigace, hledání
Tato stránka popisuje funkci zařízení SDS druhé produktové řady - protože SDS první produktové řady používají jiný protokol.

Obsah

Rychlá komunikace: S-UDP

Pomocí speciálního protokolu, kdy se data přenášejí prostřednictví UDP, je možné získávat informace z výrobků řady SDS/OnlineTechnology.

S-UDP používá následující výchozí UDP PORT: 310

Komunikace probíhá formou DOTAZ - ODPOVĚĎ. To znamená, že ten, kdo má o informace zájem (vzdálený uživatel) pošle dotaz (korektně vyplněný UDP paket, viz dále) a obratem obdrží od zařízení odpověď - UDP paket s informacemi. UDP Port na kterém je komunikace prováděna lze samozřejmě v administraci zařízení změnit.

Přenos dat využívá specifického protokolu, který umožňuje bezpečně ovládat specifické zařízení SDS.


Typické použití: komunikace zařízení SDS s protistranou (např. aplikace na mobilním telefonu).


Bezpečnost

Protokol S-UDP je založen na důsledné autentizaci strany, která posílá zprávu - zařízení SDS ověřuje identitu odesílatele příkazu, a ten může ověřit identitu SDS který odpovídá.


Je to založeno na následujícím principu:

- S-UDP protokol je zabezpečen symetrickou šifrou, se sdíleným klíčem který znají jen komunikující strany (bezpečnost je přímo úměrná úrovni zabezpečení tohoto klíče na obou stranách)

- SDS má unikátní identifikátor (zaručeně unikátní, od výrobce) který nelze změnit (je fyzicky vypálen v SoC - nenávratně přímo v chipu).


S-UDP protokol

Každý příkaz a odpověď jsou v samostatném, jediném, UDP paketu.

Každý paket je sestaven v rámci společného formátu, který je zde popsán. Samotný doplňující datový obsah (payload) je dynamický, a u některých příkazů není potřeba.

S-UDP Paket se tedy skládá z těchto základní částí (tyto části jsou právě přenášeny UDP paketem, v následující sestavě):

 [MASTER PACKET CONTENTS]

  OFFSET    | LEN    |  DATA
  ----------+--------+---------------------------------------------------------------
    0       |     28 |  HEADER
   28       |  PL*16 |  ENCRYPTED PAYLOAD (contains: payload-header and payload-data)

Pozor! Hodnota PL je velikost [ENCRYPTED PAYLOAD] vydělená 16. To znamená, že velikost [ENCRYPTED PAYLOAD] musí být beze zbytku dělitelná 16 (tzn. pouze hodnota 16, 32, 64, ...) ! Pokud je potřeba, doplní se na úplný konec (viz oblast "R") zarovnání do potřebné délky, aby se dosáhlo čisté dělitelnosti 16.

LITTLE-ENDIAN

Následující uvedené položky jsou ve formátu Little-Endian (procesory: ARM, x86):

  • uword (unsigned 16-bit)
  • dword (unsigned 32-bit)
  • slong (signed 32-bit)
  • qword (unsigned 64-bit)

Položky typu: byte, sbyte, bytes - jsou jednotlivé samostatné bajty, nesdružené do společného čísla.


Zde jsou uvedeny detailní položky:

 [MASTER PACKET CONTENTS]

  OFFSET   | LEN  |  TYPE  | DATA
  ---------+------+--------+-----------------------------

                             [HEADER]

   0       |   3  |  bytes | header "SDS"
   3       |   1  |   byte | TV = (SDS-product-line) including (S-UDP protocol master-version)
   4       |   1  |   byte | PL = number of 16B chunks - this is the payload_length of [ENCRYPTED PAYLOAD] (example: PL==10 => 160 bytes)
   5       |   1  |   byte | encryption-flag  (NOW ACCEPTS ONLY: 0x10 == XTEA-64-CTR)
   6       |   1  |   byte | reserved
   7       |   1  |   byte | CK1: basic additive checksum for [ENCRYPTED PAYLOAD] (start from (including) byte offset [28] and forward)
   8       |   4  |  dword | user_identifier (correlation identifier) - use this to correlate query to response
  12       |  16  |  bytes | CounterBlock
 ----------+------+--------+----------------------------

                             [ENCRYPTED PAYLOAD] -> everything from this point is included:

  28       |   1  |   byte | random number (shall be always different than what was used ever before)
  29       |   1  |   byte | CK2: basic additive checksum for [HEADER] (all bytes [0] to [27] included, BUT: skipping byte [7])
  30       |   2  |  uword | XR_MTU value (maximal size of the custom-payload data including R) ( XL + R <= XR_MTU )
  32       |   4  |  dword | CRC-32 (part-header and plain-text payload) -> byte [36] (included) up to [52+XL-1] (the R area is not included here)
  36       |   4  |  dword | uptime (msecs from boot)
  40       |   4  |  dword | time (epoch) (or, if no NTP is available to SDS, this will be a value of "seconds from boot")
  44       |   4  |  dword | SDS device type (0xB1900001) - THIS MUST MATCH
  48       |   1  |   byte | master_command
  49       |   1  |   byte | sub_command
  50       |   2  |  uword | XL value (exact length of the actually useful payload-data): XL = (PL*16) - R - 24

  52       |  XL  |  bytes | custom payload-data [C-PAYLOAD]

  52+XL    |   R  |  bytes | specific set of (random data filling) to round-up (the PL*16 value) to a clean 16B multiply (16, 32, 64, etc.)

 ----------+------+--------+----------------------------

Hodnota "random number" je zde proto, aby šifrované data byly pokaždé jiné, i když se přenáší stejný obsah (tzn. jedná se o zábranu stenografického odhadu obsahu payloadu).

Hodnota "time" umožňuje zařízení, které komunikuje s SDS, zabránit "replay" útoku (když se zaznamená paket a později se zopakuje - v takovém případě se na to přijde protože "time" bude významně starší). SDS kontrolu provádí vůči svému vnitřnímu času, vzdálené zařízení co s SDS komunikuje by tuto kontrolu mělo dělat také.

Protože hodnota "time" se zvyšuje pouze co 1 vteřinu, je k dispozici i hodnota "uptime" která se po resetu/bootu (kde se nastaví na nulu) zvyšuje každou 1 milisekundu o jedničku.

"CounterBlock" se využívá pro nastavení začátku šifrování a dešifrování. Všechny detaily jsou zcela shodné jako pro FULL-C funkci SDS_Crypt(). Z hlediska bezpečnosti je důležité, aby obě strany neustále používaly zvyšující se CounterBlock obsah (začít od jedničky pouze po resetu/bootu), tzn. pro každou zprávu použít poslední hodnotu counteru a na té dále stavět pro novou zprávu atd. .

Hodnota "crc32" se počítá pro dešifrované data, algoritmus je identický jako pro FULL-C funkci SDS_Crypt().

Pro zvolené XTEA-64-CTR má "CounterBlock" následující sestavu svého obsahu:

  CounterBlock:

  OFFSET    | LEN  |  TYPE  |  DATA
  ----------+------+--------+-----------------------------------------------------------------------------------------
   0        |   8  |  qword |  XTEA-64-CTR: 64-bit counter (counter is increased by 1, for each 16B of processed data)
   8        |   8  |  bytes |  (reserved) not-used area = reserved (fill with 0x00) 

Pro jiné mechanismy (do budoucna) je v CounterBlock oblasti přidána ještě 8B rezerva (např. pro AES-128 se pak využije všech 16 bajtů).


Hodnota "TV" (v [HEADER] na offsetu [3]) je určení typu a verze protokolu. Skládá se ze dvou čtyřbitových údajů, viz následující tabulka.

TV: ttttVVVV
    76543210

BIT OFFSET | LEN (bits) | content
-----------+------------+--------------------------------------------------
 7 (MSB)   |          4 |  "t": produc-line value: 1 == first, 2 == second
 3         |          4 |  "V": version: 0 = first S-UDP protocol version


V konečném důsledku, skutečnou funkční důležitost ma [C-PAYLOAD], což je blok dat, který obsahuje hodnoty a příkazy, které pomocí S-UDP chceme přenést.


Postup při příjmu S-UDP paketu

Každá strana, která přijme S-UDP paket, provede následující kroky:

1) Ověřit platnost hodnot v [HEADER]
   a. text "SDS" (platný obsah)
   b. hodnota "TV" ("master-version" a "product-line") (platný obsah)
   c. hodnota "PL" v platných mezích
   d. hodnota "encryption_flag" (platný obsah)
2) Ověřit základní additive-checksum pro [ENCRYPTED PAYLOAD]
   a. přečíst bajty [28] až [28+PL-1] a sečíst je (overflow osm bitů), výsledek musí odpovídat "CK1" hodnotě
3) Nastavit dešifrování
   a. zvolit algoritmus podle "encryption-flag" hodnoty
   b. nastavit klíč (stejný jako na protistraně, samozřejmě není přenášen přes síť)
   c. nastavit "CounterBlock" (přečíst z [HEADER])
4) Dešifrovat celou [ENCRYPTED PAYLOAD] na plain-text
   a. hodnota "PL" musí být dělitelná 16 beze zbytku (tato podmínka závisí na použitém šifrovaní)
5) Ověřit základní additive-checksum pro [HEADER] - teď totiž už máme hodnotu "CK2"
   a. přečíst bajty [0] až [27] (ovšem přeskočit byte [7] - pozor!) a sečíst je (overflow osm bitů), výsledek musí odpovídat "CK2" hodnotě
6) Ověřit další hodnoty
   a. "SDS-DEVICE-TYPE" musí odpovídat (záruka ovládání toho správného typu SDS)
   b. uschovat hodnotu "XR_MTU" pro vytváření odpovědi ("XR_MTU" omezuje velikost odpovědi, kterou můžeme zpátky odeslat)
   c. ověřit časové údaje ("time" a "uptime")
   d. ověřit "XL" vůči "PL"
7) Ověřit CRC-32 dešifrovaného payloadu
   a. spočítat CRC-32 správným algoritmem, vučí bajtům (plain-text) z [36] až [52+XL-1] včetně

8) Hotovo: teď se provede aktuální příkaz (Master Command, dle tabulky podle produktové řady viz "TV")
           a odešle odpověď (ponechat user_identifier pro korelaci) (pozor na "XR_MTU" omezení)


Postup při odesílání S-UDP paketu

Odesílatel zprávy provádí tyto kroky:

1) Je sestaven přesný obsah [C-PAYLOAD] a určena odpovídající hodnota XL
   a. obsah samozřejmě odpovídá tomu co chcete odeslat
   b. určí se i "master-command" a "sub-command" (pozor na produktovou řadu SDS - viz "TV")
2) Vyplní se [HEADER]
   a. hlavička "SDS", "encryption-flag"
   b. zapsat správnou hodnotu "TV" podle protokolu a konkrétního SDS ("master-version", "product-line")
   c. určí se nová unikátní hodnota "user_identifier", a zapíše se do [HEADER]
   d. zapíše se "CounterBlock" (hodnota pokračuje po předchozím paketu)
3) Nachystá se zaokrouhlovací oblast "R" 
   a. Pokud XL není beze zbytku dělitelná 16, musí se doplnit oblastí "R"
4) Spočítá se hodnota "PL"
   a. PL = (XL + R)/16
   b. zapsat do [HEADER]
5) Začne se vyplňovat [ENCRYPTED PAYLOAD]
   a. zapsat náhodný byte do "random number"
   b. spočítá se hodnota "CK2" (sečíst bajty [0] až [27] - ovšem přeskočit byte [7] - pozor!) 
   c. zapsat hodnotu "XR_MTU" podle možností zařízení (tzn. jak velkou odpověď lze bezpečně přijmout, podle omezení sítě)
   d. zapíší se hodnoty "uptime" a "time", zapsat hodnotu "SDS-DEVICE-TYPE"
   e. zapsat "master-command" a "sub-command"
6) Spočítá se CRC-32 (před šifrováním)
   a. spočítat crc32 pro bajty (plain-text) z offsetu [36] až [52+XL-1] včetně
7) Nastavit šifrování
   a. zvolit algoritmus (musí odpovídat tomu, co se zapsalo do "encryption-flag")
   b. nastavit klíč (stejný jako na protistraně, samozřejmě není přenášen přes síť)
   c. nastavit "CounterBlock" (stejný jako byl zapsán [HEADER])
8) Šifrovat celou [ENCRYPTED PAYLOAD] na plain-text
   a. hodnota "PL" musí být dělitelná 16 beze zbytku (tato podmínka závisí na použitém šifrovaní)
   b. aktualizovaná hodnota "CounterBlock" (zvýšená o průběh šifrování) se uschová pro další použití - viz bod " 2) c. "
9) Spočítat základní additive-checksum pro [ENCRYPTED PAYLOAD]
   a. přečíst bajty [28] až [28+PL-1] a sečíst je (overflow osm bitů), výsledek se zapíše do "CK1" hodnoty

10) Hotovo: paket se následně odešle přes síť do protistrany, která odpoví novým paketem - ten je vztažen k tomuto dotazu pomocí "user_identifier" hodnoty.


Vzorové obsahy paketů

Na stránce SUDP: examples naleznete ukázkové vzorové pakety a jejich vnitřní obsah, i se zobrazeních jednotlivých položek v paketu (před a po šifrování). Toto je vhodné pro vývojáře komunikační protistrany, kterým nestačí popis postupu na této stránce, ale chtějí také vidět jednotlivé kroky s aktuálními hodnotami.


Seznam hlavních příkazů

Obě produktové řady SDS, které jsou na trhu, mají svou sadu "master_command" příkazů. Proto je potřeba nejprve zjistit, do které produktové řady vaše SDS spadá, a podle toho dále pokračovat. Lze to přímo odvodit od typu SDS ("SDS-DEVICE-TYPE" hodnota), nebo se zeptat příkazem NOP.

Zařazení SDS do produktových řad je v tomto seznamu.

  • První produktová řada: "TV = 0001...." -> (1PŘ)
  • Druhá produktová řada: "TV = 0010...." -> (2PŘ)


(2PŘ) Master Command (druhá produktová řada: "TV = 0010...." )

Jednotlivé základní příkazy (master command):

 MASTER COMMAND  |  command
 ----------------+-------------------------------------
    0            |   NOP (replies with NOP)
    1            |   general device status
    2            |   1-Wire access
    4            |   read FC-Get list
    8            |   write FC-Set list
   16            |   FULL-C shared variable(s) access
   32            |   serial port access
   64            |   DataFlash access
  128            |   reserved

Jak lze vidět, jednotlivé master command příkazy jsou dále rozlišeny pomocí hodnoty sub command.

Každý příkaz má doplňující datovou sadu, tzn. [C-PAYLOAD]. V rámci těchto dat jsou uvedeny všechny hodnoty, které přesně určují co se má stát (popř. jsou zde všechny odpovědi na dotaz).


(2-PŘ) Master Command: [0] NOP

SDS odpoví na tento příkaz odesláním [0] NOP.

Tohoto příkazu lze využít k ověření komunikace a k vzájemné základní synchronizace.

Tento příkaz je také velmi užitečný pro získání hodnoty "TV" z [HEADER], tím pádem pro určení číslo produktové řady SDS - a tím pádem k určení které "master_command" příkazy jsou k dispozici !

[C-PAYLOAD] zde není použit (XL = 0).


(2-PŘ) Master Command: [1] General Device Status

SDS odpoví zasláním vybraných údajů, jejichž seznam je přesně daný. Tato funkce je k dispozici pro umožnění rychlého přístupu k základnímu stavu zařízení SDS, bez složité přípravy.

REPLY (master_command == 1, sent from SDS as reply)
sub_command = 0

C-PAYLOAD offset | LEN   | TYPE  | content
-----------------+-------+-------+------------------------------------------------------
   0             |     6 | bytes |  MAC ADDRESS (bytes, not text)
   6             |     1 |  byte |  Ethernet Link Status / Speed (0, 10, 100)
   7             |     1 |  byte |  Amount of users logged into SDS Web Admin
   8             |    32 | bytes |  sysLocation (missing the 0x00 terminator)
  40             |     1 |  byte |  IP Watchdog Config status
  41             |     1 |  byte |  IP Watchdog Output (relay) status
  42             |     2 | uword |  IP Watchdog RTT value (note.: 0xFFFF = not available)
  44             |     1 |  byte |  DHCP status
  45             |     1 |  byte |  reserved
  46             |     1 |  byte |  NTP status
  47             |     1 | sbyte |  NTP offset (+/- hours) (signed char)
  48             |     2 | uword |  SoC chip temperature (raw value, needs recalculation)
  50             |     1 |  byte |  GPIO-TOPB PIN(s) direction (0 == input)
  51             |     1 |  byte |  GPIO-TOPB PIN(s) pin value
  52             |  32*1 |  byte |  OPTO [1]..[32] status (0xFF == signal) (0x00 == nosignal)
  84             |  32*1 |  byte |  RELAY [1]..[32] status (active/nonactive)
 116             |  32*2 | uword |  ADC [0]..[31] RAW value
 180             |     1 |  byte |  General 1-W BUS status
 181             |     1 |  byte |  1-W BUS A - active device count
 182             |     1 |  byte |  1-W BUS B - active device count
 183             |     3 | bytes |  reserved (0x00)
 186             |     1 |  byte |  S0 Tariff Value (active/nonactive)
 187             |     1 |  byte |  number of the following S0 INPUT DB data blocks:
 188             | 31*28 |  data |  S0 INPUT [1]..[ (max) 31] DB (data block)


S0-INPUT DB offset | LEN | TYPE  | content
-------------------+-----+-------+-------------------------------------------------------
   0               |   1 |  byte |  configuration status (enabled as S0, is tariff used)
   1               |   3 | bytes |  reserved (filled with 0x00)
   4               |   4 | dword |  T0 impulse counter
   8               |   4 | dword |  T1 impulse counter
   12              |   4 | dword |  T0 offset
   16              |   4 | dword |  T1 offset
   20              |   4 | dword |  measured space between impulses (msec)
   24              |   4 | dword |  time since last registered impulse (msec)

Sestava [C-PAYLOAD] je tedy zřejmá.

Poslední blok (offset [188] až [1083] včetně) je určen pro přenos 32 S0 vstupů - často je jich ale v zařízení SDS fyzicky přítomno mnohem méně, např. jen devět - a potom zařízení SDS ve své odpovědi pošle jen devět záznamů (namísto 32) (toto se týká pouze a jenom S0 položek, né jiných v rámci paketu). To je provedeno z praktického důvodu: aby byl UDP paket dostatečně malý (a tedy rychlý na zpracování).


(2-PŘ) Master Command: [2] 1-Wire Access

Tato funkce se používá pro čtení stavu hodnot získaných z obou 1-W sběrnic, kterými SDS disponuje (některé SDS mají jen jednu sběrnici). Maximální počet prvků (chipů) na sběrnici je 64, celkem je tedy k dispozici 2x64 = 128 prvků.

QUERY/COMMAND TO SDS (master_command == 2)

sub_command | meaning
------------+-----------------------------------------------------------
          0 |  reserved
          1 |  obtain status, and list of found items on BUS A
          2 |  obtain status, and list of found items on BUS B
          4 |  list all read-values on BUS A
          8 |  list all read-values on BUS B

První možností tedy je sub_command == 1 , tzn. výpis nalezených zařízení na sběrnici A respektive B:

REPLY (master_command == 1, sent from SDS as reply)
sub_command = 1 or 2

C-PAYLOAD offset | LEN | TYPE  | content
-----------------+-----+-------+------------------------------------------------------
   0             |   1 |  byte |  global 1-W controller status (SDS status)
   1             |   1 |  byte |  number of active items on BUS A
   2             |   1 |  byte |  number of active items on BUS B
   3             |   1 |  byte |  reserved (0x00)
   4             |  12 |  data |  1-W item status #0
   . . .         | ... |   ... |  . . .
   4+12*63       |  12 |  data |  1-W item status #63

"1-W item status" ofs | LEN | TYPE  | content
----------------------+-----+-------+-------------------------------------------------------
   0                  |   1 |  byte |  ctrl: main-status
   1                  |   1 |  byte |  ctrl: sub-status 
   2                  |   2 | bytes |  reserved (filled with 0x00)
   4                  |   8 | bytes |  ROM-CODE [0]..[7]

Následuje: výpis získaných hodnot (např. změřené teploty z teplotních čidel) pro jednotlivé sběrnice :

REPLY (master_command == 1, sent from SDS as reply)
sub_command = 4 or 8

C-PAYLOAD offset | LEN | TYPE  | content
-----------------+-----+-------+------------------------------------------------------
   0             |   1 |  byte |  global 1-W controller status (SDS status)
   1             |   1 |  byte |  number of active items on BUS A
   2             |   1 |  byte |  number of active items on BUS B
   3             |   1 |  byte |  reserved (0x00)
   4             |  12 |  data |  1-W item value #0
   . . .         | ... |   ... |  . . .
   4+12*63       |  12 |  data |  1-W item value #63

"1-W item value" ofs  | LEN | TYPE  | content
----------------------+-----+-------+-------------------------------------------------------
   0                  |   1 |  byte |  ctrl: main-status
   1                  |   1 |  byte |  ctrl: sub-status
   2                  |   1 |  byte |  value of ROM-CODE offset [0] (1-W DEVICE TYPE: ID)
   3                  |   1 |  byte |  value of ROM-CODE offset [7] (1-W DEVICE TYPE: CRC)
   4                  |   4 | slong |  1-W read: primary value
   8                  |   4 | slong |  1-W read: secondary value

Každý chip na sběrnici 1-Wire má vždy primární a sekundární hodnotu, kterou SDS pro daný chip udržuje (ne vždy jsou však, v závislosti na konkrétním chipu, obě hodnoty použity). Aktuální význam je potřeba určit podle chipu (příklad: DS18B20 má "primary value" zpracovanou teplotu v degC, a "secondary value" přímou surovou 16-bit hodnotu přečtenou z čidla).


(2-PŘ) Master Command: [4] Read FC-Get List

Dotaz (query) který obsahuje seznam indexů jejichž hodnoty jsou tazatelem požadovány, se posílá do SDS, které následně odpoví (reply).

Dotaz i odpověď má dynamický obsah, který je specificky strukturován.

QUERY (master_command == 4, sent to SDS)

C-PAYLOAD offset | LEN | TYPE  | content
-----------------+-----+-------+------------------
 0               |   2 | uword | [#0] index value 
 2               |   2 | uword | [#0] TBLEN#0: type-bits and data length (L#0)
 4               | L#0 |  data | [#0] space prepared for answer from SDS

 (4+(L#0))+0     |   2 | uword | [#1] index value
 (4+(L#0))+2     |   2 | uword | [#1] TBLEN#1: type-bits and data length (L#1)
 (4+(L#0))+4     | L#1 |  data | [#1] space prepared for answer from SDS

 . . .           | ... | . . . | ...

 Z+0             |   2 | uword | [#n] index value 
 Z+2             |   2 | uword | [#n] TBLEN#n: type-bits and data length (L#n)
 Z+4             | L#n |  data | [#n] space prepared for answer from SDS

Jak lze vidět, v dotazu (query) jsou za sebou naskládány položky (indexy), na které následně SDS odpoví. Vždy musíte u každého indexu, na který se ptáte, uvést typ odpovědi (viz dále) a prostor, kam bude odpověd zapsána - to znamená, musíte znát přesnou délku, kterou má obsah pro daný index !

Pozor na množství dotazů v rámci jednoho paketu, protože velikost dotazu, a také velikost odpovědi, je omezena XR_MTU. Jakmile SDS při skládání odpovědi narazení na XR_MTU protistrany, už více odpovědí do paketu nepřidá (aby nebylo XR_MTU překročeno).

REPLY (master_command == 4, sent from SDS as reply to query)

SDS writes the values into the "[#n] space prepared for answer from SDS"

Odpověď tedy přesně sleduje (vyplňuje) původní dotaz, přičemž [C-PAYLOAD] teď obdrží skutečný datový obsah pro jednotlivé položky. Pokud poskytnete SDS menší prostor pro odpověď, než je potřeba, bude odpověď vyplněna 0x00.

Hodnota "sub_command" je nastavena SDS na počet položek (#n) v odpovědi. Toto omezuje maximální počet položek v jednom paketu na 255.

Následující popis ukazuje kódování typu proměnné a její délky, ve společném slově:

TBLEN#x: (16-bit unsigned word, little-endian) Type-Bits and Data Length (L#x)

TBLEN#x: TTTTvvvvvvvvvvvv
         FEDCBA9876543210

BIT OFFSET (hex) | LEN (bits) | content
-----------------+------------+-----------------------------------------
 F (MSB)         |          4 |  "T": type (see bit-value in next table)
 B               |         12 |  "v": length of data, in bytes

 "T" bit-values | meaning                     | FULL-C set/get
           FEDC |                             | (which function)
----------------+-----------------------------+------------------
           0000 |  unsigned integer (32-bit)  |  _u
           0001 |  signed integer (32-bit)    |  _i
           0010 |  float IEEE-754 (32-bit)    |  _f
           0100 |  string UTF-8 (L#x * 8-bit) |  _a
           1000 |  reserved (do not use)      |  

Horní 4 bity z TBLEN#x tedy určují typ položky. Pro získání délky L#x položky 'x', je potřeba hodnotu TBLEN#x odmaskovat - použít jen dolních 12 bitů.

Je vaším úkolem správně zvolit typ (T) pro každou položku, pokud zvolíte špatně, nebude údaj pro daný index zpracován.


Index Value - každá položka má svůj číselný index, viz seznam všech FULL-C indexů.


(2-PŘ) Master Command: [8] Write FC-Get List

Pokud SDS obdrží zprávu s "master_command == 8", tak nastaví příslušné FULL-C indexy na nové hodnoty (podle obsahu této přijaté zprávy).

SDS na tuto zprávu odpovídá pouze ve smyslu "úspěch" nebo "neúspěch" - takže pro skutečné ověření hodnot (zda-li se zapsaly správně) musíte proto sami zaslat další zprávu "master_command == 4".

COMMAND TO SDS (master_command == 8, sent to SDS)

C-PAYLOAD offset | LEN | TYPE  | content
-----------------+-----+-------+------------------
 0               |   2 | uword | [#0] index value 
 2               |   2 | uword | [#0] TBLEN#0: type-bits and data length (L#0)
 4               | L#0 |  data | [#0] new data value to write to SDS

 (4+(L#0))+0     |   2 | uword | [#1] index value
 (4+(L#0))+2     |   2 | uword | [#1] TBLEN#1: type-bits and data length (L#1)
 (4+(L#0))+4     | L#1 |  data | [#1] new data value to write to SDS

 . . .           | ... | . . . | ...

 Z+0             |   2 | uword | [#n] index value 
 Z+2             |   2 | uword | [#n] TBLEN#n: type-bits and data length (L#n)
 Z+4             | L#n |  data | [#n] new data value to write to SDS

Lze vidět, že formát je naprosto shodný jako formát odpovědi kterou SDS posílá pro "master_command == 4" zprávu. Nicméně, v tomto případě, je tento obsah [C-PAYLOAD] zapsán do SDS, které jej zpracuje a provede - pouze ale pokud je délka L#x přesně odpovídající danému indexu.

Odpověď, kterou na tento příkaz SDS následně posílá, je velmi jednoduchá: [C-PAYLOAD] není vůbec použito (XL=0), a "sub_command" obsahuje následující možnost:

REPLY FROM SDS (master_command == 8)

sub_command | meaning
------------+-----------------------------------------------------------
          0 |  complete failure (no item modified)
          1 |  partial failure  (some items modified, some not modified)
          2 |  success          (all items modified OK)

Další, detailnější, rozlišení selhání (failure) se neprovádí (tzn. SDS neposílá více detailnější informaci ve své odpovědi, než uvedené tři možnosti).


(2-PŘ) Master Command: [16] FULL-C Shared Variable(s) Access

Tento příkaz se využívá k přístupu ke sdíleným proměnným programu FULL-C.

Proměnné se označují vzorem, kde je na začátku velké písmeno určující typ, a pak dvě decimální číslice určující pořadí - ted sto možných hodnot.

Mohou existovat tyto sdílené proměnné :

  • S00 až S99 (hodnoty: signed 32-bit)
  • U00 až U99 (hodnoty: unsigned 32-bit)
  • F00 až F99 (hodnoty: float 32-bit)
  • T00 až T99 (hodnoty: array/text)

Rozlišování jednotlivých funkcí je závislé na hodnotě "sub_command":

QUERY-or-COMMAND TO SDS (master_command == 16, sent to SDS)

sub_command | meaning
------------+---------------------------------------------
          0 | provide list of all active shared variables
          1 | read from shared variable (single variable)
          2 | reserved
          4 | write to shared variable (single variable)
          8 | reserved

Pro "sub_command == 0" poskytne SDS odpověď, kde je uvedeno zda-li je specifická sdílená proměnná definována v právě aktivním FULL-C programu.

RESPONSE:  LIST OF SHARED VARIABLES: sub_command = 0

C-PAYLOAD offset | LEN | TYPE  | content
-----------------+-----+-------+--------------------------
  0              |  13 | bytes | Uxx existence: bit-field
 13              |  13 | bytes | Sxx existence: bit-field
 26              |  13 | bytes | Fxx existence: bit-field
 39              |  13 | bytes | Txx existence: bit-field

Jak lze vidět, v odpovědit jsou čtyři samostatné bitové pole, každé o délce 100 bitů (plus nevyužitý zbytek 4 bitů nakonci). Každý bit přestavuje existenci jedné ze sdílených proměnných, pokud je nastaven na 1 tak proměnná existuje.

Xxx existence: bit-field

BYTE -> [0] . . . [13]
BITS ->  0 . . .   100 (plus 4 at the end, which are not used)

BYTE [0] = bit 0, 1, 2, ..., 7
BYTE [1] = bit 8, 9, 10, ..., 15
...
BYTE [13] = bit 96, 97, 98 ..., 103

example: existence of "U11" => bit 11 => look at BYTE [1]

Takže pro kteroukoliv sdílenou proměnnou si lze nalézt příslušnou pozici, která ukazuje, zda-li právě daná proměnná existuje.


Další, "sub_command == 1" umožňuje z konkrétní (jedné) sdílené proměnné číst.

QUERY TO SDS: READ ONE SHARED VARIABLE: sub_command = 1

C-PAYLOAD offset | LEN | TYPE  | content
-----------------+-----+-------+--------------------------
 0               |   3 | bytes | [#0] name (example: "U25")
 1               |   1 |  byte | reserved (0x00)

A odpověď je:

REPLY FROM SDS: READ ONE SHARED VARIABLE: sub_command = 1

C-PAYLOAD offset | LEN | TYPE  | content
-----------------+-----+-------+--------------------------
 0               |   3 | bytes | [#0] name (example: "F95")
 1               |   1 |  byte | reserved (0x00)
 4               |   2 | uword | [#0] L#0: data length (L#0)
 6               |   2 | uword | reserved (0x0000)
 8               | L#0 |  data | [#0] data value from the shared variable


Dále, pro "sub_command == 4" dojde ke změně hodnoty.

COMMAND TO SDS: WRITE ONE SHARED VARIABLE: sub_command = 4

C-PAYLOAD offset | LEN | TYPE  | content
-----------------+-----+-------+--------------------------
 0               |   3 | bytes | [#0] name (example: "T12")
 1               |   1 |  byte | reserved (0x00)
 4               |   2 | uword | [#0] L#0: data length (L#0)
 6               |   2 | uword | reserved (0x0000)
 8               | L#0 |  data | [#0] new data value to write to shared variable

A odpověď je zde shodná jako odpověd pro "sub_command == 1".


(2-PŘ) Master Command: [32] Serial Port Access

Tento příkaz není pro "version == 0x00" podporován. Potřebujete novější firmware.


(2-PŘ) Master Command: [64] DataFlash (NVM) Access

Tento příkaz není pro "version == 0x00" podporován. Potřebujete novější firmware.


(2-PŘ) Master Command: [128] Reserved

Tento příkaz není v současné verzi použit. Zařízení odpoví [0] NOP.



(1-PŘ) Master Command (první produktová řada: "TV = 0001...." )

Jednotlivé základní příkazy (master command) - zatím nejsou pro první produktovou řadu definovány.

Detaily zde budou doplněny.

Osobní nástroje
Translate