From 05915ddccaf902cea0b2bf5ea39b0d46f703b89b Mon Sep 17 00:00:00 2001
From: dmlarson <dmlarson@iastate.edu>
Date: Wed, 2 May 2018 12:35:46 -0500
Subject: [PATCH] Resolve "Create a Wifi Access Point on groundstation"

---
 documentation/images/ls_output_wifiap.png   | Bin 0 -> 15615 bytes
 groundStation/README.md                     |  14 +-
 groundStation/adapters/README.md            |  15 +-
 groundStation/adapters/crazyflie/.gitignore |   2 +
 groundStation/adapters/crazyflie/Makefile   |   3 -
 groundStation/src/backend/backend.c         |  60 ++---
 groundStation/src/backend/backend_adapter.c |  12 +-
 groundStation/src/backend/config.h          |   5 +
 groundStation/src/frontend/frontend_nodes.c | 231 ++++++++++----------
 groundStation/wifiap/README.md              |  88 ++++++++
 groundStation/wifiap/golden_dhcpd.conf      |  22 ++
 groundStation/wifiap/golden_hostapd.conf    |  11 +
 groundStation/wifiap/installerScript.sh     |  67 ++++++
 groundStation/wifiap/startAP.sh             |  99 +++++++++
 groundStation/wifiap/stopAP.sh              |  50 +++++
 15 files changed, 520 insertions(+), 159 deletions(-)
 create mode 100644 documentation/images/ls_output_wifiap.png
 create mode 100644 groundStation/adapters/crazyflie/.gitignore
 create mode 100644 groundStation/wifiap/README.md
 create mode 100644 groundStation/wifiap/golden_dhcpd.conf
 create mode 100644 groundStation/wifiap/golden_hostapd.conf
 create mode 100755 groundStation/wifiap/installerScript.sh
 create mode 100755 groundStation/wifiap/startAP.sh
 create mode 100755 groundStation/wifiap/stopAP.sh

diff --git a/documentation/images/ls_output_wifiap.png b/documentation/images/ls_output_wifiap.png
new file mode 100644
index 0000000000000000000000000000000000000000..792500431df829ab1188934688a67d6fdc18ad10
GIT binary patch
literal 15615
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

literal 0
HcmV?d00001

diff --git a/groundStation/README.md b/groundStation/README.md
index 5444c06b0..a2905ea0e 100644
--- a/groundStation/README.md
+++ b/groundStation/README.md
@@ -92,14 +92,6 @@ There are a couple of already written bash scripts in the `scripts/` folder.
 
  - [Getting Started](./documentation/getting_started.md)
  - [Packet Information](./documentation/packets.md)
- - [Manual Assist Mode](./src/manual_assist/README.md)
-
-## Adapters
-
-Adapters are the MicroCART way of connecting to generic trackables that are not one of the MicroCART quads. There is one
-adapter created in house that allows the use of a Crazyflie through the Matt_test branch of [Custom_Crazyflie_Software](https://git.ece.iastate.edu/danc/Custom_CrazyFlie_Software/tree/Matt_test_branch) repo.
-This repository is part of the DANC lab and can be access similar to the MicroCART repositry. This branch makes their ground 
-station allow connects in the same manner that our backend does. In order to use this adapter
-you must first start the lateral on quad ground station in the repository mentioned above, then run the crazyflie adapter.
-After this process is setup make sure that the backend config is set properly for this new trackable and it can be controlled
-as if it were one of our quads.
+ - [Adapters](adapters/README.md)
+ - [WiFi Access Point](wifiap/README.md)
+ - [Manual Assist Mode](./src/manual_assist/README.md)
\ No newline at end of file
diff --git a/groundStation/adapters/README.md b/groundStation/adapters/README.md
index 86e7c5a5e..b7a6474c9 100644
--- a/groundStation/adapters/README.md
+++ b/groundStation/adapters/README.md
@@ -1,13 +1,22 @@
 # ADAPTERS
-Adapters are what allows for the current microcart groundstation to communicate with other vehicles. The adapters act as a translator by receiving packets from groundstation and then call the packets corrisponding callback. The developer can then modify callback functions to communicate.
+Adapters are what allows for the current microcart groundstation to communicate with other vehicles. The adapters act as a translator by receiving packets from groundstation and then call the packets corresponding callback function. The developer can then modify callback functions to communicate.
+
+There is one
+adapter created in house that allows the use of a Crazyflie through the Matt_test branch of [Custom_Crazyflie_Software](https://git.ece.iastate.edu/danc/Custom_CrazyFlie_Software/tree/Matt_test_branch) repo.
+This repository is part of the DANC lab and can be access similar to the MicroCART repositry. This branch makes their ground 
+station allow connects in the same manner that our backend does. In order to use this adapter
+you must first start the lateral on quad ground station in the repository mentioned above, then run the crazyflie adapter.
+After this process is setup make sure that the backend config is set properly for this new trackable and it can be controlled
+as if it were one of our quads.
 
 ## CREATE NEW:
 There are 3 major components that are provided for creation of a new custom adapter.
+
  - adapterlib - has functions to retrieve single groundstation packets from a socket
  - callbacks - has predefined functions for every type of instruction supported by groundstation
  - demoadapter - example code to set up a unix socket, read from it, and call the corresponding callback function
 
-These files rely upon groundstation header files and c files which are linked in the ./inc directory and should be included when compiling (for example see the crazyflie adapter makefile)
+These files rely upon groundstation header files and c files which are linked by the makefile and should be included when compiling (for example see the crazyflie adapter makefile)
 
 To create your own adapter:
 
@@ -26,7 +35,7 @@ This is a list of what groundstation and quad software functions are required.
  - commands.c - MessageTypes, findCommand()
  - callbacks.h - Typedef for command_cb
   
-###INCLUDES LOCATIONS:
+### INCLUDES LOCATIONS:
 This is a list of all the required files to include to be able to use the function listed above. *(Note these paths are relative to this README)*
 
  - ../../quad/inc/biquad_filter.h
diff --git a/groundStation/adapters/crazyflie/.gitignore b/groundStation/adapters/crazyflie/.gitignore
new file mode 100644
index 000000000..2e0b5d584
--- /dev/null
+++ b/groundStation/adapters/crazyflie/.gitignore
@@ -0,0 +1,2 @@
+inc/*
+bin/*
diff --git a/groundStation/adapters/crazyflie/Makefile b/groundStation/adapters/crazyflie/Makefile
index 60b42e770..e73c02da9 100644
--- a/groundStation/adapters/crazyflie/Makefile
+++ b/groundStation/adapters/crazyflie/Makefile
@@ -23,7 +23,6 @@ all: inc obj lib
 	mkdir bin/
 	$(CC) obj/*.o -o bin/cf_adapter
 
-
 obj: inc
 	$(CC) -c $(C) $(H) $(CFLAGS)
 	mkdir obj
@@ -62,5 +61,3 @@ clean:
 	rm -rf *.o
 	rm -rf inc/*.gch
 	rm -rf src/*.gch
-
-
diff --git a/groundStation/src/backend/backend.c b/groundStation/src/backend/backend.c
index e8500ca51..af32a1640 100644
--- a/groundStation/src/backend/backend.c
+++ b/groundStation/src/backend/backend.c
@@ -413,11 +413,13 @@ void sendVrpnPacket(struct ucart_vrpn_TrackerData *info) {
 
 void getVRPNPacket(struct ucart_vrpn_TrackerData *td) {
     int status;
-    //for (int i = 0; i < NUM_TRACKABLES; i++) {
-    //    if (strcmp(trackable, trackables[i].name) == 0) {
-    //        break;
-    //    }
-    //}
+#if VRPN_DEBUG_PRINT == 1
+    for (int i = 0; i < NUM_TRACKABLES; i++) {
+        if (strcmp(trackable, trackables[i].name) == 0) {
+            break;
+        }
+    }
+#endif
     //if ((status = ucart_vrpn_tracker_getData(trackables[i].tracker, td)) < 0) {
     // TODO - remove tracker instance
     if((status = ucart_vrpn_tracker_getData(tracker, td)) < 0) {
@@ -557,14 +559,15 @@ static ssize_t writeQuad(const uint8_t * buf, size_t count) {
     for (int i = 0; i < NUM_TRACKABLES; i++) {
         if (strcmp(trackables[i].name, trackable) == 0) {
             index = i;
-            //printf("Index: %d\tName: %s\n", index, trackables[index].name);
-            //printf("packetToQuad = '");
-            //for(int i = 0; i < (int)count; ++i) {
-            //    printf(" %.2x ", buf[i]);
-            //}
-            //printf("'\n");
+#if BACKEND_DEBUG_PRINT == 1
+            printf("Index: %d\tName: %s\n", index, trackables[index].name);
+            printf("packetToQuad = '");
+            for(int i = 0; i < (int)count; ++i) {
+                printf(" %.2x ", buf[i]);
+            }
+            printf("'\n");
+#endif
             return writeQuadIndex(buf, count, index);
-            //break;
         }
     }
     //FIXME - Should never reach here
@@ -574,11 +577,13 @@ static ssize_t writeQuad(const uint8_t * buf, size_t count) {
 static ssize_t writeQuadIndex(const uint8_t * buf, size_t count, int index) {
     ssize_t retval;
     
-    //printf("packetToQuad = '");
-    //for(int i = 0; i < (int)count; ++i) {
-    //    printf(" %.2x ", buf[i]);
-    //}
-    //printf("'\n");
+#if BACKEND_DEBUG_PRINT == 1
+    printf("packetToQuad = '");
+    for(int i = 0; i < (int)count; ++i) {
+        printf(" %.2x ", buf[i]);
+    }
+    printf("'\n");
+#endif
 
     if (trackables[index].isAdapter == 0 && getenv(NOQUAD_ENV)) {
         return count;
@@ -760,10 +765,13 @@ static void client_recv(int fd) {
 
         char * first_word;
         char * tmp = strdup(buffer);
-        // printf("tmpbuff = '%s'\n", tmp);
+#if BACKEND_DEBUG_PRINT == 1
+        printf("tmpbuff = '%s'\n", tmp);
+#endif
         first_word = strtok(tmp, " ");
-        // printf("first word = '%s'\n", first_word);
-    
+#if BACKEND_DEBUG_PRINT == 1
+        printf("first word = '%s'\n", first_word);
+#endif
         ssize_t msg_type, i;
         for (i = 0; i < MAX_TYPE_ID; ++i) {
             if ((msg_type = findCommand(first_word)) != -1)
@@ -928,11 +936,13 @@ static void quad_recv(int index) {
     }
     respBufLen += respLen;
 
-    // printf("packetFromQuad = '");
-    // for(int i = 0; i < (int)respBufLen; ++i) {
-    //  printf(" %.2x ", respBuf[i]);
-    // }
-    // printf("'\n");
+#if BACKEND_DEBUG_PRINT == 1
+    printf("packetFromQuad = '");
+    for(int i = 0; i < (int)respBufLen; ++i) {
+        printf(" %.2x ", respBuf[i]);
+    }
+    printf("'\n");
+#endif
 
     while(respBufLen) {
         datalen = DecodePacket(&m, data, CMD_MAX_LENGTH, respBuf, respBufLen);
diff --git a/groundStation/src/backend/backend_adapter.c b/groundStation/src/backend/backend_adapter.c
index 11de7f81b..9fb927f27 100644
--- a/groundStation/src/backend/backend_adapter.c
+++ b/groundStation/src/backend/backend_adapter.c
@@ -19,12 +19,14 @@
  * count - number of bytes
  */
 int adapterWrite(struct adapter_conn *conn, const char * line, size_t count) {
+#if ADAPTER_DEBUG_PRINT == 1
     //Print out packet being sent to the adapter.
-    //printf("packetToAdapter = '");
-    //for(int i = 0; i < count; ++i) {
-    //  printf(" %.2x ", ((const uint8_t *) line)[i]);
-    //}
-    //printf("'\n");
+    printf("packetToAdapter = '");
+    for(int i = 0; i < count; ++i) {
+      printf(" %.2x ", ((const uint8_t *) line)[i]);
+    }
+    printf("'\n");
+#endif
     return fwrite((const uint8_t *) line, sizeof(uint8_t), count, conn->socket);
 }
 
diff --git a/groundStation/src/backend/config.h b/groundStation/src/backend/config.h
index 3bdc2209b..85f00492d 100644
--- a/groundStation/src/backend/config.h
+++ b/groundStation/src/backend/config.h
@@ -16,6 +16,11 @@
 #include <pthread.h>
 #include <stdint.h>
 
+#define FRONTEND_DEBUG_PRINT 0
+#define ADAPTER_DEBUG_PRINT 0
+#define VRPN_DEBUG_PRINT 0
+#define BACKEND_DEBUG_PRINT 0
+
 /**
  * Socket used to communicate with the backend.
  */
diff --git a/groundStation/src/frontend/frontend_nodes.c b/groundStation/src/frontend/frontend_nodes.c
index ffa7c188e..981147169 100644
--- a/groundStation/src/frontend/frontend_nodes.c
+++ b/groundStation/src/frontend/frontend_nodes.c
@@ -5,6 +5,7 @@
 #include <inttypes.h>
 
 #include "frontend_nodes.h"
+#include "config.h"
 
 /* Get the block_id, type_id and name of
  * all of the nodes in the current comp_graph.
@@ -17,80 +18,86 @@
  * 
  */
 int frontend_getnodes(
-		struct backend_conn * conn,
-		struct frontend_node_data ** node_data,
-		size_t * num_nodes) {
-	if ((node_data == NULL) || (num_nodes == NULL)) {
-		return 1;
-	}
-
-	if ((*node_data != NULL) || (*num_nodes != 0)) {
-		return 1;
-	}
-
-	char msg[64] = "";
-	int written;
-
-	snprintf(msg, 64, "getnodes\n");
-
-	if((written = ucart_backendWrite(conn, msg)) < 0) {
-		return 1;
-	}
-
-	size_t pendingResponses = 1;
-	char * response;
-
-	while (pendingResponses) {
-		response = ucart_backendGetline(conn);
-		if (response == NULL) {
-			warnx("Line not returned from backend");
-			return 1;
-		}
-
-		if (strncmp(response, "getnodes", 8) != 0) {
-			continue;
-		}
-
-		size_t num_nodes_ret = 0;
-		size_t offset = 0;
-
-		sscanf(response, "getnodes %lu %n", &num_nodes_ret,  (int * )&offset);
-		response += offset;
-
-		/* Resize if necessary */
-		if (num_nodes_ret != *num_nodes) {
-			*num_nodes = num_nodes_ret;
-			*node_data = realloc(*node_data, sizeof(**node_data) * (*num_nodes));
-			if (!*node_data) {
-				return 1;
-			}
-		}
-
-		struct frontend_node_data * arr = *node_data;
-		for (size_t i = 0; i < *num_nodes; ++i) {
-			sscanf(response, "%" SCNd16 " %n", &arr[i].block, (int*)&offset);
-			// printf("found block %d\n", arr[i].block);
-			response += offset;
-		}
-
-		for (size_t i = 0; i < *num_nodes; ++i) {
-			sscanf(response, "%" SCNd16 " %n", &arr[i].type, (int*)&offset);
-			// printf("found type %d\n", arr[i].type);
-			response += offset;
-		}
-
-		for (size_t i = 0; i < *num_nodes; ++i) {
-			char tmp_name[512];
-			sscanf(response, " '%[^\t\n']' %n", (char *)&tmp_name, (int *)&offset);
-			arr[i].name = malloc(sizeof(*arr[i].name) * strlen(tmp_name) + 1);
-			strcpy((char*)arr[i].name, tmp_name);
-			// printf("found name '%s'\n", arr[i].name);
-			response += offset;
-		}
-		pendingResponses--;
-	}
-	
-	return 0;
+        struct backend_conn * conn,
+        struct frontend_node_data ** node_data,
+        size_t * num_nodes) {
+    if ((node_data == NULL) || (num_nodes == NULL)) {
+        return 1;
+    }
+
+    if ((*node_data != NULL) || (*num_nodes != 0)) {
+        return 1;
+    }
+
+    char msg[64] = "";
+    int written;
+
+    snprintf(msg, 64, "getnodes\n");
+
+    if((written = ucart_backendWrite(conn, msg)) < 0) {
+        return 1;
+    }
+
+    size_t pendingResponses = 1;
+    char * response;
+
+    while (pendingResponses) {
+        response = ucart_backendGetline(conn);
+        if (response == NULL) {
+            warnx("Line not returned from backend");
+            return 1;
+        }
+
+        if (strncmp(response, "getnodes", 8) != 0) {
+            continue;
+        }
+
+        size_t num_nodes_ret = 0;
+        size_t offset = 0;
+
+        sscanf(response, "getnodes %lu %n", &num_nodes_ret,  (int * )&offset);
+        response += offset;
+
+        /* Resize if necessary */
+        if (num_nodes_ret != *num_nodes) {
+            *num_nodes = num_nodes_ret;
+            *node_data = realloc(*node_data, sizeof(**node_data) * (*num_nodes));
+            if (!*node_data) {
+                return 1;
+            }
+        }
+
+        struct frontend_node_data * arr = *node_data;
+        for (size_t i = 0; i < *num_nodes; ++i) {
+            sscanf(response, "%" SCNd16 " %n", &arr[i].block, (int*)&offset);
+#if FRONTEND_DEBUG_PRINT == 1
+            printf("found block %d\n", arr[i].block);
+#endif 
+            response += offset;
+        }
+
+        for (size_t i = 0; i < *num_nodes; ++i) {
+            sscanf(response, "%" SCNd16 " %n", &arr[i].type, (int*)&offset);
+#if FRONTEND_DEBUG_PRINT == 1
+            printf("found type %d\n", arr[i].type);
+#endif 
+            response += offset;
+        }
+
+        for (size_t i = 0; i < *num_nodes; ++i) {
+            char tmp_name[512];
+            sscanf(response, " '%[^\t\n']' %n", (char *)&tmp_name, (int *)&offset);
+            arr[i].name = malloc(sizeof(*arr[i].name) * strlen(tmp_name) + 1);
+            strcpy((char*)arr[i].name, tmp_name);
+#if FRONTEND_DEBUG_PRINT == 1
+            printf("found name '%s'\n", arr[i].name);
+#endif
+            response += offset;
+        }
+        pendingResponses--;
+    }
+    
+    return 0;
 }
 
 /* Set the value of block.param
@@ -98,46 +105,46 @@ int frontend_getnodes(
  * Returns 0 on success, 1 on error
  */
 int frontend_addnode(
-		struct backend_conn * conn,
-		struct frontend_node_data * node_data) {
-	
-	char msg[16 + strlen(node_data->name)];
-	int written;
-
-	snprintf(msg, 16 + strlen(node_data->name), "addnode %" PRId16 " %s\n", node_data->type, node_data->name);
-
-	if((written = ucart_backendWrite(conn, msg)) < 0) {
-		return 1;
-	}
-
-	size_t pendingResponses = 1;
-	char * response;
-
-	while (pendingResponses) {
-		response = ucart_backendGetline(conn);
-		if (response == NULL) {
-			warnx("Line not returned from backend");
-			return 1;
-		}
-
-		if (strncmp(response, "addnode", 7) != 0) {
-			continue;
-		}
-
-		sscanf(response, "addnode %" SCNd16, &node_data->block);
-
-		pendingResponses--;
-	}
-	
-	return 0;
+        struct backend_conn * conn,
+        struct frontend_node_data * node_data) {
+    
+    char msg[16 + strlen(node_data->name)];
+    int written;
+
+    snprintf(msg, 16 + strlen(node_data->name), "addnode %" PRId16 " %s\n", node_data->type, node_data->name);
+
+    if((written = ucart_backendWrite(conn, msg)) < 0) {
+        return 1;
+    }
+
+    size_t pendingResponses = 1;
+    char * response;
+
+    while (pendingResponses) {
+        response = ucart_backendGetline(conn);
+        if (response == NULL) {
+            warnx("Line not returned from backend");
+            return 1;
+        }
+
+        if (strncmp(response, "addnode", 7) != 0) {
+            continue;
+        }
+
+        sscanf(response, "addnode %" SCNd16, &node_data->block);
+
+        pendingResponses--;
+    }
+    
+    return 0;
 }
 
 void frontend_free_node_data(
-		struct frontend_node_data *nd,
-		size_t num_nodes)
+        struct frontend_node_data *nd,
+        size_t num_nodes)
 {
-	for (size_t i = 0; i < num_nodes; i++) {
-		free(nd[i].name);
-	}
-	free(nd);
+    for (size_t i = 0; i < num_nodes; i++) {
+        free(nd[i].name);
+    }
+    free(nd);
 }
diff --git a/groundStation/wifiap/README.md b/groundStation/wifiap/README.md
new file mode 100644
index 000000000..2dba5f6d5
--- /dev/null
+++ b/groundStation/wifiap/README.md
@@ -0,0 +1,88 @@
+# WiFi Access Point
+## Basic Setup
+1.  First install the necessary pacakges to the system  
+    On Red Hat:  
+    
+    ```bash
+        sudo yum install dhcp hostapd
+    ```  
+2.  Next navigate to the Microcart/groundStation/wifiap/ directory  
+
+3.  Once you are in the directory make sure you have the necessary files  
+     ```bash
+        ls
+     ```  
+
+4.  The output should look something like the following image.  
+
+    TODO image.  
+
+5.  Next we will want to check for and backup the hostapd.conf file. The installer script will move the golden version of this file to the correct location.  
+
+    ```bash
+         ls /etc/hostapd/hostapd.conf
+    ```  
+    
+    If the file exists you will see output that looks  like the following move on to step 6  
+    
+    ```bash
+        /etc/hostapd/hostapd.conf
+    ```  
+    If you get the following double check that hostapd is installed and if it is move on to step 7  
+    
+    ```bash
+    ls: cannot access '/etc/hostapd/hostapd.conf': No such file or directory
+    ```  
+    
+6.  Make a backup of the file with the following
+
+    ```bash
+        sudo mv /etc/hostapd/hostapd.conf /etc/hostapd/hostapd.conf.backup
+    ```  
+    
+7.  Next we will do the same for the dhcpd.conf file. Check that the file exists  
+
+    ```bash
+        ls /etc/dhcp/dhcpd.conf
+    ```  
+    
+    If the file exists you will see output that looks  like the following move on to step 8  
+    
+    ```bash
+        /etc/dhcp/dhcpd.conf
+    ```  
+    
+    If you get the following double check that dhcpd is installed and if it is move on to step 9  
+    
+    ```bash
+        ls: cannot access '/etc/dhcp/dhcpd.conf': No such file or directory
+    ```  
+    
+8.  Make a backup of the file with the following
+
+    ```bash
+        sudo mv /etc/dhcp/dhcpd.conf /etc/dhcp/dhcpd.conf.backup
+    ```  
+    
+
+9.    Next run the installerScript.sh with sudo rights
+    ```bash
+        sudo ./installerScript.sh
+    ```  
+
+10. You should now see output with all "OK" meaning that the script succeeded.
+
+## How to Use
+1.    Run the start script with the following 
+
+    ```bash
+        sudo ./startAP.sh
+    ```  
+    
+    You should now see a WiFi access point Microcart.  
+    
+2.    Make sure when you are done to run the following to stop  
+
+    ```bash
+        sudo ./stopAP.sh
+    ```  
diff --git a/groundStation/wifiap/golden_dhcpd.conf b/groundStation/wifiap/golden_dhcpd.conf
new file mode 100644
index 000000000..9a8fb41df
--- /dev/null
+++ b/groundStation/wifiap/golden_dhcpd.conf
@@ -0,0 +1,22 @@
+INTERFACES="wlp2s0";
+
+option domain-name "microcart.org";
+
+subnet 192.168.1.0 netmask 255.255.255.0 {
+    range 192.168.1.10 192.168.1.20;
+    option subnet-mask 255.255.255.0;
+    option broadcast-address 192.168.1.255;
+}
+
+host quad1 {
+    hardware ethernet b8:d7:63:00:fe:ef;
+    fixed-address 192.168.1.2;
+}
+host quad2 {
+    hardware ethernet B8:D7:63:00:FE:F0;
+    fixed-address 192.168.1.3;
+}
+host phone {
+    hardware ethernet F4:09:D8:F1:6E:0E;
+    fixed-address 192.168.1.25;
+}
diff --git a/groundStation/wifiap/golden_hostapd.conf b/groundStation/wifiap/golden_hostapd.conf
new file mode 100644
index 000000000..d3f3e6527
--- /dev/null
+++ b/groundStation/wifiap/golden_hostapd.conf
@@ -0,0 +1,11 @@
+#change wlan0 to your wireless device
+interface=wlp2s0
+driver=nl80211
+ssid=MicroCART
+hw_mode=g
+channel=6
+
+auth_algs=1
+wpa=2
+wpa_passphrase=m1cr0cart
+wpa_key_mgmt=WPA-PSK
diff --git a/groundStation/wifiap/installerScript.sh b/groundStation/wifiap/installerScript.sh
new file mode 100755
index 000000000..0bf7c6f9c
--- /dev/null
+++ b/groundStation/wifiap/installerScript.sh
@@ -0,0 +1,67 @@
+#!/bin/bash
+if [[ $EUID -ne 0 ]]; then
+   printf "\nThis script must be run as root to move files around in etc and also run the hostapd service\n"
+   printf "\tRUN AS ROOT!\n"
+   exit 1
+fi
+
+printf "checking for hostapd..."
+
+if ! type "hostapd" > /dev/null ; then 
+    printf "\n\thostapd not found\n"
+    printf "\tINSTALL HOSTAPD PACKAGE!\n"
+    exit 1
+fi
+
+printf "\t OK!\n"
+
+printf "moving golden_hostpad.conf to /etc/hostapd/hostapd.conf..."
+
+if [ -f /etc/hostapd/hostapd.conf ]; then
+    printf "\n\tfile already exists! Please remove the hostapd.conf from the /etc/hostapd/ directory and try again!\n"
+    exit 1
+fi
+
+if [ ! -f ./golden_hostapd.conf ]; then
+    printf "\n\tcannot find the golden_hostapd.conf file in installer script's directory\n"
+    printf "\tRESTORE OR CREATE golden_hostapd.conf\n"
+    exit 1
+fi
+
+cp golden_hostapd.conf /etc/hostapd/hostapd.conf
+#config must be owned by root root otherwise we get an SELinux violation
+chown root /etc/hostapd/hostapd.conf
+chgrp root /etc/hostapd/hostapd.conf
+
+printf "\t OK!\n"
+
+printf "checking for dhcpd..."
+
+if ! type "dhcpd" > /dev/null ; then 
+    printf "\n\tdhcpd not found\n"
+    printf "\tINSTALL DHCPD PACKAGE!\n"
+    exit 1
+fi
+
+printf "\t OK!\n"
+
+printf "moving golden_dhcpd.conf to /etc/dhcp/dhcpd.conf..."
+
+if [ -f /etc/dhcp/dhcpd.conf ]; then
+    printf "\n\tfile already exists! Please remove the dhcpd.conf from the /etc/dhcpd/ directory and try again!\n"
+    exit 1
+fi
+
+if [ ! -f ./golden_dhcpd.conf ]; then
+    printf "\n\tcannot find the golden_dhcpd.conf file in installer script's directory\n"
+    printf "\tRESTORE OR CREATE golden_dhcpd.conf\n"
+    exit 1
+fi
+
+cp golden_dhcpd.conf /etc/dhcp/dhcpd.conf
+#config must be owned by root root otherwise we get an SELinux violation
+chown root /etc/dhcp/dhcpd.conf
+chgrp root /etc/dhcp/dhcpd.conf
+
+printf "\t OK!\n"
+
diff --git a/groundStation/wifiap/startAP.sh b/groundStation/wifiap/startAP.sh
new file mode 100755
index 000000000..85e0736e2
--- /dev/null
+++ b/groundStation/wifiap/startAP.sh
@@ -0,0 +1,99 @@
+#!/bin/bash
+
+#SETTINGS
+IP=192.168.1.1
+
+
+
+
+
+if [[ $EUID -ne 0 ]]; then
+   printf "\nThis script must be run as root to run the hostapd service\n"
+   printf "\tRUN AS ROOT!\n"
+   exit 1
+fi
+
+printf "checking for hostapd...\n"
+if ! type "hostapd" > /dev/null ; then 
+    printf "\n\thostapd not found\n"
+    printf "\tINSTALL HOSTAPD PACKAGE AND RUN THE INSTALLER SCRIPT\n"
+    exit 1
+fi
+printf "\t OK!\n"
+
+printf "checking for dhcpd...\n"
+if ! type "dhcpd" > /dev/null ; then 
+    printf "\n\thostapd not found\n"
+    printf "\tINSTALL DHCPD PACKAGE AND RUN THE INSTALLER SCRIPT\n"
+    exit 1
+fi
+printf "\t OK!\n"
+
+printf "checking settings...\n"
+if [ ! -f /etc/hostapd/hostapd.conf ]; then
+    printf "\n\tMISSING /etc/hostapd/hostapd.conf\n\tmodify golden_hostapd.conf and run the installer script\n"
+    exit 1
+fi
+printf "\t OK!\n"
+
+printf "checking settings...\n"
+if [ ! -f /etc/dhcp/dhcpd.conf ]; then
+    printf "\n\tMISSING /etc/dhcpd/dhcpd.conf\n\tmodify golden_dhcpd.conf and run the install script\n"
+    exit 1
+fi
+printf "\t OK!\n"
+
+#printf "Setting ip to $IP\n"
+#ifconfig wlp2s0 $IP
+#printf "\t OK!\n"
+
+printf "setting up wifi radio...\n"
+nmcli radio wifi off
+if [ $? -eq 0 ]; then
+    printf "\t OK!\n"
+else
+    printf "\t FAIL!\n"
+    printf "\t \"nmcli radio wifi off\" command failed\n"
+    exit 1
+fi
+
+sleep 2
+
+printf "setting up unblocking wifi...\n"
+rfkill unblock wifi
+if [ $? -eq 0 ]; then
+    printf "\t OK!\n"
+else
+    printf "\t FAIL!\n"
+    printf "\t \"rfkill unblock wifi\" command failed\n\treverting wifi state\n"
+    nmcli radio wifi on
+fi
+
+printf "running the hostapd service...\n"
+systemctl start hostapd.service
+if [ $? -eq 0 ]; then
+    printf "\t OK!\n"
+else
+    printf "\t FAIL!\n"
+    printf "\t failed to start hostapd service check run sudo systemctl start hostapd.service and check error messages\n\t reverting wifi state\n"
+    nmcli radio wifi on
+    exit 1
+fi
+
+printf "Setting ip to $IP\n"
+ifconfig wlp2s0 $IP
+printf "\t OK!\n"
+
+printf "running the dhcpd service...\n"
+systemctl start dhcpd.service
+if [ $? -eq 0 ]; then
+    printf "\t OK!\n"
+else
+    printf "\t FAIL!\n"
+    printf "\t failed to start dhcpd service check run sudo systemctl start dhcpd.service and check error messages\n\t reverting wifi state and stopping hostapd\n"
+    systemctl stop hostapd.service
+    nmcli radio wifi on
+    exit 1
+fi
+    
+printf "hostapd and dhcpd should now be running, see if you can connect!\n"
diff --git a/groundStation/wifiap/stopAP.sh b/groundStation/wifiap/stopAP.sh
new file mode 100755
index 000000000..4f5c94255
--- /dev/null
+++ b/groundStation/wifiap/stopAP.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+
+#SETTINGS
+IP=192.168.0.1
+
+
+
+
+
+if [[ $EUID -ne 0 ]]; then
+   printf "\nThis script must be run as root to run the hostapd service\n"
+   printf "\tRUN AS ROOT!\n"
+   exit 1
+fi
+
+printf "checking for and stopping running hostapd...\n"
+if (( $(ps -ef | grep -v grep | grep hostapd | wc -l) > 0 )); then
+    systemctl stop hostapd.service
+    if [ $? -eq 0 ]; then
+        printf "\t OK!\n"
+    else
+        printf "\t FAIL!\n"
+        printf "\t failed to stop hostapd service may need to restart\n"
+        exit 1
+    fi
+fi
+
+printf "checking for and stopping the dhcpd service...\n"
+if (( $(ps -ef | grep -v grep | grep dhcpd | wc -l) > 0 )); then
+    systemctl stop dhcpd.service
+    if [ $? -eq 0 ]; then
+        printf "\t OK!\n"
+    else
+        printf "\t FAIL!\n"
+        printf "\t failed to stop dhcpd service check run sudo systemct start dhcpd.service and check error messages\n"
+        exit 1
+    fi
+fi
+
+printf "setting up wifi radio...\n"
+nmcli radio wifi on
+if [ $? -eq 0 ]; then
+    printf "\t OK!\n"
+else
+    printf "\t FAIL!\n"
+    printf "\t \"nmcli radio wifi on\" command failed\n"
+    exit 1
+fi
+    
+printf "hostapd should now be off check to see if wifi is working!\n"
-- 
GitLab