/* This software is licensed under the MIT License: https://github.com/BlackTechX011/DeautherX */ #include "Stations.h" Stations::Stations() { list = new SimpleList(); } void Stations::add(uint8_t* mac, int accesspointNum) { int stationNum = findStation(mac); if (stationNum < 0) { internal_add(mac, accesspointNum); // print(list->size() - 1, list->size() == 1, false); } else { *getPkts(stationNum) += 1; *getTime(stationNum) = currentTime; } changed = true; } int Stations::findStation(uint8_t* mac) { int c = count(); for (int i = 0; i < c; i++) { if (memcmp(getMac(i), mac, 6) == 0) return i; } return -1; } void Stations::sort() { list->setCompare([](Station& a, Station& b) -> int { if (*(a.pkts) > *(b.pkts)) return -1; if (*(a.pkts) == *(b.pkts)) return 0; return 1; }); list->sort(); } void Stations::sortAfterChannel() { list->setCompare([](Station& a, Station& b) -> int { if (a.ch < b.ch) return -1; if (a.ch == b.ch) return 0; return 1; }); list->sort(); } void Stations::removeAll() { internal_removeAll(); prntln(ST_CLEARED_LIST); changed = true; } void Stations::removeOldest() { int oldest = 0; int c = count(); for (int i = 1; i < c; i++) { if (*getTime(i) > *getTime(oldest)) oldest = i; } internal_remove(oldest); changed = true; } void Stations::printAll() { prntln(ST_HEADER); int c = count(); if (c == 0) prntln(ST_LIST_EMPTY); else for (int i = 0; i < c; i++) print(i, i == 0, i == c - 1); } void Stations::printSelected() { prntln(ST_HEADER); int max = selected(); int c = count(); if (max == 0) { prntln(ST_NO_DEVICES_SELECTED); return; } for (int i = 0, j = 0; i < c && j < max; i++) { if (getSelected(i)) { print(i, j == 0, j == max - 1); j++; } } } void Stations::print(int num) { print(num, true, true); } void Stations::print(int num, bool header, bool footer) { if (!check(num)) return; if (header) { prntln(ST_TABLE_HEADER); prntln(ST_TABLE_DIVIDER); } prnt(leftRight(String(), (String)num, 2)); prnt(leftRight(String(SPACE) + getMacStr(num), String(), 18)); prnt(leftRight(String(SPACE), (String)getCh(num), 3)); prnt(leftRight(String(SPACE) + getNameStr(num), String(), 17)); prnt(leftRight(String(SPACE) + getVendorStr(num), String(), 9)); prnt(leftRight(String(SPACE), (String) * getPkts(num), 9)); prnt(leftRight(String(SPACE) + getAPStr(num), String(), 33)); prnt(leftRight(String(SPACE) + getTimeStr(num), String(), 10)); prntln(leftRight(String(SPACE) + getSelectedStr(num), String(), 9)); if (footer) prntln(ST_TABLE_DIVIDER); } String Stations::getAPStr(int num) { if (getAP(num) < 0) return String(); return accesspoints.getSSID(getAP(num)); } uint8_t* Stations::getAPMac(int num) { if (!check(num)) return 0; return WiFi.BSSID(list->get(num).ap); } String Stations::getAPMacStr(int num) { if (!check(num)) return String(); uint8_t* mac = getAPMac(num); return bytesToStr(mac, 6); } int Stations::getAP(int num) { if (!check(num)) return -1; return accesspoints.find(list->get(num).ap); } String Stations::getNameStr(int num) { if (!check(num)) return String(); return names.find(getMac(num)); } bool Stations::hasName(int num) { if (!check(num)) return false; return names.findID(getMac(num)) >= 0; } uint8_t* Stations::getMac(int num) { if (!check(num)) return 0; return list->get(num).mac; } String Stations::getMacStr(int num) { if (!check(num)) return String(); uint8_t* mac = getMac(num); return bytesToStr(mac, 6); } String Stations::getMacVendorStr(int num) { String value; if (check(num)) { value = getVendorStr(num) + ":"; uint8_t* mac = getMac(num); for (int i = 3; i < 6; i++) { if (mac[i] < 0x10) value += "0"; value += String(mac[i], HEX); if (i < 5) value += ":"; } } return value; } String Stations::getVendorStr(int num) { if (!check(num)) return String(); return searchVendor(list->get(num).mac); } String Stations::getSelectedStr(int num) { return b2a(getSelected(num)); } uint32_t* Stations::getPkts(int num) { if (!check(num)) return NULL; return list->get(num).pkts; } uint32_t* Stations::getTime(int num) { if (!check(num)) return NULL; return list->get(num).time; } String Stations::getTimeStr(int num) { if (!check(num)) return String(); uint32_t difference = currentTime - *getTime(num); if (difference < 1000) return str(ST_SMALLER_ONESEC); else if (difference < 60000) return str(ST_SMALLER_ONEMIN); else { uint32_t minutes = difference / 60000; if (minutes > 60) return str(ST_BIGER_ONEHOUR); else return (String)minutes + str(STR_MIN); } } bool Stations::getSelected(int num) { if (!check(num)) return false; return list->get(num).selected; } uint8_t Stations::getCh(int num) { if (!check(num)) return 0; return list->get(num).ch; } void Stations::select(int num) { if (!check(num)) return; internal_select(num); prnt(ST_SELECTED_STATION); prntln(num); changed = true; } void Stations::deselect(int num) { if (!check(num)) return; internal_deselect(num); prnt(ST_DESELECTED_STATION); prntln(num); changed = true; } void Stations::remove(int num) { if (!check(num)) return; prnt(ST_REMOVED_STATION); prntln(num); internal_remove(num); changed = true; } void Stations::select(String ssid) { for (int i = 0; i < list->size(); i++) { if (getAPStr(i).equalsIgnoreCase(ssid)) select(i); } } void Stations::deselect(String ssid) { for (int i = 0; i < list->size(); i++) { if (getAPStr(i).equalsIgnoreCase(ssid)) deselect(i); } } void Stations::remove(String ssid) { for (int i = 0; i < list->size(); i++) { if (getAPStr(i).equalsIgnoreCase(ssid)) remove(i); } } void Stations::selectAll() { for (int i = 0; i < count(); i++) internal_select(i); prntln(ST_SELECTED_ALL); changed = true; } void Stations::deselectAll() { for (int i = 0; i < count(); i++) internal_deselect(i); prntln(ST_DESELECTED_ALL); changed = true; } int Stations::count() { return list->size(); } int Stations::selected() { int num = 0; for (int i = 0; i < count(); i++) if (getSelected(i)) num++; return num; } bool Stations::check(int num) { if (internal_check(num)) { return true; } else { prnt(ST_ERROR_ID); prntln(num); return false; } } bool Stations::internal_check(int num) { return num >= 0 && num < count(); } void Stations::internal_select(int num) { Station changedStation = list->get(num); changedStation.selected = true; list->replace(num, changedStation); } void Stations::internal_deselect(int num) { Station changedStation = list->get(num); changedStation.selected = false; list->replace(num, changedStation); } void Stations::internal_remove(int num) { free(getMac(num)); free(getPkts(num)); free(getTime(num)); list->remove(num); } void Stations::internal_add(uint8_t* mac, int accesspointNum) { if (count() >= STATION_LIST_SIZE) removeOldest(); Station newStation; newStation.ap = accesspointNum; newStation.ch = wifi_channel; newStation.mac = (uint8_t*)malloc(6); newStation.pkts = (uint32_t*)malloc(sizeof(uint32_t)); newStation.time = (uint32_t*)malloc(sizeof(uint32_t)); newStation.selected = false; memcpy(newStation.mac, mac, 6); *newStation.pkts = 1; *newStation.time = currentTime; list->add(newStation); } void Stations::internal_removeAll() { int c = count(); for (int i = 0; i < c; i++) { free(getMac(i)); free(getPkts(i)); free(getTime(i)); } list->clear(); }