changeset 87:0e4ab6c2a99c

ubx: actually wait for acks/naks Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Mon, 22 Feb 2021 08:46:16 -0500
parents 310a6abb7454
children 2875fe2d8fd5
files capture.c iothread.c ubx.c ubx.h
diffstat 4 files changed, 78 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/capture.c	Mon Feb 22 07:56:56 2021 -0500
+++ b/capture.c	Mon Feb 22 08:46:16 2021 -0500
@@ -359,6 +359,9 @@
 	if (setvbuf(ifile, file_buffer, _IOFBF, sizeof(file_buffer)) == EOF)
 		fprintf(stderr, "Warn: Failed to mark stream as buffered\n");
 
+	/* make sure ack queuing is set up */
+	ubx_init_queue();
+
 	/* start the iothread before we make any writes to the device */
 	ret = iothread_start(ifile, rfile, verbose, !input_readonly);
 	if (ret) {
--- a/iothread.c	Mon Feb 22 07:56:56 2021 -0500
+++ b/iothread.c	Mon Feb 22 08:46:16 2021 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ * Copyright (c) 2019-2021 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -168,6 +168,10 @@
 			raw[hdr.len], raw[hdr.len + 1]);
 	}
 
+	if ((mkmsgid(hdr.class, hdr.id) == UBX_ACK_ACK) ||
+	    (mkmsgid(hdr.class, hdr.id) == UBX_ACK_NAK))
+		notify_ubx_ack(raw, hdr.len, hdr.id);
+
 	ret = log_raw_ubx(&hdr, raw, start_time, start_tick);
 	if (ret)
 		fprintf(stderr, "Failed to log raw UBX message: %s\n",
--- a/ubx.c	Mon Feb 22 07:56:56 2021 -0500
+++ b/ubx.c	Mon Feb 22 08:46:16 2021 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ * Copyright (c) 2019-2021 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -22,11 +22,33 @@
 
 #include <jeffpc/io.h>
 #include <jeffpc/hexdump.h>
+#include <jeffpc/synch.h>
+#include <jeffpc/list.h>
 
 #include "ubx.h"
 #include "xstdio.h"
 #include "rfc1145.h"
 
+static LOCK_CLASS(ack_queue_lc);
+static struct lock ack_lock;
+static struct list ack_waiters;
+
+struct ack_waiter {
+	struct list_node node;
+	struct cond cond;
+	enum ubx_msg_id id;
+	bool finished;
+	bool success;
+};
+
+void ubx_init_queue(void)
+{
+	MXINIT(&ack_lock, &ack_queue_lc);
+
+	list_create(&ack_waiters, sizeof(struct ack_waiter),
+		    offsetof(struct ack_waiter, node));
+}
+
 const char *ubx_msg_name(enum ubx_msg_id id)
 {
 	const char *names[0xffff] = {
@@ -96,12 +118,51 @@
 	return 0;
 }
 
-static int __read_ubx_ack(FILE *file, bool *ack_r)
+static bool __read_ubx_ack(FILE *file, enum ubx_msg_id id)
+{
+	struct ack_waiter waiter;
+
+	CONDINIT(&waiter.cond);
+	waiter.finished = false;
+	waiter.id = id;
+
+	MXLOCK(&ack_lock);
+	list_insert_tail(&ack_waiters, &waiter);
+
+	while (!waiter.finished)
+		CONDWAIT(&waiter.cond, &ack_lock);
+	MXUNLOCK(&ack_lock);
+
+	CONDDESTROY(&waiter.cond);
+
+	return waiter.success;
+}
+
+void notify_ubx_ack(const uint8_t *data, size_t len, bool success)
 {
-	FIXME("get ack");
+	struct ack_waiter *cur, *tmp;
+	enum ubx_msg_id id;
+
+	ASSERT3U(len, ==, 2);
+
+	id = mkmsgid(data[0], data[1]);
+
+	fprintf(stderr, "%s for %02x %02x (%s)\n", success ? "ACK" : "NAK",
+		data[0], data[1], ubx_msg_name(id));
 
-	*ack_r = true;
-	return 0;
+	MXLOCK(&ack_lock);
+	list_for_each_safe(cur, tmp, &ack_waiters) {
+		if (cur->id != id)
+			continue;
+
+		cur->finished = true;
+		cur->success = success;
+		CONDSIG(&cur->cond);
+
+		/* remove from queue */
+		list_remove(&ack_waiters, cur);
+	}
+	MXUNLOCK(&ack_lock);
 }
 
 int send_ubx(FILE *file, enum ubx_msg_id id, const void *data, size_t len)
@@ -119,9 +180,7 @@
 	if (ret)
 		return ret;
 
-	ret = __read_ubx_ack(file, &ack);
-	if (ret)
-		return ret;
+	ack = __read_ubx_ack(file, id);
 
 	return ack ? 0 : -ENOTSUP;
 }
--- a/ubx.h	Mon Feb 22 07:56:56 2021 -0500
+++ b/ubx.h	Mon Feb 22 08:46:16 2021 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ * Copyright (c) 2019-2021 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -280,12 +280,14 @@
 } __attribute__((packed,aligned(4)));
 STATIC_ASSERT(sizeof(struct ubx_rxm_sfrbx) == 8);
 
+extern void ubx_init_queue(void);
 extern const char *ubx_msg_name(enum ubx_msg_id id);
 extern int send_ubx(FILE *file, enum ubx_msg_id id, const void *data,
 		    size_t len);
 extern int send_ubx_with_ack(FILE *file, enum ubx_msg_id id, const void *data,
 			     size_t len);
 extern int enable_ubx_msg(FILE *file, enum ubx_msg_id id, int port, int rate);
+extern void notify_ubx_ack(const uint8_t *data, size_t len, bool success);
 
 extern bool parse_and_process_ubx_message(const uint8_t *buf, size_t len,
 					  const uint64_t tick,