OpenMobileAlliance / OMA_LwM2M_for_Developers

OMA LightweightM2M public resources.
http://openmobilealliance.github.io/OMA_LwM2M_for_Developers/
Other
238 stars 52 forks source link

Empty Response to a Read operation #579

Open dnav opened 5 months ago

dnav commented 5 months ago

The response to a Read operation may be empty: An Object Instance may have no readable Resource, or a Resource may not have any Resource Instance. The TS indicates that in this case, the response code is 2.05 Content and there is no attached payload since there are no values to report:

Note that the response payload may be empty, for instance when performing a Read operation on an Object with no Object Instance. In this case the response code is still 2.05 Content.

We recently faced an interoperability issue using the CoAP binding. In such a case, should the CoAP response include a Content-Format option or not?

sbernard31 commented 5 months ago

In LWM2M in addition of the sentence you share I found about that it :

Messages containing data MUST specify the payload encoding by using one of the supported data formats.

(In Data Formats for Transferring Resource Information in LWM2M v1.0.2, 1.1.1, 1.2.1)

I looked at CoAP RFC and only found :

5.9.1.5. 2.05 Content

This Response Code is like HTTP 200 "OK" but only used in response to GET requests.

The payload returned with the response is a representation of the target resource.

This response is cacheable: Caches can use the Max-Age Option to determine freshness (see Section 5.6.1) and (if present) the ETag Option for validation (see Section 5.6.2).

5.10.3. Content-Format

The Content-Format Option indicates the representation format of the message payload. The representation format is given as a numeric Content-Format identifier that is defined in the "CoAP Content- Formats" registry (Section 12.3). In the absence of the option, no default value is assumed, i.e., the representation format of any representation message payload is indeterminate (Section 5.5).

So I guess this depends a lot if you consider your response contains "no payload" or an "empty payload" which is the result of chosen encoding format.

From my point of view, a 2.05 response is "a representation of the target resource" (like explained in CoAP RFC) in a given content format. Sometime this lead to empty byte[] or empty string but this is still the result of a given encoding format. If that case, I think content format should be used (even if the payload is empty).

I checked how behave Leshan and it reject 2.05 response without content format and it does not always encode "no lwm2m node" with an empty payload. (e.g. for SenML it returns an empty array "[]")

sbernard31 commented 5 months ago

We recently faced an interoperability issue using the CoAP binding. In such a case, should the CoAP response include a Content-Format option or not?

What was the interoperability issue exactly ?

dnav commented 5 months ago

What was the interoperability issue exactly ?

It just so happens that a Leshan-based Server is returning an error "Invalid Response: Unable to decode response payload" when receiving a CoAP response with no payload and no Content-format option ;)

And in some cases, it also fails even if a content-format is present.

sbernard31 commented 5 months ago

It just so happens that a Leshan-based Server is returning an error "Invalid Response: Unable to decode response payload" when receiving a CoAP response with no payload and no Content-format option ;)

:sweat_smile: OK so now you get the reason (https://github.com/OpenMobileAlliance/OMA_LwM2M_for_Developers/issues/579#issuecomment-2158383358)

Technically we get the decoder from given content format. (We have 1 decoder by content format) Then we provide the payload to it to decode payload. If we have no content format we are not able to select decoder and we raise an error.

But if OMA clarifies that I guess we can adapt Leshan code.

And in some cases, it also fails even if a content-format is present.

This one is maybe a bug ? do you have more details ? (maybe we should continue that point in a Leshan issue ?)

dnav commented 5 months ago

This one is maybe a bug ? do you have more details ? (maybe we should continue that point in a Leshan issue ?)

https://github.com/eclipse-leshan/leshan/issues/1622

mkgillmore commented 5 months ago

Per OMA DMSO discussion, should this return 2.04 instead and we clarify how to handle 2.05 response with no content

sbernard31 commented 5 months ago

@mkgillmore,

should this return 2.04 instead

is this a question ? OR do you mean that a READ Response should be a 2.04 ?

AFAIK, this doesn't follow CoAP RFC... a READ request (so a CoAP GET) should only accept 2.05 Content as successful response.

Eventually, 2.03 Valid but this is only when ETAG is used and value doesn't change since last GET, so this is out of topic here.

sbernard31 commented 5 months ago

Note that the response payload may be empty, for instance when performing a Read operation on an Object with no Object Instance.

I rethink about that and if we strictly follow SenML spec, I don't think the "may be empty" could be about SenML. (It could concern others content format but not SenML)

Why ? because it seems in SenML "[ ]" is valid but "" (so empty payload) is not.

See rfc8428§section-11 :

SenML-Pack = [1* record]

 record = {
   ? bn => tstr,        ; Base Name
   ? bt => numeric,     ; Base Time
   ? bu => tstr,        ; Base Units
   ? bv => numeric,     ; Base Value
   ? bs => numeric,     ; Base Sum
   ? bver => uint,      ; Base Version
   ? n => tstr,        ; Name
   ? u => tstr,        ; Units
   ? s => numeric,     ; Sum
   ? t => numeric,     ; Time
   ? ut => numeric,    ; Update Time
   ? ( v => numeric // ; Numeric Value
       vs => tstr //   ; String Value
       vb => bool //   ; Boolean Value
       vd => binary-value ) ; Data Value
   * key-value-pair
}

So : Empty Object Instance === [SenML encoding] ===> Empty SenML-Pack ===[JSON encoding]==> [ ]

dnav commented 5 months ago

Note that the response payload may be empty, for instance when performing a Read operation on an Object with no Object Instance.

I rethink about that and if we strictly follow SenML spec, I don't think the "may be empty" could be about SenML. (It could concern others content format but not SenML)

Reading the TS, I understand "empty payload" as the absence of a payload in the CoAP packet, not an empty string.

Eg: Type=ACK, Code=2.05, MID=0x7d35, Token=0x20

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   | 1 | 2 |   1   |    2.05=69    |          MID=0x7d35           |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     0x20      |
   +-+-+-+-+-+-+-+-+

Hence my point that an "empty payload" should not have a Content-format, since the content-format option "indicates the representation format of the message payload." (RFC 7252)

It is not not the same thing as an "Empty SenML payload" which is indeed an empty array as you wrote.

Eg: Type=ACK, Code=2.05, MID=0x7d35, Token=0x20, option Content-format=110, Payload= "[]"

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   | 1 | 2 |   1   |    2.05=69    |          MID=0x7d35           |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     0x20      |   12   |   1  |  SenML JSON   |1 1 1 1 1 1 1 1|
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      '['      |      ']'      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
mkgillmore commented 5 months ago

Shouldn’t the response be 2.04 for no content? https://datatracker.ietf.org/doc/html/rfc7252#section-5.9.1.4

From: David Navarro @.> Sent: Monday, June 17, 2024 12:27 PM To: OpenMobileAlliance/OMA_LwM2M_for_Developers @.> Cc: Gillmore, Matthew @.>; Mention @.> Subject: [EXTERNAL] Re: [OpenMobileAlliance/OMA_LwM2M_for_Developers] Empty Response to a Read operation (Issue #579)

Note that the response payload may be empty, for instance when performing a Read operation on an Object with no Object Instance. I rethink about that and if we strictly follow SenML spec, I don't think the "may be empty" could be about SenML.  ZjQcmQRYFpfptBannerStart Warning! This email comes from outside the company. This message came from outside of Itron, if you suspect it to be spam, please delete it or if you suspect a phishing attempt, please report it using the Phish Alert Report button. Be careful and think before you click. ZjQcmQRYFpfptBannerEnd

Note that the response payload may be empty, for instance when performing a Read operation on an Object with no Object Instance.

I rethink about that and if we strictly follow SenML spec, I don't think the "may be empty" could be about SenML. (It could concern others content format but not SenML)

Reading the TS, I understand "empty payload" as the absence of a payload in the CoAP packet, not an empty string.

Eg: Type=ACK, Code=2.05, MID=0x7d35, Token: 0x20

0                   1                   2                   3

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

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

| 1 | 2 | 1 | 2.05=69 | MID=0x7d35 |

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

| 0x20 |

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

Hence my point that an "empty payload" should not have a Content-format, since the content-format option "indicates the representation format of the message payload." (RFC 7252https://urldefense.com/v3/__https:/www.rfc-editor.org/rfc/rfc7252*section-5.10.3__;Iw!!F7jv3iA!2tgywk04nWzr69e_iS_RS51mRokVIjcnMXsRzxFObp5-sjN6yv2dT3AZys3qaVJZFrJDMixsedUspj_CicByZ1aeORYu8Q$)

— Reply to this email directly, view it on GitHubhttps://urldefense.com/v3/__https:/github.com/OpenMobileAlliance/OMA_LwM2M_for_Developers/issues/579*issuecomment-2173842267__;Iw!!F7jv3iA!2tgywk04nWzr69e_iS_RS51mRokVIjcnMXsRzxFObp5-sjN6yv2dT3AZys3qaVJZFrJDMixsedUspj_CicByZ1ZcpuUwAA$, or unsubscribehttps://urldefense.com/v3/__https:/github.com/notifications/unsubscribe-auth/AJSSA5U6A264UIVB7DVOHZLZH4E5RAVCNFSM6AAAAABJB5TTBSVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCNZTHA2DEMRWG4__;!!F7jv3iA!2tgywk04nWzr69e_iS_RS51mRokVIjcnMXsRzxFObp5-sjN6yv2dT3AZys3qaVJZFrJDMixsedUspj_CicByZ1aOtJJvMw$. You are receiving this because you were mentioned.Message ID: @.**@.>>

sbernard31 commented 5 months ago

Shouldn’t the response be 2.04 for no content? https://datatracker.ietf.org/doc/html/rfc7252#section-5.9.1.4

If you read the section you shared : "This Response Code is like HTTP 204 "No Content" but only used in response to POST and PUT requests."

And reading https://datatracker.ietf.org/doc/html/rfc7252#section-5.8.1 : "Upon success, a 2.05 (Content) or 2.03 (Valid) Response Code SHOULD be present in the response."

So for me this is pretty clear : only 2.05 (Content) can be used for GET. (2.03 Valid can also be used but for GET but only when ETag is used)

IMHO, using 2.04 in this case would be a mistake.

sbernard31 commented 5 months ago

I also find https://datatracker.ietf.org/doc/html/rfc7252#section-5.5.1 :

Implementation Note: On a quality-of-implementation level, there is a strong expectation that a Content-Format indication will be provided with resource representations whenever possible. This is not a "SHOULD" level requirement solely because it is not a protocol requirement, and it also would be difficult to outline exactly in what cases this expectation can be violated.

Replying to https://github.com/OpenMobileAlliance/OMA_LwM2M_for_Developers/issues/579#issuecomment-2173842267

I understand your point.

So the question is :

Note that the response payload may be empty, for instance when performing a Read operation on an Object with no Object Instance. In this case the response code is still 2.05 Content.

Should that sentence :point_up: be interpreted as :

  1. An "empty payload" without Content Format is acceptable to express empty LWM2M Node (Object, Object Instance, Multi-Instance Resource )
  2. OR Some Content Format encoding empty LWM2M Node could lead to empty payload.

It seems we didn't find any argument allowing to reject one of them. But there some pro/con for each solutions.

1. No content format allowed : Pro :

Con :

Note : if Accept option is used in GET request, it seems that Content Format is mandatory, see : https://datatracker.ietf.org/doc/html/rfc7252#section-5.10.4 Note : Does this special case will be only about GET ? or will it be about POST/PUT too ?

2. content format mandatory Pretty much the opposite than above without any problem with Accept option or question about POST/PUT.

My personal opinion, I prefer 2.) It seems to me it's more in line with CoAP RFC spirit.

sbernard31 commented 5 months ago

@mlasch, @LukasWoodtli from Wakaama project.

Do you have any opinion about that ? How wakaama behaves without Content Format ?

dnav commented 5 months ago

Just on this point:

implementers need to handle a special case at serialization (optionally) and de-serialization (mandatory)

Your implementation already handles the special case of having a Content-format option but no payload.

A naive design would invoke the parser matching the content-format value. And for most of the formats, the parser would return an error as a 0-length buffer is not valid.

sbernard31 commented 5 months ago

Your implementation already handles the special case of having a Content-format option but no payload.

I didn't talk about Leshan in particularly. (maybe current Leshan behavior is a mistake) I was talking in a general way and I agree this is not a big con. As I said there is no big PRO or CON else one obvious solution could be easily chosen.

A naive design would invoke the parser matching the content-format value. And for most of the formats, the parser would return an error as a 0-length buffer is not valid.

Yep from my point of view this matches with interpretation : "Some Content Format (not all) encoding empty LWM2M Node could lead to empty payload."

dnav commented 5 months ago

Just to summarize my inputs:

Following #213, LwM2M allows CoAP 2.05 response messages to have no CoAP payload as stated in the CoAP Transport Binding section:

An Object Instance, a Resource or a Resource Instance are read by sending a CoAP GET to the corresponding path. The response includes the value in the corresponding format according to the specified Content-Format (see [LwM2M CORE]). The request MAY specify an Accept option containing the preferred Content-Format to receive. When the specified Content-Format is not supported by the LwM2M Client, the request MUST be rejected (error code 4.06 as defined in [CoAP]). Note that the response payload may be empty, for instance when performing a Read operation on an Object with no Object Instance. In this case the response code is still 2.05 Content.

In such a case, should the CoAP response include a Content-Format option or not?

If yes, what should be the indicated content-format?

For most of the formats used in LwM2M, an empty input buffer is not valid: Content-format option
SenML CBOR Not a valid SenML.
SenML JSON Not a valid JSON.
TLV Valid?
LwM2M CBOR Not a valid LwM2M CBOR.
Text Valid.
Opaque Valid.
sbernard31 commented 5 months ago

In such a case, should the CoAP response include a Content-Format option or not?

I guess this will depend what meaning OMA member will choose for "Note that the response payload may be empty, for instance when performing a Read operation on an Object with no Object Instance. In this case the response code is still 2.05 Content." Either It means :

  1. An "empty payload" without Content Format is acceptable to express empty LWM2M Node (Object, Object Instance, Multi-Instance Resource )
    1. OR Some Content Format ~encoding empty LWM2M Node~ could lead to empty payload.

As I prefer 2, I would answer Yes it should.

If yes, what should be the indicated content-format?

IMHO, the question doesn't really arise. Client choose to encode a LWM2M node in a given Content Format (maybe its preferred one OR the one requested by Accept option), then in some case it could result in an empty payload.

For most of the formats used in LwM2M, an empty input buffer is not valid:

I'm not sure but an empty string in Text format is valid ? and empty string is encoded as empty payload or I missed something ? Except that point, I pretty agree with that table.

Maybe this sentence :point_down: should just be deleted ? :manshrugging: ~"Note that the response payload may be empty, for instance when performing a Read operation on an Object with no Object Instance. In this case the response code is still 2.05 Content."_~

dnav commented 5 months ago

I'm not sure but an empty string in Text format is valid ? and empty string is encoded as empty payload or I missed something ? Except that point, I pretty agree with that table.

My point was that an empty string is the one-byte buffer 0x00.

sbernard31 commented 5 months ago

My point was that an empty string is the one-byte buffer 0x00.

At CoAP level, I don't think it is encoded like this. :thinking: At least, I didn't find anything about that in RFCs (but maybe I missed something) I tested with java-coap and californium, looking with wireshark => there is no payload at all. So, let me know if I'm wrong and so if issue should be opened to that project.

dnav commented 5 months ago

Double checking LwM2M dat types and RFC 3629, indeed you are right. I edited the table.

mkgillmore commented 5 months ago

@dnav is there a pull request for this table edit?

LukasWoodtli commented 5 months ago

@mlasch, @LukasWoodtli from Wakaama project.

Do you have any opinion about that ? How wakaama behaves without Content Format ?

Sorry for the late answer. I‘m no so involved into the client implementation of Wakaama. It looks like there is not a generic way in reading objects from a client in Wakaama. There are some examples that show how it can be done. But they are not part of the library itself. As far as I can tell the Wakaama client would send response with a content type. But I’m not sure how it would encode an empty payload.

In general I think it would be nice if we could send a CoAP packet with no content type and an empty payload in such a case. But not sure if that would comply with the specs of CoAP and LaM2M.