aboutsummaryrefslogtreecommitdiffstats
path: root/dynamic-layers/openembedded-layer/recipes-navigation/gpsd/gpsd/0001-Introduce-Qualcomm-PDS-service-support.patch
diff options
context:
space:
mode:
Diffstat (limited to 'dynamic-layers/openembedded-layer/recipes-navigation/gpsd/gpsd/0001-Introduce-Qualcomm-PDS-service-support.patch')
-rw-r--r--dynamic-layers/openembedded-layer/recipes-navigation/gpsd/gpsd/0001-Introduce-Qualcomm-PDS-service-support.patch544
1 files changed, 0 insertions, 544 deletions
diff --git a/dynamic-layers/openembedded-layer/recipes-navigation/gpsd/gpsd/0001-Introduce-Qualcomm-PDS-service-support.patch b/dynamic-layers/openembedded-layer/recipes-navigation/gpsd/gpsd/0001-Introduce-Qualcomm-PDS-service-support.patch
deleted file mode 100644
index b502fae..0000000
--- a/dynamic-layers/openembedded-layer/recipes-navigation/gpsd/gpsd/0001-Introduce-Qualcomm-PDS-service-support.patch
+++ /dev/null
@@ -1,544 +0,0 @@
-From 3f46e63ff08afba0ad532d4cac1957499769dc69 Mon Sep 17 00:00:00 2001
-From: Bjorn Andersson <bjorn.andersson@linaro.org>
-Date: Wed, 4 Apr 2018 04:29:09 +0000
-Subject: [PATCH] Introduce Qualcomm PDS service support
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The Qualcomm PDS service provides location data on a wide range of
-Qualcomm platforms. It used QMI encoded messages sent over a shared
-memory link, implemented in Linux as AF_QIPCRTR.
-
-A special service is available on port -2 on the local node in the
-network, which provides functionality to the node address and port of
-registered services by id. As the driver is opened this mechanism is
-used to search for a registered PDS service in the system.
-
-As the PDS driver is activated two messages are sent to the PDS service,
-the first one configures which events the service will send to the
-client (in our case NMEA reports) and the second starts the transmission
-of these packets. Similarly when the driver is deactivated a stop
-request is sent to the service.
-
-Between the start and stop request the PDS service will send NMEA
-messages to the PDS client at a rate of 1 Hz, the NMEA string is
-extracted from the QMI encoded message and handed to the nmea_parse()
-function.
-
-The PDS driver is selected by the url pds://<host>, where host is either
-a numerical identifier of the node in the AF_QIPCRTR network or the
-string "any".
-
-Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
-Signed-off-by: Aníbal Limón <anibal.limon@linaro.org>
----
- SConscript | 10 ++
- driver_pds.c | 325 +++++++++++++++++++++++++++++++++++++++++++++++++
- driver_pds.h | 20 +++
- drivers.c | 5 +
- gpsd.h | 2 +
- libgpsd_core.c | 15 ++-
- 6 files changed, 376 insertions(+), 1 deletion(-)
- create mode 100644 driver_pds.c
- create mode 100644 driver_pds.h
-
-diff --git a/SConscript b/SConstruct
-index 33e0ff326..d4ae81979 100644
---- a/SConscript
-+++ b/SConscript
-@@ -192,6 +192,7 @@ boolopts = (
- ("tripmate", True, "DeLorme TripMate support"),
- ("tsip", True, "Trimble TSIP support"),
- ("ublox", True, "u-blox Protocol support"),
-+ ("pds", True, "Qualcomm PDS support"),
- # Non-GPS protocols
- ("aivdm", True, "AIVDM support"),
- ("gpsclock", True, "GPSClock support"),
-@@ -977,6 +978,14 @@ else:
- announce("You do not have kernel CANbus available.")
- config.env["nmea2000"] = False
-
-+ if config.CheckHeader(["bits/sockaddr.h", "linux/qrtr.h"]):
-+ confdefs.append("#define HAVE_LINUX_QRTR_H 1\n")
-+ announce("You have kernel QRTR available.")
-+ else:
-+ confdefs.append("/* #undef HAVE_LINUX_QRTR_H */\n")
-+ announce("You do not have kernel QRTR available.")
-+ env["pds"] = False
-+
- # check for C11 or better, and __STDC__NO_ATOMICS__ is not defined
- # before looking for stdatomic.h
- if ((config.CheckC11() and
-@@ -1655,6 +1664,7 @@ libgpsd_sources = [
- "drivers/driver_nmea0183.c",
- "drivers/driver_nmea2000.c",
- "drivers/driver_oncore.c",
-+ "drivers/driver_pds.c",
- "drivers/driver_rtcm2.c",
- "drivers/driver_rtcm3.c",
- "drivers/drivers.c",
-diff --git a/drivers/driver_pds.c b/drivers/driver_pds.c
-new file mode 100644
-index 000000000..734b40f83
---- /dev/null
-+++ b/drivers/driver_pds.c
-@@ -0,0 +1,327 @@
-+#include "../include/gpsd_config.h" /* must be before all includes */
-+
-+#include <sys/socket.h>
-+#include <errno.h>
-+#include <fcntl.h>
-+#include <stdlib.h>
-+#include <unistd.h>
-+#include "../include/gpsd.h"
-+#include "../include/libgps.h"
-+
-+#if defined(PDS_ENABLE)
-+#include "../include/driver_pds.h"
-+
-+#include <linux/qrtr.h>
-+
-+#define QMI_PDS_SERVICE_ID 0x10
-+#define QMI_PDS_VERSION 0x2
-+
-+struct qmi_header {
-+ uint8_t type;
-+ uint16_t txn;
-+ uint16_t msg;
-+ uint16_t len;
-+} __attribute__((__packed__));
-+
-+struct qmi_tlv {
-+ uint8_t key;
-+ uint16_t len;
-+ uint8_t value[];
-+} __attribute__((__packed__));
-+
-+#define QMI_REQUEST 0
-+#define QMI_INDICATION 4
-+
-+#define QMI_LOC_REG_EVENTS 0x21
-+#define QMI_TLV_EVENT_MASK 1
-+#define QMI_EVENT_MASK_NMEA 4
-+
-+#define QMI_LOC_START 0x22
-+#define QMI_LOC_STOP 0x23
-+#define QMI_TLV_SESSION_ID 1
-+
-+#define QMI_LOC_EVENT_NMEA 0x26
-+#define QMI_TLV_NMEA 1
-+
-+static ssize_t qmi_pds_get(struct gps_device_t *session)
-+{
-+ struct sockaddr_qrtr sq;
-+ socklen_t sl = sizeof(sq);
-+ struct qmi_header *hdr;
-+ struct qmi_tlv *tlv;
-+ size_t buflen = sizeof(session->lexer.inbuffer);
-+ size_t offset;
-+ void *buf = session->lexer.inbuffer;
-+ int ret;
-+
-+ ret = recvfrom(session->gpsdata.gps_fd, buf, buflen, 0,
-+ (struct sockaddr *)&sq, &sl);
-+ if (ret < 0 && errno == EAGAIN) {
-+ session->lexer.outbuflen = 0;
-+ return 1;
-+ } else if (ret < 0) {
-+ GPSD_LOG(LOG_ERROR, &session->context->errout,
-+ "QRTR get: Unable to receive packet.\n");
-+ return -1;
-+ }
-+
-+ /* TODO: Validate sq to be our peer */
-+
-+ session->lexer.type = QMI_PDS_PACKET;
-+
-+ hdr = buf;
-+ if (hdr->type != QMI_INDICATION ||
-+ hdr->msg != QMI_LOC_EVENT_NMEA) {
-+ session->lexer.outbuflen = 0;
-+ return ret;
-+ }
-+
-+ offset = sizeof(*hdr);
-+ while (offset < (size_t)ret) {
-+ tlv = (struct qmi_tlv *)((char*)buf + offset);
-+
-+ if (offset + sizeof(*tlv) + tlv->len > (size_t)ret)
-+ break;
-+
-+ if (tlv->key == QMI_TLV_NMEA) {
-+ memcpy(session->lexer.outbuffer, tlv->value, tlv->len);
-+ session->lexer.outbuffer[tlv->len] = 0;
-+ session->lexer.outbuflen = tlv->len;
-+ break;
-+ }
-+
-+ offset += tlv->len;
-+ }
-+
-+ return ret;
-+}
-+
-+static gps_mask_t qmi_pds_parse_input(struct gps_device_t *session)
-+{
-+ return nmea_parse((char *)session->lexer.outbuffer, session);
-+}
-+
-+static void qmi_pds_event_hook(struct gps_device_t *session, event_t event)
-+{
-+ struct qmi_header *hdr;
-+ struct qmi_tlv *tlv;
-+ static int txn_id;
-+ char buf[128];
-+ char *ptr;
-+ int sock = session->gpsdata.gps_fd;
-+ int ret;
-+
-+ switch (event) {
-+ case event_deactivate:
-+ ptr = buf;
-+ hdr = (struct qmi_header *)ptr;
-+ hdr->type = QMI_REQUEST;
-+ hdr->txn = txn_id++;
-+ hdr->msg = QMI_LOC_STOP;
-+ hdr->len = sizeof(*tlv) + sizeof(uint8_t);
-+ ptr += sizeof(*hdr);
-+
-+ tlv = (struct qmi_tlv *)ptr;
-+ tlv->key = QMI_TLV_SESSION_ID;
-+ tlv->len = sizeof(uint8_t);
-+ *(uint8_t*)tlv->value = 1;
-+ ptr += sizeof(*tlv) + sizeof(uint8_t);
-+
-+ ret = send(sock, buf, ptr - buf, 0);
-+ if (ret < 0) {
-+ GPSD_LOG(LOG_ERROR, &session->context->errout,
-+ "QRTR event_hook: failed to send STOP request.\n");
-+ return;
-+ }
-+ break;
-+ case event_reactivate:
-+ ptr = buf;
-+ hdr = (struct qmi_header *)ptr;
-+ hdr->type = QMI_REQUEST;
-+ hdr->txn = txn_id++;
-+ hdr->msg = QMI_LOC_REG_EVENTS;
-+ hdr->len = sizeof(*tlv) + sizeof(uint64_t);
-+ ptr += sizeof(*hdr);
-+
-+ tlv = (struct qmi_tlv *)ptr;
-+ tlv->key = QMI_TLV_EVENT_MASK;
-+ tlv->len = sizeof(uint64_t);
-+ *(uint64_t*)tlv->value = QMI_EVENT_MASK_NMEA;
-+ ptr += sizeof(*tlv) + sizeof(uint64_t);
-+
-+ ret = send(sock, buf, ptr - buf, 0);
-+ if (ret < 0) {
-+ GPSD_LOG(LOG_ERROR, &session->context->errout,
-+ "QRTR event_hook: failed to send REG_EVENTS request.\n");
-+ return;
-+ }
-+
-+ ptr = buf;
-+ hdr = (struct qmi_header *)ptr;
-+ hdr->type = QMI_REQUEST;
-+ hdr->txn = txn_id++;
-+ hdr->msg = QMI_LOC_START;
-+ hdr->len = sizeof(*tlv) + sizeof(uint8_t);
-+ ptr += sizeof(*hdr);
-+
-+ tlv = (struct qmi_tlv *)(buf + sizeof(*hdr));
-+ tlv->key = QMI_TLV_SESSION_ID;
-+ tlv->len = sizeof(uint8_t);
-+ *(uint8_t*)tlv->value = 1;
-+ ptr += sizeof(*tlv) + sizeof(uint8_t);
-+
-+ ret = send(sock, buf, ptr - buf, 0);
-+ if (ret < 0) {
-+ GPSD_LOG(LOG_ERROR, &session->context->errout,
-+ "QRTR event_hook: failed to send START request.\n");
-+ return;
-+ }
-+ break;
-+ default:
-+ break;
-+ }
-+}
-+
-+int qmi_pds_open(struct gps_device_t *session)
-+{
-+ struct sockaddr_qrtr sq_ctrl;
-+ struct qrtr_ctrl_pkt pkt;
-+ struct sockaddr_qrtr sq;
-+ unsigned int pds_node = 0;
-+ unsigned int pds_port = 0;
-+ socklen_t sl = sizeof(sq_ctrl);
-+ char *hostname;
-+ char *endptr;
-+ int hostid;
-+ int flags;
-+ int sock;
-+ int ret;
-+
-+ hostname = session->gpsdata.dev.path + 6;
-+ if (!strcmp(hostname, "any")) {
-+ hostid = -1;
-+ } else {
-+ hostid = (int)strtol(hostname, &endptr, 10);
-+ if (endptr == hostname) {
-+ GPSD_LOG(LOG_ERROR, &session->context->errout,
-+ "QRTR open: Invalid node id.\n");
-+ return -1;
-+ }
-+ }
-+
-+
-+ sock = socket(AF_QIPCRTR, SOCK_DGRAM, 0);
-+ if (sock < 0) {
-+ GPSD_LOG(LOG_ERROR, &session->context->errout,
-+ "QRTR open: Unable to get QRTR socket.\n");
-+ return -1;
-+ }
-+
-+ ret = getsockname(sock, (struct sockaddr *)&sq_ctrl, &sl);
-+ if (ret < 0 || sq_ctrl.sq_family != AF_QIPCRTR || sl != sizeof(sq_ctrl)) {
-+ GPSD_LOG(LOG_ERROR, &session->context->errout,
-+ "QRTR open: Unable to acquire local address.\n");
-+ close(sock);
-+ return -1;
-+ }
-+
-+ memset(&pkt, 0, sizeof(pkt));
-+ pkt.cmd = QRTR_TYPE_NEW_LOOKUP;
-+ pkt.server.service = QMI_PDS_SERVICE_ID;
-+ pkt.server.instance = QMI_PDS_VERSION;
-+
-+ sq_ctrl.sq_port = QRTR_PORT_CTRL;
-+ ret = sendto(sock, &pkt, sizeof(pkt), 0, (struct sockaddr *)&sq_ctrl, sizeof(sq_ctrl));
-+ if (ret < 0) {
-+ GPSD_LOG(LOG_ERROR, &session->context->errout,
-+ "QRTR open: Unable to send lookup request.\n");
-+ close(sock);
-+ 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;
-+
-+ return session->gpsdata.gps_fd;
-+}
-+
-+void qmi_pds_close(struct gps_device_t *session)
-+{
-+ if (!BAD_SOCKET(session->gpsdata.gps_fd)) {
-+ close(session->gpsdata.gps_fd);
-+ INVALIDATE_SOCKET(session->gpsdata.gps_fd);
-+ }
-+}
-+
-+const struct gps_type_t driver_pds = {
-+ .type_name = "Qualcomm PDS", /* full name of type */
-+ .packet_type = QMI_PDS_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 */
-+ .event_hook = qmi_pds_event_hook,
-+};
-+
-+#endif /* of defined(PDS_ENABLE) */
-diff --git a/include/driver_pds.h b/include/driver_pds.h
-new file mode 100644
-index 000000000..3b373743d
---- /dev/null
-+++ b/include/driver_pds.h
-@@ -0,0 +1,20 @@
-+/*
-+ * PDS on QRTR.
-+ *
-+ * The entry points for driver_pds
-+ *
-+ * This file is Copyright (c) 2018 by the GPSD project
-+ * SPDX-License-Identifier: BSD-2-clause
-+ */
-+
-+#ifndef _DRIVER_PDS_H_
-+#define _DRIVER_PDS_H_
-+
-+#if defined(PDS_ENABLE)
-+
-+int qmi_pds_open(struct gps_device_t *session);
-+
-+void qmi_pds_close(struct gps_device_t *session);
-+
-+#endif /* of defined(PDS_ENABLE) */
-+#endif /* of ifndef _DRIVER_PDS_H_ */
-diff --git a/drivers/drivers.c b/drivers/drivers.c
-index 39e3d0a4c..7d788e1ab 100644
---- a/drivers/drivers.c
-+++ b/drivers/drivers.c
-@@ -1747,6 +1747,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;
-@@ -1844,6 +1845,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/include/gpsd.h b/include/gpsd.h
-index 57e4b0553..e9f61cc71 100644
---- a/include/gpsd.h
-+++ b/include/gpsd.h
-@@ -220,12 +220,13 @@ struct gps_lexer_t {
- #define GEOSTAR_PACKET 14
- #define NMEA2000_PACKET 15
- #define GREIS_PACKET 16
--#define MAX_GPSPACKET_TYPE 16 /* increment this as necessary */
--#define RTCM2_PACKET 17
--#define RTCM3_PACKET 18
--#define JSON_PACKET 19
--#define PACKET_TYPES 20 /* increment this as necessary */
--#define SKY_PACKET 21
-+#define QMI_PDS_PACKET 17
-+#define MAX_GPSPACKET_TYPE 17 /* increment this as necessary */
-+#define RTCM2_PACKET 18
-+#define RTCM3_PACKET 19
-+#define JSON_PACKET 20
-+#define PACKET_TYPES 21 /* increment this as necessary */
-+#define SKY_PACKET 22
- #define TEXTUAL_PACKET_TYPE(n) ((((n)>=NMEA_PACKET) && ((n)<=MAX_TEXTUAL_TYPE)) || (n)==JSON_PACKET)
- #define GPS_PACKET_TYPE(n) (((n)>=NMEA_PACKET) && ((n)<=MAX_GPSPACKET_TYPE))
- #define LOSSLESS_PACKET_TYPE(n) (((n)>=RTCM2_PACKET) && ((n)<=RTCM3_PACKET))
-@@ -462,6 +463,7 @@ typedef enum {SOURCE_UNKNOWN,
- SOURCE_USB, // potential GPS source, discoverable
- SOURCE_BLUETOOTH, // potential GPS source, discoverable
- SOURCE_CAN, // potential GPS source, fixed CAN format
-+ SOURCE_QRTR, // potential GPS source, discoverable
- SOURCE_PTY, // PTY: we don't require exclusive access
- SOURCE_TCP, // TCP/IP stream: case detected but not used
- SOURCE_UDP, // UDP stream: case detected but not used
-diff --git a/gpsd/libgpsd_core.c b/gpsd/libgpsd_core.c
-index 52bf8e5ae..a8a2ec0d3 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,
-@@ -351,6 +354,11 @@ void gpsd_deactivate(struct gps_device_t *session)
- (void)nmea2000_close(session);
- } else
- #endif /* of defined(NMEA2000_ENABLE) */
-+#if defined(PDS_ENABLE)
-+ if (session->sourcetype == SOURCE_QRTR)
-+ (void)qmi_pds_close(session);
-+ else
-+#endif /* of defined(PDS_ENABLE) */
- (void)gpsd_close(session);
- if (session->mode == O_OPTIMIZE)
- gpsd_run_device_hook(&session->context->errout,
-@@ -553,6 +561,11 @@ int gpsd_open(struct gps_device_t *session)
- return nmea2000_open(session);
- }
- #endif /* defined(NMEA2000_ENABLE) */
-+#if defined(PDS_ENABLE)
-+ if (str_starts_with(session->gpsdata.dev.path, "pds://")) {
-+ return qmi_pds_open(session);
-+ }
-+#endif /* defined(PDS_ENABLE) */
- /* fall through to plain serial open */
- /* could be a naked /dev/ppsX */
- return gpsd_serial_open(session);
-@@ -581,7 +594,7 @@ 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 ((session->servicetype == service_sensor) &&
-- (SOURCE_CAN != session->sourcetype)) {
-+ (SOURCE_CAN != session->sourcetype && SOURCE_QRTR != session->sourcetype)) {
- const struct gps_type_t **dp;
-
- for (dp = gpsd_drivers; *dp; dp++) {
---
-2.27.0.rc0
-