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

RTLWiFiAnalyzer.ino (11115B)

      1 /*******************************************************************************
      2  * Rtl WiFi Analyzer
      3  * For RTL872x only.
      4  * 
      5  * Add realtek ameba core support to Arduino IDE:
      6  * https://github.com/ambiot/ambd_arduino
      7  * 
      8  * Old patch realtek ameba core variant.cpp to RTL8720DN pinout:
      9  * https://github.com/mikey60/BW16-RTL8720DN-Module-Arduino
     10  * 
     11  * Defalult pin list for non display dev kit:
     12  * RTL8720 BW16 old patch core : CS: 18, DC: 17, RST:  2, BL: 23
     13  * RTL8720_BW16 Official core  : CS:  9, DC:  8, RST:  6, BL:  3
     14  * RTL8722 dev board           : CS: 18, DC: 17, RST: 22, BL: 23
     15  * RTL8722_mini dev board      : CS: 12, DC: 14, RST: 15, BL: 13
     16  ******************************************************************************/
     17 
     18 #define SCAN_INTERVAL 3000
     19 
     20 #include <lwip_netconf.h>
     21 #include <wifi_conf.h>
     22 #include <wifi_constants.h>
     23 #include <wifi_structures.h>
     24 #include <wl_definitions.h>
     25 #include <wl_types.h>
     26 
     27 #include <Arduino_GFX_Library.h>
     28 
     29 #define GFX_BL DF_GFX_BL // default backlight pin, you may replace DF_GFX_BL to actual backlight pin
     30 
     31 Arduino_DataBus *bus = create_default_Arduino_DataBus();
     32 /* More display class: https://github.com/moononournation/Arduino_GFX/wiki/Display-Class */
     33 Arduino_GFX *gfx = new Arduino_ILI9341(bus, DF_GFX_RST, 3 /* rotation */, false /* IPS */);
     34 
     35 static int16_t w, h, text_size, banner_height, graph24_baseline, graph50_baseline, graph_baseline, graph_height, channel24_width, channel50_width, channel_width, signal_width;
     36 
     37 // RSSI RANGE
     38 #define RSSI_CEILING -40
     39 #define RSSI_FLOOR -100
     40 
     41 // Channel legend mapping
     42 static uint16_t channel_legend[] = {
     43     1, 2, 3, 4, 5, 6, 7,      //  1,  2,  3,  4,  5,  6,  7,
     44     8, 9, 10, 11, 12, 13, 14, //  8,  9, 10, 11, 12, 13, 14,
     45     32, 0, 0, 0, 40, 0, 0,    // 32, 34, 36, 38, 40, 42, 44,
     46     0, 48, 0, 0, 0, 56, 0,    // 46, 48, 50, 52, 54, 56, 58,
     47     0, 0, 64, 0, 0, 0,        // 60, 62, 64, 68,N/A, 96,
     48     100, 0, 0, 0, 108, 0, 0,  //100,102,104,106,108,110,112,
     49     0, 116, 0, 0, 0, 124, 0,  //114,116,118,120,122,124,126,
     50     0, 0, 132, 0, 0, 0, 140,  //128,N/A,132,134,136,138,140,
     51     0, 0, 0, 149, 0, 0, 0,    //142,144,N/A,149,151,153,155,
     52     157, 0, 0, 0, 165, 0, 0,  //157,159,161,163,165,167,169,
     53     0, 173};                  //171,173
     54 
     55 // Channel color mapping
     56 static uint16_t channel_color[] = {
     57     RED, ORANGE, YELLOW, GREEN, CYAN, BLUE, MAGENTA,
     58     RED, ORANGE, YELLOW, GREEN, CYAN, BLUE, MAGENTA,
     59     RED, ORANGE, YELLOW, GREEN, CYAN, BLUE, MAGENTA,
     60     RED, ORANGE, YELLOW, GREEN, CYAN, BLUE, MAGENTA,
     61     RED, ORANGE, YELLOW, GREEN, WHITE, MAGENTA,
     62     RED, ORANGE, YELLOW, GREEN, CYAN, BLUE, MAGENTA,
     63     RED, ORANGE, YELLOW, GREEN, CYAN, BLUE, MAGENTA,
     64     RED, ORANGE, YELLOW, GREEN, CYAN, BLUE, MAGENTA,
     65     RED, ORANGE, YELLOW, GREEN, CYAN, BLUE, MAGENTA,
     66     RED, ORANGE, YELLOW, GREEN, CYAN, BLUE, MAGENTA,
     67     RED, ORANGE};
     68 
     69 static uint16_t channelIdx(int channel)
     70 {
     71   if (channel <= 14) // 2.4 GHz, channel 1-14
     72   {
     73     return channel - 1;
     74   }
     75   if (channel <= 64) // 5 GHz, channel 32 - 64
     76   {
     77     return 14 + ((channel - 32) / 2);
     78   }
     79   if (channel == 68)
     80   {
     81     return 31;
     82   }
     83   if (channel == 96)
     84   {
     85     return 33;
     86   }
     87   if (channel <= 144) // channel 98 - 144
     88   {
     89     return 34 + ((channel - 100) / 2);
     90   }
     91   // channel 149 - 177
     92   return 58 + ((channel - 149) / 2);
     93 }
     94 
     95 static uint8_t _networkCount;
     96 static char _networkSsid[WL_NETWORKS_LIST_MAXNUM][WL_SSID_MAX_LENGTH];
     97 static int32_t _networkRssi[WL_NETWORKS_LIST_MAXNUM];
     98 static uint32_t _networkEncr[WL_NETWORKS_LIST_MAXNUM];
     99 static uint8_t _networkChannel[WL_NETWORKS_LIST_MAXNUM];
    100 static char _networkMac[WL_NETWORKS_LIST_MAXNUM][18];
    101 
    102 static rtw_result_t wifidrv_scan_result_handler(rtw_scan_handler_result_t *malloced_scan_result)
    103 {
    104   rtw_scan_result_t *record;
    105 
    106   if (malloced_scan_result->scan_complete != RTW_TRUE)
    107   {
    108     record = &malloced_scan_result->ap_details;
    109     record->SSID.val[record->SSID.len] = 0; /* Ensure the SSID is null terminated */
    110 
    111     if (_networkCount < WL_NETWORKS_LIST_MAXNUM)
    112     {
    113       strcpy(_networkSsid[_networkCount], (char *)record->SSID.val);
    114       _networkRssi[_networkCount] = record->signal_strength;
    115       _networkEncr[_networkCount] = record->security;
    116       _networkChannel[_networkCount] = record->channel;
    117       sprintf(_networkMac[_networkCount], "%02X:%02X:%02X:%02X:%02X:%02X",
    118         record->BSSID.octet[0], record->BSSID.octet[1], record->BSSID.octet[2],
    119         record->BSSID.octet[3], record->BSSID.octet[4], record->BSSID.octet[5]);
    120 
    121       _networkCount++;
    122     }
    123   }
    124 
    125   return RTW_SUCCESS;
    126 }
    127 
    128 static int8_t scanNetworks()
    129 {
    130   uint8_t attempts = 10;
    131 
    132   _networkCount = 0;
    133   if (wifi_scan_networks(wifidrv_scan_result_handler, NULL) != RTW_SUCCESS)
    134   {
    135     return WL_FAILURE;
    136   }
    137 
    138   do
    139   {
    140     delay(SCAN_INTERVAL);
    141   } while ((_networkCount == 0) && (--attempts > 0));
    142   return _networkCount;
    143 }
    144 
    145 void setup()
    146 {
    147   LwIP_Init();
    148   wifi_on(RTW_MODE_STA);
    149 
    150 #if defined(LCD_PWR_PIN)
    151   pinMode(LCD_PWR_PIN, OUTPUT);    // sets the pin as output
    152   digitalWrite(LCD_PWR_PIN, HIGH); // power on
    153 #endif
    154 
    155 #ifdef GFX_BL
    156     pinMode(GFX_BL, OUTPUT);
    157     digitalWrite(GFX_BL, HIGH);
    158 #endif
    159 
    160   // init LCD
    161   gfx->begin();
    162   w = gfx->width();
    163   h = gfx->height();
    164   text_size = (h < 200) ? 1 : 2;
    165   banner_height = (text_size * 8) + 4;
    166   graph_height = ((gfx->height() - banner_height) / 2) - 30;
    167   graph24_baseline = banner_height + graph_height + 10;
    168   graph50_baseline = graph24_baseline + graph_height + 30;
    169   channel24_width = w / 17;
    170   channel50_width = w / 62;
    171 
    172   // direct draw banner to output display
    173   gfx->setTextSize(text_size);
    174   gfx->fillScreen(BLACK);
    175   gfx->setTextColor(GREEN);
    176   gfx->setCursor(2, 2);
    177   gfx->print("RTL");
    178   gfx->setTextColor(WHITE);
    179   gfx->print(" WiFi Analyzer");
    180 }
    181 
    182 void loop()
    183 {
    184   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};
    185   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};
    186   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};
    187   int32_t channel;
    188   uint16_t idx;
    189   int32_t rssi;
    190   String ssid;
    191   uint16_t color;
    192   int16_t height, offset, text_width;
    193 
    194   int n = scanNetworks();
    195 
    196   // clear old graph
    197   gfx->fillRect(0, banner_height, w, h - banner_height, BLACK);
    198   gfx->setTextSize(1);
    199 
    200   if (n == 0)
    201   {
    202     gfx->setTextColor(WHITE);
    203     gfx->setCursor(0, banner_height);
    204     gfx->println("No networks found");
    205   }
    206   else
    207   {
    208     for (int i = 0; i < n; i++)
    209     {
    210       channel = _networkChannel[i];
    211       idx = channelIdx(channel);
    212       rssi = _networkRssi[i];
    213 
    214       // channel peak stat
    215       if (peak_list[idx] < rssi)
    216       {
    217         peak_list[idx] = rssi;
    218         peak_id_list[idx] = i;
    219       }
    220 
    221       ap_count_list[idx]++;
    222     }
    223 
    224     // plot found WiFi info
    225     for (int i = 0; i < n; i++)
    226     {
    227       channel = _networkChannel[i];
    228       idx = channelIdx(channel);
    229       rssi = _networkRssi[i];
    230       color = channel_color[idx];
    231       height = constrain(map(rssi, RSSI_FLOOR, RSSI_CEILING, 1, graph_height), 1, graph_height);
    232       if (idx < 14)
    233       {
    234         graph_baseline = graph24_baseline;
    235         channel_width = channel24_width;
    236         signal_width = channel24_width * 2;
    237         offset = (idx + 2) * channel24_width;
    238       }
    239       else
    240       {
    241         graph_baseline = graph50_baseline;
    242         channel_width = channel50_width;
    243         signal_width = channel50_width * 2;
    244         offset = (idx - 14 + 2) * channel50_width;
    245       }
    246 
    247       // trim rssi with RSSI_FLOOR
    248       if (rssi < RSSI_FLOOR)
    249       {
    250         rssi = RSSI_FLOOR;
    251       }
    252 
    253       // plot chart
    254       gfx->startWrite();
    255       gfx->drawEllipseHelper(offset, graph_baseline + 1, signal_width, height, 0b0011, color);
    256       gfx->endWrite();
    257 
    258       if (i == peak_id_list[idx])
    259       {
    260         // Print SSID, signal strengh and if not encrypted
    261         String ssid = _networkSsid[i];
    262         if (ssid.length() == 0)
    263         {
    264           ssid = _networkMac[i];
    265         }
    266         text_width = (ssid.length() + 6) * 6;
    267         if (text_width > w)
    268         {
    269           offset = 0;
    270         }
    271         else
    272         {
    273           offset -= signal_width;
    274           if ((offset + text_width) > w)
    275           {
    276             offset = w - text_width;
    277           }
    278         }
    279         gfx->setTextColor(color);
    280         gfx->setCursor(offset, graph_baseline - 10 - height);
    281         gfx->print(ssid);
    282         gfx->print('(');
    283         gfx->print(rssi);
    284         gfx->print(')');
    285         if (_networkEncr[i] == RTW_SECURITY_OPEN)
    286         {
    287           gfx->print('*');
    288         }
    289       }
    290     }
    291   }
    292 
    293   // print WiFi found
    294   gfx->setTextColor(WHITE);
    295   gfx->setCursor(2, banner_height);
    296   gfx->print(n);
    297   gfx->print(" networks");
    298 
    299   // draw 2.4 GHz graph base axle
    300   gfx->drawFastHLine(0, graph24_baseline, 320, WHITE);
    301   for (idx = 0; idx < 14; idx++)
    302   {
    303     channel = channel_legend[idx];
    304     offset = (idx + 2) * channel24_width;
    305     if (channel > 0)
    306     {
    307       gfx->setTextColor(channel_color[idx]);
    308       gfx->setCursor(offset - ((channel < 10) ? 3 : 6), graph24_baseline + 2);
    309       gfx->print(channel);
    310     }
    311     if (ap_count_list[idx] > 0)
    312     {
    313       gfx->setTextColor(LIGHTGREY);
    314       gfx->setCursor(offset - ((ap_count_list[idx] < 10) ? 3 : 6), graph24_baseline + 8 + 2);
    315       gfx->print(ap_count_list[idx]);
    316     }
    317   }
    318 
    319   // draw 5 GHz graph base axle
    320   gfx->drawFastHLine(0, graph50_baseline, 320, WHITE);
    321   for (idx = 14; idx < 71; idx++)
    322   {
    323     channel = channel_legend[idx];
    324     offset = (idx - 14 + 2) * channel50_width;
    325     if (channel > 0)
    326     {
    327       gfx->setTextColor(channel_color[idx]);
    328       gfx->setCursor(offset - ((channel < 100) ? 6 : 9), graph50_baseline + 2);
    329       gfx->print(channel);
    330     }
    331     if (ap_count_list[idx] > 0)
    332     {
    333       gfx->setTextColor(DARKGREY);
    334       gfx->setCursor(offset - ((ap_count_list[idx] < 10) ? 3 : 6), graph50_baseline + 8 + 2);
    335       gfx->print(ap_count_list[idx]);
    336     }
    337   }
    338 
    339   // Wait a bit before scanning again
    340   delay(SCAN_INTERVAL);
    341 }