Open g-oikonomou opened 6 years ago
Previously a bit used for proprietary protocols similar to a short MAC address of 802.15.4 more or less. Also used in printouts in COOJA, etc for something shorter then a full 802.15.4 MAC address.
My guess is that it is only of use in research / non-IP setups. I personally use it in testbed, to match the infrastructure's node ID to the internal ID.
OK that helps. Is there an expected relationship between it, the node's LL address and the short/long address used by the radio?
I would say no (for sure not in my case)
Well there can be a mapping, if that counts as relationship
I have a module I use for my testbed runs to auto-map node-ID from radio address (per-testbed hardcoded mapping)
By "relationship" I mean if e.g. node_id
is 0xABCD does the short address also have to be 0xABCD? Does the long address need to end in 0xABCD? From what you are saying, I understand that the answer is no?
CC13xx/CC26xx platforms do node_id = short_addr;
. We should either homogenize that, or I can get rid of it altogether.
The answer is no indeed. I agree on homogenizing!
I could contribute my testbed mapping module.
When the module is not there, we could either have node_id = short_addr
or why not have no node_id
at all.
Hi there, I would like to reopen this issue. I saw that you implemented this homogenization in release 4.2. In principle, I don't have any objection against that, but it leads to some issues I am not too sure how to solve.
For the case of the Sky motes, as far as I understand the new implementation, the node_id is initialized based on the LL address, which is itself initialized using the ds2411. Okay.
The problem is that I cannot directly control anymore the desired node ID of one mote (which used to be done with the node_id_restore() function, looking at the first bytes sitting in flash). It seems that the intended way to solve this is to use the BUILD_WITH_DEPLOYMENT, but as far as I understand this, it seems I need to map the desired node ID to the LL address (which does not really solve anything, since I still can't control the LL address that I get).
The practical issue here is that we use protocols that assign specific roles to specific node ID (e.g., node 1 is the data sink of a collection scenario). If I use the BUILD_WITH_DEPLOYMENT, I can get the mapping ID <-> LLaddres, but that means that every time I exchange two nodes, I need to update the mapping... More annoying, it means if I share my code with someone, they can not run it out of the box with their nodes, because they will have different node IDs.
As a side note, if the LINKADDR_CONF_SIZE < 8, there are no guarantee to have unique node IDs anymore, which is not great either.
Here are some ideas to resolve this:
What do you think?
Hi @romain-jacob thanks for the feedback.
I am definitely against 1. due to it being platform-specific as you say, unless someone can somehow come up with a way to make the _burn()
and _restore()
functions cross-platform. What we had previously was, we had those functions for a small subset of platforms, and then other platforms were using node_id
in some undocumented, platform-specific, it-felt-like-a-good-idea-when-I-wrote-it fashion, whereas some other platforms plain and simple did not support node_id
at all.
I am not opposed to 2., but this takes us back to the OP: What are the semantics? If you specify NODE_ID=3
at build time, how is that meant to affect (if at all) a node's link layer and/or v6 address(es)?
Perhaps what we need is:
node_id
.As far as I can understand you want to be able to use the same firmware for nodes that can perform a different functions? The choice of which function to perform (e.g. sink, source) depends on some flag that comes from somewhere (at run time?). Am I on the right track here? Do you want multiple different values of this flag? For example, do you actually need unique identifiers per device, or do you just need a way to toggle across N different modes of operation? Do you need to be able to change such modes at run time? How were you previously writing those first bytes in flash?
I'm re-opening this for now.
Thanks for picking that up so quickly!
I think the requirement is really to set a unique identifier per device, but that:
I guess this concern is limited to the case where no no specific MAC or NET layers are being used (NULLMAC, NULLNET), but that's an important share of the current research I believe... Need to think about something what would fit the bill while being cross-platform... TBC
I am still not 100% sure I am following you. The way this is coming across is, you are trying to explain to me a solution, but what I am trying to achieve here is to understand the problem to begin with :)
- can be picked by the user (e.g., you want a node that has node_id = 1 in your network)
Why do you need to check for node_id==1
? Does it absolutely have to be node_id==1
? Could it be a check if the_answer==42
? Could it be some_randomly_assigned_variable & 1 == 0
?
- is small enough to be practical, i.e. 2 bytes typically in low-power networking.
Easy enough to pass at build time, but is this something you need to be able to change at run time? If so, then do you need it to persist across restarts?
Why do you need to check for node_id==1? One typical case is, you have a node playing a central role, let's call it a host, or master. Which node is playing that role is decided based on a define (or a variable), something like HOST_ID = 1. At runtime, all nodes need to check what their role is, which they will do with a test (node_id == HOST_ID), and execute the corresponding part of the code.
Another example is to check if one node id is in some list, something like is_in_list(node_id, ACTIVE_NODE_LIST).
This can be done using the current LLaddres (which comes from the DS2411 on the sky mote). Problem are (i) it's 8 bytes long, which is a lot of overhead for low-power motes (ii) if I take a subset, the IDs are not guarantee to be unique anymore (iii) the IDs are hardware specific: if I have in my code the LLaddres of my sky motes, it needs being changed by anyone else that want to use my code. The BUILD_WITH_DEPLOYMENT makes this a bit less cumbersome, but the problem remains.
Easy enough to pass at build time, but is this something you need to be able to change at run time? If so, then do you need it to persist across restarts?
Fixed at deployment time is ok. I cannot think of any protocol that updates the node ID at runtime...
Does this make things clearer?
For information, we're currently using what is basically a third option next to the two @romain-jacob mentions, one that I think is worth considering for implementation: have the node-id / MAC address be stored in a fixed address in the firmware image. Then, one firmware image is built for all nodes, but prepared for each node separately, by rewriting a particular line in the .hex
file. The result is that I can upload it with setting the node-id / MAC address from command line for a particular node with ID=1 by typing make hello-world.upload A=1
. Or, I can run the make hello-world.testbed
target, which generates a bunch of .hex files with node IDs / MAC address in predefined range and uploads them to the testbed. Swapping the hardware becomes easy, and the node ids remain the same.
We actually do something very similar to what @atiselsts for running tests on Flocklab. We define a specific symbol (called TOS_NODE_ID for historical reasons) and assign node_id = TOS_NODE_ID during initialization. When programming the hardware, the testbed uses the tos-set-symbol utility to replace the value in TOS_NODE_ID by the desired ID for specific node.
A solution in the line of 'make hello-world.upload NODE_ID=1' would be good I think.
So this is what I have done for CC2538DK (2 consecutive sections of the same wiki page):
https://github.com/contiki-ng/contiki-ng/wiki/Platform-cc2538dk#node-ieee-and-ipv6-addresses https://github.com/contiki-ng/contiki-ng/wiki/Platform-cc2538dk#scripted-multi-image-builds
Edit: Exact same logic for zoul
Hmm, interesting, but that does require rebuilding the binary for each node. I rather like the .hex file approach which decouples the "building firmware" step from the "installing firmware" step. The node id could be put in a dedicated .section
in the firmware file with a fixed (platform-specific) address, no? The address can be set from LDFLAGS, for example with the option -Wl,--section-start=.nodeid=0x5000
.
I agree with @atiselsts . Changing the node id when flashing rather than at compile time would be nicer. It does not sound like much, that that makes a big difference when you have to program 20 nodes!
My understanding is that for your use-case @romain-jacob, you don't need the deployment module at all. The point of the module is to provide compile-time well-known mappings between IDs and addresses, and this is not something you have in your setup.
What about simply having platforms optionally define their own ID initialization function, used by node_id_init
whenever BUILD_WITH_DEPLOYMENT
is unset? Would you be against that for being platform-specific @g-oikonomou?
This is the implementation of the ":.hex file override" idea I mentioned here, by the way: https://github.com/contiki-ng/contiki-ng/commit/2ced5bb7629ffbc6f798a5a077dd38ead191e3fc It's published in a branch along with our source code for the Instant protocol from EWSN paper.
Hello everyone. I am not sure if this was finalized or implemented. Having read above, a solution such as make hello-world.upload A=1
seems a good option in a research setting, but I can't find whether something like it was implemented in Contiki 4.9.
The requirement is: a unique, small, and easily configurable node_id
.
Is there a solution?
If there isn't, do we have docs on how to use BUILD_WITH_DEPLOYMENT
?
I never quite managed to get my head around this one. How do people use it? What is it needed for? I am thinking that we need to come up with a uniform way of handling it across all supported ports.