<?xml version='1.0' encoding='UTF-8'?>
<simconf version="2022112801">
  <simulation>
    <title>Parent failure: baseline, change window and restored link</title>
    <randomseed>1</randomseed>
    <motedelay_us>1000000</motedelay_us>
    <radiomedium>
      org.contikios.cooja.radiomediums.UDGM
      <transmitting_range>50.0</transmitting_range>
      <interference_range>50.0</interference_range>
      <success_ratio_tx>1.0</success_ratio_tx>
      <success_ratio_rx>1.0</success_ratio_rx>
    </radiomedium>
    <events>
      <logoutput>40000</logoutput>
    </events>
    <motetype>
      org.contikios.cooja.contikimote.ContikiMoteType
      <description>Root 1</description>
      <source>[CONFIG_DIR]/firmware/udp-server.c</source>
      <commands>make TARGET=cooja clean
make -j4 udp-server.cooja TARGET=cooja</commands>
      <moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
      <moteinterface>org.contikios.cooja.interfaces.Battery</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiVib</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
      <moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
      <moteinterface>org.contikios.cooja.interfaces.IPAddress</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiButton</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiClock</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiLED</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
      <moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
      <moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
      <mote>
        <interface_config>org.contikios.cooja.interfaces.Position<pos x="0" y="0" />
        </interface_config>
        <interface_config>org.contikios.cooja.contikimote.interfaces.ContikiMoteID<id>1</id>
        </interface_config>
      </mote>
    </motetype>
    <motetype>
      org.contikios.cooja.contikimote.ContikiMoteType
      <description>Clients: observe target 5</description>
      <source>[CONFIG_DIR]/firmware/udp-client.c</source>
      <commands>make TARGET=cooja clean
make -j4 udp-client.cooja TARGET=cooja</commands>
      <moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
      <moteinterface>org.contikios.cooja.interfaces.Battery</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiVib</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
      <moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
      <moteinterface>org.contikios.cooja.interfaces.IPAddress</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiButton</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiClock</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiLED</moteinterface>
      <moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
      <moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
      <moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
      <mote>
        <interface_config>org.contikios.cooja.interfaces.Position<pos x="-30" y="25" />
        </interface_config>
        <interface_config>org.contikios.cooja.contikimote.interfaces.ContikiMoteID<id>2</id>
        </interface_config>
      </mote>
      <mote>
        <interface_config>org.contikios.cooja.interfaces.Position<pos x="30" y="25" />
        </interface_config>
        <interface_config>org.contikios.cooja.contikimote.interfaces.ContikiMoteID<id>3</id>
        </interface_config>
      </mote>
      <mote>
        <interface_config>org.contikios.cooja.interfaces.Position<pos x="-60" y="55" />
        </interface_config>
        <interface_config>org.contikios.cooja.contikimote.interfaces.ContikiMoteID<id>4</id>
        </interface_config>
      </mote>
      <mote>
        <interface_config>org.contikios.cooja.interfaces.Position<pos x="0" y="55" />
        </interface_config>
        <interface_config>org.contikios.cooja.contikimote.interfaces.ContikiMoteID<id>5</id>
        </interface_config>
      </mote>
      <mote>
        <interface_config>org.contikios.cooja.interfaces.Position<pos x="60" y="55" />
        </interface_config>
        <interface_config>org.contikios.cooja.contikimote.interfaces.ContikiMoteID<id>6</id>
        </interface_config>
      </mote>
    </motetype>
  </simulation>
  <plugin>org.contikios.cooja.plugins.Visualizer<plugin_config>
      <skin>org.contikios.cooja.plugins.skins.IDVisualizerSkin</skin>
      <skin>org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin</skin>
      <skin>org.contikios.cooja.plugins.skins.UDGMVisualizerSkin</skin>
      <skin>org.contikios.cooja.plugins.skins.GridVisualizerSkin</skin>
      <viewport>4.0 0.0 0.0 4.0 490.0 80.0</viewport>
      <moterelations />
    </plugin_config>
    <bounds x="0" y="0" width="1000" height="475" z="1" />
  </plugin>
  <plugin>org.contikios.cooja.plugins.LogListener<plugin_config>
      <filter>Preferred parent|Rank:|Received ping|Received request|Received response</filter>
      <formatted_time />
      <coloring />
    </plugin_config>
    <bounds x="0" y="480" width="1580" height="430" z="0" />
  </plugin>
  <plugin>org.contikios.cooja.plugins.Notes<plugin_config>
      <notes>Target 5 hears relays 2 and 3. Seed 1; UDGM 50/100 m.
GUI pauses at 89 s and 150 s; click Start/Pause to continue.
At 90 s the actual preferred relay moves out of range.
At 210 s it returns. Observe whether hysteresis retains new parent.
The script measures target 5 uplink and reply outcomes.</notes>
      <decorations>true</decorations>
    </plugin_config>
    <bounds x="1005" y="0" width="575" height="215" z="3" />
  </plugin>
  <plugin>org.contikios.cooja.plugins.ScriptRunner<plugin_config>
      <script>sources={}; replies={}; sent=0; received=0; parents={}; measurements={};
TIMEOUT(300000, log.log("SUMMARY duration_us="+sim.getSimulationTime()+" sent="+sent+" root_received="+received+" clients="+Object.keys(sources).length+" reply_clients="+Object.keys(replies).length+" parents="+JSON.stringify(parents)+" measurements="+JSON.stringify(measurements)+"\n"); if(measurements.changed_us &amp;&amp; measurements.windowReceived&gt;=3 &amp;&amp; measurements.windowReplies&gt;=3 &amp;&amp; measurements.changedPing &amp;&amp; measurements.restoredPing) log.testOK(); else log.testFailed());
GENERATE_MSG(85000, "EVENT baseline-status");
GENERATE_MSG(86000, "EVENT baseline-routes");
GENERATE_MSG(89000, "EVENT GUI-baseline-pause");
GENERATE_MSG(90000, "EVENT remove-preferred-relay");
GENERATE_MSG(140000, "EVENT changed-status");
GENERATE_MSG(145000, "EVENT changed-downward-ping");
GENERATE_MSG(150000, "EVENT GUI-changed-pause");
GENERATE_MSG(210000, "EVENT restore-relay");
GENERATE_MSG(260000, "EVENT restored-status");
GENERATE_MSG(270000, "EVENT restored-downward-ping");
while(true) {
 YIELD(); msg=String(msg); log.log(time+" ID:"+id+" "+msg+"\n");
 if(msg.indexOf("Sending request")&gt;=0) sent++;
 if(id==1 &amp;&amp; msg.indexOf("Received request")&gt;=0) { received++; sources[msg.split(" from ")[1]]=true; }
 if(id!=1 &amp;&amp; msg.indexOf("Received response")&gt;=0) replies[id]=true;
 var match=msg.match(/#L (\d+) 1/); if(match) parents[id]=Number(match[1]);
 if(msg=="EVENT baseline-status") { write(sim.getMoteWithID(5),"rpl-status"); }
 if(msg=="EVENT baseline-routes") { write(sim.getMoteWithID(5),"routes"); }
 if(msg=="EVENT GUI-baseline-pause") { if(Java.type("org.contikios.cooja.Cooja").isVisualized()) sim.stopSimulation(); }
 if(msg=="EVENT remove-preferred-relay") { measurements.oldParent=parents[5]; var pos=sim.getMoteWithID(measurements.oldParent).getInterfaces().getPosition(); oldX=pos.getXCoordinate(); oldY=pos.getYCoordinate(); pos.setCoordinates(300,300,0); measurements.failure_us=time; log.log("FAULT removed_parent="+measurements.oldParent+" at_us="+time+"\n"); }
 if(msg=="EVENT changed-status") { write(sim.getMoteWithID(5),"rpl-status"); }
 if(msg=="EVENT changed-downward-ping") { write(sim.getMoteWithID(1),"ping fd00::205:5:5:5"); }
 if(msg=="EVENT GUI-changed-pause") { if(Java.type("org.contikios.cooja.Cooja").isVisualized()) sim.stopSimulation(); }
 if(msg=="EVENT restore-relay") { sim.getMoteWithID(measurements.oldParent).getInterfaces().getPosition().setCoordinates(oldX,oldY,0); measurements.restored_us=time; }
 if(msg=="EVENT restored-status") { write(sim.getMoteWithID(5),"rpl-status"); }
 if(msg=="EVENT restored-downward-ping") { write(sim.getMoteWithID(1),"ping fd00::205:5:5:5"); }
var removed=msg.match(/#L (\d+) 0/); if(removed &amp;&amp; parents[id]==Number(removed[1])) delete parents[id];
if(id==5 &amp;&amp; match &amp;&amp; time&gt;90000000 &amp;&amp; Number(match[1])!=measurements.oldParent &amp;&amp; !measurements.changed_us) { measurements.changed_us=time; measurements.newParent=Number(match[1]); }
if(measurements.failure_us &amp;&amp; !measurements.restored_us) {
 if(id==5 &amp;&amp; msg.indexOf("Sending request")&gt;=0) measurements.windowSent=(measurements.windowSent||0)+1;
 if(id==1 &amp;&amp; msg.indexOf("Received request")&gt;=0 &amp;&amp; msg.indexOf("fd00::205:5:5:5")&gt;=0) { measurements.windowReceived=(measurements.windowReceived||0)+1; if(!measurements.firstUplink_us) measurements.firstUplink_us=time; }
 if(id==5 &amp;&amp; msg.indexOf("Received response")&gt;=0) { measurements.windowReplies=(measurements.windowReplies||0)+1; if(!measurements.firstReply_us) measurements.firstReply_us=time; }
}
if(id==1 &amp;&amp; msg.indexOf("Received ping reply from fd00::205")&gt;=0) { if(time&lt;210000000) measurements.changedPing=msg; else measurements.restoredPing=msg; }

}
</script>
      <active>true</active>
    </plugin_config>
    <bounds x="1005" y="220" width="575" height="255" z="4" />
  </plugin>
</simconf>