Mesh Generic Location Server -Not configured state values +C-type implicit conversions

Mesh 1.1 Generic Location Server defines special values for long/lat and north/east when unconfigured.
Current code doesn't appear to support/use these special values, instead using zero as defaults. This looks like a bug.

When attempting to fix the code in gen_loc_internal.h, the functions  *_encode() and *_decode() for local and global state
use type conversions int -> uint, uint -> int, and float -> uint that I am having some difficulty understanding if they will always
work correctly across all Nordic platforms and compilers, or rely on potentially unspecified integer/float promotion behavior.

https://github.com/nrfconnect/sdk-nrf/blob/9abba2029b75e5b4f8990f7b55b28817ed01a0e1/subsys/bluetooth/mesh/gen_loc_internal.h#L25-L32

Idea for at least a temporary fix is to use value outside of defined WGS84 ranges [-90,90] and -180,180] to represent an unconfigured global state and
then add test for these in above functions. If want to read/write these values directly to the net_buf_simple struct, is it safe to first read out and test the
value from the buffer and then conditionally perform the float calc, or is there more going on and this could result in a different value?

Similarly the local state struct decoding casts a uint16 to an int16. Will this always correctly work for negative target int values?

Getting a full fix would of course also work.

Parents
  • Hi Erik, 
    The team acknowleded that it's a bug. We will work on it. 

    Here is some additional information (and question) could you take a look? 

    Conversion from double type of latitude\longitude is done over precalculated constants that adds more inaccuracy to the final result. However, almost always it is not possible to restore the same value as it was encoded since floor function adds inaccuracy by self. (formulas in Mesh Model 1.1 in 3.1.7.1 Global Latitude and 3.1.7.2 Global Longitude chapters).

    Furthermore, it is possible to use custom ranges for latitude and longitude. Conversion from int to uint and back during packing\unpacking from\to buffer (net_buf_simple_add_lexx\net_buf_simple_pull_lexx) will not add any errors. 

    If we are talking about casting during encoding\decoding, it will be nice to get clarification which casting customer assumes.

  • Hi Hung,
    Thx for bug ack as to default values.


    For casting, the concern is when encoding the calculation occurs using double and then casts this to net_buf uint32. MshMdl1.1 states that it is sent as int32. I couldn't find where such a type casting is defined. Is it specific to gcc, or defined in C99 and later standards?

    Similarly when decode long/lat from netbuf, how is the value recognized as an int32 and not an uint32?

    Local north, local east and altitude are also sent as int16. Unclear how the sign bit is carried over during encode/decode. Is this handled automatically by C99 integer promotion rules? Before dividing with the floating point constant I want to check whether the int16 value in msg equals special value 0x7FFF. If decode netbuf into a local int16 will this always work?

    Ps: When storing in settings subsys we use the same compact format as in the msg. It is a problem if floor function isn't deterministic, since could result in a new FLASH write every time settings_save is called.

Reply
  • Hi Hung,
    Thx for bug ack as to default values.


    For casting, the concern is when encoding the calculation occurs using double and then casts this to net_buf uint32. MshMdl1.1 states that it is sent as int32. I couldn't find where such a type casting is defined. Is it specific to gcc, or defined in C99 and later standards?

    Similarly when decode long/lat from netbuf, how is the value recognized as an int32 and not an uint32?

    Local north, local east and altitude are also sent as int16. Unclear how the sign bit is carried over during encode/decode. Is this handled automatically by C99 integer promotion rules? Before dividing with the floating point constant I want to check whether the int16 value in msg equals special value 0x7FFF. If decode netbuf into a local int16 will this always work?

    Ps: When storing in settings subsys we use the same compact format as in the msg. It is a problem if floor function isn't deterministic, since could result in a new FLASH write every time settings_save is called.

Children
No Data
Related