Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not acceptable to replace subset of resources with object write? #674

Open
H732948 opened this issue Nov 8, 2022 · 13 comments
Open

Not acceptable to replace subset of resources with object write? #674

H732948 opened this issue Nov 8, 2022 · 13 comments

Comments

@H732948
Copy link

H732948 commented Nov 8, 2022

Hi,

I have an object with three multiple type resources. I would like to be able to write either all of them, a subset of them, or one of them using object replace.

If I want to write new values to a subset of the resources using an object replace, I specify the new values for the resources I want to write as well as no value, empty brackets, for the resources I don't want to write. But that makes Wakaama return "NOT_ACCEPTABLE".

I can't find any mention in the LWM2M-specification (v. 1.0) that you're not allowed to write an empty instance to a resource.
Is this a bug in Wakaama or am I using the wrong method to achieve what I want?

Thank you and best regards,
Sam

@sbernard31
Copy link
Contributor

(warning I don't really know Wakaama behavior but I can try to answer at LWM2M level)

Just to be sure what you call "object replace" is "send a WRITE request targeting an object with replace mode" ?

But targeting an object is not allowed by the LWM2M specification, object instance Id is required.

Parameter Required Default Value Notes
Object ID Yes - Indicates the Object.
Object Instance ID Yes - Indicates the Object Instance to write.
Resource ID No - Indicates the Resource to write. If the final target is not a Resource Instance (see below), the payload is the new value for the Resource.The payload is the new value for the Resource. If no Resource ID is indicated, the Resource Instance ID MUST NOT be indicated , then the value included payload is an Object Instance containing the Resource values.
Resource Instance ID No - Indicates the Resource Instance to write. An error MUST be returned by the Client, if the Resource ID is absent, if the targeted Resource is not defined as a Multiple-Instance Resource, or if the targeted Resource Instance doesn't exist.
New Value Yes - The new value included in the payload to update the Object Instance, a Resource or a Resource Instance.

(source : LWM2M v1.1.1@core§Table: 6.3.3.-1 Write Parameters)

So let's suppose you "object replace" means "Send a WRITE request targeting object instance with replace mode".

If I want to write new values to a subset of the resources using an object replace, I specify the new values for the resources I want to write as well as no value, empty brackets, for the resources I don't want to write.

Using Replace Mode will erase existing LWM2M node with the new one you provide. The specification says :

"Replace: replaces the Object Instance or the Resource(s) with the new value provided in the "Write" operation. When the Resource is a Multiple-Instance Resource, the existing array of Resource Instances is replaced to the condition the LwM2M Client authorizes that operation."

(source : LWM2M v1.1.1@core§6.3.3. Write Operation/V1_1_1-20190617-A/HTML-Version/OMA-TS-LightweightM2M_Core-V1_1_1-20190617-A.html#6-3-3-0-633-Write-Operation)

So my understanding is that you don't need to put resource you don't want to write.

@pehrnord
Copy link

Hi and thanks for the speedy response!
I am also involved with this, so I would like to clarify and make sure we understand correctly:
What we have is an object instance with three multiple resources. We would like to, in one write, be able to clear all resource instances on a resource (replace with 0 resource instances), and replace all resource instances with new instances in another of the three resources.

Assuming we "Send a WRITE request targeting object instance with replace mode" in this case, should we:

  1. Issue a write with 0 resource instances to the resource we wish to clear (this causes wakaama to return NOT_ACCEPTABLE), or
  2. Not address that resource at all and only target the resources which will have new instances, which would then clear the unaddressed resources implicitly

Our implementation uses lwm2m v1.0 if that matters

@sbernard31
Copy link
Contributor

Our implementation uses lwm2m v1.0 if that matters

AFAIK, on this particular point the LWM2M specification is identical in v1.0.x and v1.1.x :

"Replace: replaces the Object Instance or the Resource(s) with the new value provided in the “Write” operation.
When the Resource is a Multiple-Instance Resource, the existing array of Resource Instances is replaced under the
condition that the LwM2M Client authorizes that operation."

Source : http://openmobilealliance.org/release/LightweightM2M/V1_0_2-20180209-A/OMA-TS-LightweightM2M-V1_0_2-20180209-A.pdf

@pehrnord
Copy link

"Replace: replaces the Object Instance or the Resource(s) with the new value provided in the “Write” operation.

I would then assume that it is option 1 that is the correct way to do this:

  1. Issue a write with 0 resource instances to the resource we wish to clear (this causes wakaama to return NOT_ACCEPTABLE)

Meaning this https://github.com/eclipse/wakaama/blob/89b9d3efda98ce66c33c233f4a5d9cdcb3f45aa7/core/objects.c#L391
is a bug?

Might be because of this conflict in the spec? OpenMobileAlliance/OMA_LwM2M_for_Developers#551

@sbernard31
Copy link
Contributor

Assuming we "Send a WRITE request targeting object instance with replace mode" in this case, should we:

  1. Issue a write with 0 resource instances to the resource we wish to clear (this causes wakaama to return NOT_ACCEPTABLE),
    or
  2. Not address that resource at all and only target the resources which will have new instances, which would then clear the unaddressed resources implicitly

Oh OK, I didn't get the question, It's much clear now

I guess generally both should works but the specification doesn't explicitly say how this should be encoded ... so this could differ from one implementation to another
And this is also depend of the Content Format you're using.

E.g : For SenML+json from LWM2M v1.1.x : we never get a clear answer about that : OpenMobileAlliance/OMA_LwM2M_for_Developers#494

I tested with Leshan and it support both with some different behavior depending on content format.

Let's suppose you have an instance 0 of object 3441 which looks like :

/3441/0/1110 :  { 0 = "string1",  1 = "string2" }
/3441/0/1120 :  { 1= 11, 1 = 22 }

1. if you try to write

/3441/0/1110 :  { 3 = "newString"}

All content format will behave the same way and resource /3441/0/1120 will not exist anymore, if you try to read it you get 404 NON_FOUND.

2. if you try to write

/3441/0/1110 :  { 3 = "newString"}
/3441/0/1120 :  { }

All content format will behave like above ☝️ (return NOT FOUND) except for TLV.
For TLV, if you try to read /3441/0/1120, the resource exists and you get an 2.05 Content with an empty resource.

@sbernard31
Copy link
Contributor

sbernard31 commented Nov 10, 2022

Meaning this https://github.com/eclipse/wakaama/blob/89b9d3efda98ce66c33c233f4a5d9cdcb3f45aa7/core/objects.c#L391
is a bug?

Not sure it's really a bug as the specification is inconsistent but maybe it would be better to support both case.
(Again I'm not an active committer on Wakaama)

@sbernard31
Copy link
Contributor

Did you try, the 2. way ? Does it work ?

sbernard31 added a commit to eclipse-leshan/leshan that referenced this issue Nov 10, 2022
@pehrnord
Copy link

From my understanding, when we try method 2, our wakaama client rejects the "/3441/0/1120 : { }" part of the write with error code COAP_406_NOT_ACCEPTABLE.
And when trying method 1, the leshan server will not perform the write because both resources in our case are marked as Mandatory.
In our case, TLV is used

@sbernard31
Copy link
Contributor

Arf mandatory resource ... another not clear topic of the LWM2M specification : OpenMobileAlliance/OMA_LwM2M_for_Developers#77 (comment)

And when trying method 1, the leshan server will not perform the write because both resources in our case are marked as Mandatory.

That's surprise me, I don't remember there is a kind of checks like this... 🤔
Could you share the error / stacktrace ?
Or maybe you just talk about leshan-server-demo UI ?

@sbernard31
Copy link
Contributor

I don't remember there is this kind of check at Leshan Server side but anyway if it exits it make sense.

Is it a custom Model created by you OR a registered Model from OMA ?
Maybe you could change the model (as workaround)?

But again I think the best will be to support method 2 at wakaama side.

It would be great to get feedback from wakaama team ?
@rettichschnidi @tuve @mlasch

@pehrnord
Copy link

I will see if I can find out more info tomorrow

@pehrnord
Copy link

All content format will behave like above ☝️ (return NOT FOUND) except for TLV.
For TLV, if you try to read /3441/0/1120, the resource exists and you get an 2.05 Content with an empty resource.

A followup question for this: If we implement support for method 2 in wakaama, what should be returned when the resource is read in this case? NOT_FOUND or CONTENT + empty resource?
It seems preferable to have TLV, json, senml behaving the same.

@sbernard31
Copy link
Contributor

sbernard31 commented Nov 14, 2022

It seems preferable to have TLV, json, senml behaving the same.

Ideally, I agree.

In practice, I think that an empty resource or no resource at all (NOT FOUND) is not the same semantically speaking.
So ideally, when you write an empty resource, you should read an empty resource.
And if you write no resource at all, you should get a NOT_FOUND.

But we can not implement this for all ContentFormat because some Content Format encodes both exactly in the same way.

Eg. for SenML JSON

/3441/0/1110 :  { 3 = "newString"}

will be encoded in

 [{"n":"/3441/0/1110/3","vs":"newString"},

and

/3441/0/1110 :  { 3 = "newString"}
/3441/0/1120 :  { }

will also be encoded in :

 [{"n":"/3441/0/1110/3","vs":"newString"},

So I don't know if it is better to :

  • have consistent behavior with all format
  • OR do the best we can do by content format.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants