aboutsummaryrefslogtreecommitdiff
path: root/GEOLOC/lib/gps.c
diff options
context:
space:
mode:
Diffstat (limited to 'GEOLOC/lib/gps.c')
-rw-r--r--GEOLOC/lib/gps.c147
1 files changed, 147 insertions, 0 deletions
diff --git a/GEOLOC/lib/gps.c b/GEOLOC/lib/gps.c
new file mode 100644
index 0000000..4eec6cc
--- /dev/null
+++ b/GEOLOC/lib/gps.c
@@ -0,0 +1,147 @@
+#include "gps.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <unistd.h>
+
+#define GPS_DEV_FILE "/dev/ttyS0" // Define GPS serial port file
+#define BUFFER_SIZE 100 // Define receive buffer size
+
+/**
+ * Configure UART channel
+ * TODO : Set baud rate to ???? see NMEA datasheet
+ */
+void configSerialPort(int fd){
+ struct termios Termios;
+ tcgetattr(fd,&Termios);
+ Termios.c_lflag |= ICANON;
+ tcsetattr(fd,TCSANOW,&Termios);
+ tcflush(fd, TCIFLUSH); // Clear already received frames
+}
+
+/**
+ * Fetch NMEA Frame type
+ * TODO : Other frame types
+ */
+NMEA_TYPE getNMEA_TYPE(unsigned char *data){
+ unsigned char* typeChar=malloc(sizeof(char)*4);
+ typeChar[3]='\0';
+ memcpy(typeChar, data+3,3);
+ if(strcmp(typeChar, "GGA")==0){
+ return(GGA);
+ }
+ free(typeChar);
+ return(NONE);
+}
+
+/**
+ * Build NMEA frame from array of char
+ * TODO : Other GGA parameters
+ */
+struct NMEA_GGA buildNMEA_GGA(unsigned char *data){
+// data="$GPGGA,095003.000,2055.9571,S,05517.4159,E,1,6,1.59,138.8,M,-9.9,M,,*5D"; // To test !!!
+ struct NMEA_GGA frame;
+ unsigned char *buffer=malloc(sizeof(char)*strlen(data));
+ memcpy(buffer,data,strlen(data));
+
+ short i=1;
+ char *saveP;
+ char *token=strtok_r(buffer,",",&saveP);
+ while(token!=NULL){
+ if(strlen(token)>0){
+ char tmp[6];
+ switch(i){
+ case 2: // Fetch hour, min, sec and ms
+ memcpy(tmp,token,2);tmp[2]='\0';
+ frame.hour=atoi(tmp);
+ memcpy(tmp,token+2,2);
+ frame.min=atoi(tmp);
+ memcpy(tmp,token+4,2);
+ frame.sec=atoi(tmp);
+ memcpy(tmp,token+7,3);tmp[3]='\0';
+ frame.ms=atoi(tmp);
+ break;
+ case 3: // Fetch Latitude
+ memcpy(tmp,token,2);tmp[2]='\0';
+ frame.latDeg=atoi(tmp);
+ memcpy(tmp,token+2,2);
+ frame.latMin=atoi(tmp);
+ memcpy(tmp,token+5,4);tmp[4]='\0';
+ frame.latSec=atoi(tmp);
+ frame.latSec=frame.latSec/10000;
+ frame.latSec=(3600*frame.latSec)/60; // Convertion degrès min en degrès sec
+ break;
+ case 4: // Fetch latitude direction
+ frame.latDir=token[0];
+ break;
+ case 5: // Fetch longitude
+ memcpy(tmp,token,3);tmp[3]='\0';
+ frame.lonDeg=atoi(tmp);
+ tmp[2]='\0';
+ memcpy(tmp,token+3,2);
+ frame.lonMin=atoi(tmp);
+ memcpy(tmp,token+6,4);tmp[4]='\0';
+ frame.lonSec=atoi(tmp);
+ frame.lonSec=frame.lonSec/10000;
+ frame.lonSec=(3600*frame.lonSec)/60; // Convertion degrès min en degrès sec
+ break;
+ case 6: // Fetch longitude direction
+ frame.lonDir=token[0];
+ break;
+ case 7: // Fetch GPS state
+ frame.state=atoi(token);
+ break;
+ case 8: // Fetch number of statellites
+ frame.sats=atoi(token);
+ break;
+ }
+ }
+ token=strtok_r(NULL,",",&saveP);
+ i++;
+ }
+
+ free(buffer);
+ return(frame);
+
+}
+
+/**
+ * Fetch NMEA FRAME
+ */
+struct NMEA_GGA getNMEA_GGAFrame(){
+
+ int fd; // File descriptor
+ const char *device = "/dev/ttyS0";
+ fd = open(device, O_RDWR);
+ if(fd == -1) {
+ printf( "Failed to open gps device.\n" );
+ }
+
+ // Configure the serial port
+ configSerialPort(fd);
+
+ struct NMEA_GGA frame; // Def empty frame
+ short i;
+ // Try to feth the GGA frame (100 times max)
+ for(i=0;i<100;i++){
+ char out[BUFFER_SIZE];
+ memset(out,0,BUFFER_SIZE);
+ read(fd,out,BUFFER_SIZE);
+ if(strlen(out)>1){
+ if(getNMEA_TYPE(out)==GGA){
+ frame=buildNMEA_GGA(out);
+ //if(frame.state!=UNFIXED){
+ // printf("%d:%d:%d:%d\nLat : %d deg %d min %f sec %d Dir\n",frame.hour,frame.min,frame.sec,frame.ms,frame.latDeg,frame.latMin,frame.latSec, frame.latDir);
+ // printf("Lon : %d deg %d min %f sec %d Dir\n",frame.lonDeg,frame.lonMin,frame.lonSec, frame.lonDir);
+ // printf("Sats : %d",frame.sats);
+ // printf("%s",out);
+ //}
+ break; // If the frame is found, exit
+ }
+ }
+ }
+ close(fd);
+ return(frame);
+}