# reorder.cpp

Sometimes you get a packet that you'd rather deal with later. This can happen for a number of reasons; an example could be if you are expecting an ordered sequence of packets, but (for whatever reason) occasionally packets arrive out of order. If the out-of-order packet could just be stored temporarily, until the missing packets ahead of it had arrived, then everything could be handled smoothly.

The Memory object and the SFBMemory::remember(const u8*) function provide such an ability, as illustrated here. If room is available, `Memory.remember(packet)` makes a copy of its packet argument, stores that copy internally, and arranges for reflexes to be triggered on the copy some time in the future (between loop() calls, typically). (Like one's own unconscious memory, perhaps) there's no particular timing or ordering guarantees about when remembered packets will be recalled.

As an illustration, this sketch sends out packets containing steadily increasing counts, but occasionally sends packets out of order. When the reflex handler detects a jump in the sequence, it simply remembers the out-of-order packet(s), and reacts to them again later (when hopefully all the missing prior pieces have arrived.

In this output sequence, the sketch has been running a while, and is now outputting sequence numbers in the 90's, when another board is detected, at its sequence 4:

    s91
    Ln 68.000 (Re)starting at 4
    Ln 68.001 Sequence 4
    s92
    Ln 69.001 Sequence 5
    s93
    Ln 70.002 Sequence 6
    s94
    Ln 71.005 Sequence 7
    Ln 71.021 Sequence 8
    Ln 71.041 Sequence 9
    s95
    Ln 72.004 Sequence 10
    s96
    Ln 73.008 Sequence 11
    Ln 73.061 Sequence 12
    s97
    Ln 73.121 Sequence 13
    Ln 73.141 Sequence 14
    Ln 73.161 Sequence 15
    Ln 74.006 Sequence 16
    s98
    Ln 75.007 Sequence 17
    s99
    Ln 76.008 Sequence 18
    s100
    Ln 77.009 Sequence 19
    s103
    s102
    s101
    Ln 78.012 Sequence 20

This output and timing suggests that several runs of 's' packets (7-9, 11-12, 13-16) arrived out of order and were temporarily remembered, so the sequence outputs continue in order. (And note our 's103'-'s101' being sent out of order, as well.)

    // Use Memory.remember(u8*) to reorder out-of-sequence packets

    u32 lastSequence = 0;           // Last sequence# received in order
    void handleS(u8 * packet) {
      u32 sequence;
      if (packetScanf(packet,"s%d\n",&sequence) != 3) return; // Analyze input, ignore bad packets

      if (lastSequence == 0 || sequence-lastSequence > 5) {   // If just starting, or we're way off
        lastSequence = sequence-1;                            // Reset
        logNormal("(Re)starting at %d\n",sequence);           // and announce that
      }

      if (lastSequence+1 < sequence)     // If packet is out of order,
        Memory.remember(packet);         // just remember it for later..
      else {                             // Else it's what we want..
        lastSequence = sequence;         // So advance
        logNormal("Sequence %d\n",lastSequence); // and report it
      }
    }

    void setup() {
      Body.reflex('s',handleS);     // Set up reflex
    }

    u32 loops = 0;            // Last sequence# we sent out
    void loop() {
      if (random(10)!=0)      // 90% of the time, just issue next sequence #
        pprintf("s%d\n",++loops);
      else {                  // but 10% of the time, issue a few backwards..
        u32 incr = random(4)+2;     // incr=2..5
        loops += incr;
        for (u32 i = 0; i < incr; ++i)
          pprintf("s%d\n",loops-i);
      }
      ledToggle(BODY_RGB_RED_PIN);  // Show a heartbeat.
      delay(1000);            // Wait a second
    }