acid-drop

- Hacking the planet from a LilyGo T-Deck using custom firmware
git clone git://git.acid.vegas/acid-drop.git
Log | Files | Refs | Archive | README | LICENSE

WioWiFiAnalyzer.ino (9741B)

      1 /*
      2  * Wio WiFi Analyzer
      3  * Require Wio Terminal.
      4  * 
      5  * Libraries:
      6  * https://github.com/Seeed-Studio/Seeed_Arduino_FS/releases/tag/v2.0.2
      7  * https://github.com/Seeed-Studio/Seeed_Arduino_SFUD/releases/tag/v2.0.1
      8  * https://github.com/Seeed-Studio/Seeed_Arduino_mbedtls/archive/d1ca0175e24768120781bf4a43a1fb2c39fce85f.zip
      9  * https://github.com/Seeed-Studio/Seeed_Arduino_rpcUnified/releases/tag/v2.1.1
     10  * https://github.com/Seeed-Studio/Seeed_Arduino_rpcWiFi/releases/tag/v1.0.2
     11  * 
     12  * Firmware:
     13  * https://github.com/Seeed-Studio/seeed-ambd-firmware/releases/tag/v2.1.1
     14  */
     15 
     16 #define SCAN_INTERVAL 1000
     17 
     18 #include <Arduino_GFX_Library.h>
     19 
     20 #define GFX_BL DF_GFX_BL // default backlight pin, you may replace DF_GFX_BL to actual backlight pin
     21 
     22 Arduino_GFX *gfx = create_default_Arduino_GFX();
     23 
     24 #include "rpcWiFi.h"
     25 
     26 int16_t w, h, text_size, banner_height, graph24_baseline, graph50_baseline, graph_baseline, graph_height, channel24_width, channel50_width, channel_width, signal_width;
     27 
     28 // RSSI RANGE
     29 #define RSSI_CEILING -40
     30 #define RSSI_FLOOR -100
     31 
     32 // Channel legend mapping
     33 uint16_t channel_legend[] = {
     34     1, 2, 3, 4, 5, 6, 7,      //  1,  2,  3,  4,  5,  6,  7,
     35     8, 9, 10, 11, 12, 13, 14, //  8,  9, 10, 11, 12, 13, 14,
     36     32, 0, 0, 0, 40, 0, 0,    // 32, 34, 36, 38, 40, 42, 44,
     37     0, 48, 0, 0, 0, 56, 0,    // 46, 48, 50, 52, 54, 56, 58,
     38     0, 0, 64, 0, 0, 0,        // 60, 62, 64, 68,N/A, 96,
     39     100, 0, 0, 0, 108, 0, 0,  //100,102,104,106,108,110,112,
     40     0, 116, 0, 0, 0, 124, 0,  //114,116,118,120,122,124,126,
     41     0, 0, 132, 0, 0, 0, 140,  //128,N/A,132,134,136,138,140,
     42     0, 0, 0, 149, 0, 0, 0,    //142,144,N/A,149,151,153,155,
     43     157, 0, 0, 0, 165, 0, 0,  //157,159,161,163,165,167,169,
     44     0, 173};                  //171,173
     45 
     46 // Channel color mapping
     47 uint16_t channel_color[] = {
     48     RED, ORANGE, YELLOW, GREEN, CYAN, BLUE, MAGENTA,
     49     RED, ORANGE, YELLOW, GREEN, CYAN, BLUE, MAGENTA,
     50     RED, ORANGE, YELLOW, GREEN, CYAN, BLUE, MAGENTA,
     51     RED, ORANGE, YELLOW, GREEN, CYAN, BLUE, MAGENTA,
     52     RED, ORANGE, YELLOW, GREEN, WHITE, MAGENTA,
     53     RED, ORANGE, YELLOW, GREEN, CYAN, BLUE, MAGENTA,
     54     RED, ORANGE, YELLOW, GREEN, CYAN, BLUE, MAGENTA,
     55     RED, ORANGE, YELLOW, GREEN, CYAN, BLUE, MAGENTA,
     56     RED, ORANGE, YELLOW, GREEN, CYAN, BLUE, MAGENTA,
     57     RED, ORANGE, YELLOW, GREEN, CYAN, BLUE, MAGENTA,
     58     RED, ORANGE};
     59 
     60 uint8_t scan_count = 0;
     61 
     62 uint16_t channelIdx(int channel)
     63 {
     64   if (channel <= 14) // 2.4 GHz, channel 1-14
     65   {
     66     return channel - 1;
     67   }
     68   if (channel <= 64) // 5 GHz, channel 32 - 64
     69   {
     70     return 14 + ((channel - 32) / 2);
     71   }
     72   if (channel == 68)
     73   {
     74     return 31;
     75   }
     76   if (channel == 96)
     77   {
     78     return 33;
     79   }
     80   if (channel <= 144)
     81   {
     82     return 34 + ((channel - 100) / 2); // channe;
     83   }
     84   return 58 + ((channel - 149) / 2);
     85 }
     86 
     87 void setup()
     88 {
     89   // Set WiFi to station mode and disconnect from an AP if it was previously connected
     90   WiFi.mode(WIFI_STA);
     91   WiFi.disconnect();
     92   delay(100);
     93 
     94 #if defined(LCD_PWR_PIN)
     95   pinMode(LCD_PWR_PIN, OUTPUT);    // sets the pin as output
     96   digitalWrite(LCD_PWR_PIN, HIGH); // power on
     97 #endif
     98 
     99 #ifdef GFX_BL
    100     pinMode(GFX_BL, OUTPUT);
    101     digitalWrite(GFX_BL, HIGH);
    102 #endif
    103 
    104   // init LCD
    105   gfx->begin();
    106   w = gfx->width();
    107   h = gfx->height();
    108   text_size = (h < 200) ? 1 : 2;
    109   banner_height = (text_size * 8) + 4;
    110   graph_height = ((gfx->height() - banner_height) / 2) - 30;
    111   graph24_baseline = banner_height + graph_height + 10;
    112   graph50_baseline = graph24_baseline + graph_height + 30;
    113   channel24_width = w / 17;
    114   channel50_width = w / 62;
    115 
    116   // init banner
    117   gfx->setTextSize(text_size);
    118   gfx->fillScreen(BLACK);
    119   gfx->setTextColor(BLUE);
    120   gfx->setCursor(2, 2);
    121   gfx->print("Wio");
    122   gfx->setTextColor(WHITE);
    123   gfx->print(" WiFi Analyzer");
    124 }
    125 
    126 void loop()
    127 {
    128   uint8_t ap_count_list[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    129   int32_t peak_list[] = {RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR, RSSI_FLOOR};
    130   int16_t peak_id_list[] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
    131   int32_t channel;
    132   uint16_t idx;
    133   int32_t rssi;
    134   String ssid;
    135   uint16_t color;
    136   int16_t height, offset, text_width;
    137 
    138   // WiFi.scanNetworks will return the number of networks found
    139   int n = WiFi.scanNetworks(false /* async */, true /* show_hidden */, true /* passive */, 500 /* max_ms_per_chan */);
    140 
    141   // clear old graph
    142   gfx->fillRect(0, banner_height, w, h - banner_height, BLACK);
    143   gfx->setTextSize(1);
    144 
    145   if (n == 0)
    146   {
    147     gfx->setTextColor(WHITE);
    148     gfx->setCursor(0, banner_height);
    149     gfx->println("No networks found");
    150   }
    151   else
    152   {
    153     for (int i = 0; i < n; i++)
    154     {
    155       channel = WiFi.channel(i);
    156       idx = channelIdx(channel);
    157       rssi = WiFi.RSSI(i);
    158 
    159       // channel peak stat
    160       if (peak_list[idx] < rssi)
    161       {
    162         peak_list[idx] = rssi;
    163         peak_id_list[idx] = i;
    164       }
    165 
    166       ap_count_list[idx]++;
    167     }
    168 
    169     // plot found WiFi info
    170     for (int i = 0; i < n; i++)
    171     {
    172       channel = WiFi.channel(i);
    173       idx = channelIdx(channel);
    174       rssi = WiFi.RSSI(i);
    175       color = channel_color[idx];
    176       height = constrain(map(rssi, RSSI_FLOOR, RSSI_CEILING, 1, graph_height), 1, graph_height);
    177       if (idx < 14)
    178       {
    179         graph_baseline = graph24_baseline;
    180         channel_width = channel24_width;
    181         signal_width = channel24_width * 2;
    182         offset = (idx + 2) * channel24_width;
    183       }
    184       else
    185       {
    186         graph_baseline = graph50_baseline;
    187         channel_width = channel50_width;
    188         signal_width = channel50_width * 2;
    189         offset = (idx - 14 + 2) * channel50_width;
    190       }
    191 
    192       // trim rssi with RSSI_FLOOR
    193       if (rssi < RSSI_FLOOR)
    194       {
    195         rssi = RSSI_FLOOR;
    196       }
    197 
    198       // plot chart
    199       // gfx->drawLine(offset, graph_baseline - height, offset - signal_width, graph_baseline + 1, color);
    200       // gfx->drawLine(offset, graph_baseline - height, offset + signal_width, graph_baseline + 1, color);
    201       gfx->startWrite();
    202       gfx->drawEllipseHelper(offset, graph_baseline + 1, signal_width, height, 0b0011, color);
    203       gfx->endWrite();
    204 
    205       if (i == peak_id_list[idx])
    206       {
    207         // Print SSID, signal strengh and if not encrypted
    208         String ssid = WiFi.SSID(i);
    209         if (ssid.length() == 0)
    210         {
    211           ssid = WiFi.BSSIDstr(i);
    212         }
    213         text_width = (ssid.length() + 6) * 6;
    214         if (text_width > w)
    215         {
    216           offset = 0;
    217         }
    218         else
    219         {
    220           if ((offset + text_width) > w)
    221           {
    222             offset = w - text_width;
    223           }
    224         }
    225         gfx->setTextColor(color);
    226         gfx->setCursor(offset, graph_baseline - 10 - height);
    227         gfx->print(ssid);
    228         gfx->print('(');
    229         gfx->print(rssi);
    230         gfx->print(')');
    231         if (WiFi.encryptionType(i) == WIFI_AUTH_OPEN)
    232         {
    233           gfx->print('*');
    234         }
    235       }
    236     }
    237   }
    238 
    239   // print WiFi found
    240   gfx->setTextColor(WHITE);
    241   gfx->setCursor(2, banner_height);
    242   gfx->print(n);
    243   gfx->print(" networks");
    244 
    245   // draw 2.4 GHz graph base axle
    246   gfx->drawFastHLine(0, graph24_baseline, 320, WHITE);
    247   for (idx = 0; idx < 14; idx++)
    248   {
    249     channel = channel_legend[idx];
    250     offset = (idx + 2) * channel24_width;
    251     if (channel > 0)
    252     {
    253       gfx->setTextColor(channel_color[idx]);
    254       gfx->setCursor(offset - ((channel < 10) ? 3 : 6), graph24_baseline + 2);
    255       gfx->print(channel);
    256     }
    257     if (ap_count_list[idx] > 0)
    258     {
    259       gfx->setTextColor(DARKGREY);
    260       gfx->setCursor(offset - ((ap_count_list[idx] < 10) ? 3 : 6), graph24_baseline + 8 + 2);
    261       gfx->print(ap_count_list[idx]);
    262     }
    263   }
    264 
    265   // draw 5 GHz graph base axle
    266   gfx->drawFastHLine(0, graph50_baseline, 320, WHITE);
    267   for (idx = 14; idx < 71; idx++)
    268   {
    269     channel = channel_legend[idx];
    270     offset = (idx - 14 + 2) * channel50_width;
    271     if (channel > 0)
    272     {
    273       gfx->setTextColor(channel_color[idx]);
    274       gfx->setCursor(offset - ((channel < 100) ? 6 : 9), graph50_baseline + 2);
    275       gfx->print(channel);
    276     }
    277     if (ap_count_list[idx] > 0)
    278     {
    279       gfx->setTextColor(DARKGREY);
    280       gfx->setCursor(offset - ((ap_count_list[idx] < 10) ? 3 : 6), graph50_baseline + 8 + 2);
    281       gfx->print(ap_count_list[idx]);
    282     }
    283   }
    284 
    285   // Wait a bit before scanning again
    286   delay(SCAN_INTERVAL);
    287 
    288 #if defined(SCAN_COUNT_SLEEP)
    289   //POWER SAVING
    290   if (++scan_count >= SCAN_COUNT_SLEEP)
    291   {
    292 #if defined(LCD_PWR_PIN)
    293     pinMode(LCD_PWR_PIN, INPUT); // disable pin
    294 #endif
    295 #if defined(GFX_BL)
    296     pinMode(GFX_BL, INPUT); // disable pin
    297 #endif
    298   }
    299 #endif // defined(SCAN_COUNT_SLEEP)
    300 }