Added NMEA passthrough for GPS attached to marauder to be available on serial port, such as to flipper apps that use UART GPS, as long as they do 115200.

This commit is contained in:
Kragg Malak
2023-11-26 11:26:18 -07:00
parent 7a79860b17
commit c4af8003de
6 changed files with 310 additions and 7 deletions

View File

@@ -196,15 +196,17 @@ void CommandLine::filterAccessPoints(String filter) {
} }
void CommandLine::runCommand(String input) { void CommandLine::runCommand(String input) {
if (input != "") if (input == "") return;
Serial.println("#" + input);
if(wifi_scan_obj.scanning() && wifi_scan_obj.currentScanMode == WIFI_SCAN_GPS_NMEA){
if(input != STOPSCAN_CMD) return;
}
else else
return; Serial.println("#" + input);
LinkedList<String> cmd_args = this->parseCommand(input, " "); LinkedList<String> cmd_args = this->parseCommand(input, " ");
//// Admin commands //// Admin commands
// Help // Help
if (cmd_args.get(0) == HELP_CMD) { if (cmd_args.get(0) == HELP_CMD) {
Serial.println(HELP_HEAD); Serial.println(HELP_HEAD);
@@ -217,6 +219,7 @@ void CommandLine::runCommand(String input) {
Serial.println(HELP_LED_CMD); Serial.println(HELP_LED_CMD);
Serial.println(HELP_GPS_DATA_CMD); Serial.println(HELP_GPS_DATA_CMD);
Serial.println(HELP_GPS_CMD); Serial.println(HELP_GPS_CMD);
Serial.println(HELP_NMEA_CMD);
// WiFi sniff/scan // WiFi sniff/scan
Serial.println(HELP_EVIL_PORTAL_CMD); Serial.println(HELP_EVIL_PORTAL_CMD);
@@ -273,8 +276,19 @@ void CommandLine::runCommand(String input) {
// return; // return;
//} //}
uint8_t old_scan_mode=wifi_scan_obj.currentScanMode;
wifi_scan_obj.StartScan(WIFI_SCAN_OFF); wifi_scan_obj.StartScan(WIFI_SCAN_OFF);
#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"); Serial.println("Stopping WiFi tran/recv");
// If we don't do this, the text and button coordinates will be off // If we don't do this, the text and button coordinates will be off
@@ -299,6 +313,7 @@ void CommandLine::runCommand(String input) {
#ifdef HAS_GPS #ifdef HAS_GPS
if (gps_obj.getGpsModuleStatus()) { if (gps_obj.getGpsModuleStatus()) {
int get_arg = this->argSearch(&cmd_args, "-g"); int get_arg = this->argSearch(&cmd_args, "-g");
int nmea_arg = this->argSearch(&cmd_args, "-n");
if (get_arg != -1) { if (get_arg != -1) {
String gps_info = cmd_args.get(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()); Serial.println("Lon: " + gps_obj.getLon());
else if (gps_info == "alt") else if (gps_info == "alt")
Serial.println("Alt: " + (String)gps_obj.getAlt()); Serial.println("Alt: " + (String)gps_obj.getAlt());
else if (gps_info == "accuracy")
Serial.println("Accuracy: " + (String)gps_obj.getAccuracy());
else if (gps_info == "date") else if (gps_info == "date")
Serial.println("Date/Time: " + gps_obj.getDatetime()); 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 else
Serial.println("You did not provide a valid argument"); 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 #endif
} }

View File

@@ -47,6 +47,7 @@ const char PROGMEM LS_CMD[] = "ls";
const char PROGMEM LED_CMD[] = "led"; const char PROGMEM LED_CMD[] = "led";
const char PROGMEM GPS_DATA_CMD[] = "gpsdata"; const char PROGMEM GPS_DATA_CMD[] = "gpsdata";
const char PROGMEM GPS_CMD[] = "gps"; const char PROGMEM GPS_CMD[] = "gps";
const char PROGMEM NMEA_CMD[] = "nmea";
// WiFi sniff/scan // WiFi sniff/scan
const char PROGMEM EVIL_PORTAL_CMD[] = "evilportal"; const char PROGMEM EVIL_PORTAL_CMD[] = "evilportal";
@@ -95,7 +96,8 @@ const char PROGMEM HELP_SETTINGS_CMD[] = "settings [-s <setting> enable/disable>
const char PROGMEM HELP_LS_CMD[] = "ls <directory>"; const char PROGMEM HELP_LS_CMD[] = "ls <directory>";
const char PROGMEM HELP_LED_CMD[] = "led -s <hex color>/-p <rainbow>"; const char PROGMEM HELP_LED_CMD[] = "led -s <hex color>/-p <rainbow>";
const char PROGMEM HELP_GPS_DATA_CMD[] = "gpsdata"; const char PROGMEM HELP_GPS_DATA_CMD[] = "gpsdata";
const char PROGMEM HELP_GPS_CMD[] = "gps [-g] <fix/sat/lon/lat/alt/date>"; const char PROGMEM HELP_GPS_CMD[] = "gps [-g] <fix/sat/lon/lat/alt/date/accuracy/nmea>";
const char PROGMEM HELP_NMEA_CMD[] = "nmea";
// WiFi sniff/scan // WiFi sniff/scan
const char PROGMEM HELP_EVIL_PORTAL_CMD[] = "evilportal [-c start [-w html.html]/sethtml <html.html>]"; const char PROGMEM HELP_EVIL_PORTAL_CMD[] = "evilportal [-c start [-w html.html]/sethtml <html.html>]";

View File

@@ -2,6 +2,8 @@
#ifdef HAS_GPS #ifdef HAS_GPS
extern GpsInterface gps_obj;
char nmeaBuffer[100]; char nmeaBuffer[100];
MicroNMEA nmea(nmeaBuffer, sizeof(nmeaBuffer)); MicroNMEA nmea(nmeaBuffer, sizeof(nmeaBuffer));
@@ -33,6 +35,170 @@ void GpsInterface::begin() {
while (Serial2.available()) while (Serial2.available())
Serial2.read(); 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<String>* GpsInterface::get_queue(){
return this->queue;
}
void GpsInterface::new_queue(){
this->queue=new LinkedList<String>;
}
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 // Thanks JosephHewitt
@@ -56,6 +222,9 @@ String GpsInterface::dt_string_from_gps(){
} }
void GpsInterface::setGPSInfo() { void GpsInterface::setGPSInfo() {
String nmea_sentence = String(nmea.getSentence());
if(nmea_sentence != "") this->nmea_sentence = nmea_sentence;
this->good_fix = nmea.isValid(); this->good_fix = nmea.isValid();
this->num_sats = nmea.getNumSatellites(); this->num_sats = nmea.getNumSatellites();
@@ -113,6 +282,14 @@ bool GpsInterface::getGpsModuleStatus() {
return this->gps_enabled; return this->gps_enabled;
} }
String GpsInterface::getNmea() {
return this->nmea_sentence;
}
String GpsInterface::getNmeaNotimp() {
return this->notimp_nmea_sentence;
}
void GpsInterface::main() { void GpsInterface::main() {
while (Serial2.available()) { while (Serial2.available()) {
//Fetch the character one by one //Fetch the character one by one

View File

@@ -6,6 +6,8 @@
#include "configs.h" #include "configs.h"
void gps_nmea_notimp(MicroNMEA& nmea);
class GpsInterface { class GpsInterface {
public: public:
void begin(); void begin();
@@ -20,9 +22,36 @@ class GpsInterface {
float getAlt(); float getAlt();
float getAccuracy(); float getAccuracy();
String getDatetime(); String getDatetime();
String getNmea();
String getNmeaNotimp();
void setType(String t);
void enqueue(MicroNMEA& nmea);
LinkedList<String>* 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: private:
// GPS Info // GPS Info
String nmea_sentence = "";
String notimp_nmea_sentence = "";
String lat = ""; String lat = "";
String lon = ""; String lon = "";
float altf = 0.0; float altf = 0.0;
@@ -33,6 +62,11 @@ class GpsInterface {
bool good_fix = false; bool good_fix = false;
uint8_t num_sats = 0; uint8_t num_sats = 0;
type_t type_flag = GPSTYPE_ALL;
bool queue_enabled_flag=0;
LinkedList<String> *queue=NULL;
String dt_string_from_gps(); String dt_string_from_gps();
void setGPSInfo(); void setGPSInfo();
}; };

View File

@@ -1097,6 +1097,38 @@ void WiFiScan::RunGPSInfo() {
#endif #endif
} }
void WiFiScan::RunGPSNmea() {
#ifdef HAS_GPS
LinkedList<String> *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;i<size;i++){
Serial.println(buffer->get(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() void WiFiScan::RunInfo()
{ {
String sta_mac = this->getStaMAC(); String sta_mac = this->getStaMAC();
@@ -4308,6 +4340,12 @@ void WiFiScan::main(uint32_t currentTime)
this->RunGPSInfo(); 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) { else if (currentScanMode == WIFI_SCAN_EVIL_PORTAL) {
evil_portal_obj.main(currentScanMode); evil_portal_obj.main(currentScanMode);
} }

View File

@@ -86,6 +86,7 @@
#define BT_ATTACK_SOUR_APPLE 36 #define BT_ATTACK_SOUR_APPLE 36
#define BT_ATTACK_SWIFTPAIR_SPAM 37 #define BT_ATTACK_SWIFTPAIR_SPAM 37
#define BT_ATTACK_SPAM_ALL 38 #define BT_ATTACK_SPAM_ALL 38
#define WIFI_SCAN_GPS_NMEA 39
#define GRAPH_REFRESH 100 #define GRAPH_REFRESH 100
@@ -281,6 +282,7 @@ class WiFiScan
void broadcastSetSSID(uint32_t current_time, const char* ESSID); void broadcastSetSSID(uint32_t current_time, const char* ESSID);
void RunAPScan(uint8_t scan_mode, uint16_t color); void RunAPScan(uint8_t scan_mode, uint16_t color);
void RunGPSInfo(); void RunGPSInfo();
void RunGPSNmea();
void RunMimicFlood(uint8_t scan_mode, uint16_t color); void RunMimicFlood(uint8_t scan_mode, uint16_t color);
void RunPwnScan(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); void RunBeaconScan(uint8_t scan_mode, uint16_t color);