diff --git a/main/aprs.cpp b/main/aprs.cpp index 6272b91..02b5c72 100644 --- a/main/aprs.cpp +++ b/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; 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, 16> APRSrx_FIFO; -FIFO, 4> APRStx_FIFO; +FIFO, 16> APRSrx_FIFO; // packets received on the air, to be passed to the APRS +FIFO, 4> APRStx_FIFO; // own position/status/info packets to besent to APRS static Socket APRS_Socket; // socket to talk to APRS server 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); } 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; - Len += Format_String(Line, "user "); // prepare the login line for the APRS server - Len += Parameters.getAprsCall(Line+Len); + Len += Format_String(Line, "user "); // user name + Len += Parameters.getAprsCall(Line+Len); // produce from the parameters 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_String(Line+Len, " vers OGN-Tracker v0.0"); + Len += Format_String(Line+Len, " vers OGN-Tracker v0.0"); // software name and version 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); } Line[Len++]='\n'; Line[Len]=0; return Len; } -int APRS_RxMsg(const char *Msg) +static int APRS_RxMsg(const char *Msg) // Handle messages received from APRS { #ifdef DEBUG_PRINT xSemaphoreTake(CONS_Mutex, portMAX_DELAY); @@ -79,6 +79,97 @@ int APRS_RxMsg(const char *Msg) #endif 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 *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 *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; Idx0) + { 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" void vTaskAPRS(void* pvParameters) { esp_err_t Err; @@ -94,7 +185,7 @@ void vTaskAPRS(void* pvParameters) xSemaphoreGive(CONS_Mutex); #endif for( ; ; ) // main (endless) loop - { vTaskDelay(5000); + { vTaskDelay(15000); // this wait should be more intelligent Err=WIFI_Start(); // start WiFi #ifdef DEBUG_PRINT xSemaphoreTake(CONS_Mutex, portMAX_DELAY); @@ -155,9 +246,9 @@ void vTaskAPRS(void* pvParameters) Format_String(CONS_UART_Write, "\n"); xSemaphoreGive(CONS_Mutex); #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 { vTaskDelay(1000); if(WIFI_State.isConnected==1) break; @@ -174,94 +265,10 @@ void vTaskAPRS(void* pvParameters) Format_String(CONS_UART_Write, "\n"); xSemaphoreGive(CONS_Mutex); #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 *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 *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; Idx0) - { 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); WIFI_Disconnect(); WIFI_IP.ip.addr=0; vTaskDelay(2000); diff --git a/main/main.cpp b/main/main.cpp index 9e76b00..7372490 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -125,19 +125,24 @@ void app_main(void) #ifdef WITH_AERO xTaskCreate(vTaskAERO, "AERO", 2000, 0, tskIDLE_PRIORITY+3, 0); #endif -#ifdef WITH_APRS - xTaskCreate(vTaskAPRS, "APRS", 4000, 0, tskIDLE_PRIORITY+2, 0); -#endif #ifdef WITH_STRATUX xTaskCreate(vTaskSTX, "STX", 4000, 0, tskIDLE_PRIORITY+3, 0); #endif + #ifdef WITH_AP #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 - if(Parameters.APname[0]) // start WiFi AP when APname non-empty + bool StartAP = Parameters.APname[0]; // start WiFi AP when APname non-empty #endif + if(StartAP) 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 #if defined(WITH_OLED) || defined(WITH_U8G2_OLED) || defined(WITH_ST7789) || defined(WITH_ILI9341) xTaskCreate(vTaskDISP, "DISP", 3000, 0, tskIDLE_PRIORITY+2, 0);