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

RTLWiFiAnalyzerUTF8.ino (11060B)

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