changeset 44:9ed7bbc034bf

capture: rewrite argument parsing to be more flexible Allow the user to specify which GNSS constellations to use without having to recompile. Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Thu, 16 Jan 2020 11:33:32 -0500
parents f6497b2822c8
children d71fc34c755d
files capture.c
diffstat 1 files changed, 108 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/capture.c	Thu Jan 16 11:13:56 2020 -0500
+++ b/capture.c	Thu Jan 16 11:33:32 2020 -0500
@@ -33,15 +33,22 @@
 
 static void usage(const char *prog)
 {
-	fprintf(stderr, "Usage: %s <device> <ubxport> <log>\n", prog);
+	fprintf(stderr, "Usage: %s [-cegrs] -d <device> [-u <ubxport>] "
+		"-l <log>\n", prog);
 	fprintf(stderr, "\n");
-	fprintf(stderr, "  <device>       path or - for standard in\n");
-	fprintf(stderr, "  <ubxport>      port number (0=DCC, 1=UART, 3=USB, 4=SPI)\n");
-	fprintf(stderr, "  <log>          path for framed UBX message log\n");
+	fprintf(stderr, "  -c             enable BeiDou\n");
+	fprintf(stderr, "  -e             enable Galileo\n");
+	fprintf(stderr, "  -g             enable GPS\n");
+	fprintf(stderr, "  -r             enable GLONASS\n");
+	fprintf(stderr, "  -s             enable SBAS & QZSS\n");
+	fprintf(stderr, "  -d <device>    path or - for standard in\n");
+	fprintf(stderr, "  -u <ubxport>   port number (0=DCC, 1=UART, 3=USB, 4=SPI)\n");
+	fprintf(stderr, "  -l <log>       path for framed UBX message log\n");
 	exit(1);
 }
 
-static int cfg_port(FILE *file, bool ro, uint8_t ubxport)
+static int cfg_port(FILE *file, bool ro, uint8_t ubxport, bool beidou,
+		    bool galileo, bool gps, bool glonass, bool sbas)
 {
 	struct ubx_cfg_prt_uart prt_uart = {
 		.port = ubxport,
@@ -69,37 +76,43 @@
 				.gnssid = GNSSID_GPS,
 				.res_trk_ch = 4,
 				.max_trk_ch = 8,
-				.flags = cpu32_to_le(0x00010001), /* L1, enable */
+				.flags = cpu32_to_le(0x00010000) /* L1 */ |
+					 cpu32_to_le(gps ? 0x1 : 0x0),
 			},
 			{
 				.gnssid = GNSSID_GALILEO,
 				.res_trk_ch = 8,
 				.max_trk_ch = 10,
-				.flags = cpu32_to_le(0x00010001), /* E1, enable */
+				.flags = cpu32_to_le(0x00010000) /* E1 */ |
+					 cpu32_to_le(galileo ? 0x1 : 0x0),
 			},
 			{
 				.gnssid = GNSSID_GLONASS,
 				.res_trk_ch = 6,
 				.max_trk_ch = 8,
-				.flags = cpu32_to_le(0x00010001), /* L1, enable */
+				.flags = cpu32_to_le(0x00010000) /* L1 */ |
+					 cpu32_to_le(glonass ? 0x1 : 0x0),
 			},
 			{
 				.gnssid = GNSSID_BEIDOU,
 				.res_trk_ch = 6,
 				.max_trk_ch = 8,
-				.flags = cpu32_to_le(0x00010000), /* B1I */
+				.flags = cpu32_to_le(0x00010000) /* B1I */ |
+					 cpu32_to_le(beidou ? 0x1 : 0x0),
 			},
 			{
 				.gnssid = GNSSID_SBAS,
 				.res_trk_ch = 3,
 				.max_trk_ch = 4,
-				.flags = cpu32_to_le(0x00010001), /* L1, enable */
+				.flags = cpu32_to_le(0x00010000) /* L1 */ |
+					 cpu32_to_le(sbas ? 0x1 : 0x0),
 			},
 			{
 				.gnssid = GNSSID_QZSS,
 				.res_trk_ch = 4,
 				.max_trk_ch = 8,
-				.flags = cpu32_to_le(0x00010001), /* L1C, enable */
+				.flags = cpu32_to_le(0x00010000) /* L1C */ |
+					 cpu32_to_le(sbas ? 0x1 : 0x0),
 			},
 		},
 	};
@@ -185,32 +198,96 @@
 	struct stat stat;
 	struct termios termios;
 	bool input_readonly;
+	const char *device;
+	const char *log;
+	bool enable_beidou;
+	bool enable_galileo;
+	bool enable_gps;
+	bool enable_glonass;
+	bool enable_sbas;
 	uint8_t ubxport;
 	FILE *ifile;
 	FILE *rfile;
+	int opt;
 	int ret;
 	int fd;
 
-	if (argc != 4)
-		usage(argv[0]);
+	device = NULL;
+	log = NULL;
+	enable_beidou = false;
+	enable_galileo = false;
+	enable_gps = false;
+	enable_glonass = false;
+	enable_sbas = false;
+	ubxport = 3;
 
-	ret = str2u8(argv[2], &ubxport);
-	if (ret) {
-		fprintf(stderr, "Error: invalid ubxport - must be a number\n");
-		return 2;
+	while ((opt = getopt(argc, argv, "+cegrsd:l:u:")) != -1) {
+		switch (opt) {
+			case 'c':
+				enable_beidou = true;
+				break;
+			case 'e':
+				enable_galileo = true;
+				break;
+			case 'g':
+				enable_gps = true;
+				break;
+			case 'r':
+				enable_glonass = true;
+				break;
+			case 's':
+				enable_sbas = true;
+				break;
+			case 'd':
+				device = optarg;
+				break;
+			case 'l':
+				log = optarg;
+				break;
+			case 'u':
+				if (str2u8(optarg, &ubxport)) {
+					fprintf(stderr, "Error: '%s' is not "
+						"a valid ublox port.\n",
+						optarg);
+					usage(argv[0]);
+				}
+
+				if (ubxport > 6) {
+					fprintf(stderr, "Error: invalid ubxport"
+						" - must be [0,6] (got %u)\n",
+						ubxport);
+					usage(argv[0]);
+				}
+				break;
+			default:
+				usage(argv[0]);
+		}
 	}
 
-	if (ubxport > 6) {
-		fprintf(stderr, "Error: invalid ubxport - must be [0,6] (got %u)\n",
-			ubxport);
-		return 3;
+	if (optind != argc)
+		usage(argv[0]);
+
+	if (!device) {
+		fprintf(stderr, "Missing device name\n");
+		usage(argv[0]);
 	}
 
-	if (!strcmp(argv[1], "/dev/stdin") || !strcmp(argv[1], "-")) {
-		argv[1] = "/dev/stdin";
+	if (!log) {
+		fprintf(stderr, "Missing log name\n");
+		usage(argv[0]);
+	}
+
+	if (!enable_beidou && !enable_galileo && !enable_gps &&
+	    !enable_glonass && !enable_sbas) {
+		fprintf(stderr, "Missing GNSS constellation selection\n");
+		usage(argv[0]);
+	}
+
+	if (!strcmp(device, "/dev/stdin") || !strcmp(device, "-")) {
+		device = "/dev/stdin";
 		input_readonly = true;
 	} else {
-		ret = xstat(argv[1], &stat);
+		ret = xstat(device, &stat);
 		if (ret < 0) {
 			fprintf(stderr, "Error: failed to stat input: %s\n",
 				xstrerror(ret));
@@ -220,11 +297,11 @@
 		input_readonly = !S_ISCHR(stat.st_mode);
 	}
 
-	fd = xopen(argv[1], input_readonly ? O_RDONLY : O_RDWR, 0);
+	fd = xopen(device, input_readonly ? O_RDONLY : O_RDWR, 0);
 	if (fd < 0) {
 		fprintf(stderr, "Error: Could not open device %s: %s\n",
-			argv[1], xstrerror(fd));
-		return 5;
+			device, xstrerror(fd));
+		usage(argv[0]);
 	}
 
 	if (!input_readonly) {
@@ -262,7 +339,7 @@
 		return 9;
 	}
 
-	rfile = fopen(argv[3], "wb");
+	rfile = fopen(log, "wb");
 	if (rfile == NULL) {
 		fprintf(stderr, "Error: Failed to fopen log: %s\n",
 			xstrerror(-errno));
@@ -272,7 +349,9 @@
 	if (setvbuf(ifile, file_buffer, _IOFBF, sizeof(file_buffer)) == EOF)
 		fprintf(stderr, "Warn: Failed to mark stream as buffered\n");
 
-	ret = cfg_port(ifile, input_readonly, ubxport);
+	ret = cfg_port(ifile, input_readonly, ubxport, enable_beidou,
+		       enable_galileo, enable_gps, enable_glonass,
+		       enable_sbas);
 	if (ret) {
 		fprintf(stderr, "Error: Failed to configure port: %s\n",
 			xstrerror(ret));