 +		return -1;
 +	}
 +
-+	for (;;) {
-+		sl = sizeof(sq);
-+
-+		ret = recvfrom(sock, &pkt, sizeof(pkt), 0, (struct sockaddr *)&sq, &sl);
-+		if (ret < 0) {
-+			GPSD_LOG(LOG_ERROR, &session->context->errout,
-+				 "QRTR open: Unable to receive lookup request.\n");
-+			close(sock);
-+			return -1;
-+		}
-+
-+		if (sl != sizeof(sq) || sq.sq_node != sq_ctrl.sq_node ||
-+		    sq.sq_port != sq_ctrl.sq_port) {
-+			GPSD_LOG(LOG_ERROR, &session->context->errout,
-+				 "QRTR open: Received message is not ctrl message, ignoring.\n");
-+			continue;
-+		}
-+
-+		if (pkt.cmd != QRTR_TYPE_NEW_SERVER)
-+			continue;
-+
-+		/* All fields zero indicates end of lookup response */
-+		if (!pkt.server.service && !pkt.server.instance &&
-+		    !pkt.server.node && !pkt.server.port)
-+			break;
-+
-+		/* Filter results based on specified node */
-+		if (hostid != -1 && hostid != (int)pkt.server.node)
-+			continue;
-+
-+		pds_node = pkt.server.node;
-+		pds_port = pkt.server.port;
-+	}
-+
-+	if (!pds_node && !pds_port) {
-+		GPSD_LOG(LOG_ERROR, &session->context->errout,
-+			 "QRTR open: No PDS service found.\n");
-+		close(sock);
-+		return -1;
-+	}
-+
-+	flags = fcntl(sock, F_GETFL, 0);
-+	flags |= O_NONBLOCK;
-+	fcntl(sock, F_SETFL, flags);
-+
-+	GPSD_LOG(LOG_INF, &session->context->errout,
-+		 "QRTR open: Found PDS at %d %d.\n", pds_node, pds_port);
-+
-+	sq.sq_family = AF_QIPCRTR;
-+	sq.sq_node = pds_node;
-+	sq.sq_port = pds_port;
-+	ret = connect(sock, (struct sockaddr *)&sq, sizeof(sq));
-+	if (ret < 0) {
-+		GPSD_LOG(LOG_ERROR, &session->context->errout,
-+			 "QRTR open: Failed to connect socket.\n");
-+		close(sock);
-+		return -1;
-+	}
-+
 +	gpsd_switch_driver(session, "Qualcomm PDS");
 +	session->gpsdata.gps_fd = sock;
 +	session->sourcetype = SOURCE_QRTR;
-+	session->servicetype = service_sensor;
++	session->servicetype = SERVICE_SENSOR;
 +
 +	return session->gpsdata.gps_fd;
 +}
 +
 +void qmi_pds_close(struct gps_device_t *session)
 +{
++	int i;
++
 +	if (!BAD_SOCKET(session->gpsdata.gps_fd)) {
 +		close(session->gpsdata.gps_fd);
 +		INVALIDATE_SOCKET(session->gpsdata.gps_fd);
 +	}
++
++	for (i = 0; i < QMI_PDS_MAX; i++) {
++		if (pds_devices[i] == NULL)
++			continue;
++
++		if (strcmp(pds_devices[i]->gpsdata.dev.path,
++				session->gpsdata.dev.path) == 0) {
++			pds_devices[i] = NULL;
++			break;
++		}
++	}
 +}
 +
 +const struct gps_type_t driver_pds = {
 +    .type_name      = "Qualcomm PDS",       /* full name of type */
-+    .packet_type    = QMI_PDS_PACKET,	/* associated lexer packet type */
++    .packet_type    = NMEA_PACKET,	/* associated lexer packet type */
 +    .flags	    = DRIVER_STICKY,	/* remember this */
 +    .channels       = 12,		/* not an actual GPS at all */
 +    .get_packet     = qmi_pds_get,	/* how to get a packet */
-+    .parse_packet   = qmi_pds_parse_input,	/* how to interpret a packet */
++    .parse_packet   = generic_parse_input,	/* how to interpret a packet */
 +    .event_hook	    = qmi_pds_event_hook,
++    .control_send   = qmi_control_send,
 +};
 +
 +#endif /* of defined(PDS_ENABLE) */
+diff --git a/drivers/drivers.c b/drivers/drivers.c
+index 5c7c67b30..47a292423 100644
+--- a/drivers/drivers.c
++++ b/drivers/drivers.c
+@@ -1694,6 +1694,7 @@ extern const struct gps_type_t driver_greis;
+ extern const struct gps_type_t driver_italk;
+ extern const struct gps_type_t driver_navcom;
+ extern const struct gps_type_t driver_nmea2000;
++extern const struct gps_type_t driver_pds;
+ extern const struct gps_type_t driver_oncore;
+ extern const struct gps_type_t driver_sirf;
+ extern const struct gps_type_t driver_skytraq;
+@@ -1787,6 +1788,10 @@ static const struct gps_type_t *gpsd_driver_array[] = {
+     &driver_nmea2000,
+ #endif /* NMEA2000_ENABLE */
+ 
++#ifdef PDS_ENABLE
++    &driver_pds,
++#endif /* PDS_ENABLE */
++
+ #ifdef RTCM104V2_ENABLE
+     &driver_rtcm104v2,
+ #endif /* RTCM104V2_ENABLE */
+diff --git a/gpsd/libgpsd_core.c b/gpsd/libgpsd_core.c
+index 60a7c2e2f..ceebb1a2a 100644
+--- a/gpsd/libgpsd_core.c
++++ b/gpsd/libgpsd_core.c
+@@ -39,6 +39,9 @@
+ #if defined(NMEA2000_ENABLE)
+     #include "../include/driver_nmea2000.h"
+ #endif /* defined(NMEA2000_ENABLE) */
++#if defined(PDS_ENABLE)
++#include "../include/driver_pds.h"
++#endif /* defined(PDS_ENABLE) */
+ 
+ // pass low-level data to devices straight through
+ ssize_t gpsd_write(struct gps_device_t *session,
+@@ -358,6 +361,11 @@ void gpsd_deactivate(struct gps_device_t *session)
+     } else
+ #endif  // of defined(NMEA2000_ENABLE)
+     {
++#if defined(PDS_ENABLE)
++    if (SOURCE_QRTR == session->sourcetype)
++	(void)qmi_pds_close(session);
++    else
++#endif /* of defined(PDS_ENABLE) */
+         (void)gpsd_close(session);
+     }
+     if (O_OPTIMIZE == session->mode) {
+@@ -629,6 +637,11 @@ int gpsd_open(struct gps_device_t *session)
+ #endif  // defined(NMEA2000_ENABLE)
+     /* fall through to plain serial open.
+      * could be a naked /dev/ppsX */
++#if defined(PDS_ENABLE)
++    if (str_starts_with(session->gpsdata.dev.path, "pds://")) {
++	    return qmi_pds_open(session);
++    }
++#endif /* defined(PDS_ENABLE) */
+     return gpsd_serial_open(session);
+ }
+ 
+@@ -656,7 +669,8 @@ int gpsd_activate(struct gps_device_t *session, const int mode)
+ #ifdef NON_NMEA0183_ENABLE
+     // if it's a sensor, it must be probed
+     if ((SERVICE_SENSOR == session->servicetype) &&
+-        (SOURCE_CAN != session->sourcetype)) {
++        (SOURCE_CAN != session->sourcetype) && 
++        (SOURCE_QRTR != session->sourcetype)) {
+         const struct gps_type_t **dp;
+ 
+         for (dp = gpsd_drivers; *dp; dp++) {
 diff --git a/include/driver_pds.h b/include/driver_pds.h
 new file mode 100644
 index 000000000..3b373743d

+	uint8_t value[];
+} __attribute__((__packed__));
+
+#define QMI_REQUEST			0
+#define QMI_INDICATION			4
+

+		}
+		break;
+	case event_reactivate:
+		if (!session->driver.pds.ready)
+			return;
+
+		ptr = buf;
+		hdr = (struct qmi_header *)ptr;
+		hdr->type = QMI_REQUEST;
