diff --git a/Makefile b/Makefile index edfdc6e..f8ca163 100644 --- a/Makefile +++ b/Makefile @@ -4,23 +4,17 @@ # PROGNAME=view1090 -ifdef PREFIX -BINDIR=$(PREFIX)/bin -SHAREDIR=$(PREFIX)/share/$(PROGNAME) -EXTRACFLAGS=-DHTMLPATH=\"$(SHAREDIR)\" -endif - CFLAGS=-O2 -g -Wall -W LIBS=-lm -lSDL2 -lSDL2_ttf -lSDL2_gfx -CC=gcc +CC=g++ all: view1090 %.o: %.c $(CC) $(CFLAGS) $(EXTRACFLAGS) -c $< -view1090: view1090.o anet.o interactive.o mode_ac.o mode_s.o net_io.o planeObj.o input.o draw.o font.o init.o mapdata.o status.o parula.o monokai.o - $(CC) -g -o view1090 view1090.o anet.o interactive.o mode_ac.o mode_s.o net_io.o planeObj.o input.o draw.o font.o init.o mapdata.o status.o parula.o monokai.o $(LIBS) $(LDFLAGS) +view1090: view1090.o anet.o interactive.o planeObj.o mode_ac.o mode_s.o net_io.o input.o draw.o font.o init.o mapdata.o status.o parula.o monokai.o + $(CC) -g -o view1090 view1090.o anet.o interactive.o planeObj.o mode_ac.o mode_s.o net_io.o input.o draw.o font.o init.o mapdata.o status.o parula.o monokai.o $(LIBS) $(LDFLAGS) clean: rm -f *.o view1090 diff --git a/anet.c b/anet.c index 859c98c..fd31f3d 100644 --- a/anet.c +++ b/anet.c @@ -122,7 +122,7 @@ int anetResolve(char *err, char *host, char *ipbuf) struct sockaddr_in sa; sa.sin_family = AF_INET; - if (inet_aton(host, (void*)&sa.sin_addr) == 0) { + if (inet_aton(host, (in_addr*)&sa.sin_addr) == 0) { struct hostent *he; he = gethostbyname(host); @@ -168,7 +168,7 @@ static int anetTcpGenericConnect(char *err, char *addr, int port, int flags) memset(&sa,0,sizeof(sa)); sa.sin_family = AF_INET; sa.sin_port = htons((uint16_t)port); - if (inet_aton(addr, (void*)&sa.sin_addr) == 0) { + if (inet_aton(addr, (in_addr*)&sa.sin_addr) == 0) { struct hostent *he; he = gethostbyname(addr); @@ -271,7 +271,7 @@ int anetTcpServer(char *err, int port, char *bindaddr) sa.sin_family = AF_INET; sa.sin_port = htons((uint16_t)port); sa.sin_addr.s_addr = htonl(INADDR_ANY); - if (bindaddr && inet_aton(bindaddr, (void*)&sa.sin_addr) == 0) { + if (bindaddr && inet_aton(bindaddr, (in_addr*)&sa.sin_addr) == 0) { anetSetError(err, "invalid bind address"); close(s); return ANET_ERR; diff --git a/draw.c b/draw.c index 158b422..6602458 100644 --- a/draw.c +++ b/draw.c @@ -389,7 +389,7 @@ void drawScaleBars() while(scaleBarDist < appData.screen_width) { lineRGBA(appData.renderer,10+scaleBarDist,8,10+scaleBarDist,16*appData.screen_uiscale,style.scaleBarColor.r, style.scaleBarColor.g, style.scaleBarColor.b, 255); - if (Modes.metric) { + if (modes.metric) { snprintf(scaleLabel,13,"%dkm", (int)pow(10,scalePower)); } else { snprintf(scaleLabel,13,"%dmi", (int)pow(10,scalePower)); @@ -504,10 +504,10 @@ void drawGeography() { latLonFromScreenCoords(&screen_lat_min, &screen_lon_min, 0, appData.screen_height * -0.2); latLonFromScreenCoords(&screen_lat_max, &screen_lon_max, appData.screen_width, appData.screen_height * 1.2); - drawPolys(&root, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max); + drawPolys(&(appData.root), screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max); } -void drawSignalMarks(struct planeObj *p, int x, int y) { +void drawSignalMarks(PlaneObj *p, int x, int y) { unsigned char * pSig = p->signalLevel; unsigned int signalAverage = (pSig[0] + pSig[1] + pSig[2] + pSig[3] + pSig[4] + pSig[5] + pSig[6] + pSig[7] + 3) >> 3; @@ -525,7 +525,7 @@ void drawSignalMarks(struct planeObj *p, int x, int y) { } -void drawPlaneText(struct planeObj *p) { +void drawPlaneText(PlaneObj *p) { int maxCharCount = 0; int currentCharCount; @@ -547,7 +547,7 @@ void drawPlaneText(struct planeObj *p) { if(p->pressure * appData.screen_width < 0.2f) { char alt[10] = " "; - if (Modes.metric) { + if (modes.metric) { currentCharCount = snprintf(alt,10," %dm", (int) (p->altitude / 3.2828)); } else { currentCharCount = snprintf(alt,10," %d'", p->altitude); @@ -563,7 +563,7 @@ void drawPlaneText(struct planeObj *p) { } char speed[10] = " "; - if (Modes.metric) { + if (modes.metric) { currentCharCount = snprintf(speed,10," %dkm/h", (int) (p->speed * 1.852)); } else { currentCharCount = snprintf(speed,10," %dmph", p->speed); @@ -599,7 +599,7 @@ void drawPlaneText(struct planeObj *p) { p->h = currentLine * appData.mapFontHeight; } -void drawSelectedPlaneText(struct planeObj *p) { +void drawSelectedPlaneText(PlaneObj *p) { if(p == NULL) { return; } @@ -625,7 +625,7 @@ void drawSelectedPlaneText(struct planeObj *p) { } char alt[10] = " "; - if (Modes.metric) { + if (modes.metric) { currentCharCount = snprintf(alt,10," %dm", (int) (p->altitude / 3.2828)); } else { currentCharCount = snprintf(alt,10," %d'", p->altitude); @@ -641,7 +641,7 @@ void drawSelectedPlaneText(struct planeObj *p) { } char speed[10] = " "; - if (Modes.metric) { + if (modes.metric) { currentCharCount = snprintf(speed,10," %dkm/h", (int) (p->speed * 1.852)); } else { currentCharCount = snprintf(speed,10," %dmph", p->speed); @@ -654,11 +654,11 @@ void drawSelectedPlaneText(struct planeObj *p) { } void resolveLabelConflicts() { - struct planeObj *p = planes; + PlaneObj *p = appData.planes; while(p) { - struct planeObj *check_p = planes; + PlaneObj *check_p = appData.planes; int p_left = p->x - 10 * appData.screen_uiscale; int p_right = p->x + p->w + 10 * appData.screen_uiscale; @@ -747,7 +747,7 @@ void resolveLabelConflicts() { check_p = check_p -> next; } - check_p = planes; + check_p = appData.planes; //check against plane icons (include self) @@ -803,7 +803,7 @@ void resolveLabelConflicts() { //update - p = planes; + p = appData.planes; while(p) { //incorporate acceleration from label conflict resolution @@ -844,29 +844,29 @@ void resolveLabelConflicts() { void drawPlanes() { - struct planeObj *p = planes; + PlaneObj *p = appData.planes; time_t now = time(NULL); SDL_Color planeColor; // draw all trails first so they don't cover up planes and text // also find closest plane to selection point while(p) { - if ((now - p->seen) < Modes.interactive_display_ttl) { + if ((now - p->seen) < modes.interactive_display_ttl) { drawTrail(p->oldLon, p->oldLat, p->oldHeading, p->oldSeen, p->oldIdx); } p = p->next; } - if(selectedPlane) { - appData.mapTargetLon = selectedPlane->lon; - appData.mapTargetLat = selectedPlane->lat; + if(appData.selectedPlane) { + appData.mapTargetLon = appData.selectedPlane->lon; + appData.mapTargetLat = appData.selectedPlane->lat; } - p = planes; + p = appData.planes; while(p) { - if ((now - p->seen) < Modes.interactive_display_ttl) { + if ((now - p->seen) < modes.interactive_display_ttl) { if (p->lon && p->lat) { int x, y; @@ -900,7 +900,7 @@ void drawPlanes() { usey = y + (mstime() - p->msSeenLatLon) * vely; } - if(p == selectedPlane) { + if(p == appData.selectedPlane) { // this logic should be in input, register a callback for click? float elapsed = mstime() - appData.touchDownTime; @@ -935,7 +935,7 @@ void drawPlanes() { p->cy = usey; } - if(p != selectedPlane) { + if(p != appData.selectedPlane) { drawPlaneText(p); } @@ -946,7 +946,7 @@ void drawPlanes() { p = p->next; } - drawSelectedPlaneText(selectedPlane); + drawSelectedPlaneText(appData.selectedPlane); if(appData.touchx && appData.touchy) { @@ -1071,8 +1071,8 @@ void drawMouse() { void registerClick() { if(appData.tapCount == 1 && appData.isDragging == 0) { - struct planeObj *p = planes; - struct planeObj *selection = NULL; + PlaneObj *p = appData.planes; + PlaneObj *selection = NULL; while(p) { if(appData.touchx && appData.touchy) { @@ -1091,8 +1091,8 @@ void registerClick() { p = p->next; } - //if(selectedPlane == NULL) { - selectedPlane = selection; + //if(appData.selectedPlane == NULL) { + appData.selectedPlane = selection; //} } else if(appData.tapCount == 2) { appData.mapTargetMaxDist = 0.25 * appData.maxDist; diff --git a/dump1090.h b/dump1090.h index 9ad4de0..2de8b0d 100644 --- a/dump1090.h +++ b/dump1090.h @@ -227,7 +227,7 @@ struct aircraft { struct aircraft *next; // Next aircraft in our linked list }; -struct stDF { +typedef struct stDF { struct stDF *pNext; // Pointer to next item in the linked list struct stDF *pPrev; // Pointer to previous item in the linked list struct aircraft *pAircraft; // Pointer to the Aircraft structure for this DF @@ -238,7 +238,7 @@ struct stDF { } tDF; // Program global state -struct { // Internal state +typedef struct Modes{ // Internal state pthread_t reader_thread; pthread_mutex_t data_mutex; // Mutex to synchronize buffer access @@ -372,6 +372,8 @@ struct { // Internal state unsigned int stat_blocks_dropped; } Modes; +extern Modes modes; + // The struct we use to store information about a decoded message. struct modesMessage { // Generic fields diff --git a/init.c b/init.c index dd4e08d..103ad61 100644 --- a/init.c +++ b/init.c @@ -48,7 +48,7 @@ void init(char *title) { appData.mapTargetLat = 0; appData.mapTargetMaxDist = 0; appData.isDragging = 0; - selectedPlane = NULL; + appData.selectedPlane = NULL; if(appData.fullscreen) { //SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear"); // make the scaled rendering look smoother. diff --git a/interactive.c b/interactive.c index 5d1d9c4..5884a33 100644 --- a/interactive.c +++ b/interactive.c @@ -60,19 +60,19 @@ void interactiveCreateDF(struct aircraft *a, struct modesMessage *mm) { pDF->pAircraft = a; memcpy(pDF->msg, mm->msg, MODES_LONG_MSG_BYTES); - // if (!pthread_mutex_lock(&Modes.pDF_mutex)) { - // if ((pDF->pNext = Modes.pDF)) { - // Modes.pDF->pPrev = pDF; + // if (!pthread_mutex_lock(&modes.pDF_mutex)) { + // if ((pDF->pNext = modes.pDF)) { + // modes.pDF->pPrev = pDF; // } - // Modes.pDF = pDF; - // pthread_mutex_unlock(&Modes.pDF_mutex); + // modes.pDF = pDF; + // pthread_mutex_unlock(&modes.pDF_mutex); // } else { // free(pDF); // } - if ((pDF->pNext = Modes.pDF)) { - Modes.pDF->pPrev = pDF; + if ((pDF->pNext = modes.pDF)) { + modes.pDF->pPrev = pDF; } - Modes.pDF = pDF; + modes.pDF = pDF; } } @@ -86,12 +86,12 @@ void interactiveRemoveStaleDF(time_t now) { // Only fiddle with the DF list if we gain possession of the mutex // If we fail to get the mutex we'll get another chance to tidy the // DF list in a second or so. - // if (!pthread_mutex_trylock(&Modes.pDF_mutex)) { - // pDF = Modes.pDF; + // if (!pthread_mutex_trylock(&modes.pDF_mutex)) { + // pDF = modes.pDF; // while(pDF) { - // if ((now - pDF->seen) > Modes.interactive_delete_ttl) { - // if (Modes.pDF == pDF) { - // Modes.pDF = NULL; + // if ((now - pDF->seen) > modes.interactive_delete_ttl) { + // if (modes.pDF == pDF) { + // modes.pDF = NULL; // } else { // prev->pNext = NULL; // } @@ -107,13 +107,13 @@ void interactiveRemoveStaleDF(time_t now) { // prev = pDF; pDF = pDF->pNext; // } // } - // pthread_mutex_unlock (&Modes.pDF_mutex); + // pthread_mutex_unlock (&modes.pDF_mutex); // } - pDF = Modes.pDF; + pDF = modes.pDF; while(pDF) { - if ((now - pDF->seen) > Modes.interactive_delete_ttl) { - if (Modes.pDF == pDF) { - Modes.pDF = NULL; + if ((now - pDF->seen) > modes.interactive_delete_ttl) { + if (modes.pDF == pDF) { + modes.pDF = NULL; } else { prev->pNext = NULL; } @@ -134,19 +134,19 @@ void interactiveRemoveStaleDF(time_t now) { struct stDF *interactiveFindDF(uint32_t addr) { struct stDF *pDF = NULL; - // if (!pthread_mutex_lock(&Modes.pDF_mutex)) { - // pDF = Modes.pDF; + // if (!pthread_mutex_lock(&modes.pDF_mutex)) { + // pDF = modes.pDF; // while(pDF) { // if (pDF->addr == addr) { - // pthread_mutex_unlock (&Modes.pDF_mutex); + // pthread_mutex_unlock (&modes.pDF_mutex); // return (pDF); // } // pDF = pDF->pNext; // } - // pthread_mutex_unlock (&Modes.pDF_mutex); + // pthread_mutex_unlock (&modes.pDF_mutex); // } - pDF = Modes.pDF; + pDF = modes.pDF; while(pDF) { if (pDF->addr == addr) { return (pDF); @@ -197,7 +197,7 @@ struct aircraft *interactiveCreateAircraft(struct modesMessage *mm) { // exists with this address. // struct aircraft *interactiveFindAircraft(uint32_t addr) { - struct aircraft *a = Modes.aircrafts; + struct aircraft *a = modes.aircrafts; while(a) { if (a->addr == addr) return (a); @@ -231,7 +231,7 @@ struct aircraft *interactiveFindAircraft(uint32_t addr) { // and Mode C. Therefore we have to check BOTH A AND C for EVERY S. // void interactiveUpdateAircraftModeA(struct aircraft *a) { - struct aircraft *b = Modes.aircrafts; + struct aircraft *b = modes.aircrafts; while(b) { if ((b->modeACflags & MODEAC_MSG_FLAG) == 0) {// skip any fudged ICAO records @@ -272,7 +272,7 @@ void interactiveUpdateAircraftModeA(struct aircraft *a) { //========================================================================= // void interactiveUpdateAircraftModeS() { - struct aircraft *a = Modes.aircrafts; + struct aircraft *a = modes.aircrafts; while(a) { int flags = a->modeACflags; @@ -295,15 +295,15 @@ struct aircraft *interactiveReceiveData(struct modesMessage *mm) { struct aircraft *a, *aux; // Return if (checking crc) AND (not crcok) AND (not fixed) - if (Modes.check_crc && (mm->crcok == 0) && (mm->correctedbits == 0)) + if (modes.check_crc && (mm->crcok == 0) && (mm->correctedbits == 0)) return NULL; // Lookup our aircraft or create a new one a = interactiveFindAircraft(mm->addr); if (!a) { // If it's a currently unknown aircraft.... a = interactiveCreateAircraft(mm); // ., create a new record for it, - a->next = Modes.aircrafts; // .. and put it at the head of the list - Modes.aircrafts = a; + a->next = modes.aircrafts; // .. and put it at the head of the list + modes.aircrafts = a; } else { /* If it is an already known aircraft, move it on head * so we keep aircrafts ordered by received message time. @@ -312,14 +312,14 @@ struct aircraft *interactiveReceiveData(struct modesMessage *mm) { * since the aircraft that is currently on head sent a message, * othewise with multiple aircrafts at the same time we have an * useless shuffle of positions on the screen. */ - if (0 && Modes.aircrafts != a && (time(NULL) - a->seen) >= 1) { - aux = Modes.aircrafts; + if (0 && modes.aircrafts != a && (time(NULL) - a->seen) >= 1) { + aux = modes.aircrafts; while(aux->next != a) aux = aux->next; /* Now we are a node before the aircraft to remove. */ aux->next = aux->next->next; /* removed. */ /* Add on head */ - a->next = Modes.aircrafts; - Modes.aircrafts = a; + a->next = modes.aircrafts; + modes.aircrafts = a; } } @@ -432,7 +432,7 @@ struct aircraft *interactiveReceiveData(struct modesMessage *mm) { } // If we are Logging DF's, and it's not a Mode A/C - if ((Modes.bEnableDFLogging) && (mm->msgtype < 32)) { + if ((modes.bEnableDFLogging) && (mm->msgtype < 32)) { interactiveCreateDF(a,mm); } @@ -446,22 +446,22 @@ struct aircraft *interactiveReceiveData(struct modesMessage *mm) { // MODES_INTERACTIVE_DELETE_TTL seconds we remove the aircraft from the list. // void interactiveRemoveStaleAircrafts(void) { - struct aircraft *a = Modes.aircrafts; + struct aircraft *a = modes.aircrafts; struct aircraft *prev = NULL; time_t now = time(NULL); // Only do cleanup once per second - if (Modes.last_cleanup_time != now) { - Modes.last_cleanup_time = now; + if (modes.last_cleanup_time != now) { + modes.last_cleanup_time = now; interactiveRemoveStaleDF(now); while(a) { - if ((now - a->seen) > Modes.interactive_delete_ttl) { + if ((now - a->seen) > modes.interactive_delete_ttl) { // Remove the element from the linked list, with care // if we are removing the first element if (!prev) { - Modes.aircrafts = a->next; free(a); a = Modes.aircrafts; + modes.aircrafts = a->next; free(a); a = modes.aircrafts; } else { prev->next = a->next; free(a); a = prev->next; } diff --git a/mapdata.c b/mapdata.c index 8ddc70c..a959cf8 100644 --- a/mapdata.c +++ b/mapdata.c @@ -1,7 +1,11 @@ #include "dump1090.h" #include "mapdata.h" +#include "structs.h" #include +int mapPoints_count; +float *mapPoints; + void initQuadTree(QuadTree *tree) { if(tree == NULL) { return; @@ -126,30 +130,30 @@ void initMaps() { // load quad tree - root.lat_min = 180; - root.lon_min = 180; - root.lat_max = -180; - root.lon_max = -180; + appData.root.lat_min = 180; + appData.root.lon_min = 180; + appData.root.lat_max = -180; + appData.root.lon_max = -180; - root.nw = NULL; - root.ne = NULL; - root.sw = NULL; - root.se = NULL; + appData.root.nw = NULL; + appData.root.ne = NULL; + appData.root.sw = NULL; + appData.root.se = NULL; for(int i = 0; i < mapPoints_count; i+=2) { if(mapPoints[i] == 0) continue; - if(mapPoints[i] < root.lon_min) { - root.lon_min = mapPoints[i]; - } else if(mapPoints[i] > root.lon_max) { - root.lon_max = mapPoints[i]; + if(mapPoints[i] < appData.root.lon_min) { + appData.root.lon_min = mapPoints[i]; + } else if(mapPoints[i] > appData.root.lon_max) { + appData.root.lon_max = mapPoints[i]; } - if(mapPoints[i+1] < root.lat_min) { - root.lat_min = mapPoints[i+1]; - } else if(mapPoints[i+1] > root.lat_max) { - root.lat_max = mapPoints[i+1]; + if(mapPoints[i+1] < appData.root.lat_min) { + appData.root.lat_min = mapPoints[i+1]; + } else if(mapPoints[i+1] > appData.root.lat_max) { + appData.root.lat_max = mapPoints[i+1]; } } @@ -159,7 +163,7 @@ void initMaps() { for(int i = 0; i < mapPoints_count; i+=2) { if(mapPoints[i] == 0) { - QTInsert(&root, currentPolygon); + QTInsert(&appData.root, currentPolygon); currentPolygon = (Polygon*)malloc(sizeof(Polygon)); initPolygon(currentPolygon); continue; diff --git a/mapdata.h b/mapdata.h index 5d384ca..1d78867 100644 --- a/mapdata.h +++ b/mapdata.h @@ -1,11 +1,6 @@ #ifndef MAPPOINTS_H #define MAPPOINTS_H -float *mapPoints_relative; -int mapPoints_count; - -float *mapPoints; - typedef struct Point{ float lat; float lon; @@ -38,6 +33,4 @@ typedef struct QuadTree{ struct QuadTree *se; } QuadTree; -QuadTree root; - #endif \ No newline at end of file diff --git a/mode_s.c.REMOVED.git-id b/mode_s.c.REMOVED.git-id index 4263876..6035912 100644 --- a/mode_s.c.REMOVED.git-id +++ b/mode_s.c.REMOVED.git-id @@ -1 +1 @@ -cd129a02b926ab42fbf9f41ab984f4bb2a3e5e59 \ No newline at end of file +aaf101fcf91be4f20921260cd579f3fa5dda321e \ No newline at end of file diff --git a/monokai.h b/monokai.h index 06f752a..969ec5d 100644 --- a/monokai.h +++ b/monokai.h @@ -1,14 +1,14 @@ #include "structs.h" -SDL_Color pink; -SDL_Color purple; -SDL_Color blue; -SDL_Color green; -SDL_Color yellow; -SDL_Color orange; -SDL_Color lightGrey; -SDL_Color grey; -SDL_Color darkGrey; -SDL_Color black; -SDL_Color white; -SDL_Color red; \ No newline at end of file +extern SDL_Color pink; +extern SDL_Color purple; +extern SDL_Color blue; +extern SDL_Color green; +extern SDL_Color yellow; +extern SDL_Color orange; +extern SDL_Color lightGrey; +extern SDL_Color grey; +extern SDL_Color darkGrey; +extern SDL_Color black; +extern SDL_Color white; +extern SDL_Color red; \ No newline at end of file diff --git a/net_io.c b/net_io.c index a979883..5b30103 100644 --- a/net_io.c +++ b/net_io.c @@ -59,23 +59,23 @@ void modesInitNet(void) { int j; struct service svc[MODES_NET_SERVICES_NUM] = { - {"Raw TCP output", &Modes.ros, Modes.net_output_raw_port, 1}, - {"Raw TCP input", &Modes.ris, Modes.net_input_raw_port, 1}, - {"Beast TCP output", &Modes.bos, Modes.net_output_beast_port, 1}, - {"Beast TCP input", &Modes.bis, Modes.net_input_beast_port, 1}, - {"HTTP server", &Modes.https, Modes.net_http_port, 1}, - {"Basestation TCP output", &Modes.sbsos, Modes.net_output_sbs_port, 1} + {"Raw TCP output", &modes.ros, modes.net_output_raw_port, 1}, + {"Raw TCP input", &modes.ris, modes.net_input_raw_port, 1}, + {"Beast TCP output", &modes.bos, modes.net_output_beast_port, 1}, + {"Beast TCP input", &modes.bis, modes.net_input_beast_port, 1}, + {"HTTP server", &modes.https, modes.net_http_port, 1}, + {"Basestation TCP output", &modes.sbsos, modes.net_output_sbs_port, 1} }; memcpy(&services, &svc, sizeof(svc));//services = svc; - Modes.clients = NULL; + modes.clients = NULL; #ifdef _WIN32 - if ( (!Modes.wsaData.wVersion) - && (!Modes.wsaData.wHighVersion) ) { + if ( (!modes.wsaData.wVersion) + && (!modes.wsaData.wHighVersion) ) { // Try to start the windows socket support - if (WSAStartup(MAKEWORD(2,1),&Modes.wsaData) != 0) + if (WSAStartup(MAKEWORD(2,1),&modes.wsaData) != 0) { fprintf(stderr, "WSAStartup returned Error\n"); } @@ -85,16 +85,16 @@ void modesInitNet(void) { for (j = 0; j < MODES_NET_SERVICES_NUM; j++) { services[j].enabled = (services[j].port != 0); if (services[j].enabled) { - int s = anetTcpServer(Modes.aneterr, services[j].port, Modes.net_bind_address); + int s = anetTcpServer(modes.aneterr, services[j].port, modes.net_bind_address); if (s == -1) { fprintf(stderr, "Error opening the listening port %d (%s): %s\n", - services[j].port, services[j].descr, Modes.aneterr); + services[j].port, services[j].descr, modes.aneterr); exit(1); } - anetNonBlock(Modes.aneterr, s); + anetNonBlock(modes.aneterr, s); *services[j].socket = s; } else { - if (Modes.debug & MODES_DEBUG_NET) printf("%s port is disabled\n", services[j].descr); + if (modes.debug & MODES_DEBUG_NET) printf("%s port is disabled\n", services[j].descr); } } @@ -115,29 +115,29 @@ struct client * modesAcceptClients(void) { for (j = 0; j < MODES_NET_SERVICES_NUM; j++) { if (services[j].enabled) { - fd = anetTcpAccept(Modes.aneterr, *services[j].socket, NULL, &port); + fd = anetTcpAccept(modes.aneterr, *services[j].socket, NULL, &port); if (fd == -1) continue; - anetNonBlock(Modes.aneterr, fd); + anetNonBlock(modes.aneterr, fd); c = (struct client *) malloc(sizeof(*c)); c->service = *services[j].socket; - c->next = Modes.clients; + c->next = modes.clients; c->fd = fd; c->buflen = 0; - Modes.clients = c; - anetSetSendBuffer(Modes.aneterr,fd, (MODES_NET_SNDBUF_SIZE << Modes.net_sndbuf_size)); + modes.clients = c; + anetSetSendBuffer(modes.aneterr,fd, (MODES_NET_SNDBUF_SIZE << modes.net_sndbuf_size)); - if (*services[j].socket == Modes.sbsos) Modes.stat_sbs_connections++; - if (*services[j].socket == Modes.ros) Modes.stat_raw_connections++; - if (*services[j].socket == Modes.bos) Modes.stat_beast_connections++; + if (*services[j].socket == modes.sbsos) modes.stat_sbs_connections++; + if (*services[j].socket == modes.ros) modes.stat_raw_connections++; + if (*services[j].socket == modes.bos) modes.stat_beast_connections++; j--; // Try again with the same listening port - if (Modes.debug & MODES_DEBUG_NET) + if (modes.debug & MODES_DEBUG_NET) printf("Created new client %d\n", fd); } } - return Modes.clients; + return modes.clients; } // //========================================================================= @@ -147,10 +147,10 @@ struct client * modesAcceptClients(void) { void modesFreeClient(struct client *c) { // Unhook this client from the linked list of clients - struct client *p = Modes.clients; + struct client *p = modes.clients; if (p) { if (p == c) { - Modes.clients = c->next; + modes.clients = c->next; } else { while ((p) && (p->next != c)) { p = p->next; @@ -170,306 +170,20 @@ void modesFreeClient(struct client *c) { // void modesCloseClient(struct client *c) { close(c->fd); - if (c->service == Modes.sbsos) { - if (Modes.stat_sbs_connections) Modes.stat_sbs_connections--; - } else if (c->service == Modes.ros) { - if (Modes.stat_raw_connections) Modes.stat_raw_connections--; - } else if (c->service == Modes.bos) { - if (Modes.stat_beast_connections) Modes.stat_beast_connections--; + if (c->service == modes.sbsos) { + if (modes.stat_sbs_connections) modes.stat_sbs_connections--; + } else if (c->service == modes.ros) { + if (modes.stat_raw_connections) modes.stat_raw_connections--; + } else if (c->service == modes.bos) { + if (modes.stat_beast_connections) modes.stat_beast_connections--; } - if (Modes.debug & MODES_DEBUG_NET) + if (modes.debug & MODES_DEBUG_NET) printf("Closing client %d\n", c->fd); c->fd = -1; } -// -//========================================================================= -// -// Send the specified message to all clients listening for a given service -// -void modesSendAllClients(int service, void *msg, int len) { - struct client *c = Modes.clients; - while (c) { - // Read next before servicing client incase the service routine deletes the client! - struct client *next = c->next; - - if (c->fd != -1) { - if (c->service == service) { -#ifndef _WIN32 - int nwritten = write(c->fd, msg, len); -#else - int nwritten = send(c->fd, msg, len, 0 ); -#endif - if (nwritten != len) { - modesCloseClient(c); - } - } - } else { - modesFreeClient(c); - } - c = next; - } -} -// -//========================================================================= -// -// Write raw output in Beast Binary format with Timestamp to TCP clients -// -void modesSendBeastOutput(struct modesMessage *mm) { - char *p = &Modes.beastOut[Modes.beastOutUsed]; - int msgLen = mm->msgbits / 8; - char * pTimeStamp; - char ch; - int j; - int iOutLen = msgLen + 9; // Escape, msgtype, timestamp, sigLevel, msg - - *p++ = 0x1a; - if (msgLen == MODES_SHORT_MSG_BYTES) - {*p++ = '2';} - else if (msgLen == MODES_LONG_MSG_BYTES) - {*p++ = '3';} - else if (msgLen == MODEAC_MSG_BYTES) - {*p++ = '1';} - else - {return;} - - pTimeStamp = (char *) &mm->timestampMsg; - for (j = 5; j >= 0; j--) { - *p++ = (ch = pTimeStamp[j]); - if (0x1A == ch) {*p++ = ch; iOutLen++;} - } - - *p++ = (ch = mm->signalLevel); - if (0x1A == ch) {*p++ = ch; iOutLen++;} - - for (j = 0; j < msgLen; j++) { - *p++ = (ch = mm->msg[j]); - if (0x1A == ch) {*p++ = ch; iOutLen++;} - } - - Modes.beastOutUsed += iOutLen; - if (Modes.beastOutUsed >= Modes.net_output_raw_size) - { - modesSendAllClients(Modes.bos, Modes.beastOut, Modes.beastOutUsed); - Modes.beastOutUsed = 0; - Modes.net_output_raw_rate_count = 0; - } -} -// -//========================================================================= -// -// Write raw output to TCP clients -// -void modesSendRawOutput(struct modesMessage *mm) { - char *p = &Modes.rawOut[Modes.rawOutUsed]; - int msgLen = mm->msgbits / 8; - int j; - unsigned char * pTimeStamp; - - if (Modes.mlat && mm->timestampMsg) { - *p++ = '@'; - pTimeStamp = (unsigned char *) &mm->timestampMsg; - for (j = 5; j >= 0; j--) { - sprintf(p, "%02X", pTimeStamp[j]); - p += 2; - } - Modes.rawOutUsed += 12; // additional 12 characters for timestamp - } else - *p++ = '*'; - - for (j = 0; j < msgLen; j++) { - sprintf(p, "%02X", mm->msg[j]); - p += 2; - } - - *p++ = ';'; - *p++ = '\n'; - - Modes.rawOutUsed += ((msgLen*2) + 3); - if (Modes.rawOutUsed >= Modes.net_output_raw_size) - { - modesSendAllClients(Modes.ros, Modes.rawOut, Modes.rawOutUsed); - Modes.rawOutUsed = 0; - Modes.net_output_raw_rate_count = 0; - } -} -// -//========================================================================= -// -// Write SBS output to TCP clients -// The message structure mm->bFlags tells us what has been updated by this message -// -void modesSendSBSOutput(struct modesMessage *mm) { - char msg[256], *p = msg; - uint32_t offset; - struct timeb epocTime_receive, epocTime_now; - struct tm stTime_receive, stTime_now; - int msgType; - - // - // SBS BS style output checked against the following reference - // http://www.homepages.mcb.net/bones/SBS/Article/Barebones42_Socket_Data.htm - seems comprehensive - // - - // Decide on the basic SBS Message Type - if ((mm->msgtype == 4) || (mm->msgtype == 20)) { - msgType = 5; - } else if ((mm->msgtype == 5) || (mm->msgtype == 21)) { - msgType = 6; - } else if ((mm->msgtype == 0) || (mm->msgtype == 16)) { - msgType = 7; - } else if (mm->msgtype == 11) { - msgType = 8; - } else if ((mm->msgtype != 17) && (mm->msgtype != 18)) { - return; - } else if ((mm->metype >= 1) && (mm->metype <= 4)) { - msgType = 1; - } else if ((mm->metype >= 5) && (mm->metype <= 8)) { - if (mm->bFlags & MODES_ACFLAGS_LATLON_VALID) - {msgType = 2;} - else - {msgType = 7;} - } else if ((mm->metype >= 9) && (mm->metype <= 18)) { - if (mm->bFlags & MODES_ACFLAGS_LATLON_VALID) - {msgType = 3;} - else - {msgType = 7;} - } else if (mm->metype != 19) { - return; - } else if ((mm->mesub == 1) || (mm->mesub == 2)) { - msgType = 4; - } else { - return; - } - - // Fields 1 to 6 : SBS message type and ICAO address of the aircraft and some other stuff - p += sprintf(p, "MSG,%d,111,11111,%06X,111111,", msgType, mm->addr); - - // Find current system time - ftime(&epocTime_now); // get the current system time & date - stTime_now = *localtime(&epocTime_now.time); - - // Find message reception time - if (mm->timestampMsg && !mm->remote) { // Make sure the records' timestamp is valid before using it - epocTime_receive = Modes.stSystemTimeBlk; // This is the time of the start of the Block we're processing - offset = (int) (mm->timestampMsg - Modes.timestampBlk); // This is the time (in 12Mhz ticks) into the Block - offset = offset / 12000; // convert to milliseconds - epocTime_receive.millitm += offset; // add on the offset time to the Block start time - if (epocTime_receive.millitm > 999) { // if we've caused an overflow into the next second... - epocTime_receive.millitm -= 1000; - epocTime_receive.time ++; // ..correct the overflow - } - stTime_receive = *localtime(&epocTime_receive.time); - } else { - epocTime_receive = epocTime_now; // We don't have a usable reception time; use the current system time - stTime_receive = stTime_now; - } - - // Fields 7 & 8 are the message reception time and date - p += sprintf(p, "%04d/%02d/%02d,", (stTime_receive.tm_year+1900),(stTime_receive.tm_mon+1), stTime_receive.tm_mday); - p += sprintf(p, "%02d:%02d:%02d.%03d,", stTime_receive.tm_hour, stTime_receive.tm_min, stTime_receive.tm_sec, epocTime_receive.millitm); - - // Fields 9 & 10 are the current time and date - p += sprintf(p, "%04d/%02d/%02d,", (stTime_now.tm_year+1900),(stTime_now.tm_mon+1), stTime_now.tm_mday); - p += sprintf(p, "%02d:%02d:%02d.%03d", stTime_now.tm_hour, stTime_now.tm_min, stTime_now.tm_sec, epocTime_now.millitm); - - // Field 11 is the callsign (if we have it) - if (mm->bFlags & MODES_ACFLAGS_CALLSIGN_VALID) {p += sprintf(p, ",%s", mm->flight);} - else {p += sprintf(p, ",");} - - // Field 12 is the altitude (if we have it) - force to zero if we're on the ground - if ((mm->bFlags & MODES_ACFLAGS_AOG_GROUND) == MODES_ACFLAGS_AOG_GROUND) { - p += sprintf(p, ",0"); - } else if (mm->bFlags & MODES_ACFLAGS_ALTITUDE_VALID) { - p += sprintf(p, ",%d", mm->altitude); - } else { - p += sprintf(p, ","); - } - - // Field 13 is the ground Speed (if we have it) - if (mm->bFlags & MODES_ACFLAGS_SPEED_VALID) { - p += sprintf(p, ",%d", mm->velocity); - } else { - p += sprintf(p, ","); - } - - // Field 14 is the ground Heading (if we have it) - if (mm->bFlags & MODES_ACFLAGS_HEADING_VALID) { - p += sprintf(p, ",%d", mm->heading); - } else { - p += sprintf(p, ","); - } - - // Fields 15 and 16 are the Lat/Lon (if we have it) - if (mm->bFlags & MODES_ACFLAGS_LATLON_VALID) {p += sprintf(p, ",%1.5f,%1.5f", mm->fLat, mm->fLon);} - else {p += sprintf(p, ",,");} - - // Field 17 is the VerticalRate (if we have it) - if (mm->bFlags & MODES_ACFLAGS_VERTRATE_VALID) {p += sprintf(p, ",%d", mm->vert_rate);} - else {p += sprintf(p, ",");} - - // Field 18 is the Squawk (if we have it) - if (mm->bFlags & MODES_ACFLAGS_SQUAWK_VALID) {p += sprintf(p, ",%x", mm->modeA);} - else {p += sprintf(p, ",");} - - // Field 19 is the Squawk Changing Alert flag (if we have it) - if (mm->bFlags & MODES_ACFLAGS_FS_VALID) { - if ((mm->fs >= 2) && (mm->fs <= 4)) { - p += sprintf(p, ",-1"); - } else { - p += sprintf(p, ",0"); - } - } else { - p += sprintf(p, ","); - } - - // Field 20 is the Squawk Emergency flag (if we have it) - if (mm->bFlags & MODES_ACFLAGS_SQUAWK_VALID) { - if ((mm->modeA == 0x7500) || (mm->modeA == 0x7600) || (mm->modeA == 0x7700)) { - p += sprintf(p, ",-1"); - } else { - p += sprintf(p, ",0"); - } - } else { - p += sprintf(p, ","); - } - - // Field 21 is the Squawk Ident flag (if we have it) - if (mm->bFlags & MODES_ACFLAGS_FS_VALID) { - if ((mm->fs >= 4) && (mm->fs <= 5)) { - p += sprintf(p, ",-1"); - } else { - p += sprintf(p, ",0"); - } - } else { - p += sprintf(p, ","); - } - - // Field 22 is the OnTheGround flag (if we have it) - if (mm->bFlags & MODES_ACFLAGS_AOG_VALID) { - if (mm->bFlags & MODES_ACFLAGS_AOG) { - p += sprintf(p, ",-1"); - } else { - p += sprintf(p, ",0"); - } - } else { - p += sprintf(p, ","); - } - - p += sprintf(p, "\r\n"); - modesSendAllClients(Modes.sbsos, msg, p-msg); -} -// -//========================================================================= -// -void modesQueueOutput(struct modesMessage *mm) { - if (Modes.stat_sbs_connections) {modesSendSBSOutput(mm);} - if (Modes.stat_beast_connections) {modesSendBeastOutput(mm);} - if (Modes.stat_raw_connections) {modesSendRawOutput(mm);} -} -// //========================================================================= // // This function decodes a Beast binary format message @@ -495,7 +209,7 @@ int decodeBinMessage(struct client *c, char *p) { ch = *p++; /// Get the message type if (0x1A == ch) {p++;} - if ((ch == '1') && (Modes.mode_ac)) { // skip ModeA/C unless user enables --modes-ac + if ((ch == '1') && (modes.mode_ac)) { // skip ModeA/C unless user enables --modes-ac msgLen = MODEAC_MSG_BYTES; } else if (ch == '2') { msgLen = MODES_SHORT_MSG_BYTES; @@ -609,7 +323,7 @@ int decodeHexMessage(struct client *c, char *hex) { && (l != (MODES_LONG_MSG_BYTES * 2)) ) {return (0);} // Too short or long message... broken - if ( (0 == Modes.mode_ac) + if ( (0 == modes.mode_ac) && (l == (MODEAC_MSG_BYTES * 2)) ) {return (0);} // Right length for ModeA/C, but not enabled @@ -633,216 +347,6 @@ int decodeHexMessage(struct client *c, char *hex) { // //========================================================================= // -// Return a description of planes in json. No metric conversion -// -char *aircraftsToJson(int *len) { - time_t now = time(NULL); - struct aircraft *a = Modes.aircrafts; - int buflen = 1024; // The initial buffer is incremented as needed - char *buf = (char *) malloc(buflen), *p = buf; - int l; - - l = snprintf(p,buflen,"[\n"); - p += l; buflen -= l; - while(a) { - int position = 0; - int track = 0; - - if (a->modeACflags & MODEAC_MSG_FLAG) { // skip any fudged ICAO records Mode A/C - a = a->next; - continue; - } - - if (a->bFlags & MODES_ACFLAGS_LATLON_VALID) { - position = 1; - } - - if (a->bFlags & MODES_ACFLAGS_HEADING_VALID) { - track = 1; - } - - // No metric conversion - l = snprintf(p,buflen, - "{\"hex\":\"%06x\", \"squawk\":\"%04x\", \"flight\":\"%s\", \"lat\":%f, " - "\"lon\":%f, \"validposition\":%d, \"altitude\":%d, \"vert_rate\":%d,\"track\":%d, \"validtrack\":%d," - "\"speed\":%d, \"messages\":%ld, \"seen\":%d},\n", - a->addr, a->modeA, a->flight, a->lat, a->lon, position, a->altitude, a->vert_rate, a->track, track, - a->speed, a->messages, (int)(now - a->seen)); - p += l; buflen -= l; - - //Resize if needed - if (buflen < 256) { - int used = p-buf; - buflen += 1024; // Our increment. - buf = (char *) realloc(buf,used+buflen); - p = buf+used; - } - - a = a->next; - } - - //Remove the final comma if any, and closes the json array. - if (*(p-2) == ',') { - *(p-2) = '\n'; - p--; - buflen++; - } - - l = snprintf(p,buflen,"]\n"); - p += l; buflen -= l; - - *len = p-buf; - return buf; -} -// -//========================================================================= -// -#define MODES_CONTENT_TYPE_HTML "text/html;charset=utf-8" -#define MODES_CONTENT_TYPE_CSS "text/css;charset=utf-8" -#define MODES_CONTENT_TYPE_JSON "application/json;charset=utf-8" -#define MODES_CONTENT_TYPE_JS "application/javascript;charset=utf-8" -// -// Get an HTTP request header and write the response to the client. -// gain here we assume that the socket buffer is enough without doing -// any kind of userspace buffering. -// -// Returns 1 on error to signal the caller the client connection should -// be closed. -// -int handleHTTPRequest(struct client *c, char *p) { - char hdr[512]; - int clen, hdrlen; - int httpver, keepalive; - int statuscode = 500; - char *url, *content; - char ctype[48]; - char getFile[1024]; - char *ext; - - if (Modes.debug & MODES_DEBUG_NET) - printf("\nHTTP request: %s\n", c->buf); - - // Minimally parse the request. - httpver = (strstr(p, "HTTP/1.1") != NULL) ? 11 : 10; - if (httpver == 10) { - // HTTP 1.0 defaults to close, unless otherwise specified. - //keepalive = strstr(p, "Connection: keep-alive") != NULL; - } else if (httpver == 11) { - // HTTP 1.1 defaults to keep-alive, unless close is specified. - //keepalive = strstr(p, "Connection: close") == NULL; - } - keepalive = 0; - - // Identify he URL. - p = strchr(p,' '); - if (!p) return 1; // There should be the method and a space - url = ++p; // Now this should point to the requested URL - p = strchr(p, ' '); - if (!p) return 1; // There should be a space before HTTP/ - *p = '\0'; - - if (Modes.debug & MODES_DEBUG_NET) { - printf("\nHTTP keep alive: %d\n", keepalive); - printf("HTTP requested URL: %s\n\n", url); - } - - if (strlen(url) < 2) { - snprintf(getFile, sizeof getFile, "%s/gmap.html", HTMLPATH); // Default file - } else { - snprintf(getFile, sizeof getFile, "%s/%s", HTMLPATH, url); - } - - // Select the content to send, we have just two so far: - // "/" -> Our google map application. - // "/data.json" -> Our ajax request to update planes. - if (strstr(url, "/data.json")) { - statuscode = 200; - content = aircraftsToJson(&clen); - //snprintf(ctype, sizeof ctype, MODES_CONTENT_TYPE_JSON); - } else { - struct stat sbuf; - int fd = -1; - char *rp, *hrp; - - rp = realpath(getFile, NULL); - hrp = realpath(HTMLPATH, NULL); - hrp = (hrp ? hrp : HTMLPATH); - clen = -1; - content = strdup("Server error occured"); - if (rp && (!strncmp(hrp, rp, strlen(hrp)))) { - if (stat(getFile, &sbuf) != -1 && (fd = open(getFile, O_RDONLY)) != -1) { - content = (char *) realloc(content, sbuf.st_size); - if (read(fd, content, sbuf.st_size) != -1) { - clen = sbuf.st_size; - statuscode = 200; - } - } - } else { - errno = ENOENT; - } - - if (clen < 0) { - content = realloc(content, 128); - clen = snprintf(content, 128,"Error opening HTML file: %s", strerror(errno)); - statuscode = 404; - } - - if (fd != -1) { - close(fd); - } - } - - // Get file extension and content type - snprintf(ctype, sizeof ctype, MODES_CONTENT_TYPE_HTML); // Default content type - ext = strrchr(getFile, '.'); - - if (strlen(ext) > 0) { - if (strstr(ext, ".json")) { - snprintf(ctype, sizeof ctype, MODES_CONTENT_TYPE_JSON); - } else if (strstr(ext, ".css")) { - snprintf(ctype, sizeof ctype, MODES_CONTENT_TYPE_CSS); - } else if (strstr(ext, ".js")) { - snprintf(ctype, sizeof ctype, MODES_CONTENT_TYPE_JS); - } - } - - // Create the header and send the reply - hdrlen = snprintf(hdr, sizeof(hdr), - "HTTP/1.1 %d \r\n" - "Server: Dump1090\r\n" - "Content-Type: %s\r\n" - "Connection: %s\r\n" - "Content-Length: %d\r\n" - "Cache-Control: no-cache, must-revalidate\r\n" - "Expires: Sat, 26 Jul 1997 05:00:00 GMT\r\n" - "\r\n", - statuscode, - ctype, - keepalive ? "keep-alive" : "close", - clen); - - if (Modes.debug & MODES_DEBUG_NET) { - printf("HTTP Reply header:\n%s", hdr); - } - - // Send header and content. -#ifndef _WIN32 - if ( (write(c->fd, hdr, hdrlen) != hdrlen) - || (write(c->fd, content, clen) != clen) ) { -#else - if ( (send(c->fd, hdr, hdrlen, 0) != hdrlen) - || (send(c->fd, content, clen, 0) != clen) ) { -#endif - free(content); - return 1; - } - free(content); - Modes.stat_http_requests++; - return !keepalive; -} -// -//========================================================================= -// // This function polls the clients using read() in order to receive new // messages from the net. // @@ -906,13 +410,15 @@ void modesReadFromClient(struct client *c, char *sep, e = s = c->buf; // Start with the start of buffer, first message - if (c->service == Modes.bis) { + + + if (c->service == modes.bis) { // 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)) { // The first byte of buffer 'should' be 0x1a + while (left && ((s = (char*)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 @@ -988,13 +494,7 @@ void modesReadFromClients(void) { struct client *next = c->next; if (c->fd >= 0) { - if (c->service == Modes.ris) { - modesReadFromClient(c,"\n",decodeHexMessage); - } else if (c->service == Modes.bis) { modesReadFromClient(c,"",decodeBinMessage); - } else if (c->service == Modes.https) { - modesReadFromClient(c,"\r\n\r\n",handleHTTPRequest); - } } else { modesFreeClient(c); } diff --git a/parula.h b/parula.h index 4b925d5..1bf6cb8 100644 --- a/parula.h +++ b/parula.h @@ -1 +1 @@ -int parula[128][3]; \ No newline at end of file +extern int parula[128][3]; \ No newline at end of file diff --git a/planeObj.c b/planeObj.c index 92b665d..0f7740e 100644 --- a/planeObj.c +++ b/planeObj.c @@ -11,8 +11,8 @@ static uint64_t mstime(void) { return mst; } -struct planeObj *findPlaneObj(uint32_t addr) { - struct planeObj *p = planes; +PlaneObj *findPlaneObj(uint32_t addr) { + PlaneObj *p = appData.planes; while(p) { if (p->addr == addr) return (p); @@ -21,8 +21,8 @@ struct planeObj *findPlaneObj(uint32_t addr) { return (NULL); } -struct planeObj *createPlaneObj(struct aircraft *a) { - struct planeObj *p = (struct planeObj *) malloc(sizeof(*p)); +PlaneObj *createPlaneObj(struct aircraft *a) { + PlaneObj *p = (PlaneObj *) malloc(sizeof(*p)); memset(p, 0, sizeof(*p)); @@ -51,9 +51,9 @@ struct planeObj *createPlaneObj(struct aircraft *a) { } void updatePlanes() { - struct aircraft *a = Modes.aircrafts; + struct aircraft *a = modes.aircrafts; - struct planeObj *p = planes; + PlaneObj *p = appData.planes; while(p) { p->live = 0; @@ -65,8 +65,8 @@ void updatePlanes() { p = findPlaneObj(a->addr); if (!p) { p = createPlaneObj(a); - p->next = planes; - planes = p; + p->next = appData.planes; + appData.planes = p; } else { p->prev_seen = p->seen; } @@ -113,15 +113,15 @@ void updatePlanes() { a = a->next; } - p = planes; - struct planeObj *prev = NULL; + p = appData.planes; + PlaneObj *prev = NULL; while(p) { if(!p->live) { if (!prev) { - planes = p->next; + appData.planes = p->next; free(p); - p = planes; + p = appData.planes; } else { prev->next = p->next; free(p); diff --git a/status.c b/status.c index a53e1ea..8d45bd7 100644 --- a/status.c +++ b/status.c @@ -54,7 +54,7 @@ void updateStatus() { a = a->next; } */ - struct planeObj *p = planes; + PlaneObj *p = appData.planes; while(p) { unsigned char * pSig = p->signalLevel; diff --git a/structs.h b/structs.h index bb51410..6fdb073 100644 --- a/structs.h +++ b/structs.h @@ -3,6 +3,44 @@ #include "defs.h" + +// mirrors aircraft struct in dump1090, separating for refactoring + +typedef struct PlaneObj { + uint32_t addr; // ICAO address + char flight[16]; // Flight number + unsigned char signalLevel[8]; // Last 8 Signal Amplitudes + double messageRate; + int altitude; // Altitude + int speed; // Velocity + int track; // Angle of flight + int vert_rate; // Vertical rate. + time_t seen; // Time at which the last packet was received + time_t seenLatLon; // Time at which the last packet was received + time_t prev_seen; + double lat, lon; // Coordinated obtained from CPR encoded data + + //history + float oldLon[TRAIL_LENGTH]; + float oldLat[TRAIL_LENGTH]; + float oldHeading[TRAIL_LENGTH]; + time_t oldSeen[TRAIL_LENGTH]; + uint8_t oldIdx; + uint64_t created; + uint64_t msSeen; + uint64_t msSeenLatLon; + int live; + + struct PlaneObj *next; // Next aircraft in our linked list + +//// label stuff + + int x, y, cx, cy, w, h; + float ox, oy, dox, doy, ddox, ddoy; + float pressure; +} PlaneObj; + + typedef struct AppData { SDL_Window *window; @@ -53,51 +91,14 @@ typedef struct AppData int mapMoved; + QuadTree root; + + PlaneObj *planes; + PlaneObj *selectedPlane; + uint64_t lastFrameTime; } AppData; -AppData appData; - -// mirrors aircraft struct in dump1090, separating for refactoring - -struct planeObj { - uint32_t addr; // ICAO address - char flight[16]; // Flight number - unsigned char signalLevel[8]; // Last 8 Signal Amplitudes - double messageRate; - int altitude; // Altitude - int speed; // Velocity - int track; // Angle of flight - int vert_rate; // Vertical rate. - time_t seen; // Time at which the last packet was received - time_t seenLatLon; // Time at which the last packet was received - time_t prev_seen; - double lat, lon; // Coordinated obtained from CPR encoded data - - //history - float oldLon[TRAIL_LENGTH]; - float oldLat[TRAIL_LENGTH]; - float oldHeading[TRAIL_LENGTH]; - time_t oldSeen[TRAIL_LENGTH]; - uint8_t oldIdx; - uint64_t created; - uint64_t msSeen; - uint64_t msSeenLatLon; - int live; - - struct planeObj *next; // Next aircraft in our linked list - -//// label stuff - - int x, y, cx, cy, w, h; - float ox, oy, dox, doy, ddox, ddoy; - float pressure; -}; - -struct planeObj *planes; - - -struct planeObj *selectedPlane; struct { double msgRate; @@ -121,9 +122,14 @@ typedef struct Style { SDL_Color buttonColor; } Style; -Style style; +// globals +extern AppData appData; +extern Style style; // functions +#ifdef __cplusplus +extern "C" { +#endif //font.c TTF_Font *loadFont(char *, int); @@ -158,6 +164,8 @@ void drawStatus(); //planeObj.c void updatePlanes(); - +#ifdef __cplusplus +} +#endif #endif \ No newline at end of file diff --git a/view1090.REMOVED.git-id b/view1090.REMOVED.git-id index 17c1af3..951fcba 100644 --- a/view1090.REMOVED.git-id +++ b/view1090.REMOVED.git-id @@ -1 +1 @@ -b7d48859caf08d954d9a9d596481d36962f33b98 \ No newline at end of file +56c0107a5f8eb9b1a33224437cf439396118c999 \ No newline at end of file diff --git a/view1090.c b/view1090.c index e1bb485..9b93dee 100644 --- a/view1090.c +++ b/view1090.c @@ -33,13 +33,19 @@ int go = 1; + +AppData appData; +Style style; + +Modes modes; + // // ============================= Utility functions ========================== // void sigintHandler(int dummy) { NOTUSED(dummy); signal(SIGINT, SIG_DFL); // reset signal handler - bit extra safety - Modes.exit = 1; // Signal to threads that we are done + modes.exit = 1; // Signal to threads that we are done } // @@ -47,26 +53,26 @@ void sigintHandler(int dummy) { // void view1090InitConfig(void) { // Default everything to zero/NULL - memset(&Modes, 0, sizeof(Modes)); + memset(&modes, 0, sizeof(Modes)); memset(&View1090, 0, sizeof(View1090)); // Now initialise things that should not be 0/NULL to their defaults - Modes.check_crc = 1; + modes.check_crc = 1; strcpy(View1090.net_input_beast_ipaddr,VIEW1090_NET_OUTPUT_IP_ADDRESS); - Modes.net_input_beast_port = MODES_NET_OUTPUT_BEAST_PORT; - Modes.interactive_rows = MODES_INTERACTIVE_ROWS; - Modes.interactive_delete_ttl = MODES_INTERACTIVE_DELETE_TTL; - Modes.interactive_display_ttl = MODES_INTERACTIVE_DISPLAY_TTL; - Modes.fUserLat = MODES_USER_LATITUDE_DFLT; - Modes.fUserLon = MODES_USER_LONGITUDE_DFLT; + modes.net_input_beast_port = MODES_NET_OUTPUT_BEAST_PORT; + modes.interactive_rows = MODES_INTERACTIVE_ROWS; + modes.interactive_delete_ttl = MODES_INTERACTIVE_DELETE_TTL; + modes.interactive_display_ttl = MODES_INTERACTIVE_DISPLAY_TTL; + modes.fUserLat = MODES_USER_LATITUDE_DFLT; + modes.fUserLon = MODES_USER_LONGITUDE_DFLT; - Modes.interactive = 0; - Modes.quiet = 1; + modes.interactive = 0; + modes.quiet = 1; // Map options appData.maxDist = 25.0; - appData.centerLon = Modes.fUserLon; - appData.centerLat = Modes.fUserLat; + appData.centerLon = modes.fUserLon; + appData.centerLat = modes.fUserLat; // Display options appData.screen_uiscale = 1; @@ -87,15 +93,15 @@ void view1090InitConfig(void) { // void view1090Init(void) { - // pthread_mutex_init(&Modes.pDF_mutex,NULL); - // pthread_mutex_init(&Modes.data_mutex,NULL); - // pthread_cond_init(&Modes.data_cond,NULL); + // pthread_mutex_init(&modes.pDF_mutex,NULL); + // pthread_mutex_init(&modes.data_mutex,NULL); + // pthread_cond_init(&modes.data_cond,NULL); #ifdef _WIN32 - if ( (!Modes.wsaData.wVersion) - && (!Modes.wsaData.wHighVersion) ) { + if ( (!modes.wsaData.wVersion) + && (!modes.wsaData.wHighVersion) ) { // Try to start the windows socket support - if (WSAStartup(MAKEWORD(2,1),&Modes.wsaData) != 0) + if (WSAStartup(MAKEWORD(2,1),&modes.wsaData) != 0) { fprintf(stderr, "WSAStartup returned Error\n"); } @@ -103,32 +109,32 @@ void view1090Init(void) { #endif // Allocate the various buffers used by Modes - if ( NULL == (Modes.icao_cache = (uint32_t *) malloc(sizeof(uint32_t) * MODES_ICAO_CACHE_LEN * 2))) + if ( NULL == (modes.icao_cache = (uint32_t *) malloc(sizeof(uint32_t) * MODES_ICAO_CACHE_LEN * 2))) { fprintf(stderr, "Out of memory allocating data buffer.\n"); exit(1); } // Clear the buffers that have just been allocated, just in-case - memset(Modes.icao_cache, 0, sizeof(uint32_t) * MODES_ICAO_CACHE_LEN * 2); + memset(modes.icao_cache, 0, sizeof(uint32_t) * MODES_ICAO_CACHE_LEN * 2); // Validate the users Lat/Lon home location inputs - if ( (Modes.fUserLat > 90.0) // Latitude must be -90 to +90 - || (Modes.fUserLat < -90.0) // and - || (Modes.fUserLon > 360.0) // Longitude must be -180 to +360 - || (Modes.fUserLon < -180.0) ) { - Modes.fUserLat = Modes.fUserLon = 0.0; - } else if (Modes.fUserLon > 180.0) { // If Longitude is +180 to +360, make it -180 to 0 - Modes.fUserLon -= 360.0; + if ( (modes.fUserLat > 90.0) // Latitude must be -90 to +90 + || (modes.fUserLat < -90.0) // and + || (modes.fUserLon > 360.0) // Longitude must be -180 to +360 + || (modes.fUserLon < -180.0) ) { + modes.fUserLat = modes.fUserLon = 0.0; + } else if (modes.fUserLon > 180.0) { // If Longitude is +180 to +360, make it -180 to 0 + modes.fUserLon -= 360.0; } // If both Lat and Lon are 0.0 then the users location is either invalid/not-set, or (s)he's in the // Atlantic ocean off the west coast of Africa. This is unlikely to be correct. // Set the user LatLon valid flag only if either Lat or Lon are non zero. Note the Greenwich meridian // is at 0.0 Lon,so we must check for either fLat or fLon being non zero not both. // Testing the flag at runtime will be much quicker than ((fLon != 0.0) || (fLat != 0.0)) - Modes.bUserFlags &= ~MODES_USER_LATLON_VALID; - if ((Modes.fUserLat != 0.0) || (Modes.fUserLon != 0.0)) { - Modes.bUserFlags |= MODES_USER_LATLON_VALID; + modes.bUserFlags &= ~MODES_USER_LATLON_VALID; + if ((modes.fUserLat != 0.0) || (modes.fUserLon != 0.0)) { + modes.bUserFlags |= MODES_USER_LATLON_VALID; } // Prepare error correction tables @@ -140,8 +146,8 @@ int setupConnection(struct client *c) { int fd; // Try to connect to the selected ip address and port. We only support *ONE* input connection which we initiate.here. - if ((fd = anetTcpConnect(Modes.aneterr, View1090.net_input_beast_ipaddr, Modes.net_input_beast_port)) != ANET_ERR) { - anetNonBlock(Modes.aneterr, fd); + if ((fd = anetTcpConnect(modes.aneterr, View1090.net_input_beast_ipaddr, modes.net_input_beast_port)) != ANET_ERR) { + anetNonBlock(modes.aneterr, fd); // // Setup a service callback client structure for a beast binary input (from dump1090) // This is a bit dodgy under Windows. The fd parameter is a handle to the internet @@ -157,8 +163,8 @@ int setupConnection(struct client *c) { c->buflen = 0; c->fd = c->service = - Modes.bis = fd; - Modes.clients = c; + modes.bis = fd; + modes.clients = c; } return fd; } @@ -236,21 +242,21 @@ int main(int argc, char **argv) { int more = ((j + 1) < argc); // There are more arguments if (!strcmp(argv[j],"--net-bo-port") && more) { - Modes.net_input_beast_port = atoi(argv[++j]); + modes.net_input_beast_port = atoi(argv[++j]); } else if (!strcmp(argv[j],"--port") && more) { - Modes.net_input_beast_port = atoi(argv[++j]); + modes.net_input_beast_port = atoi(argv[++j]); } else if (!strcmp(argv[j],"--net-bo-ipaddr") && more) { strcpy(View1090.net_input_beast_ipaddr, argv[++j]); } else if (!strcmp(argv[j],"--server") && more) { strcpy(View1090.net_input_beast_ipaddr, argv[++j]); } else if (!strcmp(argv[j],"--lat") && more) { - Modes.fUserLat = atof(argv[++j]); - appData.centerLat = Modes.fUserLat; + modes.fUserLat = atof(argv[++j]); + appData.centerLat = modes.fUserLat; } else if (!strcmp(argv[j],"--lon") && more) { - Modes.fUserLon = atof(argv[++j]); - appData.centerLon = Modes.fUserLon; + modes.fUserLon = atof(argv[++j]); + appData.centerLon = modes.fUserLon; } else if (!strcmp(argv[j],"--metric")) { - Modes.metric = 1; + modes.metric = 1; } else if (!strcmp(argv[j],"--fullscreen")) { appData.fullscreen = 1; } else if (!strcmp(argv[j],"--uiscale") && more) { @@ -275,7 +281,7 @@ int main(int argc, char **argv) { c = (struct client *) malloc(sizeof(*c)); while(1) { if ((fd = setupConnection(c)) == ANET_ERR) { - fprintf(stderr, "Waiting on %s:%d\n", View1090.net_input_beast_ipaddr, Modes.net_input_beast_port); + fprintf(stderr, "Waiting on %s:%d\n", View1090.net_input_beast_ipaddr, modes.net_input_beast_port); sleep(1); } else { break; @@ -283,6 +289,7 @@ int main(int argc, char **argv) { } int go; + init("sdl1090"); @@ -295,9 +302,7 @@ int main(int argc, char **argv) { getInput(); interactiveRemoveStaleAircrafts(); - draw(); - if ((fd == ANET_ERR) || (recv(c->fd, pk_buf, sizeof(pk_buf), MSG_PEEK | MSG_DONTWAIT) == 0)) { free(c); usleep(1000000); @@ -306,7 +311,6 @@ int main(int argc, char **argv) { continue; } modesReadFromClient(c,"",decodeBinMessage); - //usleep(10000); }