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

[Question] Decoding of Object Instances during WRITE Request #1369

Closed
horeich opened this issue Dec 6, 2022 · 25 comments
Closed

[Question] Decoding of Object Instances during WRITE Request #1369

horeich opened this issue Dec 6, 2022 · 25 comments
Labels
question Any question about leshan

Comments

@horeich
Copy link

horeich commented Dec 6, 2022

Question

Hello,

I've got a problem understanding the process of decoding and writing to specific resources during a Object Instance WRITE Request from server towards client.

I'm trying to explain the problem using an example:
Let's assume, during Registration the Object Instance /3/0 was reported to the server but the client internally only support 3/0/1 and 3/0/2 (let's leave aside mandatory resources).

What happens...
1.) ... in case the server sends a WRITE request for /3/0 to the client which contains the resources 3/0/1 3/0/2 and 3/0/3 in the payload; does the client just ignore the value for /3/0/3 and report CREATED 2.04?

2.) ... in case the server sends a WRITE request for /3/0 to the client but only the resource 3/0/1 is encoded in the payload, does the client just set the value for /3/0/1 (report CREATED 2.04) and ignores that one resource is missing?

Thank you,
Andy

@horeich horeich added the question Any question about leshan label Dec 6, 2022
@horeich horeich changed the title [Question] Decoding of Object Instances [Question] Decoding of Object Instances during WRITE Request Dec 6, 2022
@sbernard31
Copy link
Contributor

sbernard31 commented Dec 6, 2022

(Note that I didn't check if Leshan client behaves like this but it SHOULD)

About 1)
The question is how to behave if server try to write unsupported optional resource ?

LWM2M-v1.1.1@core§6.3.3. Write Operation says :

Any optional resources included in the "Write" operation that are not supported by the LwM2M Client MUST be silently ignored.

So, I think yes, "the client just ignore the value for /3/0/3 and report CREATED 2.04"

About 2)
I guess you are talking about Partial Update Write (and not Replace Write) ?

LWM2M-v1.1.1@core§6.3.3. Write Operation says :

Partial Update: updates Resources provided in the new value and leaves other existing Resources unchanged. When the Resource is a Multiple-Instance Resource, the existing array of Resource Instances is updated meaning some Instances may be created or overwritten to the condition the LwM2M Client authorizes such operations. Deleting via Partial Update is not possible.

So, I think that " client just set the value for /3/0/1 (report CREATED 2.04) and ignores that one resource is missing".


let's leave aside mandatory resources

Answers would probably not be the same for mandatory resources.

@horeich
Copy link
Author

horeich commented Dec 6, 2022

Thank you very much for your answer. You're right I also have to keep Mandatory and Partial Update in mind.

So if not all Mandatory Resources of Instance /3/0/ are updated during Partial Update, I assume that is still OK? But if I do not update all Mandatory Resource during Replace Update it will be rejected, right? Because Replace is basically a Create call carrying a payload.

@sbernard31
Copy link
Contributor

So if not all Mandatory Resources of Instance /3/0/ are updated during Partial Update, I assume that is still OK? But if I do not update all Mandatory Resource during Replace Update it will be rejected, right?

Yep, at least this is my understanding.

Because Replace is basically a Create call carrying a payload.

I would say Replace is a kind of Delete then Create.

@horeich
Copy link
Author

horeich commented Dec 6, 2022

Alright, that clarifies a lot.

Any optional resources included in the "Write" operation that are not supported by the LwM2M Client MUST be silently ignored.

That leaves me with the following question:
When I try to do a Replace on a resource that is not supported by the client (e.g. taken from the example above: /3/0/3), then it will also be silently ignored and not deleted/created, right? At least, that would be the expected behaviour when checking out the CREATE Operation:

The Object Instance created in the LwM2M Client by the LwM2M Server MUST be an Object type supported by the
LwM2M Client and announced to the LwM2M Server using the “Register” and “Update” operations of the LwM2M Client
Registration Interface.

@sbernard31
Copy link
Contributor

sbernard31 commented Dec 6, 2022

I'm not sure I get you ?

When I try to do a Replace on a resource that is not supported by the client (e.g. taken from the example above: /3/0/3),

You mean send a Write Replace Request directly on resource /3/0/3 ?
OR
You mean send a Write Replace Request on /3/0 with a payload containing /3/0/3 resource ?

@horeich
Copy link
Author

horeich commented Dec 6, 2022

You mean send a Write Replace Request on /3/0 with a payload containing /3/0/3 resource ?

Yes, sorry for being inaccurate. I was talking about this case.

But the other case is interesting, too :)

@sbernard31
Copy link
Contributor

You mean send a Write Replace Request on /3/0 with a payload containing /3/0/3 resource.

The whole 3/0 instance is replaced.
That means that we remove the previous one and we replace it by a new one with resources given in the payload.
If a resource is not supported, client will just ignore that resource.
If no resource is supported in the payload you will create a kind of empty instance...

@horeich
Copy link
Author

horeich commented Dec 6, 2022

Yes that makes sense. So if the Replace Write does not contain the Mandatory Resources of that Object Instance, it will be rejected then. So the Client requires some check whether these are present or not, I guess.

@sbernard31
Copy link
Contributor

Yep.

@horeich
Copy link
Author

horeich commented Dec 6, 2022

Awesome! Really appreciate your prompt and concise replies. Will see if any question pops up later today or tomorrow. Otherwise, I'll close this thread.

@sbernard31
Copy link
Contributor

You're welcome.

Could I ask what you are doing with LWM2M ? It seems to me that you currently try to implement a kind of LWM2M client, is that correct ?

@horeich
Copy link
Author

horeich commented Dec 7, 2022

Of course, it's no secret. I'm/We're working on a LwM2M client fully in C++. The focus of the implementation lies in its easy integration with existing applications which is something, imo, many current implementations struggle with (LwM2M dictates the implementation of network and application layers). The idea is to fully detach application layer integration from the LwM2M client and treat LwM2M as what it is: a high-level network stack.

The client will be publicly available on github.

@sbernard31
Copy link
Contributor

Thx for detailed explanation 🙏

The idea is to fully detach application layer integration from the LwM2M client and treat LwM2M as what it is: a high-level network stack.

What do you consider as application layer ? e.g. Object implementations seems not really pure network layer, or ?
I mean it's not clear to me exactly what it will looks like 🤔

When you said :

The client will be publicly available on github.

Does it means it will be released under FOSS license ?

@horeich
Copy link
Author

horeich commented Dec 7, 2022

I think the objects are a "design flaw" in LwM2M because they make your general application design less flexible. So I strip the objects of their influnce in the application, so they solely have the function to manage data exchange.

The application API will look something like this:

lwM2MClient.SetResourceValue(ServerObject::Id, 0, ServerObject::BindingId, 0, LwM2MCpp::BindingU); // this is how you change the value -> triggers notify if observe is activated
lwM2MClient.SetResourceCallback(ServerObject::Id, 0, ServerObject::BindingId, 0, this, &LwM2MExample::ChangeBinding); // application will be notified if server changes binding
lwM2MClient.SetExecuteCallback(DeviceObject::Id, 0, 4, this, &LwM2MExample::Reboot); // application subscribes to reboot requested by server

You see the application layer itself basically subscribes to LwM2M object which are used as proxies for network data exchange. This is mainly done by a callback design (e.g. in contrast to the observer pattern leshan uses). This way, we avoid application dependencies within the LwM2M client implementation. To keep the API clean it requires lots of meta programming in the background, though.

Hope this makes sense.

Does it means it will be released under FOSS license ?

Yes that's the plan.

@sbernard31
Copy link
Contributor

You see the application layer itself basically subscribes to LwM2M object which are used as proxies for network data exchange. This is mainly done by a callback design (e.g. in contrast to the observer pattern leshan uses). This way, we avoid application dependencies within the LwM2M client implementation. To keep the API clean it requires lots of meta programming in the background, though.

I'm not sure I see the nuance. (Note that I didn't know Cpp so much so I maybe missed something)

But I also see LwM2mInstanceEnabler or LwM2mObjectEnabler from Leshan as a kind of way to bind LWM2M with your application code.
I mean you can directly code the application logic in this object but you can also just call you application API in the object and so this is just a kind of adapter.

I try to understand because if there is some idea to better organize Leshan code, I would like to have it in mind. (not sure I will change the code but at least I know how we could do better) 🙂

Yes that's the plan.

👍 Great news !

@horeich
Copy link
Author

horeich commented Dec 8, 2022

But I also see LwM2mInstanceEnabler or LwM2mObjectEnabler from Leshan as a kind of way to bind LWM2M with your application code.

You're right that works well, too. I intend to give the user of LwM2M stack less flexibility (not even a real adapter) which is probably not the goal of the Leshan implementation as it aims at maximal flexibility and integration. I'm far from a Java expert, though, the latest experience was the one I had with a Leshan microservice implementation. Sometimes I wish Leshan was implemented in C# with all its latest async features :)

However, our C++ client is still wip, so I'm happy to keep the discussion running. More questions will pop up for sure!

@sbernard31
Copy link
Contributor

Sometimes I wish Leshan was implemented in C# with all its latest async features :)

Often when you implement an open source library, you are stuck to old version to allow maximum reusability. (Currently leshan use java8 as minimal version 😬.

Without thinking of this too much, if I should create Leshan now, I would give a try to Rust. 🤔

Let me know if we should close this issue ?

@horeich
Copy link
Author

horeich commented Dec 19, 2022

One more thing regarding Bootstrap-Write I stumbled across:

The spec says:

Once a "Bootstrap-Write" operation initiated on the "Bootstrap" interface by the LwM2M Server, the LwM2M Client MUST write the value included in the payload regardless of an existence of the targeting Object Instance(s) or Resource(s) and access rights.

What exactly does the part "regardless of an existance of the targeting Object Instance mean? Does it mean, it will be created in case doesn't exist yet?

@sbernard31
Copy link
Contributor

Yep, I didn't double check this but If I remember well Bootstrap-Write is a kind of "Write Update or Create".

@horeich
Copy link
Author

horeich commented Jan 9, 2023

Thank you! I have another little issue with bootstrapping: When using the default configuration I firstly get the Security Object Instance /1 sent down to the client. So far so good. But why does it send next the LwM2M server config on Server Object Instance /0? Shouldn't it be also on /1 to match the Security Object Instance? This way it tries to overwrite my Boostrap Server config which is located in Instance /0
grafik

@sbernard31
Copy link
Contributor

I'm not sure I get the point but maybe you missed some points :

1. Server object (object Id:1) only contains LWM2M server, not bootstrap server

This LwM2M Objects provides the data related to a LwM2M Server. A Bootstrap-Server has no such an Object Instance associated to it.

(source : http://www.openmobilealliance.org/release/LightweightM2M/V1_1_1-20190617-A/HTML-Version/OMA-TS-LightweightM2M_Core-V1_1_1-20190617-A.html#13-2-0-E2-LwM2M-Object-LwM2M-Server)

2. The way to link a Server Instance and a Security instance is not by comparing the instance id but by comparing short server id from resource /0/?/10 and resource /1/?/0.

This way it tries to overwrite my Boostrap Server config which is located in Instance /0

So this should not be an issue on object Server(1) but for completeness, you could face some kind of bootstrap config overwritting on object Security(0).

There is some explanation about it Bootstrap server UI demo :

Note that Security /0 Object Instance storing LWM2M Bootstrap server data can not be deleted using Delete Request.
Adding Security instance without knowing the Instance ID of Bootstrap Server could lead to some unexpected behavior (see OMA#522, OMA#523).
By default, this wizard use the convention that LWM2M Bootstrap Server Security instance ID is 0.
If your client don't use this convention, you can use autoIdForSecurityObject=true and so Leshan will start the Bootstrap session with a Discover request to know which Security instance ID is used for the Bootstrap Server."

HTH

@horeich
Copy link
Author

horeich commented Jan 10, 2023

Ok, thanks for the clarification, I missed that obious detail.

There is some explanation about it Bootstrap server UI demo

Thanks for pointing that out, I followed the discussion. In theory, should a client support multiple bootstrapping configurations to fetch LwM2M Server configs from different bootstrapping servers?

@sbernard31
Copy link
Contributor

Nope, a client can only have 1 bootstrap server at a time.

The LwM2M Client MUST have at most one LwM2M Bootstrap-Server Account.

source : http://www.openmobilealliance.org/release/LightweightM2M/V1_1_1-20190617-A/HTML-Version/OMA-TS-LightweightM2M_Core-V1_1_1-20190617-A.html#6-1-2-0-612-Bootstrap-Information

@horeich
Copy link
Author

horeich commented Jan 12, 2023

Another thing I overlooked! Thank you again. I think we can close this thread, otherwise it'll become very offtopic (regarding the original question). If ok, I'll open a new issue when running into further trouble.

@sbernard31
Copy link
Contributor

You're welcome 😉

I think we can close this thread, otherwise it'll become very offtopic (regarding the original question). If ok, I'll open a new issue when running into further trouble.

let's do it.

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

No branches or pull requests

2 participants