diff --git a/dump1090.h b/dump1090.h index dd55c50..3f8d34f 100644 --- a/dump1090.h +++ b/dump1090.h @@ -159,7 +159,7 @@ #define MODES_INTERACTIVE_DELETE_TTL 300 // Delete from the list after 300 seconds #define MODES_INTERACTIVE_DISPLAY_TTL 60 // Delete from display after 60 seconds -#define MODES_NET_MAX_FD 1024 +#define MODES_NET_MAX_FD 1024 #define MODES_NET_INPUT_RAW_PORT 30001 #define MODES_NET_OUTPUT_RAW_PORT 30002 #define MODES_NET_OUTPUT_SBS_PORT 30003 @@ -181,8 +181,8 @@ struct client { int fd; // File descriptor int service; // TCP port the client is connected to - char buf[MODES_CLIENT_BUF_SIZE+1]; // Read buffer int buflen; // Amount of data on buffer + char buf[MODES_CLIENT_BUF_SIZE+1]; // Read buffer }; // Structure used to describe an aircraft in iteractive mode @@ -405,6 +405,8 @@ void modesInitErrorInfo (); struct aircraft* interactiveReceiveData(struct modesMessage *mm); void interactiveShowData(void); void interactiveRemoveStaleAircrafts(void); +int decodeBinMessage (struct client *c, char *p); + // // Functions exported from net_io.c // @@ -412,6 +414,7 @@ void modesInitNet (void); void modesReadFromClients (void); void modesSendAllClients (int service, void *msg, int len); void modesQueueOutput (struct modesMessage *mm); +void modesReadFromClient(struct client *c, char *sep, int(*handler)(struct client *, char *)); #ifdef __cplusplus } diff --git a/interactive.c b/interactive.c index 061da78..6bc4efb 100644 --- a/interactive.c +++ b/interactive.c @@ -41,6 +41,40 @@ static uint64_t mstime(void) { mst += tv.tv_usec/1000; return mst; } + +#ifdef _WIN32 +// Standard error macro for reporting API errors +#define PERR(bSuccess, api){if(!(bSuccess)) printf("%s:Error %d from %s on line %d\n", __FILE__, GetLastError(), api, __LINE__);} + +void cls( HANDLE hConsole ) { + COORD coordScreen = { 0, 0 }; // here's where we'll home the cursor + BOOL bSuccess; + DWORD cCharsWritten; + CONSOLE_SCREEN_BUFFER_INFO csbi; // to get buffer info + DWORD dwConSize; // number of character cells in the current buffer + + // get the number of character cells in the current buffer + bSuccess = GetConsoleScreenBufferInfo( hConsole, &csbi ); + PERR( bSuccess, "GetConsoleScreenBufferInfo" ); + dwConSize = csbi.dwSize.X * csbi.dwSize.Y; + + // fill the entire screen with blanks + bSuccess = FillConsoleOutputCharacter( hConsole, (TCHAR) ' ', dwConSize, coordScreen, &cCharsWritten ); + PERR( bSuccess, "FillConsoleOutputCharacter" ); + + // get the current text attribute + bSuccess = GetConsoleScreenBufferInfo( hConsole, &csbi ); + PERR( bSuccess, "ConsoleScreenBufferInfo" ); + + // now set the buffer's attributes accordingly + bSuccess = FillConsoleOutputAttribute( hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten ); + PERR( bSuccess, "FillConsoleOutputAttribute" ); + + // put the cursor at (0, 0) + bSuccess = SetConsoleCursorPosition( hConsole, coordScreen ); + PERR( bSuccess, "SetConsoleCursorPosition" ); +} +#endif // //========================= Interactive mode =============================== // @@ -342,7 +376,7 @@ void interactiveShowData(void) { #ifndef _WIN32 printf("\x1b[H\x1b[2J"); // Clear the screen #else - system("cls"); + cls(GetStdHandle(STD_OUTPUT_HANDLE)); #endif if (Modes.interactive_rtl1090 == 0) { @@ -439,7 +473,7 @@ void interactiveShowData(void) { //========================================================================= // // When in interactive mode If we don't receive new nessages within -// MODES_INTERACTIVE__DELETE_TTL seconds we remove the aircraft from the list. +// MODES_INTERACTIVE_DELETE_TTL seconds we remove the aircraft from the list. // void interactiveRemoveStaleAircrafts(void) { struct aircraft *a = Modes.aircrafts; diff --git a/net_io.c b/net_io.c index 538c92b..50bf803 100644 --- a/net_io.c +++ b/net_io.c @@ -759,24 +759,29 @@ void modesReadFromClient(struct client *c, char *sep, int left; int nread; int fullmsg; + int bContinue = 1; char *s, *e; - while(1) { + while(bContinue) { fullmsg = 0; left = MODES_CLIENT_BUF_SIZE - c->buflen; // If our buffer is full discard it, this is some badly formatted shit - if (left == 0) { + if (left <= 0) { c->buflen = 0; left = MODES_CLIENT_BUF_SIZE; // If there is garbage, read more to discard it ASAP } nread = read(c->fd, c->buf+c->buflen, left); + // If we didn't get all the data we asked for, then return once we've processed what we did get. + if (nread != left) { + bContinue = 0; + } + if ( (nread < 0) && (errno != EAGAIN)) { // Error, or end of file + modesFreeClient(c->fd); + } if (nread <= 0) { - if (nread == 0 || errno != EAGAIN) { // Error, or end of file - modesFreeClient(c->fd); - } break; // Serve next client } c->buflen += nread; @@ -787,12 +792,12 @@ void modesReadFromClient(struct client *c, char *sep, e = s = c->buf; // Start with the start of buffer, first message if (c->service == Modes.bis) { - // This is the Bease Binary scanning case. + // This is the Beast Binary scanning case. // If there is a complete message still in the buffer, there must be the separator 'sep' // in the buffer, note that we full-scan the buffer at every read for simplicity. left = c->buflen; // Length of valid search for memchr() - while (left && ((s = memchr(e, (char) 0x1a, left)) != NULL)) { // In reality the first byte of buffer 'should' be 0x1a + while (left && ((s = memchr(e, (char) 0x1a, left)) != NULL)) { // The first byte of buffer 'should' be 0x1a s++; // skip the 0x1a if (*s == '1') { e = s + MODEAC_MSG_BYTES + 8; // point past remainder of message @@ -820,10 +825,11 @@ void modesReadFromClient(struct client *c, char *sep, s = e; // For the buffer remainder below } else { + // // This is the ASCII scanning case, AVR RAW or HTTP at present // If there is a complete message still in the buffer, there must be the separator 'sep' // in the buffer, note that we full-scan the buffer at every read for simplicity. - + // while ((e = strstr(s, sep)) != NULL) { // end of first message if found *e = '\0'; // The handler expects null terminated strings if (handler(c, s)) { // Pass message to handler. @@ -835,10 +841,10 @@ void modesReadFromClient(struct client *c, char *sep, } } - if (fullmsg) { // We processed something - so - c->buflen = &(c->buf[c->buflen]) - s; // The unprocessed buffer length - memmove(c->buf, s, c->buflen); // move what's remaining to the start of the buffer - } else { // If no message was decoded process the next client + if (fullmsg) { // We processed something - so + c->buflen = &(c->buf[c->buflen]) - s; // Update the unprocessed buffer length + memmove(c->buf, s, c->buflen); // Move what's remaining to the start of the buffer + } else { // If no message was decoded process the next client break; } }