2.3. Mobile Entity (ME)¶
A Mobile Entity (ME) is the core logic of the application which can be constituted of several tasks or even of several processes. MEs are based on SO3 operating system.
2.3.1. ME ID Information¶
All information related to the identity of the ME (SPID, name, short desc, etc.) is primarly found in its ME device tree (DT).
2.3.1.1. Device tree properties bindings and entries in vbstore¶
The following properties are used in a ME dts.
Property |
Description |
---|---|
<spid> |
Species ID in a 64-bit value encoding |
<spadcaps> |
Species Aptitude Capabilities in a 64-bit value encoding |
<me_name> |
Name of this ME (for example SOO.outdoor) |
<me_shortdesc> |
Short description of this ME (must contain 1024 char. max.) |
The following entries are dedicated to the ME ID information.
/soo/me/<domID>/spid
/soo/me/<domID>/spadcaps
/soo/me/<domID>/name
/soo/me/<domID>/shortdesc
The Migration Manager provides a facility to get the list of MEs with their ID Information in the kernel and in the user space via an ioctl.
2.3.1.2. Species Identifier (SPID)¶
A Mobile Entity is identified by its SPID, a unique 64-bit identifier corresponding to its species (for example, “SOO.blind” has a unique SPID that is associated). Several ME of the same SPIDs are de facto in various smart objects, possibly in the same smart object until one instance decide to kill the other one(s).
The following SPID are currently assigned:
2.3.1.2.1. Basic mobile entities¶
SPID |
ME Description |
---|---|
0x0010000000000001 |
SOO.refso3 used as reference ME. A new ME can be based on this model. There are mainly two configurations (hence two dts) with and without ramfs. |
0x0010000000000002 |
SOO.ledctrl is the ME running in SOO.ledctrl smart object which is a Raspberry Pi 4 enhanced with the Sense HAT extension. This ME basically uses the led matrix and joystick. It is mainly used for demonstration purposes. |
2.3.1.2.2. Mobile entities devoted to SOO.domotics family¶
SPID |
ME Description |
||
---|---|---|---|
0x0020000000000001 |
SOO.blind is devoted to the handling of a “standard” blind which provides the user with features such as putting the blinds up or down, but the ME can also perform synergies with SOO.outdoor for example to decide how to manipulate the blinds, according to the weather condition |
||
0x0020000000000002 |
SOO.outdoor is able to collect data from any weather station. This ME can be used in conjunction with other MEs which can use this kind of data. |
||
0x0020000000000003 |
SOO.wagoled is able to received event from an EnOcean switch and redirect the received commnand to the Wago ecosystem. |
2.3.1.2.3. System and housekeeping mobile entities¶
SPID |
ME Description |
---|---|
0x0030000000000001 |
SOO.agency enables the upgrade of agency image within a smart object. The ME has an embedded of the new version of agency. All smart objects can be updated. |
0x0030000000000002 |
SOO.net can transport networking data packet from a SOO.net smart object to any other smart objects. The ME can then collect data packet to forward them to the network. |
2.3.1.3. Species Aptitude Descriptor (SPAD)¶
Each ME may have one or several SPAD (Species Aptitude Descriptor). The SPAD
determines a specific
feature (or set of features).
The SPAD is also used to tell the agency if the ME is inclined to cooperate with other ME.
Enabling the possibility for an ME to perform cooperation with other ME requires to call the following function in the main application of the ME:
-
void spad_enable_cooperate(void)¶
2.3.2. Lifecycle of a Mobile Entity¶
The ME may frequently migrate from one smart object to another one. Actually, a memory snapshot of the ME to migrate is performed by the agency, which is transfered to the other smart object. Of course, the snapshot requires the ME to be in a consistent state; that is why the ME must suspend its frontend drivers before the snapshot is done. All frontend drivers will be resumed right after the copy; these operations happen with efficient inter-CPU interrupt (IPI) mechanisms and are performed very quickly; In most cases, the running ME is briefly interrupted and does not cause any significant latency.
Hence, when a ME is injected into a smart object by the user, or coming from another smart object, the agency initiates a sequence of callbacks function execution within the context of the ME, but from the CPU’s agency, i.e. CPU #0. The residing ME has its own callback sequence which involves suspending (before the snapshot) and resuming (after the snapshot) the backend drivers. The callback sequences are therefore slightly different between the residing ME and the migrated ME.
Furthermore, in the migrating (arriving) ME, the ME has to create and initialize the vbstore
entries
related to itself as well as to all frontend drivers managed by the ME.
Finally, the newly injected ME (from a tablet/smartphone or automatically from the SD-card at the boot time) has a dedicated callback sequence as well.
All these callback sequences are described in the next sections.
2.3.2.1. State of a Mobile Entity¶
Any ME has an internal state to manage its behaviour. The state can be changed at any time by the different callbacks. The following functions are available to manage the ME state:
-
void set_ME_state(ME_state_t state)¶
To set a ME in a specific state
-
int get_ME_state(void)¶
To get the current a ME state.
State |
Description |
---|---|
ME_state_booting |
ME is currently booting… |
ME_state_preparing |
ME is being paused during the boot process, in the case of an injection, before the frontend initialization |
ME_state_living |
ME is full-functional and activated (all frontend devices are consistent) |
ME_state_suspended |
ME is suspended before migrating. This state is maintained for the resident ME instance |
ME_state_migrating |
ME just arrived in SOO |
ME_state_dormant |
ME is resident, but not living (running) |
ME_state_killed |
ME has been killed before to be resumed |
ME_state_terminated |
ME has been terminated (by a force_terminate) |
ME_state_dead |
ME does not exist |
2.3.2.2. Callback functions¶
There are two kinds of callback functions in a ME: domcalls
and dc_event
based callbacks.
Domcalls are functions which are called by the agency directly, on its dedicated CPU (CPU #0),
in the context of the ME. Callbaks using dc_event are triggered from the CPU agency through an IPI
(Inter-Processor Interrupt) and the ME executes the code itself, enabling the possibility to use
its scheduler (it is not the case with domcalls of course).
2.3.2.2.1. Callback functions - domcalls¶
A domcall function is typically called by the agency and executed on the agency CPU. There is an switch of address space to reach the memory context of the ME and to be able to access its variables. Consequently, asynchronous activities which could require access to the ME scheduler is strictly forbidden.
-
int cb_pre_propagate(soo_domcall_arg_t *args)¶
It is called right before the migration, i.e. the snapshot of the ME.
args
is of typepre_propagate_args_t
and has astatus
field which can have the following value:PROPAGATE_STATUS_YES
orPROPAGATE_STATUS_NO
indicating if the ME can be propagated or not. If the ME is not propagated, no further callback functions are executed.
-
int cb_pre_activate(soo_domcall_arg_t *args)¶
Called after a migration to see if it makes sense for this ME to be resumed in this smart object. If not, the ME state can be set to
ME_state_killed
-
int cb_cooperate(soo_domcall_arg_t *args)¶
This a very important callback function which allows the migrated ME to exchange information with other MEs which reside in the smart object.
args
is of type cooperate_args_t containing a field calledrole
The role can be
COOPERATE_INITIATOR
orCOOPERATE_TARGET
depending in which ME the cooperate() function is executed. The first role is given to the migrated ME while the second role is given to the residing ME when the migrated ME performed a call to the cooperate() function in this (residing) ME. This mechanism clearly enables inter-ME collaboration and is useful to decide which ME must stay alive or be killed.
2.3.2.2.2. Callback functions - dc_event¶
The following callback functions are executed in the ME context on the CPU belonging to the ME. Asynchronous activities requiring the ME scheduler are authorized.
-
int cb_pre_suspend(soo_domcall_arg_t *args)¶
Called before suspending the frontend drivers.
-
int cb_pre_resume(soo_domcall_arg_t *args)¶
Called before resuming the frontend drivers
-
int cb_post_activate(soo_domcall_arg_t *args)¶
This callback function is called once all frontend drivers have been resumed. It is the final callback function called at the end of each migration process.
-
int cb_force_terminate(void)¶
Tell the ME that a force terminate will be performed for this ME. The ME state is changed during this callback and is typically set to
ME_state_terminated
Note
The suspend and resume callbacks are not specific to a particular ME and is a generic procedure to suspend and to resume frontend drivers. The code of this callbacks should NOT be changed.
2.3.2.3. Callback sequence in the injected ME¶
pre_activate
-> cooperate
The ME state is set to ME_state_living
2.3.2.4. Callback sequence in the residing ME¶
pre_propagate
-> pre_suspend
-> suspend
(snapshot) resume
-> post_activate
The ME state is set to ME_state_living
2.3.2.5. Callback sequence in the migrating ME¶
pre_propagate
-> pre_suspend
-> suspend
(snapshot & migrating) pre_activate
-> cooperate
-> resume
-> post_activate
The ME state is set to ME_state_living
2.3.3. ME Interactions with the User Interface application¶
The ME can manage XML messages and events in order to interact with a GUI running on the tablet. The following helpers are very helpful to this purpose. The messages/events are forwarded to the vuihandler frontend.
2.3.3.1. Message handling¶
This function prepare a XML message based on its ID and value:
-
void xml_prepare_message(char *buffer, char *id, char *value)¶
The buffer is allocated by the caller and will contain the XML formatted message.
2.3.3.2. Event handling¶
-
void xml_parse_event(char *buffer, char *id, char *action)¶
The event message (pointed by buffer) contains a specific action with an associated ID. These fields can be retrieved with this function. The caller must allocate the memory.