| 1627 | } |
| 1628 | |
| 1629 | void updateSSIDFrequency(const String &ssid) { |
| 1630 | if (ssid.isEmpty() || ssid == "*WILDCARD*") return; |
| 1631 | auto it = ssidFrequency.find(ssid); |
| 1632 | if (it != ssidFrequency.end()) { |
| 1633 | it->second++; |
| 1634 | } else { |
| 1635 | if (ssidFrequency.size() >= MAX_POPULAR_SSIDS) return; |
| 1636 | ssidFrequency[ssid] = 1; |
| 1637 | } |
| 1638 | static unsigned long lastSort = 0; |
| 1639 | if (millis() - lastSort > 5000) { |
| 1640 | lastSort = millis(); |
| 1641 | popularSSIDs.clear(); |
| 1642 | for (const auto &pair : ssidFrequency) { |
| 1643 | popularSSIDs.push_back(std::make_pair(pair.first, pair.second)); |
| 1644 | if (popularSSIDs.size() >= MAX_POPULAR_SSIDS) break; |
| 1645 | } |
| 1646 | std::sort(popularSSIDs.begin(), popularSSIDs.end(), [](const auto &a, const auto &b) { |
| 1647 | return a.second > b.second; |
| 1648 | }); |
| 1649 | } |
| 1650 | } |
| 1651 | |
| 1652 | void checkCloneAttackOpportunities() { |
| 1653 | if (!attackConfig.enableCloneMode || popularSSIDs.empty()) return; |