kopia lustrzana https://github.com/pjalocha/esp32-ogn-tracker
Only turn APRS when AP is off, timeout to detect idle connection, reorganize for clarity
rodzic
81ce496e81
commit
caeb24db65
211
main/aprs.cpp
211
main/aprs.cpp
|
@ -21,21 +21,21 @@
|
||||||
|
|
||||||
// ======================================================================================================
|
// ======================================================================================================
|
||||||
|
|
||||||
static wifi_ap_record_t AP[8];
|
static wifi_ap_record_t AP[8]; // lists of Access Points from the WiFi scan
|
||||||
static uint16_t APs=0;
|
static uint16_t APs=0;
|
||||||
|
|
||||||
const int MaxLineLen=512;
|
const int MaxLineLen=512;
|
||||||
static char Line[MaxLineLen];
|
static char Line[MaxLineLen]; // for printing and buffering
|
||||||
|
|
||||||
static void AP_Print(void (*Output)(char))
|
static void AP_Print(void (*Output)(char)) // print lists of AP's
|
||||||
{ for(uint16_t Idx=0; Idx<APs; Idx++)
|
{ for(uint16_t Idx=0; Idx<APs; Idx++)
|
||||||
{ Line[0]='0'+Idx; Line[1]=':'; Line[2]=' ';
|
{ Line[0]='0'+Idx; Line[1]=':'; Line[2]=' ';
|
||||||
uint8_t Len=3+AP_Print(Line+3, AP+Idx);
|
uint8_t Len=3+AP_Print(Line+3, AP+Idx);
|
||||||
Format_String(Output, Line); }
|
Format_String(Output, Line); }
|
||||||
}
|
}
|
||||||
|
|
||||||
FIFO<OGN_RxPacket<OGN_Packet>, 16> APRSrx_FIFO;
|
FIFO<OGN_RxPacket<OGN_Packet>, 16> APRSrx_FIFO; // packets received on the air, to be passed to the APRS
|
||||||
FIFO<OGN_TxPacket<OGN_Packet>, 4> APRStx_FIFO;
|
FIFO<OGN_TxPacket<OGN_Packet>, 4> APRStx_FIFO; // own position/status/info packets to besent to APRS
|
||||||
|
|
||||||
static Socket APRS_Socket; // socket to talk to APRS server
|
static Socket APRS_Socket; // socket to talk to APRS server
|
||||||
bool APRS_isConnected(void) { return APRS_Socket.isConnected(); }
|
bool APRS_isConnected(void) { return APRS_Socket.isConnected(); }
|
||||||
|
@ -53,22 +53,22 @@ static uint16_t APRS_CallPass(const char *Call) // calc. pas
|
||||||
Low=toupper(Low); Hash^=(Low); }
|
Low=toupper(Low); Hash^=(Low); }
|
||||||
return Hash&0x7FFF; }
|
return Hash&0x7FFF; }
|
||||||
|
|
||||||
static uint8_t LoginLine(char *Line, /* , const char *Call,*/ uint16_t Range=0 )
|
static uint8_t LoginLine(char *Line, uint16_t Range=0 ) // produce login line for the APRS server
|
||||||
{ uint8_t Len=0;
|
{ uint8_t Len=0;
|
||||||
Len += Format_String(Line, "user "); // prepare the login line for the APRS server
|
Len += Format_String(Line, "user "); // user name
|
||||||
Len += Parameters.getAprsCall(Line+Len);
|
Len += Parameters.getAprsCall(Line+Len); // produce from the parameters
|
||||||
uint16_t Pass = APRS_CallPass(Line+5);
|
uint16_t Pass = APRS_CallPass(Line+5);
|
||||||
Len += Format_String(Line+Len, " pass ");
|
Len += Format_String(Line+Len, " pass "); // password
|
||||||
Len += Format_UnsDec(Line+Len, Pass);
|
Len += Format_UnsDec(Line+Len, Pass);
|
||||||
Len += Format_String(Line+Len, " vers OGN-Tracker v0.0");
|
Len += Format_String(Line+Len, " vers OGN-Tracker v0.0"); // software name and version
|
||||||
if(Range)
|
if(Range)
|
||||||
{ Len += Format_String(Line+Len, " filter m/");
|
{ Len += Format_String(Line+Len, " filter m/"); // ask for traffic 5km around own location
|
||||||
Len += Format_UnsDec(Line+Len, Range); }
|
Len += Format_UnsDec(Line+Len, Range); }
|
||||||
Line[Len++]='\n';
|
Line[Len++]='\n';
|
||||||
Line[Len]=0;
|
Line[Len]=0;
|
||||||
return Len; }
|
return Len; }
|
||||||
|
|
||||||
int APRS_RxMsg(const char *Msg)
|
static int APRS_RxMsg(const char *Msg) // Handle messages received from APRS
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_PRINT
|
#ifdef DEBUG_PRINT
|
||||||
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||||
|
@ -79,6 +79,97 @@ int APRS_RxMsg(const char *Msg)
|
||||||
#endif
|
#endif
|
||||||
return 0; }
|
return 0; }
|
||||||
|
|
||||||
|
static int APRS_Dialog(void) // connect to APRS and talk to the server exchaging data
|
||||||
|
{
|
||||||
|
int ConnErr=APRS_Socket.Connect(APRS_Host, APRS_Port); // connect to the APRS server
|
||||||
|
if(ConnErr>=0) // if connection succesfull
|
||||||
|
{ uint8_t LoginLen = LoginLine(Line, 5);
|
||||||
|
#ifdef DEBUG_PRINT
|
||||||
|
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||||
|
Format_String(CONS_UART_Write, "Connected to ");
|
||||||
|
IP_Print(CONS_UART_Write, APRS_Socket.getIP());
|
||||||
|
Format_String(CONS_UART_Write, "\nAPRS <- ");
|
||||||
|
Format_String(CONS_UART_Write, Line);
|
||||||
|
xSemaphoreGive(CONS_Mutex);
|
||||||
|
#endif
|
||||||
|
TickType_t LastRx = xTaskGetTickCount(); // to detect idle connection
|
||||||
|
APRS_Socket.setReceiveTimeout(1); // [sec] receive timeout
|
||||||
|
// APRS_Socket.setBlocking(0);
|
||||||
|
int Write=APRS_Socket.Send(Line, LoginLen); // send login to the APRS server
|
||||||
|
int LinePtr=0;
|
||||||
|
for( ; ; )
|
||||||
|
{ int Left = MaxLineLen-LinePtr; if(Left<128) break; // how much space left for receive data
|
||||||
|
int Read=APRS_Socket.Receive(Line+LinePtr, Left-1); // read more data from the socket
|
||||||
|
#ifdef DEBUG_PRINT
|
||||||
|
if(Read<0) // if error then print it
|
||||||
|
{ xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||||
|
Format_String(CONS_UART_Write, "APRS: ");
|
||||||
|
Format_SignDec(CONS_UART_Write, Read);
|
||||||
|
Format_String(CONS_UART_Write, "\n");
|
||||||
|
xSemaphoreGive(CONS_Mutex); }
|
||||||
|
#endif
|
||||||
|
if(Read<0) break; // if an error reading from the APRS server
|
||||||
|
if(Read==0) // no more data on the receive
|
||||||
|
{ TickType_t Idle = xTaskGetTickCount()-LastRx; // [ms] reception idling
|
||||||
|
if(Idle>=60000) break; // if idle for more than one minute then break the loop thus go for disconnect
|
||||||
|
bool TimeValid = GPS_DateTime.isTimeValid() && GPS_DateTime.isDateValid();
|
||||||
|
uint32_t Time = GPS_DateTime.getUnixTime();
|
||||||
|
char *Msg = Line+LinePtr;
|
||||||
|
while(APRStx_FIFO.Full()) // if own packets to be sent to the APRS
|
||||||
|
{ OGN_TxPacket<OGN_Packet> *TxPacket=APRStx_FIFO.getRead();
|
||||||
|
if(TimeValid)
|
||||||
|
{ uint8_t Len = TxPacket->Packet.WriteAPRS(Msg, Time); Msg[Len++]='\n'; Msg[Len]=0;
|
||||||
|
#ifdef DEBUG_PRINT
|
||||||
|
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||||
|
Format_String(CONS_UART_Write, "APRS <- ");
|
||||||
|
Format_String(CONS_UART_Write, Msg);
|
||||||
|
xSemaphoreGive(CONS_Mutex);
|
||||||
|
#endif
|
||||||
|
int Write = APRS_Socket.Send(Msg, Len); if(Write<0) break; } // send the message to APRS, break the look when an error
|
||||||
|
APRStx_FIFO.Read(); }
|
||||||
|
while(APRSrx_FIFO.Full()) // if received packets to be forwarded to the APRS
|
||||||
|
{ OGN_RxPacket<OGN_Packet> *RxPacket=APRSrx_FIFO.getRead();
|
||||||
|
uint8_t RxErr = RxPacket->RxErr;
|
||||||
|
if(TimeValid && RxErr<=8)
|
||||||
|
{ uint8_t Len = RxPacket->Packet.WriteAPRS(Msg, Time, "OGNTRK");
|
||||||
|
if(RxErr) { Msg[Len++]=' '; Msg[Len++]='0'+RxErr; Msg[Len++]='e'; }
|
||||||
|
Msg[Len++]='\n'; Msg[Len]=0;
|
||||||
|
#ifdef DEBUG_PRINT
|
||||||
|
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||||
|
Format_String(CONS_UART_Write, "APRS <- ");
|
||||||
|
Format_String(CONS_UART_Write, Msg);
|
||||||
|
xSemaphoreGive(CONS_Mutex);
|
||||||
|
#endif
|
||||||
|
int Write = APRS_Socket.Send(Msg, Len); if(Write<0) break; }
|
||||||
|
APRSrx_FIFO.Read(); }
|
||||||
|
continue; }
|
||||||
|
LastRx = xTaskGetTickCount();
|
||||||
|
int LineLen = LinePtr+Read;
|
||||||
|
int MsgPtr = 0;
|
||||||
|
Line[LineLen]=0;
|
||||||
|
for(int Idx=LinePtr; Idx<LineLen; Idx++)
|
||||||
|
{ char ch=Line[Idx]; if(ch==0) break;
|
||||||
|
if(ch=='\n')
|
||||||
|
{ Line[Idx]=0; APRS_RxMsg(Line+MsgPtr); MsgPtr=Idx+1; }
|
||||||
|
}
|
||||||
|
if(MsgPtr>0)
|
||||||
|
{ int Copy=LineLen-MsgPtr;
|
||||||
|
if(Copy>0)
|
||||||
|
{ memcpy(Line, Line+MsgPtr, Copy); LinePtr=0; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef DEBUG_PRINT
|
||||||
|
else // if connection failed to the APRS server
|
||||||
|
{ xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||||
|
Format_String(CONS_UART_Write, "Failed to connect to APRS -> ");
|
||||||
|
Format_SignDec(CONS_UART_Write, ConnErr);
|
||||||
|
Format_String(CONS_UART_Write, "\n");
|
||||||
|
xSemaphoreGive(CONS_Mutex); }
|
||||||
|
#endif
|
||||||
|
APRS_Socket.Disconnect();
|
||||||
|
return 0; }
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
void vTaskAPRS(void* pvParameters)
|
void vTaskAPRS(void* pvParameters)
|
||||||
{ esp_err_t Err;
|
{ esp_err_t Err;
|
||||||
|
@ -94,7 +185,7 @@ void vTaskAPRS(void* pvParameters)
|
||||||
xSemaphoreGive(CONS_Mutex);
|
xSemaphoreGive(CONS_Mutex);
|
||||||
#endif
|
#endif
|
||||||
for( ; ; ) // main (endless) loop
|
for( ; ; ) // main (endless) loop
|
||||||
{ vTaskDelay(5000);
|
{ vTaskDelay(15000); // this wait should be more intelligent
|
||||||
Err=WIFI_Start(); // start WiFi
|
Err=WIFI_Start(); // start WiFi
|
||||||
#ifdef DEBUG_PRINT
|
#ifdef DEBUG_PRINT
|
||||||
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||||
|
@ -155,9 +246,9 @@ void vTaskAPRS(void* pvParameters)
|
||||||
Format_String(CONS_UART_Write, "\n");
|
Format_String(CONS_UART_Write, "\n");
|
||||||
xSemaphoreGive(CONS_Mutex);
|
xSemaphoreGive(CONS_Mutex);
|
||||||
#endif
|
#endif
|
||||||
if(Err) continue; // if connection failed then give up
|
if(Err) continue; // if connection failed then give up ad move on to the next AP
|
||||||
|
|
||||||
WIFI_IP.ip.addr = 0;
|
WIFI_IP.ip.addr = 0; WIFI_IP.gw.addr=0;
|
||||||
for(uint8_t Idx=0; Idx<10; Idx++) // wait to obtain local IP from DHCP
|
for(uint8_t Idx=0; Idx<10; Idx++) // wait to obtain local IP from DHCP
|
||||||
{ vTaskDelay(1000);
|
{ vTaskDelay(1000);
|
||||||
if(WIFI_State.isConnected==1) break;
|
if(WIFI_State.isConnected==1) break;
|
||||||
|
@ -174,94 +265,10 @@ void vTaskAPRS(void* pvParameters)
|
||||||
Format_String(CONS_UART_Write, "\n");
|
Format_String(CONS_UART_Write, "\n");
|
||||||
xSemaphoreGive(CONS_Mutex);
|
xSemaphoreGive(CONS_Mutex);
|
||||||
#endif
|
#endif
|
||||||
if(WIFI_IP.ip.addr==0) { WIFI_Disconnect(); continue; } // if getting local IP failed then give up
|
if(WIFI_IP.ip.addr==0) { WIFI_Disconnect(); continue; } // if getting local IP failed then give up and try another AP
|
||||||
|
|
||||||
|
APRS_Dialog(); // talk to the APRS server
|
||||||
|
|
||||||
int ConnErr=APRS_Socket.Connect(APRS_Host, APRS_Port); // connect to the APRS server
|
|
||||||
if(ConnErr>=0) // if connection succesfull
|
|
||||||
{
|
|
||||||
uint8_t LoginLen = LoginLine(Line, 5);
|
|
||||||
#ifdef DEBUG_PRINT
|
|
||||||
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
|
||||||
Format_String(CONS_UART_Write, "Connected to ");
|
|
||||||
IP_Print(CONS_UART_Write, APRS_Socket.getIP());
|
|
||||||
Format_String(CONS_UART_Write, "\nAPRS <- ");
|
|
||||||
Format_String(CONS_UART_Write, Line);
|
|
||||||
xSemaphoreGive(CONS_Mutex);
|
|
||||||
#endif
|
|
||||||
APRS_Socket.setReceiveTimeout(1); // [sec] receive timeout
|
|
||||||
// APRS_Socket.setBlocking(0);
|
|
||||||
int Write=APRS_Socket.Send(Line, LoginLen); // send login to the APRS server
|
|
||||||
int LinePtr=0;
|
|
||||||
// for(int Idx=0; Idx<120; Idx++) // wait for some time and watch what the server sends to us
|
|
||||||
for( ; ; )
|
|
||||||
{ int Left = MaxLineLen-LinePtr; if(Left<128) break; // how much space left for receive data
|
|
||||||
int Read=APRS_Socket.Receive(Line+LinePtr, Left-1); // read moredatafrom the socket
|
|
||||||
#ifdef DEBUG_PRINT
|
|
||||||
if(Read<0)
|
|
||||||
{ xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
|
||||||
Format_String(CONS_UART_Write, "APRS: ");
|
|
||||||
Format_SignDec(CONS_UART_Write, Read);
|
|
||||||
Format_String(CONS_UART_Write, "\n");
|
|
||||||
xSemaphoreGive(CONS_Mutex); }
|
|
||||||
#endif
|
|
||||||
if(Read<0) break; // if an error reading from the APRS server
|
|
||||||
if(Read==0) // no more data on the receive
|
|
||||||
{ bool TimeValid = GPS_DateTime.isTimeValid() && GPS_DateTime.isDateValid();
|
|
||||||
uint32_t Time = GPS_DateTime.getUnixTime();
|
|
||||||
char *Msg = Line+LinePtr;
|
|
||||||
while(APRStx_FIFO.Full())
|
|
||||||
{ OGN_TxPacket<OGN_Packet> *TxPacket=APRStx_FIFO.getRead();
|
|
||||||
if(TimeValid)
|
|
||||||
{ uint8_t Len = TxPacket->Packet.WriteAPRS(Msg, Time); Msg[Len++]='\n'; Msg[Len]=0;
|
|
||||||
#ifdef DEBUG_PRINT
|
|
||||||
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
|
||||||
Format_String(CONS_UART_Write, "APRS <- ");
|
|
||||||
Format_String(CONS_UART_Write, Msg);
|
|
||||||
xSemaphoreGive(CONS_Mutex);
|
|
||||||
#endif
|
|
||||||
int Write = APRS_Socket.Send(Msg, Len); if(Write<0) break; }
|
|
||||||
APRStx_FIFO.Read(); }
|
|
||||||
while(APRSrx_FIFO.Full())
|
|
||||||
{ OGN_RxPacket<OGN_Packet> *RxPacket=APRSrx_FIFO.getRead();
|
|
||||||
uint8_t RxErr = RxPacket->RxErr;
|
|
||||||
if(TimeValid && RxErr<=8)
|
|
||||||
{ uint8_t Len = RxPacket->Packet.WriteAPRS(Msg, Time, "OGNTRK");
|
|
||||||
if(RxErr)
|
|
||||||
{ Msg[Len++]=' '; Msg[Len++]='0'+RxErr; Msg[Len++]='e'; }
|
|
||||||
Msg[Len++]='\n'; Msg[Len]=0;
|
|
||||||
#ifdef DEBUG_PRINT
|
|
||||||
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
|
||||||
Format_String(CONS_UART_Write, "APRS <- ");
|
|
||||||
Format_String(CONS_UART_Write, Msg);
|
|
||||||
xSemaphoreGive(CONS_Mutex);
|
|
||||||
#endif
|
|
||||||
int Write = APRS_Socket.Send(Msg, Len); if(Write<0) break; }
|
|
||||||
APRSrx_FIFO.Read(); }
|
|
||||||
continue; }
|
|
||||||
int LineLen = LinePtr+Read;
|
|
||||||
int MsgPtr = 0;
|
|
||||||
Line[LineLen]=0;
|
|
||||||
for(int Idx=LinePtr; Idx<LineLen; Idx++)
|
|
||||||
{ char ch=Line[Idx]; if(ch==0) break;
|
|
||||||
if(ch=='\n')
|
|
||||||
{ Line[Idx]=0; APRS_RxMsg(Line+MsgPtr); MsgPtr=Idx+1; }
|
|
||||||
}
|
|
||||||
if(MsgPtr>0)
|
|
||||||
{ int Copy=LineLen-MsgPtr;
|
|
||||||
if(Copy>0)
|
|
||||||
{ memcpy(Line, Line+MsgPtr, Copy); LinePtr=0; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifdef DEBUG_PRINT
|
|
||||||
else // if connection failed to the APRS server
|
|
||||||
{ xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
|
||||||
Format_String(CONS_UART_Write, "Failed to connect to APRS -> ");
|
|
||||||
Format_SignDec(CONS_UART_Write, ConnErr);
|
|
||||||
Format_String(CONS_UART_Write, "\n");
|
|
||||||
xSemaphoreGive(CONS_Mutex); }
|
|
||||||
#endif
|
|
||||||
APRS_Socket.Disconnect();
|
|
||||||
vTaskDelay(5000);
|
vTaskDelay(5000);
|
||||||
WIFI_Disconnect(); WIFI_IP.ip.addr=0;
|
WIFI_Disconnect(); WIFI_IP.ip.addr=0;
|
||||||
vTaskDelay(2000);
|
vTaskDelay(2000);
|
||||||
|
|
|
@ -125,19 +125,24 @@ void app_main(void)
|
||||||
#ifdef WITH_AERO
|
#ifdef WITH_AERO
|
||||||
xTaskCreate(vTaskAERO, "AERO", 2000, 0, tskIDLE_PRIORITY+3, 0);
|
xTaskCreate(vTaskAERO, "AERO", 2000, 0, tskIDLE_PRIORITY+3, 0);
|
||||||
#endif
|
#endif
|
||||||
#ifdef WITH_APRS
|
|
||||||
xTaskCreate(vTaskAPRS, "APRS", 4000, 0, tskIDLE_PRIORITY+2, 0);
|
|
||||||
#endif
|
|
||||||
#ifdef WITH_STRATUX
|
#ifdef WITH_STRATUX
|
||||||
xTaskCreate(vTaskSTX, "STX", 4000, 0, tskIDLE_PRIORITY+3, 0);
|
xTaskCreate(vTaskSTX, "STX", 4000, 0, tskIDLE_PRIORITY+3, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WITH_AP
|
#ifdef WITH_AP
|
||||||
#ifdef WITH_AP_BUTTON
|
#ifdef WITH_AP_BUTTON
|
||||||
if(Button_isPressed() && Parameters.APname[0]) // start WiFi AP when button pressed during startup and APname non-empty
|
bool StartAP = Button_isPressed() && Parameters.APname[0]; // start WiFi AP when button pressed during startup and APname non-empty
|
||||||
#else
|
#else
|
||||||
if(Parameters.APname[0]) // start WiFi AP when APname non-empty
|
bool StartAP = Parameters.APname[0]; // start WiFi AP when APname non-empty
|
||||||
#endif
|
#endif
|
||||||
|
if(StartAP)
|
||||||
xTaskCreate(vTaskAP, "AP", 4000, 0, tskIDLE_PRIORITY+3, 0);
|
xTaskCreate(vTaskAP, "AP", 4000, 0, tskIDLE_PRIORITY+3, 0);
|
||||||
|
#else // WITH_AP
|
||||||
|
const bool StartAP=0;
|
||||||
|
#endif // WITH_AP
|
||||||
|
#ifdef WITH_APRS
|
||||||
|
if(!StartAP)
|
||||||
|
xTaskCreate(vTaskAPRS, "APRS", 4000, 0, tskIDLE_PRIORITY+2, 0);
|
||||||
#endif
|
#endif
|
||||||
#if defined(WITH_OLED) || defined(WITH_U8G2_OLED) || defined(WITH_ST7789) || defined(WITH_ILI9341)
|
#if defined(WITH_OLED) || defined(WITH_U8G2_OLED) || defined(WITH_ST7789) || defined(WITH_ILI9341)
|
||||||
xTaskCreate(vTaskDISP, "DISP", 3000, 0, tskIDLE_PRIORITY+2, 0);
|
xTaskCreate(vTaskDISP, "DISP", 3000, 0, tskIDLE_PRIORITY+2, 0);
|
||||||
|
|
Ładowanie…
Reference in New Issue