For debugging purposes may be interesting to force a certain topology, specially for multi-hop networks. Some debugging code has been introduced and can be controlled by defined constants. Forcing a topology is done at two layers of the stack, at MAC layer, packets are filtered so a particular node can only receive information from certain neighbors.
In file IEEE802154e.c
#include "stdlib.h" //debug -- this define is used to force multihop. Look at isValidAdv and isValidRxFrame functions. Comment it if you don't want to hardcode multihop. #define FORCE_MULTIHOP #define GINA_FORCE_MULTIHOP //#define TELOSB_FORCE_MULTIHOP //=========================== variables =======================================
There are different defined constants that are used to control the forced topology.
- FORCE_MULTIHOP controls whether forced topology is active or not.
GINA_FORCE_MULTIHOP enables the multihop topology for a gina setting. You can use more than one define in case you want to have different networks and don't want to rewrite the code all the time.
TELOSB_FORCE_MULTIHOP enables multihop for a set of telosb motes (or any other platform)
If you want to force a particular topology you need to know the ID of the motes that will be involved and modify the isValidAdv and isValidRxFrame functions as follows. For data packets you want that motes only receive packets and acks from certain motes. Hence you filter whenever a packet is received as follows:
#ifdef GINA_FORCE_MULTIHOP switch(add->addr_64b[7]){ case 0xED: res=res&(ieee802514_header->src.addr_64b[7]==0xC9);//only PKT from C9 break; case 0xC9: res=res&(ieee802514_header->src.addr_64b[7]==0xED ||ieee802514_header->src.addr_64b[7]==0xD8);//only PKT from ED or D8 break; case 0xD8: res=res&(ieee802514_header->src.addr_64b[7]==0xC9||ieee802514_header->src.addr_64b[7]==0xDC);//only PKT from C9 or DC break; case 0xDC: res=res&(ieee802514_header->src.addr_64b[7]==0xD8||ieee802514_header->src.addr_64b[7]==0x9B);//only PKT from D8 or 9B break; case 0x9B: res=res&(ieee802514_header->src.addr_64b[7]==0xDC);//only PKT from DC break; } #endif
Also we need to filter ADV packet as we only want that motes join to a particular parent.
#ifdef GINA_FORCE_MULTIHOP switch(add->addr_64b[7]){ case 0xC9: res=res&(ieee802514_header->src.addr_64b[7]==0xED);//only ADV from ED break; case 0xDC: res=res&(ieee802514_header->src.addr_64b[7]==0xD8);//only ADV from D8 break; case 0xD8: res=res&(ieee802514_header->src.addr_64b[7]==0xC9);//only ADV from C5 break; case 0x9B: res=res&(ieee802514_header->src.addr_64b[7]==0xDC);//only ADV from DC break; } #endif
At network layer we also need to ensure that motes choose always the correct preferred parent so we force the selection:
In file neighbors.c first enable the feature.
#include "linkcost.h" //to force routing topology -- see above. #define FORCE_MULTIHOP #define GINA_FORCE_MULTIHOP //#define TELOSB_FORCE_MULTIHOP
then in function neighbors_updateMyDAGrankAndNeighborPreference
#ifdef FORCE_MULTIHOP #ifdef GINA_FORCE_MULTIHOP // below to enforce the routing switch ((idmanager_getMyID(ADDR_64B))->addr_64b[7]) { case 0x9B: if (neighbors_vars.neighbors[i].addr_64b.addr_64b[7]==0xDC) { neighbors_vars.myDAGrank=neighbors_vars.neighbors[i].DAGrank+temp_linkCost; temp_preferredParentExists=TRUE; temp_preferredParentRow=i; } break; case 0xDC: if (neighbors_vars.neighbors[i].addr_64b.addr_64b[7]==0xD8) { neighbors_vars.myDAGrank=neighbors_vars.neighbors[i].DAGrank+temp_linkCost; temp_preferredParentExists=TRUE; temp_preferredParentRow=i; } break; case 0xC9: if (neighbors_vars.neighbors[i].addr_64b.addr_64b[7]==0xED) { neighbors_vars.myDAGrank=neighbors_vars.neighbors[i].DAGrank+temp_linkCost; temp_preferredParentExists=TRUE; temp_preferredParentRow=i; } break; case 0xD8: if (neighbors_vars.neighbors[i].addr_64b.addr_64b[7]==0xC9) { neighbors_vars.myDAGrank=neighbors_vars.neighbors[i].DAGrank+temp_linkCost; temp_preferredParentExists=TRUE; temp_preferredParentRow=i; } break; default: break; } #endif
According to your ID force who is your parent. In this example we want that mote with ID: D8 always selects as a preferred parent mote with ID C9.