aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVotre Nom <git-account@loicguegan.fr>2017-08-30 10:48:11 +0400
committerVotre Nom <git-account@loicguegan.fr>2017-08-30 10:48:11 +0400
commitf37f200792444fee2f74e807acfd5be7c9180cd7 (patch)
tree135975e83d27a144d56f27e1ee4dc6fe0fe91af0
Init repo
-rw-r--r--GEOLOC/Makefile34
-rw-r--r--GEOLOC/Readme.md47
-rw-r--r--GEOLOC/app/Makefile18
-rw-r--r--GEOLOC/app/anchor/Makefile22
-rw-r--r--GEOLOC/app/anchor/app.c83
-rw-r--r--GEOLOC/app/anchor/app.h17
-rw-r--r--GEOLOC/app/anchor/records.c51
-rw-r--r--GEOLOC/app/anchor/records.h17
-rw-r--r--GEOLOC/app/anchor/socket/Makefile15
-rw-r--r--GEOLOC/app/anchor/socket/clientBC.c45
-rw-r--r--GEOLOC/app/anchor/socket/clientTCP.c46
-rw-r--r--GEOLOC/app/anchor/socket/com.c44
-rw-r--r--GEOLOC/app/anchor/socket/com.h40
-rw-r--r--GEOLOC/app/anchor/socket/gwframe.h16
-rw-r--r--GEOLOC/app/anchor/socket/serverBC.c51
-rw-r--r--GEOLOC/app/anchor/socket/serverTCP.c61
-rw-r--r--GEOLOC/app/frame.c22
-rw-r--r--GEOLOC/app/frame.h21
-rw-r--r--GEOLOC/app/mobile/app.c84
-rw-r--r--GEOLOC/app/mobile/app.h16
-rw-r--r--GEOLOC/lib/config.c51
-rw-r--r--GEOLOC/lib/config.h62
-rw-r--r--GEOLOC/lib/dragino.c40
-rw-r--r--GEOLOC/lib/dragino.h38
-rw-r--r--GEOLOC/lib/fskconfig.c66
-rw-r--r--GEOLOC/lib/fskconfig.h67
-rw-r--r--GEOLOC/lib/gps.c147
-rw-r--r--GEOLOC/lib/gps.h53
-rw-r--r--GEOLOC/lib/types.h10
-rw-r--r--GEOLOC/main.c51
-rw-r--r--Readme.md6
31 files changed, 1341 insertions, 0 deletions
diff --git a/GEOLOC/Makefile b/GEOLOC/Makefile
new file mode 100644
index 0000000..fdf543d
--- /dev/null
+++ b/GEOLOC/Makefile
@@ -0,0 +1,34 @@
+EXEC=GEOLOC
+export TARGET=MOBILE# ANCHOR or MOBILE
+export ANCHOR_ID=2# Define the anchor id
+export IS_MASTER=0# Define if this anchor is master or not
+export CC=gcc -g -D TARGET=$(TARGET) -D ANCHOR_ID=$(ANCHOR_ID) -D IS_MASTER=$(IS_MASTER) -Ilib -lm -pthread
+export LDFLAGS=-lwiringPi
+
+all:$(EXEC)
+
+$(EXEC): main.o lib/dragino.o lib/config.o lib/fskconfig.o app/app.o lib/gps.o
+ $(CC) $^ -o $(EXEC) $(LDFLAGS)
+
+main.o: main.c
+ $(CC) -c $< -o $@
+
+lib/dragino.o: lib/dragino.c
+ $(CC) -c $^ -o $@
+
+lib/config.o: lib/config.c
+ $(CC) -c $^ -o $@
+
+lib/fskconfig.o: lib/fskconfig.c
+ $(CC) -c $^ -o $@
+
+lib/gps.o: lib/gps.c
+ $(CC) -c $^ -o $@
+
+app/app.o:
+ $(MAKE) -C ./app
+
+clean:
+ -$(MAKE) -C ./app clean
+ -find ./ -name "*.o" -delete
+ -rm $(EXEC)
diff --git a/GEOLOC/Readme.md b/GEOLOC/Readme.md
new file mode 100644
index 0000000..d12a02e
--- /dev/null
+++ b/GEOLOC/Readme.md
@@ -0,0 +1,47 @@
+GEOLOC
+===================
+
+
+Some explanations about the GEOLOC project.
+
+----------
+
+
+Folders structure
+-------------
+
+#### <i class="icon-folder"></i> lib
+
+Contains library for accessing to dragino shield components (GPS and SX1276). It contains also tools for SX1276 registers configurations.
+
+
+#### <i class="icon-folder"></i> app
+
+Contains mobile application (turtle transmitter) and anchor application (gateway).
+
+
+#### <i class="icon-folder"></i> app/anchor/socket
+
+Contains application for gateway communication.
+
+#### <i class="icon-folder"></i> records
+
+Folder created by the GEOLOC application to store received frame from mobile application and slave gateways.
+
+Build the project
+-------------
+
+Configure the project by changing variable from <i>Makefile</i> :
+
+1. **TARGET** : Choose between MOBILE or ANCHOR (take care to do not add space at the end of the variable)
+2. **ANCHOR_ID** : Change the anchor id
+3. **IS_MASTER** : Define if the anchor is the master 1 for yes and 0 for no
+
+Next run the next command in the project root folder to build the project :
+
+ make
+ To clear the project run :
+
+
+ make clean
+ \ No newline at end of file
diff --git a/GEOLOC/app/Makefile b/GEOLOC/app/Makefile
new file mode 100644
index 0000000..4f23251
--- /dev/null
+++ b/GEOLOC/app/Makefile
@@ -0,0 +1,18 @@
+
+all: app.o
+
+app.o:
+ifeq ($(TARGET),ANCHOR)
+ $(MAKE) -C ./anchor
+ cp anchor/app.o ./
+else
+ $(CC) -c ./mobile/app.c -o ./app.o
+endif
+ $(CC) -c frame.c -o frame.o
+ ld -r app.o frame.o -o app_tmp.o
+ mv app_tmp.o $@
+
+.PHONY: clean
+
+clean:
+ -rm ./app.o ./frame.o
diff --git a/GEOLOC/app/anchor/Makefile b/GEOLOC/app/anchor/Makefile
new file mode 100644
index 0000000..91280a1
--- /dev/null
+++ b/GEOLOC/app/anchor/Makefile
@@ -0,0 +1,22 @@
+
+all: app.o
+
+app.o: socket.o app_tmp.o records.o
+ ld -r $^ -o $@
+ -rm app_tmp.o
+
+socket.o:
+ $(MAKE) -C ./socket
+ cp socket/socket.o ./
+
+records.o:records.c
+ $(CC) -c $^ -o $@
+
+app_tmp.o:app.c
+ $(CC) -c $^ -o $@
+
+.PHONY: clean
+
+clean:
+ $(MAKE) clean -C ./socket
+ -rm ./*.o
diff --git a/GEOLOC/app/anchor/app.c b/GEOLOC/app/anchor/app.c
new file mode 100644
index 0000000..4ff2c6e
--- /dev/null
+++ b/GEOLOC/app/anchor/app.c
@@ -0,0 +1,83 @@
+#include <stdio.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <string.h>
+#include "app.h"
+#include "../frame.h"
+#include <pthread.h>
+#include "../../lib/gps.h"
+#include "socket/com.h"
+#include "records.h"
+
+//extern struct NMEA_GGA NmeaGgaFrame;
+pthread_mutex_t mutex_NmeaGgaFrame; // Mutex for thread that use MASTER_IP
+
+void runApp(Config config){
+ // Hello msg
+ printf("\n|Starting gateway application|\n\n");
+
+ // Start GW communication
+ startGWCom();
+
+ // Ensure we are in standby mode and apply configuration
+ config.mode=MODE_STDBY;
+ applyMode(config);
+ applyConfig(config);
+
+ config.mode=MODE_RX;
+ applyMode(config);
+
+ pthread_t frameHandlerThread;
+
+ printf("Wait for packet...\n");
+ while(1){
+ if(digitalRead(0x7)==1){
+ // Build parameters
+ Frame frame=pullFrame();
+ int rssi=fetchRSSI();
+ void *param;
+ param=malloc(sizeof(Frame)+sizeof(int));
+ *((Frame *)param)=frame;
+ *((int *)(param+sizeof(Frame)))=rssi;
+ // Run thread
+ pthread_create(&frameHandlerThread, NULL, handleMessage, param);
+ config.mode=MODE_STDBY;
+ applyMode(config);
+ config.mode=MODE_RX;
+ applyMode(config);
+ }
+ }
+ pthread_join(frameHandlerThread,NULL);
+
+}
+
+void *handleMessage(void *args){
+ // Fetch parameters
+ Frame frame=*((Frame *)args);
+ int rssi=*((int *)(args+sizeof(Frame)));
+
+ // Print informations
+ printf("Packet receive !!!\n\n");
+ printf("Frame info :\nId : %d\nStamp : %d\nData 1-6 : %d %d %d %d %d %d\nRSSI : %d\n\n",
+ frame.id, frame.stamp,
+ frame.data[0],frame.data[1],frame.data[2],frame.data[3],frame.data[4],frame.data[5],
+ rssi);
+
+ GWFrame masterFrame;
+ masterFrame.slaveID=ANCHOR_ID;
+
+ pthread_mutex_lock(& mutex_NmeaGgaFrame);
+ masterFrame.ggaFrame=getNMEA_GGAFrame();
+ pthread_mutex_unlock(& mutex_NmeaGgaFrame);
+
+ masterFrame.frame=frame;
+ masterFrame.rssi=rssi;
+
+ if(!IS_MASTER){
+ sendDataToMaster(masterFrame);
+ }
+ else{
+ saveFrame(masterFrame);
+ }
+}
diff --git a/GEOLOC/app/anchor/app.h b/GEOLOC/app/anchor/app.h
new file mode 100644
index 0000000..06d569b
--- /dev/null
+++ b/GEOLOC/app/anchor/app.h
@@ -0,0 +1,17 @@
+#ifndef app_h
+#define app_h
+
+#include "../frame.h"
+#include "../../lib/config.h"
+
+/**
+ * Run the application
+ */
+void runApp(Config config);
+
+/**
+ * Used to handle received frame from mobile
+ */
+void *handleMessage(void *args);
+
+#endif
diff --git a/GEOLOC/app/anchor/records.c b/GEOLOC/app/anchor/records.c
new file mode 100644
index 0000000..db14206
--- /dev/null
+++ b/GEOLOC/app/anchor/records.c
@@ -0,0 +1,51 @@
+
+#include "records.h"
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+void saveFrame(GWFrame frame){
+ // Create records dir if not exists
+ mkdir(RECORDS_DIR,0777);
+
+// // Build string
+ char idStr[50];
+ sprintf(idStr,"/anchor_%d", frame.slaveID);
+ char filePath[200];
+ filePath[0]='\0';
+ strcat(filePath, RECORDS_DIR);
+ strcat(filePath, idStr);
+
+// // Save in file
+ FILE *file;
+ short writeHeader=0;
+ pthread_mutex_lock (& mutex_file);
+ if(access( filePath, F_OK ) == -1){
+ writeHeader=1;
+ }
+ file=fopen(filePath,"a+");
+ if(file!=NULL){
+ if(writeHeader){
+ fprintf(file,"GWID,GPSSTATE,LatDeg,LatMin,LatSec,LatDir,LonDeg,LonMin,LonSec,LonDir,turtleID,rssi\n");
+ }
+ fprintf(file,"%d,%d,%d,%d,%f,%d,%d,%d,%f,%d,%d,%d\n",
+ frame.slaveID,
+ frame.ggaFrame.state,
+ frame.ggaFrame.latDeg,
+ frame.ggaFrame.latMin,
+ frame.ggaFrame.latSec,
+ frame.ggaFrame.latDir,
+ frame.ggaFrame.lonDeg,
+ frame.ggaFrame.lonMin,
+ frame.ggaFrame.lonSec,
+ frame.ggaFrame.lonDir,
+ frame.frame.id,
+ frame.rssi);
+ fclose(file);
+ }
+ else{
+ printf("Failed to open file %s.\n",filePath);
+ }
+ pthread_mutex_unlock (& mutex_file);
+}
diff --git a/GEOLOC/app/anchor/records.h b/GEOLOC/app/anchor/records.h
new file mode 100644
index 0000000..db17b8a
--- /dev/null
+++ b/GEOLOC/app/anchor/records.h
@@ -0,0 +1,17 @@
+#ifndef records_h
+#define records_h
+
+#include <pthread.h>
+#include "socket/gwframe.h"
+
+#define RECORDS_DIR "./records"
+
+// Mutex for thread writing in same file
+pthread_mutex_t mutex_file;
+
+/**
+ * Save GWFrame into file
+ */
+void saveFrame(GWFrame frame);
+
+#endif
diff --git a/GEOLOC/app/anchor/socket/Makefile b/GEOLOC/app/anchor/socket/Makefile
new file mode 100644
index 0000000..84632b2
--- /dev/null
+++ b/GEOLOC/app/anchor/socket/Makefile
@@ -0,0 +1,15 @@
+
+all:socket.o
+
+socket.o: clientTCP.c serverTCP.c clientBC.c serverBC.c com.c
+ $(CC) -c clientTCP.c
+ $(CC) -c serverTCP.c
+ $(CC) -c clientBC.c
+ $(CC) -c serverBC.c
+ $(CC) -c com.c
+ ld -r ./*.o -o $@
+
+.PHONY: clean
+
+clean:
+ -rm ./*.o
diff --git a/GEOLOC/app/anchor/socket/clientBC.c b/GEOLOC/app/anchor/socket/clientBC.c
new file mode 100644
index 0000000..8230a6d
--- /dev/null
+++ b/GEOLOC/app/anchor/socket/clientBC.c
@@ -0,0 +1,45 @@
+#include<stdio.h>
+#include<string.h> //strlen
+#include<sys/socket.h>
+#include <unistd.h>
+#include<arpa/inet.h> //inet_addr
+#include "com.h"
+
+
+
+
+void rcvIPFromMaster()
+{
+ int socketID;
+ struct sockaddr_in SockAddr;
+ int allowBC=1;
+
+ socketID=socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ setsockopt(socketID,SOL_SOCKET,SO_BROADCAST,(void*) &allowBC,sizeof(allowBC));
+
+ SockAddr.sin_family=AF_INET;
+ SockAddr.sin_port=htons(DATA_PORT);
+ SockAddr.sin_addr.s_addr=htonl(INADDR_BROADCAST);
+
+
+ int binded=bind(socketID,(struct sockaddr *) &SockAddr,sizeof(SockAddr));
+ if(binded<0){
+ puts("Failed to bind socket for receiving IP from master.");
+ close(socketID);
+ }
+ else{
+ listen(socketID,3);
+ socklen_t src_addr_len=sizeof(SockAddr);
+ char buffer[MASTER_IP_SIZE];
+ memset(buffer, 0x0,MASTER_IP_SIZE);
+ recvfrom(socketID,buffer,sizeof(buffer),0,(struct sockaddr*)&SockAddr,&src_addr_len);
+ close(socketID);
+ puts(buffer);
+
+ pthread_mutex_lock(&mutex_master_ip);
+ memset(MASTER_IP, 0x0,MASTER_IP_SIZE);
+ memcpy(MASTER_IP, buffer,MASTER_IP_SIZE);
+ pthread_mutex_unlock(&mutex_master_ip);
+ }
+
+}
diff --git a/GEOLOC/app/anchor/socket/clientTCP.c b/GEOLOC/app/anchor/socket/clientTCP.c
new file mode 100644
index 0000000..621da24
--- /dev/null
+++ b/GEOLOC/app/anchor/socket/clientTCP.c
@@ -0,0 +1,46 @@
+#include<stdio.h>
+#include<string.h> //strlen
+#include <stdlib.h>
+#include<sys/socket.h>
+#include <unistd.h>
+#include<arpa/inet.h> //inet_addr
+#include "com.h"
+
+void sendDataToMaster(GWFrame frame){
+
+ int socket_desc;
+ struct sockaddr_in server;
+ socket_desc=socket(AF_INET, SOCK_STREAM,0);
+ char message[1000]="GET / HTTP/1.1\r\n\r\n";
+ char serverReply[2000];
+
+ if(socket_desc==-1){
+ puts("Failed to create socket.");
+ }
+ else{
+ // Configure server
+ pthread_mutex_lock(&mutex_master_ip);
+ server.sin_addr.s_addr = inet_addr(MASTER_IP);
+ pthread_mutex_unlock(&mutex_master_ip);
+ server.sin_family = AF_INET;
+ server.sin_port = htons(DATA_PORT);
+
+ if(connect(socket_desc,(struct sockaddr *)&server, sizeof(server))<0){
+ puts("Failed to connect to server");
+ }
+ else{
+ puts("Socket connected");
+ if(send(socket_desc, &frame, sizeof(GWFrame),0)<0){
+ puts("Failed to send message.");
+ }
+ puts("Data send !");
+ if(recv(socket_desc, serverReply,2000,0)<0){
+ puts("Timeout");
+ }
+ puts(serverReply);
+
+ }
+
+ close(socket_desc);
+ }
+}
diff --git a/GEOLOC/app/anchor/socket/com.c b/GEOLOC/app/anchor/socket/com.c
new file mode 100644
index 0000000..f0fa1d2
--- /dev/null
+++ b/GEOLOC/app/anchor/socket/com.c
@@ -0,0 +1,44 @@
+#include <stdio.h>
+#include <string.h>
+#include <pthread.h>
+#include "com.h"
+#include "../records.h"
+
+static void *rcvIPFromMasterThread(void *args){
+ while(1){
+ rcvIPFromMaster();
+ puts("Master IP receive !");
+ //delay(IP_SEND_INTERVAL/2); // Add delay to free cpu resources
+ }
+}
+
+static void *sendIPToSlaveThread(void *args){
+ while(1){
+ puts("Send Master IP to slave...");
+ sendIPToSlave();
+ delay(IP_SEND_INTERVAL); // Wait five minutes
+ }
+}
+
+
+static void *rcvDataFromSlaveThread(void *args){
+ while(1){
+ GWFrame frame;
+ frame=rcvDataFromSlave();
+ puts("Frame receive from a slave !");
+ saveFrame(frame);
+ }
+}
+
+void startGWCom(){
+
+#if IS_MASTER != 0
+ pthread_t sendIPThread, rcvDataThread;
+ pthread_create(&sendIPThread, NULL, sendIPToSlaveThread, NULL);
+ pthread_create(&rcvDataThread, NULL, rcvDataFromSlaveThread, NULL);
+#else
+ pthread_t rcvIPThread;
+ pthread_create(&rcvIPThread, NULL, rcvIPFromMasterThread, NULL);
+#endif
+
+}
diff --git a/GEOLOC/app/anchor/socket/com.h b/GEOLOC/app/anchor/socket/com.h
new file mode 100644
index 0000000..18539e5
--- /dev/null
+++ b/GEOLOC/app/anchor/socket/com.h
@@ -0,0 +1,40 @@
+#ifndef com_h
+#define com_h
+
+#include "gwframe.h"
+
+#define IP_SEND_INTERVAL 300000
+#define DATA_PORT 8888
+#define IFACE "wlan0"
+#define MASTER_IP_SIZE 100 // Buffer size for IP address char
+
+char MASTER_IP[MASTER_IP_SIZE]; // Master IP (global variable)
+pthread_mutex_t mutex_master_ip; // Mutex for thread that use MASTER_IP
+
+/**
+ * Init GW communication
+ */
+void startGWCom();
+
+/**
+ * Send GW frame to master GW
+ */
+void sendDataToMaster(GWFrame frame);
+
+/**
+ * Start master GW slave frame receiver server
+ */
+GWFrame rcvDataFromSlave();
+
+/**
+ * Start slave ip reveiver server
+ */
+void rcvIPFromMaster();
+
+/**
+ * Send master ip to slaves (broadcast UDP)
+ */
+void sendIPToSlave();
+
+
+#endif
diff --git a/GEOLOC/app/anchor/socket/gwframe.h b/GEOLOC/app/anchor/socket/gwframe.h
new file mode 100644
index 0000000..b454d8c
--- /dev/null
+++ b/GEOLOC/app/anchor/socket/gwframe.h
@@ -0,0 +1,16 @@
+#ifndef gwframe_h
+#define gwframe_h
+
+#include "../../frame.h"
+#include "../../../lib/gps.h"
+
+typedef struct GWFrame GWFrame;
+struct GWFrame {
+ short slaveID;
+ struct NMEA_GGA ggaFrame;
+ int rssi;
+ Frame frame;
+};
+
+
+#endif
diff --git a/GEOLOC/app/anchor/socket/serverBC.c b/GEOLOC/app/anchor/socket/serverBC.c
new file mode 100644
index 0000000..2e2da88
--- /dev/null
+++ b/GEOLOC/app/anchor/socket/serverBC.c
@@ -0,0 +1,51 @@
+#include<stdio.h>
+#include<string.h> //strlen
+#include<sys/socket.h>
+#include <net/if.h>
+#include "com.h"
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include<arpa/inet.h> //inet_addr
+
+
+
+static char *getIp(){
+ int fd;
+ struct ifreq ifr;
+
+ char iface[] = IFACE;
+
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+
+ //Type of address to retrieve - IPv4 IP address
+ ifr.ifr_addr.sa_family = AF_INET;
+
+ //Copy the interface name in the ifreq structure
+ strncpy(ifr.ifr_name , iface , IFNAMSIZ-1);
+
+ ioctl(fd, SIOCGIFADDR, &ifr);
+
+ close(fd);
+ return(inet_ntoa(( (struct sockaddr_in *)&ifr.ifr_addr )->sin_addr));
+}
+
+void sendIPToSlave()
+{
+ int socketID;
+ struct sockaddr_in SockAddr;
+ int allowBC=1;
+
+ socketID=socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ setsockopt(socketID,SOL_SOCKET,SO_BROADCAST,(void*) &allowBC,sizeof(allowBC));
+
+ SockAddr.sin_family=AF_INET;
+ SockAddr.sin_port=htons(DATA_PORT);
+ SockAddr.sin_addr.s_addr=htonl(INADDR_BROADCAST);
+
+ char *addr;
+ addr=getIp();
+ sendto(socketID,addr,strlen(addr),0,(struct sockaddr*)&SockAddr, sizeof(SockAddr));
+
+}
+
+
diff --git a/GEOLOC/app/anchor/socket/serverTCP.c b/GEOLOC/app/anchor/socket/serverTCP.c
new file mode 100644
index 0000000..2ed9b71
--- /dev/null
+++ b/GEOLOC/app/anchor/socket/serverTCP.c
@@ -0,0 +1,61 @@
+
+#include<stdio.h>
+#include<string.h> //strlen
+#include<sys/socket.h>
+#include <unistd.h>
+#include<arpa/inet.h> //inet_addr
+#include "com.h"
+#include "./gwframe.h"
+#include "../records.h"
+
+
+int serverTCP_socket_desc=-1;
+
+GWFrame rcvDataFromSlave(){
+
+ if(serverTCP_socket_desc==-1){
+ // Create socket
+ serverTCP_socket_desc=socket(AF_INET, SOCK_STREAM,0);
+ if(serverTCP_socket_desc==-1){
+ puts("Failed to create socket");
+ exit(1);
+ }
+ struct sockaddr_in listen_addr;
+
+ listen_addr.sin_family = AF_INET;
+ listen_addr.sin_addr.s_addr = INADDR_ANY;
+ listen_addr.sin_port = htons(DATA_PORT);
+
+ int binded=bind(serverTCP_socket_desc,(struct sockaddr *) &listen_addr,sizeof(listen_addr));
+ if(binded<0){
+ puts("Failed to bind, trying until it work...");
+ while(binded<0){
+ binded=bind(serverTCP_socket_desc,(struct sockaddr *) &listen_addr,sizeof(listen_addr));
+ sleep(1);
+ }
+ puts("Bind succeed !");
+ }
+
+ listen(serverTCP_socket_desc,3);
+ }
+
+ int client,len;
+ struct sockaddr_in client_addr;
+ client=accept(serverTCP_socket_desc, (struct sockaddr *)&client_addr, (socklen_t*)&len);
+ if(client<0){
+ close(serverTCP_socket_desc);
+ serverTCP_socket_desc=-1;
+ puts("Acceptation failed");
+ }
+ else{
+ GWFrame frame;
+ recv(client, &frame, sizeof(GWFrame),0);
+ char msg[100]="Données bien reçus par la gateway maitre.";
+ write(client, msg,strlen(msg));
+ close(client);
+ return(frame);
+
+ }
+}
+
+
diff --git a/GEOLOC/app/frame.c b/GEOLOC/app/frame.c
new file mode 100644
index 0000000..1908075
--- /dev/null
+++ b/GEOLOC/app/frame.c
@@ -0,0 +1,22 @@
+#include "frame.h"
+
+
+void pushFrame(Frame frame){
+ writeReg(REG_FIFO, frame.id);
+ writeReg(REG_FIFO, frame.stamp);
+ int i;
+ for(i=0;i<FRAME_DATA_SIZE;i++){
+ writeReg(REG_FIFO,frame.data[i]);
+ }
+}
+
+Frame pullFrame(){
+ Frame frame;
+ frame.id=readReg(REG_FIFO);
+ frame.stamp=readReg(REG_FIFO);
+ int i;
+ for(i=0;i<FRAME_DATA_SIZE;i++){
+ frame.data[i]=readReg(REG_FIFO);
+ }
+ return(frame);
+}
diff --git a/GEOLOC/app/frame.h b/GEOLOC/app/frame.h
new file mode 100644
index 0000000..27a76cf
--- /dev/null
+++ b/GEOLOC/app/frame.h
@@ -0,0 +1,21 @@
+#ifndef frame_h
+#define frame_h
+
+#define FRAME_SIZE 10
+#define FRAME_DATA_SIZE 8
+
+#include "../lib/types.h"
+#include "../lib/dragino.h"
+#include "../lib/config.h"
+
+typedef struct Frame Frame;
+struct Frame {
+ byte id;
+ byte stamp;
+ byte data[FRAME_DATA_SIZE];
+};
+
+void pushFrame(Frame frame);
+Frame pullFrame();
+
+#endif
diff --git a/GEOLOC/app/mobile/app.c b/GEOLOC/app/mobile/app.c
new file mode 100644
index 0000000..6887948
--- /dev/null
+++ b/GEOLOC/app/mobile/app.c
@@ -0,0 +1,84 @@
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include "app.h"
+#include "../frame.h"
+#include <string.h>
+#include "../../lib/gps.h"
+#include <unistd.h>
+
+extern struct NMEA_GGA NmeaGgaFrame;
+
+void runApp(Config config){
+
+ // Hello msg
+ printf("\n|Starting mobile application|\n\n");
+
+ // Ensure we are in standby mode and apply configuration
+ config.mode=MODE_STDBY;
+ applyMode(config);
+ applyConfig(config);
+
+ // Write frame on sx1276
+ Frame frame;
+ frame.id=234;
+ frame.stamp=81;
+ frame.data[0]=76;
+ frame.data[1]=17;
+ frame.data[2]=16;
+ frame.data[3]=87;
+ frame.data[4]=12;
+ frame.data[5]=106;
+ pushFrame(frame);
+ config.mode=MODE_TX;
+ applyMode(config); // Send frame
+
+ // Wait for frame to be sending
+ while(1){
+ if(digitalRead(0x7)==1){
+ printf("Packet send !!!\n\n");
+ config.mode=MODE_STDBY;
+ applyMode(config);
+ saveGPSPosition();
+ delay(2000);
+ // Write frame on sx1276
+ pushFrame(frame);
+ config.mode=MODE_TX;
+ applyMode(config); // Send frame
+ }
+ }
+}
+
+void saveGPSPosition(){
+
+ // Fetch GPS position
+ NmeaGgaFrame=getNMEA_GGAFrame();
+
+ // Save in file
+ FILE *file;
+ char filePath[]="gps.csv";
+ short writeHeader=0;
+ if(access( filePath, F_OK ) == -1){
+ writeHeader=1;
+ }
+ file=fopen(filePath,"a+");
+ if(file!=NULL){
+ if(writeHeader){
+ fprintf(file,"GPSSTATE,LatDeg,LatMin,LatSec,LatDir,LonDeg,LonMin,LonSec,LonDir\n");
+ }
+ fprintf(file,"%d,%d,%d,%f,%d,%d,%d,%f,%d\n",
+ NmeaGgaFrame.state,
+ NmeaGgaFrame.latDeg,
+ NmeaGgaFrame.latMin,
+ NmeaGgaFrame.latSec,
+ NmeaGgaFrame.latDir,
+ NmeaGgaFrame.lonDeg,
+ NmeaGgaFrame.lonMin,
+ NmeaGgaFrame.lonSec,
+ NmeaGgaFrame.lonDir);
+ fclose(file);
+ }
+ else{
+ printf("Failed to open file %s.\n",filePath);
+ }
+}
diff --git a/GEOLOC/app/mobile/app.h b/GEOLOC/app/mobile/app.h
new file mode 100644
index 0000000..80e661b
--- /dev/null
+++ b/GEOLOC/app/mobile/app.h
@@ -0,0 +1,16 @@
+#ifndef app_h
+#define app_h
+
+#include "../../lib/config.h"
+
+/**
+ * Run the application
+ */
+void runApp(Config config);
+
+/**
+ * Save the GPS position
+ */
+void saveGPSPosition();
+
+#endif
diff --git a/GEOLOC/lib/config.c b/GEOLOC/lib/config.c
new file mode 100644
index 0000000..b086628
--- /dev/null
+++ b/GEOLOC/lib/config.c
@@ -0,0 +1,51 @@
+#include "config.h"
+
+void applyConfig(Config config){
+
+ // Apply modulation and mode
+ byte reg=readReg(REG_OP_MODE) &0x3F ; // Fetch opmode register and clear modulation and mode bits
+ reg=reg | config.mod; // Apply modulation and mode
+ writeReg(REG_OP_MODE,reg); // Send register back to module
+
+ // Apply carrier frequency
+ int cFreq=config.cFreq/FSTEP;
+ reg=cFreq >> 16 ;
+ writeReg(REG_FRF_MSB,reg); // Send register to module
+ reg=(cFreq&0x00FFFF) >> 8 ;
+ writeReg(REG_FRF_MID,reg); /// Send register to module
+ reg=(cFreq&0x0000FF);
+ writeReg(REG_FRF_LSB,reg); // Send register to module
+
+ // Set LNAGain
+ reg=readReg(REG_LNA) & 0x7F;
+ writeReg(REG_LNA, reg|config.lnaGain);
+
+
+ // Apply PaBoost, max output power and outputPower
+ byte Pmax=round((config.maxPower-10.8)/0.6);
+ Pmax=(Pmax & 0x07)<<4;
+ byte outputPower;
+ if(config.paSelect==PA_SELECT_ON){
+ outputPower=config.outputPower-32;
+ }
+ else{
+ outputPower=config.outputPower-Pmax+15;
+ }
+ outputPower=config.outputPower & 0x0F;
+ reg=config.paSelect|outputPower|Pmax;
+ writeReg(REG_PA_CONFIG, reg);
+
+
+ // Apply FSK configuration
+ if(config.mod==MOD_FSK){
+ applyFSKConfig(config.fsk);
+ }
+}
+
+void applyMode(Config config){
+ // Apply modulation and mode
+ byte reg=readReg(REG_OP_MODE) &0xF8 ; // Fetch opmode register and clear mode
+ reg=config.mode | reg; // Apply mode
+ writeReg(REG_OP_MODE,reg); // Send register back to module
+
+}
diff --git a/GEOLOC/lib/config.h b/GEOLOC/lib/config.h
new file mode 100644
index 0000000..47a7151
--- /dev/null
+++ b/GEOLOC/lib/config.h
@@ -0,0 +1,62 @@
+#ifndef config_h
+#define config_h
+
+#include "dragino.h"
+#include "types.h"
+#include "fskconfig.h"
+#include <math.h>
+
+// Define General Registers
+#define REG_FIFO 0x00
+#define REG_OP_MODE 0x01
+#define REG_VERSION 0x42
+#define REG_FRF_MSB 0x06
+#define REG_FRF_MID 0x07
+#define REG_FRF_LSB 0x08
+#define REG_PA_CONFIG 0x09
+
+// Define General Registers values
+#define MODE_SLEEP 0x00
+#define MODE_STDBY 0x01
+#define MODE_TX 0x03
+#define MODE_RX 0x05
+#define MOD_LORA 0x80
+#define MOD_FSK 0x00
+#define MOD_OOK 0x40
+#define LNA_GAIN_G1 0x20
+#define LNA_GAIN_G2 0x40
+#define LNA_GAIN_G3 0x60
+#define LNA_GAIN_G4 0x80
+#define LNA_GAIN_G5 0xA0
+#define LNA_GAIN_G6 0xC0
+#define PA_SELECT_ON 0x80
+#define PA_SELECT_OFF 0x00
+
+
+
+// Define global configuration
+typedef struct Config Config;
+struct Config {
+ byte mod;
+ byte mode;
+ int cFreq;
+ FSKConfig fsk; // FSK Specific configuration
+ byte lnaGain;
+ byte paSelect;
+ short maxPower;
+ short outputPower;
+ // TODO LORA Specific configuration
+};
+
+
+/**
+ * Apply global configuration (module mode is unchanged here)
+ */
+void applyConfig(Config config);
+
+/**
+ * Change SX1276 mode (SLEEP, TX, RX etc...)
+ */
+void applyMode(Config config);
+
+#endif
diff --git a/GEOLOC/lib/dragino.c b/GEOLOC/lib/dragino.c
new file mode 100644
index 0000000..30de48a
--- /dev/null
+++ b/GEOLOC/lib/dragino.c
@@ -0,0 +1,40 @@
+#include "dragino.h"
+
+
+void initPins(){
+ // Init WiringPi
+ wiringPiSetup();
+ pinMode(NSS_PIN, OUTPUT);
+ pinMode(DIO0_PIN, INPUT);
+ pinMode(RESET_PIN, OUTPUT);
+ wiringPiSPISetup(CHANNEL, BIT_RATE);
+}
+
+byte readReg(byte address){
+ byte buffer[2];
+ buffer[0]=address & 0x7F; // Set read flag (SX1276 datasheet page 80)
+ buffer[1]=0x00;
+
+ digitalWrite(NSS_PIN, LOW);
+ wiringPiSPIDataRW(CHANNEL, buffer, 2);
+ digitalWrite(NSS_PIN, HIGH);
+
+ return(buffer[1]);
+}
+void writeReg(byte address, byte data){
+ byte buffer[2];
+ buffer[0]=address | 0x80; // Set write flag (SX1276 datasheet page 80)
+ buffer[1]=data;
+
+ digitalWrite(NSS_PIN, LOW);
+ wiringPiSPIDataRW(CHANNEL, buffer, 2);
+ digitalWrite(NSS_PIN, HIGH);
+}
+
+void reset(){
+ // SX1276 datasheet page 116
+ digitalWrite(RESET_PIN, LOW);
+ delay(100);
+ digitalWrite(RESET_PIN, HIGH);
+ delay(100);
+}
diff --git a/GEOLOC/lib/dragino.h b/GEOLOC/lib/dragino.h
new file mode 100644
index 0000000..082de14
--- /dev/null
+++ b/GEOLOC/lib/dragino.h
@@ -0,0 +1,38 @@
+#ifndef dragino_h
+#define dragino_h
+
+#include "types.h"
+#include <wiringPi.h>
+#include <wiringPiSPI.h>
+
+// Define WiringPi Parameters
+#define CHANNEL 0
+#define BIT_RATE 500000
+
+// Define dragino shield pin for use SPI protocol (see http://wiki.dragino.com/index.php?title=Lora/GPS_HAT)
+#define NSS_PIN 6
+#define RESET_PIN 0
+#define DIO0_PIN 7
+#define TX_PIN 15
+
+/**
+ * Configure WiringPi for SPI
+ */
+void initPins();
+
+/**
+ * Used to init and reset SX1276
+ */
+void reset();
+
+/**
+ * Read in SX1276 register
+ */
+byte readReg(byte address);
+
+/**
+ * Write in SX1276 register
+ */
+void writeReg(byte address, byte value);
+
+#endif
diff --git a/GEOLOC/lib/fskconfig.c b/GEOLOC/lib/fskconfig.c
new file mode 100644
index 0000000..42f3775
--- /dev/null
+++ b/GEOLOC/lib/fskconfig.c
@@ -0,0 +1,66 @@
+#include "fskconfig.h"
+
+void applyFSKConfig(FSKConfig fsk){
+
+ // Set preambleDetection
+ byte reg=readReg(REG_PREAMBLE_DETECT)&0x7F;
+ writeReg(REG_PREAMBLE_DETECT, fsk.preambleDetection | reg);
+
+ // Set preamble size
+ reg=fsk.preambleSize>>8;
+ writeReg(REG_PREAMBLE_MSB, reg);
+ reg=fsk.preambleSize & 0x00ff;
+ writeReg(REG_PREAMBLE_LSB, reg);
+
+ // Set crcOn
+ reg=readReg(REG_PACKET_CONFIG_1) & 0xEF;
+ writeReg(REG_PACKET_CONFIG_1,reg|fsk.crcOn);
+
+ // Set crc autoclear
+ reg=readReg(REG_PACKET_CONFIG_1) & 0xF7;
+ writeReg(REG_PACKET_CONFIG_1,reg|fsk.crcAutoClearOff);
+
+ // Set payloadLength
+ reg=readReg(REG_PACKET_CONFIG_2) & 0xF8;
+ byte payloadLengthMSB=(fsk.payloadLength >> 8) &0x7;
+ byte payloadLengthLSB=fsk.payloadLength &0xFF;
+ writeReg(REG_PACKET_CONFIG_2,payloadLengthMSB|reg);
+ writeReg(REG_PAYLOAD_LENGTH, payloadLengthLSB);
+
+ // Set fifo threshold
+ reg=readReg(REG_FIFO_THRESH) & 0xC0;
+ reg=reg| (fsk.fifoThreshold & 0x3F);
+ writeReg(REG_FIFO_THRESH,reg);
+
+ // Set fixedPayloadLength
+ reg=readReg(REG_PACKET_CONFIG_1) & 0x7F;
+ writeReg(REG_PACKET_CONFIG_1,reg | fsk.fixedPayloadLength);
+
+ // Set frequency dev
+ short freqDev=fsk.freqDev/FSTEP;
+ byte freqDevMSB=freqDev>>8;
+ byte freqDevLSB=freqDev&0x00FF;
+ writeReg(REG_FDEV_MSB, freqDevMSB);
+ writeReg(REG_FDEV_LSB, freqDevLSB);
+
+ // Apply bitrate //
+ short bitrate=FXOSC/fsk.bitrate;
+ byte bitrateMSB=bitrate>>8;
+ byte bitrateLSB=bitrate & 0x00FF;
+ writeReg(REG_BITRATE_MSB, bitrateMSB);
+ writeReg(REG_BITRATE_LSB, bitrate & 0x0F);
+
+ // Apply rssi smoothing
+ reg=readReg(REG_RSSI_CONFIG) & 0xF8;
+ reg=reg|fsk.rssiSmoothing;
+ writeReg(REG_RSSI_CONFIG,reg);
+
+}
+
+
+int fetchRSSI(){
+ int value=readReg(REG_RSSI_VALUE);
+ value=(-value)/2; // See SX1276 datasheet page 86
+ return(value);
+}
+
diff --git a/GEOLOC/lib/fskconfig.h b/GEOLOC/lib/fskconfig.h
new file mode 100644
index 0000000..ea6d771
--- /dev/null
+++ b/GEOLOC/lib/fskconfig.h
@@ -0,0 +1,67 @@
+#ifndef fskconfig_h
+#define fskconfig_h
+
+#include "dragino.h"
+#include "types.h"
+
+// Define FSK Registers
+#define REG_PREAMBLE_DETECT 0x1f
+#define REG_PREAMBLE_MSB 0x25
+#define REG_PREAMBLE_LSB 0x26
+#define REG_PACKET_CONFIG_1 0x30
+#define REG_PACKET_CONFIG_2 0x31
+#define REG_PAYLOAD_LENGTH 0x32
+#define REG_FIFO_THRESH 0x35
+#define REG_LNA 0x0C
+#define REG_FDEV_MSB 0x04
+#define REG_FDEV_LSB 0x05
+#define REG_BITRATE_MSB 0x02
+#define REG_BITRATE_LSB 0x03
+#define REG_RSSI_CONFIG 0x0E
+#define REG_RSSI_VALUE 0x11
+
+// Define FSK configuration parameters values
+#define CRC_ON 0x10
+#define CRC_OFF 0x00
+#define CRC_AUTOCLEAR_OFF_ON 0x08
+#define CRC_AUTOCLEAR_OFF_OFF 0x00
+#define FIXED_PAYLOAD_LENGTH_ON 0x80
+#define FIXED_PAYLOAD_LENGTH_OFF 0x00
+#define PREAMBLE_DETECTION_ON 0x80
+#define PREAMBLE_DETECTION_OFF 0x00
+#define RSSI_SAMPLE_2 0x00
+#define RSSI_SAMPLE_4 0x01
+#define RSSI_SAMPLE_8 0x02
+#define RSSI_SAMPLE_16 0x03
+#define RSSI_SAMPLE_32 0x04
+#define RSSI_SAMPLE_64 0x05
+#define RSSI_SAMPLE_128 0x06
+#define RSSI_SAMPLE_256 0x07
+
+
+// Define FSK Configuration
+typedef struct FSKConfig FSKConfig;
+struct FSKConfig {
+ byte preambleDetection;
+ short preambleSize;
+ short fifoThreshold;
+ short payloadLength;
+ short freqDev;
+ short bitrate;
+ byte rssiSmoothing;
+ byte crcOn;
+ byte crcAutoClearOff;
+ byte fixedPayloadLength;
+};
+
+/**
+ * Apply FSK configuration
+ */
+void applyFSKConfig(FSKConfig fsk);
+
+/**
+ * Fetch FSK RSSI
+ */
+int fetchRSSI();
+
+#endif
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);
+}
diff --git a/GEOLOC/lib/gps.h b/GEOLOC/lib/gps.h
new file mode 100644
index 0000000..49dbdd6
--- /dev/null
+++ b/GEOLOC/lib/gps.h
@@ -0,0 +1,53 @@
+#ifndef gps_h
+#define gps_h
+
+/**
+ * Define NMEA frame types
+ */
+typedef enum NMEA_TYPE NMEA_TYPE;
+enum NMEA_TYPE { GGA=125,NONE }; // TODO : other frame type
+
+/**
+ * Define compass N,S,E,W
+ */
+typedef enum COMPASS COMPASS;
+enum COMPASS { NORTH=78, SOUTH=83, EAST=69, WEST=87};
+
+/**
+ * Define GPS state
+ */
+typedef enum GPS_STATE GPS_STATE;
+enum GPS_STATE { FIXED_GPS=1, FIXED_DGPS=2, UNFIXED=0};
+
+/**
+ * Define NMEA GGA FRAME
+ */
+struct NMEA_GGA {
+ short hour;
+ short min;
+ short sec;
+ short ms;
+
+ short latDeg;
+ short latMin;
+ float latSec;
+ COMPASS latDir;
+
+ short lonDeg;
+ short lonMin;
+ float lonSec;
+ COMPASS lonDir;
+
+ short sats;
+ GPS_STATE state;
+
+ // TODO : Finish Frame
+
+};
+
+/**
+ * Fetch the last NMEA_GGA frame
+ */
+struct NMEA_GGA getNMEA_GGAFrame();
+
+#endif
diff --git a/GEOLOC/lib/types.h b/GEOLOC/lib/types.h
new file mode 100644
index 0000000..01c0e97
--- /dev/null
+++ b/GEOLOC/lib/types.h
@@ -0,0 +1,10 @@
+#ifndef type_h
+#define type_h
+
+#define FXOSC 32000000 // SX1276 clock frequency (SX1276 datasheet page 14)
+#define FSTEP 61 // Default FSTEP (SX1276 datasheet page 15)
+
+// Define byte size for convenience
+typedef unsigned char byte;
+
+#endif
diff --git a/GEOLOC/main.c b/GEOLOC/main.c
new file mode 100644
index 0000000..07ef640
--- /dev/null
+++ b/GEOLOC/main.c
@@ -0,0 +1,51 @@
+#include "lib/dragino.h"
+#include "lib/config.h"
+#include "app/frame.h"
+#if TARGET == ANCHOR
+ #include "app/anchor/app.h"
+#else
+ #include "app/mobile/app.h"
+#endif
+#include <stdio.h>
+#include "lib/gps.h"
+
+
+// NMEA_GGA Frame
+struct NMEA_GGA NmeaGgaFrame;
+
+int main(){
+
+ // Init dragino pins
+ initPins();
+
+ // Init sx1276
+ reset();
+
+ // Init configuration
+ Config config;
+ config.mod=MOD_FSK; // Choose modulation
+ config.mode=MODE_SLEEP; // Standby mode at startup
+ config.cFreq=868100000; // Choose carrier frequency
+ config.fsk.preambleSize=1; // Choose preamble size
+ config.fsk.crcOn=CRC_OFF; // ON/OFF CRC check
+ config.fsk.freqDev=5002; // Choose frequency deviation
+ config.fsk.preambleDetection=PREAMBLE_DETECTION_ON; // ON/OFF preamble detection
+ config.lnaGain=LNA_GAIN_G1; // Choose LNA GAIN
+ config.fsk.crcAutoClearOff=CRC_AUTOCLEAR_OFF_OFF; // ON/OFF CRC autoclean
+ config.fsk.bitrate=4800; // Choose bitrate
+ config.fsk.fixedPayloadLength=FIXED_PAYLOAD_LENGTH_OFF; // ON/OFF Fixed payload length
+ config.fsk.payloadLength=FRAME_SIZE; // Choose payload length
+ config.fsk.fifoThreshold=FRAME_SIZE-1; // Choose fifo threshold
+ config.paSelect=PA_SELECT_ON; // Toggle PA BOOST
+ config.maxPower=15; // Define max power
+ config.outputPower=17; // Set the output power
+ config.fsk.rssiSmoothing=RSSI_SAMPLE_256; // Set rssi sample
+
+ // Fetch GPS position
+ NmeaGgaFrame=getNMEA_GGAFrame();
+
+ // Run ANCHOR or MOBILE application according to Makefile TARGET definition
+ runApp(config);
+
+ return(0);
+}
diff --git a/Readme.md b/Readme.md
new file mode 100644
index 0000000..8a25afa
--- /dev/null
+++ b/Readme.md
@@ -0,0 +1,6 @@
+Folders structure
+==================
+
+#### <i class="icon-folder"></i> GEOLOC
+
+It contains source code for turtle and gateways and a Readme for details.