The current system looks like this:
TOS_Msg.type = AM_SURGEMSG
TOS_Msg.data ---------> MultihopMsg.fields
MultihopMsg.data -----> SurgeMsg.fieldsWhat we have now is a single global namespace for all nested combinations of messages. That is, a TOS_Msg with type AM_SURGEMSG must contain a MultihopMsg containing a SurgeMsg.
What I'm arguing for is something more like this:
TOS_Msg.type = AM_MULTIHOPMSG
TOS_Msg.data ---------> MultihopMsg.fields
MultihopMsg.type = MH_SURGEMSG
MultihopMsg.data ------> SurgeMsg.fieldsI'd like to see explicit type information at each level, with a separate namespace for each level of containment. Following what Alec said, this allows a cleaner encapsulation of services, and requires less coordination between users of protocols at different layers.
Your message seems to imply something like my second example, but with each nested type having a globally unique value. I would actually argue that as long as the type of each contained message is always stored by the container message in a field named "type", possibly with a fixed offset from the start of the message, then we could have a separate namespace at each level and still perform automatic recursive processing. Each message type will still have a uniquely associated ID, but it needs only to be interpreted in the context of its containing messages.
I'm not sure why this would require wiring information in mig, and in fact, because each message is wholly independent of its container, it should require even less information about the containment hierarchy.
If a unique name is required for each distinct nested set of messages, as in the current model, then the namespace would probably be exhausted sooner than if a name was only associated with each message. If we allowed overlap, such that two messages could share the same ID as long as one was intended to be sent out within a MultihopMsg and the other to be sent out within a BcastMsg, then we would have even less chance of namespace exhaustion.
Gil
Cory Sharp wrote:
I took me a second to realize what you're arguing for, but I think I'll agree. You propose that for a TOS_Msg.data structured something like this
/-- TOS_Msg.data ------------------------\ AM1 [header1] AM2 [header2] ... AMn [body]
then all AM's (AM1, AM2, ..., AMn) should live is a globally unique namespace.
This directly addresses a problem we had developing PEG's routing where each AM generated a new namespace for the nested AM's within it. This required wiring information be available to mig, etc (which I never did and just created the extremely grotesque peg.m in matlab). Placing AM's in a global namespace removes that need for wiring, just looping over consequitive AM's in the message.
One problem, managing and posibly exhausing that namespace are issues for a large project. In PEG, we had more than 50 Config values. Each config value effectively had it's own AM within the Config namespace, and it was hard enough to coordinate AM's just for those Config values.
It might be worth considering solutions to namespace exhaustion, otherwise you might hit a hard wall at just the wrong time -- deep into development. Otherwise, I think it's a great idea.
- Cory
Gilman Edwin Tolle wrote:
I've been thinking a bit about a question, and I'd like to get the opinions of the list:
Are Active Message IDs intended to be in 1-1 correspondence with message formats?
Most of what I've seen indicates yes: * We give names like AM_SURGEMSG to numeric IDs. * The mig-generated Java message classes contain explicit AM IDs. * TinyOS components expect to be able to correctly extract pieces from messages based only on the "type" field in the container TOS_Msg structure.
However, some messages have been designed to be "generic container" messages, of which I can think of two: BcastMsg and MultihopMsg. These messages seem to have no uniquely associated type, and to use them, the programmer must take explicit action to copy the type from the "inner messages" they contain to the outer TOS_Msg containing them. In a TinyOS component, this action requires an extra line of wiring directly to GenericComm. In a Java app, this requires passing the inner message containing the correct type to the registerListener() function, then typecasting each incoming message to the "outer message". In addition, to correctly send a container message, Java developers must hand-edit the generated container message class file to set the type because none is automatically included.
This departure from the 1-1 model makes several techniques much more challenging, in addition to requiring extra effort by the programmer to understand and use. For instance, creating an independent Java program that can receive all MultihopMsgs passed over the UART, parse the MultihopMsg part, and then keep statistics is not possible in a generic way. In addition, automatically and recursively extracting the parts from a nested message for more effective message logging is impossible without explicit type information at each level of nesting.
So, I wonder why this decision was made, and whether it would be a good idea to reverse it.
Reassociating container messages with a unique type is easy enough, and adding an internal type field to each container message can re-establish the missing type information about the internal message. Parameterized TinyOS interfaces can be dispatched just as easily on inner type fields as on outer type fields, and this would obviate the need to wire GenericComm directly. Java interface classes will no longer need hand-editing or misdirection, and much more flexible message parsing becomes possible.
If I've misunderstood anything, let me know.
Gil
_______________________________________________ Tinyos-users mailing list [EMAIL PROTECTED] http://mail.Millennium.Berkeley.EDU/mailman/listinfo/tinyos-users
