diff --git a/esp32_marauder/CommandLine.cpp b/esp32_marauder/CommandLine.cpp index 92e89e6..3d1b83b 100644 --- a/esp32_marauder/CommandLine.cpp +++ b/esp32_marauder/CommandLine.cpp @@ -196,15 +196,17 @@ void CommandLine::filterAccessPoints(String filter) { } void CommandLine::runCommand(String input) { - if (input != "") - Serial.println("#" + input); + if (input == "") return; + + if(wifi_scan_obj.scanning() && wifi_scan_obj.currentScanMode == WIFI_SCAN_GPS_NMEA){ + if(input != STOPSCAN_CMD) return; + } else - return; + Serial.println("#" + input); LinkedList cmd_args = this->parseCommand(input, " "); - + //// Admin commands - // Help if (cmd_args.get(0) == HELP_CMD) { Serial.println(HELP_HEAD); @@ -217,6 +219,7 @@ void CommandLine::runCommand(String input) { Serial.println(HELP_LED_CMD); Serial.println(HELP_GPS_DATA_CMD); Serial.println(HELP_GPS_CMD); + Serial.println(HELP_NMEA_CMD); // WiFi sniff/scan Serial.println(HELP_EVIL_PORTAL_CMD); @@ -273,9 +276,20 @@ void CommandLine::runCommand(String input) { // return; //} + uint8_t old_scan_mode=wifi_scan_obj.currentScanMode; + wifi_scan_obj.StartScan(WIFI_SCAN_OFF); - Serial.println("Stopping WiFi tran/recv"); + #ifdef HAS_GPS + gps_obj.disable_queue(); + #endif + + if(old_scan_mode == WIFI_SCAN_GPS_NMEA) + Serial.println("END OF NMEA STREAM"); + else if(old_scan_mode == WIFI_SCAN_GPS_DATA) + Serial.println("Stopping GPS data updates"); + else + Serial.println("Stopping WiFi tran/recv"); // If we don't do this, the text and button coordinates will be off #ifdef HAS_SCREEN @@ -299,6 +313,7 @@ void CommandLine::runCommand(String input) { #ifdef HAS_GPS if (gps_obj.getGpsModuleStatus()) { int get_arg = this->argSearch(&cmd_args, "-g"); + int nmea_arg = this->argSearch(&cmd_args, "-n"); if (get_arg != -1) { String gps_info = cmd_args.get(get_arg + 1); @@ -313,11 +328,46 @@ void CommandLine::runCommand(String input) { Serial.println("Lon: " + gps_obj.getLon()); else if (gps_info == "alt") Serial.println("Alt: " + (String)gps_obj.getAlt()); + else if (gps_info == "accuracy") + Serial.println("Accuracy: " + (String)gps_obj.getAccuracy()); else if (gps_info == "date") Serial.println("Date/Time: " + gps_obj.getDatetime()); + else if (gps_info == "nmea"){ + int notimp_arg = this->argSearch(&cmd_args, "-p"); + int recd_arg = this->argSearch(&cmd_args, "-r"); + if(notimp_arg == -1 && recd_arg == -1){ + gps_obj.sendSentence(Serial, gps_obj.generateGXgga()); + gps_obj.sendSentence(Serial, gps_obj.generateGXrmc()); + } + else if(notimp_arg == -1) + Serial.println(gps_obj.getNmea()); + else + Serial.println(gps_obj.getNmeaNotimp()); + } else Serial.println("You did not provide a valid argument"); } + else if(nmea_arg != -1){ + String nmea_type = cmd_args.get(nmea_arg + 1); + + if (nmea_type == "all" || nmea_type == "gps" || nmea_type == "glonass" || nmea_type== "galileo") + gps_obj.setType(nmea_type); + else + Serial.println("You did not provide a valid argument"); + } + else if(cmd_args.size()>0) + Serial.println("You did not provide a valid flag"); + else + Serial.println("You did not provide an argument"); + } + #endif + } + else if (cmd_args.get(0) == NMEA_CMD) { + #ifdef HAS_GPS + if (gps_obj.getGpsModuleStatus()) { + gps_obj.enable_queue(); + wifi_scan_obj.currentScanMode = WIFI_SCAN_GPS_NMEA; + wifi_scan_obj.StartScan(WIFI_SCAN_GPS_NMEA, TFT_CYAN); } #endif } diff --git a/esp32_marauder/CommandLine.h b/esp32_marauder/CommandLine.h index c1023b5..5c12c70 100644 --- a/esp32_marauder/CommandLine.h +++ b/esp32_marauder/CommandLine.h @@ -47,6 +47,7 @@ const char PROGMEM LS_CMD[] = "ls"; const char PROGMEM LED_CMD[] = "led"; const char PROGMEM GPS_DATA_CMD[] = "gpsdata"; const char PROGMEM GPS_CMD[] = "gps"; +const char PROGMEM NMEA_CMD[] = "nmea"; // WiFi sniff/scan const char PROGMEM EVIL_PORTAL_CMD[] = "evilportal"; @@ -95,7 +96,8 @@ const char PROGMEM HELP_SETTINGS_CMD[] = "settings [-s enable/disable> const char PROGMEM HELP_LS_CMD[] = "ls "; const char PROGMEM HELP_LED_CMD[] = "led -s /-p "; const char PROGMEM HELP_GPS_DATA_CMD[] = "gpsdata"; -const char PROGMEM HELP_GPS_CMD[] = "gps [-g] "; +const char PROGMEM HELP_GPS_CMD[] = "gps [-g] "; +const char PROGMEM HELP_NMEA_CMD[] = "nmea"; // WiFi sniff/scan const char PROGMEM HELP_EVIL_PORTAL_CMD[] = "evilportal [-c start [-w html.html]/sethtml ]"; diff --git a/esp32_marauder/GpsInterface.cpp b/esp32_marauder/GpsInterface.cpp index ab6153c..f1c0c6a 100644 --- a/esp32_marauder/GpsInterface.cpp +++ b/esp32_marauder/GpsInterface.cpp @@ -2,6 +2,8 @@ #ifdef HAS_GPS +extern GpsInterface gps_obj; + char nmeaBuffer[100]; MicroNMEA nmea(nmeaBuffer, sizeof(nmeaBuffer)); @@ -33,6 +35,170 @@ void GpsInterface::begin() { while (Serial2.available()) Serial2.read(); } + + this->queue_enabled_flag=0; + this->queue=NULL; + this->new_queue(); + + nmea.setUnknownSentenceHandler(gps_nmea_notimp); +} + +//passthrough for other objects +void gps_nmea_notimp(MicroNMEA& nmea){ + gps_obj.enqueue(nmea); +} + +void GpsInterface::enqueue(MicroNMEA& nmea){ + String nmea_sentence = String(nmea.getSentence()); + + if(nmea_sentence != ""){ + this->notimp_nmea_sentence = nmea_sentence; + + if(this->queue_enabled_flag){ + if(!this->queue) this->new_queue(); + this->queue->add(String(nmea_sentence)); + } + } +} + +void GpsInterface::enable_queue(){ + this->flush_queue(); + this->queue_enabled_flag=1; +} + +void GpsInterface::disable_queue(){ + this->queue_enabled_flag=0; + this->flush_queue(); +} + +bool GpsInterface::queue_enabled(){ + return this->queue_enabled_flag; +} + +LinkedList* GpsInterface::get_queue(){ + return this->queue; +} + +void GpsInterface::new_queue(){ + this->queue=new LinkedList; +} + +void GpsInterface::flush_queue(){ + if(this->queue) delete this->queue; + this->new_queue(); +} + +void GpsInterface::sendSentence(const char* sentence){ + MicroNMEA::sendSentence(Serial2, sentence); +} + +void GpsInterface::sendSentence(Stream &s, const char* sentence){ + MicroNMEA::sendSentence(s, sentence); +} + +void GpsInterface::setType(String t){ + if(t == "gps") + this->type_flag=GPSTYPE_GPS; + else if(t == "glonass") + this->type_flag=GPSTYPE_GLONASS; + else if(t == "galileo") + this->type_flag=GPSTYPE_GALILEO; + else + this->type_flag=GPSTYPE_ALL; +} + +const char* GpsInterface::generateGXgga(){ + String msg_type="$G"; + if(this->type_flag == GPSTYPE_GPS) + msg_type+='P'; + else if(this->type_flag == GPSTYPE_GLONASS) + msg_type+='L'; + else if(this->type_flag == GPSTYPE_GALILEO) + msg_type+='A'; + else + msg_type+='N'; + msg_type+="GGA,"; + + char timeStr[8]; + sprintf(timeStr, "%02d%02d%02d,", (int)(nmea.getHour()), (int)(nmea.getMinute()), (int)(nmea.getSecond())); + + long lat = nmea.getLatitude(); + char latDir = lat < 0 ? 'S' : 'N'; + lat = abs(lat); + char latStr[12]; + sprintf(latStr, "%02ld%08.5f,", lat / 1000000, ((lat % 1000000)*60) / 1000000.0); + + long lon = nmea.getLongitude(); + char lonDir = lon < 0 ? 'W' : 'E'; + lon = abs(lon); + char lonStr[13]; + sprintf(lonStr, "%03ld%08.5f,", lon / 1000000, ((lon % 1000000)*60) / 1000000.0); + + int fixQuality = nmea.isValid() ? 1 : 0; + char fixStr[3]; + sprintf(fixStr, "%01d,", fixQuality); + + int numSatellites = nmea.getNumSatellites(); + char satStr[4]; + sprintf(satStr, "%02d,", numSatellites); + + unsigned long hdop = nmea.getHDOP(); + char hdopStr[14]; + sprintf(hdopStr, "%01.2f,", 2.5 * (((float)(hdop))/10)); + + long altitude; + if(!nmea.getAltitude(altitude)) altitude=0; + char altStr[14]; + sprintf(altStr, "%01.1f,", altitude/1000.0); + + String message = msg_type + timeStr + latStr + latDir + "," + lonStr + lonDir + + "," + fixStr + satStr + hdopStr + altStr + "M,,M,,"; + + return message.c_str(); +} + +const char* GpsInterface::generateGXrmc(){ + String msg_type="$G"; + if(this->type_flag == GPSTYPE_GPS) + msg_type+='P'; + else if(this->type_flag == GPSTYPE_GLONASS) + msg_type+='L'; + else if(this->type_flag == GPSTYPE_GALILEO) + msg_type+='A'; + else + msg_type+='N'; + msg_type+="RMC,"; + + char timeStr[8]; + sprintf(timeStr, "%02d%02d%02d,", (int)(nmea.getHour()), (int)(nmea.getMinute()), (int)(nmea.getSecond())); + + char dateStr[8]; + sprintf(dateStr, "%02d%02d%02d,", (int)(nmea.getDay()), (int)(nmea.getMonth()), (int)(nmea.getYear()%100)); + + char status = nmea.isValid() ? 'A' : 'V'; + char mode = nmea.isValid() ? 'A' : 'N'; + + long lat = nmea.getLatitude(); + char latDir = lat < 0 ? 'S' : 'N'; + lat = abs(lat); + char latStr[12]; + sprintf(latStr, "%02ld%08.5f,", lat / 1000000, ((lat % 1000000)*60) / 1000000.0); + + long lon = nmea.getLongitude(); + char lonDir = lon < 0 ? 'W' : 'E'; + lon = abs(lon); + char lonStr[13]; + sprintf(lonStr, "%03ld%08.5f,", lon / 1000000, ((lon % 1000000)*60) / 1000000.0); + + char speedStr[14]; + sprintf(speedStr, "%01.1f,", nmea.getSpeed() / 1000.0); + + char courseStr[14]; + sprintf(courseStr, "%01.1f,", nmea.getCourse() / 1000.0); + + String message = msg_type + timeStr + status + "," + latStr + latDir + "," + + lonStr + lonDir + "," + speedStr + courseStr + dateStr + ",," + mode; + return message.c_str(); } // Thanks JosephHewitt @@ -56,6 +222,9 @@ String GpsInterface::dt_string_from_gps(){ } void GpsInterface::setGPSInfo() { + String nmea_sentence = String(nmea.getSentence()); + if(nmea_sentence != "") this->nmea_sentence = nmea_sentence; + this->good_fix = nmea.isValid(); this->num_sats = nmea.getNumSatellites(); @@ -113,6 +282,14 @@ bool GpsInterface::getGpsModuleStatus() { return this->gps_enabled; } +String GpsInterface::getNmea() { + return this->nmea_sentence; +} + +String GpsInterface::getNmeaNotimp() { + return this->notimp_nmea_sentence; +} + void GpsInterface::main() { while (Serial2.available()) { //Fetch the character one by one diff --git a/esp32_marauder/GpsInterface.h b/esp32_marauder/GpsInterface.h index 7f7a935..b11ef05 100644 --- a/esp32_marauder/GpsInterface.h +++ b/esp32_marauder/GpsInterface.h @@ -6,6 +6,8 @@ #include "configs.h" +void gps_nmea_notimp(MicroNMEA& nmea); + class GpsInterface { public: void begin(); @@ -20,9 +22,36 @@ class GpsInterface { float getAlt(); float getAccuracy(); String getDatetime(); + String getNmea(); + String getNmeaNotimp(); + + void setType(String t); + + void enqueue(MicroNMEA& nmea); + LinkedList* get_queue(); + void flush_queue(); + void new_queue(); + void enable_queue(); + void disable_queue(); + bool queue_enabled(); + + void sendSentence(const char* sentence); + void sendSentence(Stream &s, const char* sentence); + + const char* generateGXgga(); + const char* generateGXrmc(); + + enum type_t { + GPSTYPE_ALL, + GPSTYPE_GPS, + GPSTYPE_GLONASS, + GPSTYPE_GALILEO + }; private: // GPS Info + String nmea_sentence = ""; + String notimp_nmea_sentence = ""; String lat = ""; String lon = ""; float altf = 0.0; @@ -33,6 +62,11 @@ class GpsInterface { bool good_fix = false; uint8_t num_sats = 0; + type_t type_flag = GPSTYPE_ALL; + + bool queue_enabled_flag=0; + LinkedList *queue=NULL; + String dt_string_from_gps(); void setGPSInfo(); }; diff --git a/esp32_marauder/WiFiScan.cpp b/esp32_marauder/WiFiScan.cpp index abbb234..5f18cbc 100644 --- a/esp32_marauder/WiFiScan.cpp +++ b/esp32_marauder/WiFiScan.cpp @@ -1097,6 +1097,38 @@ void WiFiScan::RunGPSInfo() { #endif } +void WiFiScan::RunGPSNmea() { + #ifdef HAS_GPS + LinkedList *buffer=gps_obj.get_queue(); + + static String old_nmea_sentence=""; + if(buffer && gps_obj.queue_enabled()){ + gps_obj.new_queue(); + int size=buffer->size(); + for(int i=0;iget(i)); + } + delete buffer; + } else { + if(buffer){ + if(buffer->size()>0) gps_obj.flush_queue(); + } else { + gps_obj.new_queue(); + } + + String nmea_sentence=gps_obj.getNmeaNotimp(); + if(nmea_sentence != "" && nmea_sentence != old_nmea_sentence){ + old_nmea_sentence=nmea_sentence; + Serial.println(nmea_sentence); + } + } + + gps_obj.sendSentence(Serial, gps_obj.generateGXgga()); + gps_obj.sendSentence(Serial, gps_obj.generateGXrmc()); + + #endif +} + void WiFiScan::RunInfo() { String sta_mac = this->getStaMAC(); @@ -4308,6 +4340,12 @@ void WiFiScan::main(uint32_t currentTime) this->RunGPSInfo(); } } + else if (currentScanMode == WIFI_SCAN_GPS_NMEA) { + if (currentTime - initTime >= 1000) { + this->initTime = millis(); + this->RunGPSNmea(); + } + } else if (currentScanMode == WIFI_SCAN_EVIL_PORTAL) { evil_portal_obj.main(currentScanMode); } diff --git a/esp32_marauder/WiFiScan.h b/esp32_marauder/WiFiScan.h index 46f076a..420ca53 100644 --- a/esp32_marauder/WiFiScan.h +++ b/esp32_marauder/WiFiScan.h @@ -86,6 +86,7 @@ #define BT_ATTACK_SOUR_APPLE 36 #define BT_ATTACK_SWIFTPAIR_SPAM 37 #define BT_ATTACK_SPAM_ALL 38 +#define WIFI_SCAN_GPS_NMEA 39 #define GRAPH_REFRESH 100 @@ -281,6 +282,7 @@ class WiFiScan void broadcastSetSSID(uint32_t current_time, const char* ESSID); void RunAPScan(uint8_t scan_mode, uint16_t color); void RunGPSInfo(); + void RunGPSNmea(); void RunMimicFlood(uint8_t scan_mode, uint16_t color); void RunPwnScan(uint8_t scan_mode, uint16_t color); void RunBeaconScan(uint8_t scan_mode, uint16_t color);