# netled.cpp

The Net object provides an easy-to-use mechanism allowing nodes to offer services to each other, and to respond to service requests using the ordinary reflex processing mechanism familiar from all SFB programming.In this simple 'net LED' sketch, the 'service' to be provided is lighting the LED red or blue, for which the sketch defines service code 'l' (ell). A long button click on a board toggles whether that board provides the 'l' service to the network, while a short button click sends a 'toggle' request to the nearest 'l' service provider, causing it to toggle its LED and send an appropriate reply.

When first encountering SFB networking, it's easy to confuse service types (in this sketch, 'l'), with packet reflex types (in this sketch, 't' and 'r') -- but they are very different beasts. Rather than thinking of a service type as being similar to a packet type, a network service type is better seen as similar to a face or a direction: Just as you can send and receive any and all packet types to and from your NORTH face, say, you can also send and receive any packet types to and from service 'l'.

The difference, of course, is that you don't have to know where service 'l' is actually being provided -- Net will route your requests and replies for you, via some shortest path through the grid.

    /* Networking demo that toggles a remote LED:
     *  - Defines service 'l' for LED toggling (red vs blue).
     *  - Long button press toggles whether board is an 'LED provider'
     *  - Short button press sends a 'toggle LED' request to nearest LED provider.
     *  - 'Toggle reply' causes matching flash on the button-pressed board
     */

    bool iProvideLight = false;     // Initially, I'm not an 'LED provider'
    bool ledRed = false;            // When I am, remember what color I'm showing

    void handleToggleRequest(u8 * packet) { // This function runs on the service provider
      ledRed = !ledRed;             // Toggle our color
      facePrintf(packetSource(packet),"r%d\n",ledRed); // And reply back to the requester
    }
    void handleToggleReply(u8 * packet) {  // This function runs on the service requester
      u32 isRed;
      if (packetScanf(packet,"r%d\n",&isRed) != 3)   // Analyze packet
        return;                                      // ignore bogus ones
      if (isRed) ledOn(BODY_RGB_RED_PIN);   // Match the provider's color
      else ledOn(BODY_RGB_BLUE_PIN);
      delay(50);                     // Brief flash.. mustn't delay long in packet handler!
    }

    void setup() {
      Body.reflex('t',handleToggleRequest); // For when I'm a provider
      Body.reflex('r',handleToggleReply);   // For when I'm a requester
      Net.begin();                          // Start the net!
    }

    void loop() {
      u32 start = millis();                 // Capture current time
      while (buttonDown()) delay(10);       // Wait for button up
      u32 pressTime = millis()-start;       // Compute how long the button was down
      if (pressTime > 500) {                // If over half second: Long click
        iProvideLight = !iProvideLight;     // Toggle my status
        if (iProvideLight) Net.offer('l');  // And update network advertising
        else Net.withhold('l');
      } else if (pressTime > 50)            // If >50ms and <500ms: Short click
        Net.printf('l',"t\n");              // So send toggle request to service 'l'

      // Set our LED
      ledOff(BODY_RGB_RED_PIN);
      ledOff(BODY_RGB_BLUE_PIN);
      if (iProvideLight) {
        if (ledRed) ledOn(BODY_RGB_RED_PIN);
        else ledOn(BODY_RGB_BLUE_PIN);
      }
    }