From 22d9eb2c7574f5cd5a85ae466952f18d1e16e3ed Mon Sep 17 00:00:00 2001 From: pthrr Date: Sun, 25 Oct 2020 22:31:48 +0100 Subject: [PATCH] modified project structure and added logic to main function --- Makefile | 51 +++++++++++++++++++ README.md | 17 +++++++ bin/m17enc | Bin 0 -> 13472 bytes dummy.c => example/dummy.c | 0 obj/M17_RF_streamgen.o | Bin 0 -> 6152 bytes obj/main.o | Bin 0 -> 5128 bytes M17_RF_streamgen.c => src/M17_RF_streamgen.c | 51 +++++++++++++++---- 7 files changed, 109 insertions(+), 10 deletions(-) create mode 100644 Makefile create mode 100755 bin/m17enc rename dummy.c => example/dummy.c (100%) create mode 100644 obj/M17_RF_streamgen.o create mode 100644 obj/main.o rename M17_RF_streamgen.c => src/M17_RF_streamgen.c (79%) diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b7fccb3 --- /dev/null +++ b/Makefile @@ -0,0 +1,51 @@ +CC := gcc +CCFLAG := -Wall -O2 -std=c99 +DBGFLAG := -g +CCOBJFLAG := $(CCFLAG) -c + +BIN_PATH := bin +OBJ_PATH := obj +SRC_PATH := src +DBG_PATH := debug + +TARGET_NAME := m17enc +TARGET := $(BIN_PATH)/$(TARGET_NAME) +TARGET_DEBUG := $(DBG_PATH)/$(TARGET_NAME) +MAIN_SRC := src/M17_RF_streamgen.c + +SRC := $(foreach x, $(SRC_PATH), $(wildcard $(addprefix $(x)/*,.c*))) +OBJ := $(addprefix $(OBJ_PATH)/, $(addsuffix .o, $(notdir $(basename $(SRC))))) +OBJ_DEBUG := $(addprefix $(DBG_PATH)/, $(addsuffix .o, $(notdir $(basename $(SRC))))) + +DISTCLEAN_LIST := $(OBJ) $(OBJ_DEBUG) +CLEAN_LIST := $(TARGET) $(TARGET_DEBUG) $(DISTCLEAN_LIST) + +default: all + +$(TARGET): $(OBJ) + $(CC) $(CCFLAG) -o $@ $? + +$(OBJ_PATH)/%.o: $(SRC_PATH)/%.c* + $(CC) $(CCOBJFLAG) -o $@ $< + +$(DBG_PATH)/%.o: $(SRC_PATH)/%.c* + $(CC) $(CCOBJFLAG) $(DBGFLAG) -o $@ $< + +$(TARGET_DEBUG): $(OBJ_DEBUG) + $(CC) $(CCFLAG) $(DBGFLAG) $? -o $@ + +.PHONY: all +all: $(TARGET) + +.PHONY: debug +debug: $(TARGET_DEBUG) + +.PHONY: clean +clean: + @echo CLEAN $(CLEAN_LIST) + @rm -f $(CLEAN_LIST) + +.PHONY: distclean +distclean: + @echo CLEAN $(DISTCLEAN_LIST) + @rm -f $(DISTCLEAN_LIST) diff --git a/README.md b/README.md index 20ed3ac..7b4955e 100644 --- a/README.md +++ b/README.md @@ -4,3 +4,20 @@ Generates an M17 RF stream for Codec2-encoded speech files ('c2enc' output). **M17_RF_streamgen.c** - main program. Just a sketch right now. **dummy.c** - can generate a pseudorandom bitstream with legitimate sync patterns. This can be used to check receivers. + +# Installation + +``` +make +``` + +# Nomenclature + +# Example +This example records local audio and generates a M17-compliant RF stream into +a file. Codec2 and SoX need to be installed. + +``` +rec -t raw -r 8000 --buffer 2048 -e signed-integer -b 16 -c 1 - | \ +c2enc 3200 - - | m17enc DL1FROM DL1TO - out.raw +``` diff --git a/bin/m17enc b/bin/m17enc new file mode 100755 index 0000000000000000000000000000000000000000..d232d3580270cf7352a38de3d906027bf26f5754 GIT binary patch literal 13472 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 o^%KW8`EFYWs(w{c8>h8r<)bb& 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 literal 0 HcmV?d00001 diff --git a/obj/main.o b/obj/main.o new file mode 100644 index 0000000000000000000000000000000000000000..cda7c3cfcff138668ee83976c7dc63beecc74da5 GIT binary patch literal 5128 zcmbtXZ*UvM72lH-OHPbVP7O8xYK7XtZ4#lgO-O)tbhaF?2MuImyJaSTD(g?|i7XlE zls{#fx;+BiI4bTi{l>J@=1V`dOq+=tIuj(D#xYY`JDw>W=u92>fd4c&BuwI(g1T>S zSKeIYFYS8n-rL{)-rKitpZ3;2>#Nmxs#qfJ=s}zh+Dmxvr2O*hFqD6Mi!!}@m)sCQ`ceQ#FJWmG>kAUzyQ)1TpZDN= zje(1o?fJ}GfsrroKJtD(GeeZ>qucbQJ1NmL*}IyX#m2>hlL?>P@FI<3WNnwWV`S|i z?Jk^u{=tzoAC`lES^iamk7K>KefhO@KIu0t>+5}G+H_dv=Qn|0dAy`tQl=AQ^6B@o zjznwCeymSOSYNBjU6IF&#rc}*)k#=SLS88-1-aHK*LHd224obCiNd0zuw)PB9g_Z` zWE5u>+w*NUV}T?d>+c z=(TDX*X#}&HxtDb+s#?BO#O1z+=s5Z$Hc=VY@R}8n_M=j)&7YRtBtT&^a#G@xX*tl*M z>gWsg*!UAR=ti56xom7KF_iho`CSkbGrJS?3IX8J7hDWhJ}|kaZ>SG!{1cDf0hVt< zochPk^HfesSX!av#E(87k#g^;`nx5ZzaN;Pe5}!l^U21l<*nFQQS~blWvcoYD_U33 zShx^utdhvfiEhp?@6>C7l)!w0e74R`Ncy}}K0QHa&72DvAK&68cW#s}AIcZ!zh%y9 zB2!dsLTnA=v>VF5dXJ&x;i=@^)~nQ=TchE`-tyhpMO_tj`oxj${wG;?HeXaogq}m zr1bp*NIK?`?yYgU#>h^234R|Nn*yo2J-W@NZFak!*kaq~b`c1U#sGPs?KB0&dYK+# zGDzeA)6alxcY9v7b-L?+VsCeQ^Nx0R^QlcixBsOo)xAe|_PPVMlkPpL+poHt38CFx zPYl}K^eBFV`LQwiIFWBNy&gb9&D)5{DZA?SzT_Y-bmBW;>)h;aCWy+Nsau#;WdX(N zK%bT>joK@IDG;)gze>$cJXss$PeLx5FBq#A2zErPO+ZZ5j;e0M0I(B3m6{#Vqvf_C zJGy=C=3d`E?>1_^2{l{1Y-hODVh6+Np&{7#8QvsdT(zTWu9hX7$6JLw(;6fg)D+a6 zwe=IA5NZh zA$~sh*XSrhYeaI4K~%sMs}jDI;NZv0$Ro`E-5cOu3;r47KWM?ZKZW8vTL|%Wp`plN z$`?h4(#gp2a6A=F$Kv6kh?W^VhJ2w8KfK!DrNFBNUag4HqLE}WJ9sD+?vG^SZGIH) z3O&`XhQd$n+t<_C8}3!xL!Dui)iTL=>Xr#mM>=&Ro$O8xYN5Vf*6XBmqi}dQGnmp6 z;po6&HnKmLifXw`ylr=Qw?YF(v3OPsM`E!I%4VXbGMtG=hEO6sOeRZ&(>V<#j%Eh6 zILaPRMZ*fxjt|GfN;t<9l!zwN**KXmt3{%RVY+Z4GMF@n+f31FiWU|K1WUcOlusl$ z$-Y9K|GjGc&b6UXNf}h`R;O9+& zFAMylz=ul|kLRMmhuxF$3`E3GU^dH`U ze^}s)`*lRXw+Zw9K)@dm@E0vOKY34Ca323_0uJ-?_DcZ=|NIO3YYWc#zY%b8f6oXw z_<{UE`=fvZpSKAC2R@JA&J00_`E)TH>h0^~;p?gs@J0dm5*->0GYaho>3bcYVg08q zIIjco_XU2e-%0MDe-Fhvgu8IL`Lf4{v`9blk@M1&16<3*lM$a5Kc*pHETTn_uRohb zzDycAKv#U^a4wSw63J+}Va`ClXnJTUo+8$%v=;YuJ=wR59(l|rJ`hfjf4k!4Nd7Oy zORQn*_%_@^@zcO$%;ae~gTCOr+YZ7i%_X)c@CVjFsu #include #include +#include #define LEAD_PREAM 40 //first (lead) preamble length in ms @@ -33,12 +34,13 @@ const uint8_t sync_1[2]={0x32, 0x43}; //SYNC for the link setup frame const uint8_t sync_2[2]={0x2B, 0x7E}; //SYNC for all subsequent frames uint8_t ConvolLUT[32]; //a look-up table for convolutional encoder -uint8_t type_1[30]; //type-1 packed bits +uint8_t type_1[30]; //type-1 packed bits uint8_t type_1_u[300]; //type-1 unpacked bits uint8_t type_2[500]; //type-2 unpacked bits uint8_t type_3[384]; uint8_t type_4[384]; FILE *f_out; +FILE *f_in; //Takes an ASCII callsign in a null terminated char* and encodes it using base 40. //Returns -1 (all Fs) if the provided callsign is longer than 9 characters, which @@ -164,16 +166,17 @@ int main(int argc, char *argv[]) { uint16_t type=(1<<0)|(0b10<<1); //type indicator - stream, voice, codec2 3200bps, no encryption uint8_t nonce[16]={0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0}; - - if(argc==4) + + if(argc==5) { - dest_addr.val=encode_callsign_base40(argv[2]); - src_addr.val=encode_callsign_base40(argv[3]); + // link setup + dest_addr.val=encode_callsign_base40(argv[1]); + src_addr.val=encode_callsign_base40(argv[2]); printf("DEST\t0x%012llX\n", dest_addr.val); printf("SRC \t0x%012llX\n", src_addr.val); - f_out=fopen(argv[1], "wb"); + f_out=fopen(argv[4], "wb"); //preamble for(uint16_t i=0; i<(LEAD_PREAM*9600)/1000; i++) @@ -206,14 +209,42 @@ int main(int argc, char *argv[]) //convolutionally encode type-1 to type-2 ; - - fclose(f_out); - + + // frames + if(!strcmp(argv[3], "-")) + { + f_in = stdin; + } else { + f_in = fopen(argv[1], "rb"); + + if(f_in == NULL) + { + printf("No valid input data to work with\n"); + + return 1; + } + } + + uint8_t payload[16]; + size_t bytes = 0; + + while(1) + { + bytes = fread(payload, 1, 16, f_in); + fwrite(payload, 1, 16, f_out); + + if(bytes < 16) + if(feof(f_in)) break; + } + + fclose(f_in); + fclose(f_out); + return 0; } else { - printf("Not enough params\n"); + printf("Invalid number of params\n"); return 1; }