apps: Remove gpsd as dependency in favor of manual installation

This also adds supporting code to handle the presence of these
applications or lack thereof.

Change-Id: If104e5e0be211e596c5d3b68510a11d5dd171914
diff --git a/docs/install.rst b/docs/install.rst
index 1ff8399..90bcc58 100644
--- a/docs/install.rst
+++ b/docs/install.rst
@@ -239,4 +239,12 @@
 
 - ``2024-08``: ndn-cxx 0.9.0, NFD 24.07, NLSR 24.08, PSync 0.5.0,
   ndn-tools 24.07, and compatible versions of ndn-traffic-generator
-  and infoedit.
\ No newline at end of file
+  and infoedit.
+
+Using gpsd (Experimental)
+----------------
+
+The gpsd application included currently is based on in-progress work and
+is not treated as part of the main dependencies. To use it, install the
+`gpsd` and `nc` (netcat) from your package manager, if not already present,
+to enable the functionality.
\ No newline at end of file
diff --git a/minindn/apps/gpsd.py b/minindn/apps/gpsd.py
index 7ec79d0..7626de1 100644
--- a/minindn/apps/gpsd.py
+++ b/minindn/apps/gpsd.py
@@ -25,9 +25,13 @@
 import math
 import time
 import datetime
+from subprocess import TimeoutExpired, DEVNULL
 from typing import Optional, Tuple
 
+from mininet.log import error
+
 from minindn.apps.application import Application
+from minindn.util import getPopen
 
 
 class Gpsd(Application):
@@ -222,6 +226,19 @@
         """
         Start a thread to periodically send GPS data for the node.
         """
+        try:
+            gpsd_present = getPopen(self.node, "gpsd -V", stdout=DEVNULL, stderr=DEVNULL).wait(timeout=5)
+            nc_present = getPopen(self.node, "nc -h", stdout=DEVNULL, stderr=DEVNULL).wait(timeout=5)
+            if gpsd_present > 0:
+                error("The application is currently missing gpsd as a dependency. This must be installed manually.\n")
+            elif nc_present > 0:
+                error("The application is currently missing netcat as a dependency. This must be installed manually.\n")
+            if (gpsd_present + nc_present) > 0:
+                raise RuntimeError("Missing dependency for gpsd helper")
+        except TimeoutExpired as e:
+            error("The application is unable to validate if you have all required dependencies for gpsd.\n")
+            raise e
+
         Application.start(self, command="gpsd -n udp://127.0.0.1:7150")
 
         self.location_thread = threading.Thread(target=self.__feedGPStoGPSD, args=(self.node,))
diff --git a/util/pkgdep/debian-like.sh b/util/pkgdep/debian-like.sh
index fbab0ce..c3fe636 100644
--- a/util/pkgdep/debian-like.sh
+++ b/util/pkgdep/debian-like.sh
@@ -26,7 +26,6 @@
   build-essential
   ca-certificates
   git
-  gpsd
   libboost-atomic-dev
   libboost-chrono-dev
   libboost-date-time-dev
diff --git a/util/pkgdep/fedora.sh b/util/pkgdep/fedora.sh
index 5a2056e..c80971b 100644
--- a/util/pkgdep/fedora.sh
+++ b/util/pkgdep/fedora.sh
@@ -33,7 +33,6 @@
   boost-devel
   ca-certificates
   gcc-c++
-  gpsd
   libpcap-devel
   openssl-devel
   python3-pip