diff --git a/src/Makefile.am b/src/Makefile.am
index 5704382..1e6468f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -42,12 +42,15 @@ FSK_SRC = fsk.h fsk.c
BAUDOT_SRC = baudot.h baudot.c
+UIC_SRC = uic_codes.h uic_codes.c
+
DATABITS_SRC = \
databits.h \
databits_ascii.c \
databits_binary.c \
databits_callerid.c \
- databits_baudot.c $(BAUDOT_SRC)
+ databits_baudot.c $(BAUDOT_SRC) \
+ databits_uic.c $(UIC_SRC)
minimodem_LDADD = $(DEPS_LIBS)
minimodem_SOURCES = minimodem.c $(DATABITS_SRC) $(FSK_SRC) $(SIMPLEAUDIO_SRC)
diff --git a/src/Makefile.in b/src/Makefile.in
index 877217e..666da62 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -111,15 +111,16 @@ CONFIG_CLEAN_VPATH_FILES =
am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"
PROGRAMS = $(bin_PROGRAMS)
am__objects_1 = baudot.$(OBJEXT)
-am__objects_2 = databits_ascii.$(OBJEXT) databits_binary.$(OBJEXT) \
+am__objects_2 = uic_codes.$(OBJEXT)
+am__objects_3 = databits_ascii.$(OBJEXT) databits_binary.$(OBJEXT) \
databits_callerid.$(OBJEXT) databits_baudot.$(OBJEXT) \
- $(am__objects_1)
-am__objects_3 = fsk.$(OBJEXT)
-am__objects_4 = simpleaudio.$(OBJEXT) simple-tone-generator.$(OBJEXT) \
+ $(am__objects_1) databits_uic.$(OBJEXT) $(am__objects_2)
+am__objects_4 = fsk.$(OBJEXT)
+am__objects_5 = simpleaudio.$(OBJEXT) simple-tone-generator.$(OBJEXT) \
simpleaudio-pulse.$(OBJEXT) simpleaudio-alsa.$(OBJEXT) \
simpleaudio-benchmark.$(OBJEXT) simpleaudio-sndfile.$(OBJEXT)
-am_minimodem_OBJECTS = minimodem.$(OBJEXT) $(am__objects_2) \
- $(am__objects_3) $(am__objects_4)
+am_minimodem_OBJECTS = minimodem.$(OBJEXT) $(am__objects_3) \
+ $(am__objects_4) $(am__objects_5)
minimodem_OBJECTS = $(am_minimodem_OBJECTS)
am__DEPENDENCIES_1 =
minimodem_DEPENDENCIES = $(am__DEPENDENCIES_1)
@@ -314,12 +315,14 @@ SIMPLEAUDIO_SRC = \
FSK_SRC = fsk.h fsk.c
BAUDOT_SRC = baudot.h baudot.c
+UIC_SRC = uic_codes.h uic_codes.c
DATABITS_SRC = \
databits.h \
databits_ascii.c \
databits_binary.c \
databits_callerid.c \
- databits_baudot.c $(BAUDOT_SRC)
+ databits_baudot.c $(BAUDOT_SRC) \
+ databits_uic.c $(UIC_SRC)
minimodem_LDADD = $(DEPS_LIBS)
minimodem_SOURCES = minimodem.c $(DATABITS_SRC) $(FSK_SRC) $(SIMPLEAUDIO_SRC)
@@ -417,6 +420,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/databits_baudot.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/databits_binary.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/databits_callerid.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/databits_uic.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsk.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minimodem.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simple-tone-generator.Po@am__quote@
@@ -425,6 +429,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simpleaudio-pulse.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simpleaudio-sndfile.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simpleaudio.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uic_codes.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
diff --git a/src/databits.h b/src/databits.h
index ba9c12b..bb2cf88 100644
--- a/src/databits.h
+++ b/src/databits.h
@@ -17,6 +17,32 @@
* along with this program. If not, see .
*/
+// Reverses the ordering of the bits on an integer
+static inline unsigned long long
+bit_reverse(unsigned long long value,
+ unsigned int bits)
+{
+ unsigned int out = 0;
+
+ while (bits--) {
+ out = (out << 1) | (value & 1);
+ value >>= 1;
+ }
+
+ return out;
+}
+
+// Gets "bits" bits from "value" starting "offset" bits from the start
+static inline unsigned long long
+bit_window(unsigned long long value,
+ unsigned int offset,
+ unsigned int bits)
+{
+ unsigned long long mask = (1ULL << bits) - 1;
+ value = (value >> offset) & mask;
+ return value;
+}
+
typedef int (databits_encoder)(
unsigned int *databits_outp, char char_out );
@@ -55,4 +81,10 @@ unsigned int
databits_decode_callerid( char *dataout_p, unsigned int dataout_size,
unsigned long long bits, unsigned int n_databits );
+unsigned int
+databits_decode_uic_ground( char *dataout_p, unsigned int dataout_size,
+ unsigned long long bits, unsigned int n_databits );
+unsigned int
+databits_decode_uic_train( char *dataout_p, unsigned int dataout_size,
+ unsigned long long bits, unsigned int n_databits );
diff --git a/src/databits_uic.c b/src/databits_uic.c
new file mode 100755
index 0000000..02da420
--- /dev/null
+++ b/src/databits_uic.c
@@ -0,0 +1,74 @@
+/*
+ * databits_uic.c
+ *
+ * Copyright (C) 2014 Marcos Vives Del Sol
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include "databits.h"
+#include "uic_codes.h"
+
+/*
+ * UIC-751-3 Ground-train decoder
+ */
+
+unsigned int
+databits_decode_uic(char *output,
+ unsigned long long input,
+ unsigned int type)
+{
+ int written;
+
+ if (!output) {
+ return 0;
+ }
+
+ unsigned int code = (unsigned int) bit_reverse(bit_window(input, 24, 8), 8);
+ written = sprintf(output, "Train ID: %X%X%X%X%X%X - Message: %02X (%s)\n",
+ (unsigned int) bit_window(input, 0, 4),
+ (unsigned int) bit_window(input, 4, 4),
+ (unsigned int) bit_window(input, 8, 4),
+ (unsigned int) bit_window(input, 12, 4),
+ (unsigned int) bit_window(input, 16, 4),
+ (unsigned int) bit_window(input, 20, 4),
+ code,
+ uic_message_meaning(code, type)
+ );
+
+ return written;
+}
+
+unsigned int
+databits_decode_uic_ground(char *output,
+ unsigned int outputSize,
+ unsigned long long input,
+ unsigned int inputSize)
+{
+ return databits_decode_uic(output,
+ input,
+ UIC_TYPE_GROUNDTRAIN);
+}
+
+unsigned int
+databits_decode_uic_train(char *output,
+ unsigned int outputSize,
+ unsigned long long input,
+ unsigned int inputSize)
+{
+ return databits_decode_uic(output,
+ input,
+ UIC_TYPE_TRAINGROUND);
+}
diff --git a/src/minimodem.c b/src/minimodem.c
index d80ed50..a4d7b8c 100644
--- a/src/minimodem.c
+++ b/src/minimodem.c
@@ -81,7 +81,8 @@ static void fsk_transmit_frame(
float bfsk_mark_f,
float bfsk_space_f,
float bfsk_nstartbits,
- float bfsk_nstopbits
+ float bfsk_nstopbits,
+ int bfsk_msb_first
)
{
int i;
@@ -89,7 +90,13 @@ static void fsk_transmit_frame(
simpleaudio_tone(sa_out, bfsk_space_f,
bit_nsamples * bfsk_nstartbits); // start
for ( i=0; i> i ) & 1;
+ unsigned int bit;
+ if (bfsk_msb_first) {
+ bit = ( bits >> (n_data_bits - i - 1) ) & 1;
+ } else {
+ bit = ( bits >> i ) & 1;
+ }
+
float tone_freq = bit == 1 ? bfsk_mark_f : bfsk_space_f;
simpleaudio_tone(sa_out, tone_freq, bit_nsamples);
}
@@ -107,6 +114,7 @@ static void fsk_transmit_stdin(
int n_data_bits,
float bfsk_nstartbits,
float bfsk_nstopbits,
+ int bfsk_msb_first,
unsigned int bfsk_do_tx_sync_bytes,
unsigned int bfsk_sync_byte,
databits_encoder encode
@@ -156,14 +164,14 @@ static void fsk_transmit_stdin(
for ( j=0; j> 32), (unsigned int)bits, bfsk_n_data_bits, bfsk_nstartbits, (unsigned int)(frame_bits_mask >> 32), (unsigned int)(frame_bits_mask));
- bits = ( bits >> frame_bits_shift ) & frame_bits_mask;
+ bits = bit_window(bits, bfsk_nstartbits, bfsk_n_data_bits);
+ if (bfsk_msb_first) {
+ bits = bit_reverse(bits, bfsk_n_data_bits);
+ }
+ debug_log("Input: %08x%08x - Databits: %i - Shift: %i\n", (unsigned int)(bits >> 32), (unsigned int)bits, bfsk_n_data_bits, bfsk_nstartbits);
unsigned int dataout_size = 4096;
char dataoutbuf[4096];
diff --git a/src/uic_codes.c b/src/uic_codes.c
new file mode 100755
index 0000000..9b3cafe
--- /dev/null
+++ b/src/uic_codes.c
@@ -0,0 +1,68 @@
+/*
+ * uic_codes.c
+ *
+ * Copyright (C) 2014 Marcos Vives Del Sol
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include "uic_codes.h"
+
+uic_message uic_ground_to_train_messages[] = {
+ { 0x00, "Test" },
+ { 0x02, "Run slower" },
+ { 0x03, "Extension of telegram" },
+ { 0x04, "Run faster" },
+ { 0x06, "Written order" },
+ { 0x08, "Speech" },
+ { 0x09, "Emergency stop" },
+ { 0x0C, "Announcem. by loudspeaker" },
+ { 0x55, "Idle" },
+ { -1, NULL }
+};
+
+uic_message uic_train_to_ground_messages[] = {
+ { 0x08, "Communic. desired" },
+ { 0x0A, "Acknowl. of order" },
+ { 0x06, "Advice" },
+ { 0x00, "Test" },
+ { 0x09, "Train staff wish to comm." },
+ { 0x0C, "Telephone link desired" },
+ { 0x03, "Extension of telegram" },
+ { -1, NULL }
+};
+
+const char * uic_message_meaning(unsigned int code,
+ unsigned int type)
+{
+ uic_message * messages;
+ if (type == UIC_TYPE_GROUNDTRAIN) {
+ messages = uic_ground_to_train_messages;
+ } else if (type == UIC_TYPE_TRAINGROUND) {
+ messages = uic_train_to_ground_messages;
+ } else {
+ assert(0);
+ }
+
+ while (messages->code != -1) {
+ if (messages->code == code) {
+ return messages->meaning;
+ }
+ messages++;
+ }
+
+ return "Unknown";
+}
diff --git a/src/uic_codes.h b/src/uic_codes.h
new file mode 100755
index 0000000..e72a10f
--- /dev/null
+++ b/src/uic_codes.h
@@ -0,0 +1,34 @@
+/*
+ * uic_codes.h
+ *
+ * Copyright (C) 2014 Marcos Vives Del Sol
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+typedef struct {
+ unsigned int code;
+ char * meaning;
+} uic_message;
+
+enum {
+ UIC_TYPE_GROUNDTRAIN,
+ UIC_TYPE_TRAINGROUND,
+};
+
+extern uic_message uic_ground_to_train_messages[];
+extern uic_message uic_train_to_ground_messages[];
+
+const char * uic_message_meaning(unsigned int code,
+ unsigned int type);