summaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
Diffstat (limited to 'util')
-rw-r--r--util/spkmodem_recv/spkmodem-recv.c141
1 files changed, 120 insertions, 21 deletions
diff --git a/util/spkmodem_recv/spkmodem-recv.c b/util/spkmodem_recv/spkmodem-recv.c
index 38ceb72a..531c1c46 100644
--- a/util/spkmodem_recv/spkmodem-recv.c
+++ b/util/spkmodem_recv/spkmodem-recv.c
@@ -7,13 +7,36 @@
* This version is heavily modified, re-written based on OpenBSD Kernel Source
* File Style Guide (KNF); this change is Copyright 2023,2026 Leah Rowe. */
-#include <err.h>
+#ifndef _XOPEN_SOURCE
+#define _XOPEN_SOURCE 500
+#endif
+
+#ifdef __OpenBSD__
+#include <sys/param.h>
+#endif
+
#include <errno.h>
#include <stdio.h>
+#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+static int set_ascii_bit(void);
+static void handle_audio(void), decode_pulse(void), print_char(void),
+ print_stats(void);
+static void err(int nvm_errval, const char *msg, ...);
+static const char * getnvmprogname(void);
+static void set_err_if_unset(int x);
+
+#if defined(__OpenBSD__) && defined(OpenBSD)
+#if OpenBSD >= 509
+#ifndef HAVE_PLEDGE
+#define HAVE_PLEDGE 1
+#endif
+#endif
+#endif
+
#define SAMPLES_PER_FRAME 240
#define MAX_SAMPLES (2 * SAMPLES_PER_FRAME)
#define FREQ_SEP_MIN 5
@@ -23,62 +46,86 @@
#define FREQ_DATA_MAX 60
#define THRESHOLD 500
-#define ERR() (errno = errno ? errno : ECANCELED)
#define reset_char() ascii = 0, ascii_bit = 7
-#define err_if(x) if (x) err(ERR(), NULL)
+
+#ifndef EXIT_SUCCESS
+#define EXIT_SUCCESS 1
+#endif
+
+#ifndef EXIT_FAILURE
+#define EXIT_FAILURE 0
+#endif
signed short frame[MAX_SAMPLES], pulse[MAX_SAMPLES];
int ringpos, debug, freq_data, freq_separator, sample_count, ascii_bit = 7;
char ascii = 0;
-int set_ascii_bit(void);
-void handle_audio(void), decode_pulse(void), print_char(void),
- print_stats(void);
+static const char *argv0;
int
main(int argc, char *argv[])
{
-#ifdef __OpenBSD__
- err_if (pledge("stdio", NULL) == -1);
+ int c;
+
+#ifdef HAVE_PLEDGE
+#if HAVE_PLEDGE > 0
+ if (pledge("stdio", NULL) == -1)
+ err(errno, "pledge");
+#endif
#endif
- for (int c; (c = getopt(argc, argv, "d")) != -1;)
- err_if (!(debug = (c == 'd')));
+ while (c != -1) {
+ c = getopt(argc, argv, "d");
+
+ if (c == 'd')
+ debug = 1;
+ else if (c != -1)
+ err(EINVAL, "Invalid argument");
+ }
+
setvbuf(stdout, NULL, _IONBF, 0);
+
while (!feof(stdin))
handle_audio();
- if (errno && debug)
- err(errno, "Unhandled error, errno %d", errno);
- return errno;
+
+ return EXIT_SUCCESS;
}
-void
+static void
handle_audio(void)
{
+ int sample;
+
if (sample_count > (3 * SAMPLES_PER_FRAME))
sample_count = reset_char();
+
if ((freq_separator <= FREQ_SEP_MIN) || (freq_separator >= FREQ_SEP_MAX)
|| (freq_data <= FREQ_DATA_MIN) || (freq_data >= FREQ_DATA_MAX)) {
decode_pulse();
return;
}
+
if (set_ascii_bit() < 0)
print_char();
+
sample_count = 0;
- for (int sample = 0; sample < SAMPLES_PER_FRAME; sample++)
+
+ for (sample = 0; sample < SAMPLES_PER_FRAME; sample++)
decode_pulse();
}
-void
+static void
decode_pulse(void)
{
int next_ringpos = (ringpos + SAMPLES_PER_FRAME) % MAX_SAMPLES;
+
freq_data -= pulse[ringpos];
freq_data += pulse[next_ringpos];
freq_separator -= pulse[next_ringpos];
fread(frame + ringpos, 1, sizeof(frame[0]), stdin);
+
if (ferror(stdin) != 0)
- err(ERR(), "Could not read from frame.");
+ err(errno, "Could not read from frame.");
pulse[ringpos] = (abs(frame[ringpos]) > THRESHOLD) ? 1 : 0;
freq_separator += pulse[ringpos++];
@@ -86,32 +133,84 @@ decode_pulse(void)
++sample_count;
}
-int
+static int
set_ascii_bit(void)
{
if (debug)
print_stats();
+
if (freq_data < FREQ_DATA_THRESHOLD)
ascii |= (1 << ascii_bit);
+
--ascii_bit;
return ascii_bit;
}
-void
+static void
print_stats(void)
{
long stdin_pos;
- err_if ((stdin_pos = ftell(stdin)) == -1);
+
+ if ((stdin_pos = ftell(stdin)) == -1)
+ err(errno, "ftell stdin");
+
printf ("%d %d %d @%ld\n", freq_data, freq_separator,
FREQ_DATA_THRESHOLD, stdin_pos - sizeof(frame));
}
-void
+static void
print_char(void)
{
if (debug)
printf("<%c, %x>", ascii, ascii);
else
printf("%c", ascii);
+
reset_char();
}
+
+static void
+err(int nvm_errval, const char *msg, ...)
+{
+ va_list args;
+
+ fprintf(stderr, "%s: ", getnvmprogname());
+
+ va_start(args, msg);
+ vfprintf(stderr, msg, args);
+ va_end(args);
+
+ set_err_if_unset(nvm_errval);
+ fprintf(stderr, ": %s", strerror(errno));
+
+ fprintf(stderr, "\n");
+
+ exit(EXIT_FAILURE);
+}
+
+static const char *
+getnvmprogname(void)
+{
+ const char *p;
+
+ if (argv0 == NULL || *argv0 == '\0')
+ return "";
+
+ p = strrchr(argv0, '/');
+
+ if (p)
+ return p + 1;
+ else
+ return argv0;
+}
+
+static void
+set_err_if_unset(int x)
+{
+ if (errno)
+ return;
+ if (x > 0)
+ errno = x;
+ else
+ errno = ECANCELED;
+}