diff --git a/README.md b/README.md index 9f79894..8067f42 100644 --- a/README.md +++ b/README.md @@ -36,44 +36,11 @@ to solve any issue related to ``ImportError: libgnuradio-m17.so.1.0.0: cannot op When running the flowgraph found in ``examples`` with ``gnuradio-companion ../examples/m17_streamer.grc`` - + -the output should be +See examples/README.md for the expected output and unit testing examples. -``` -Generating: '.../M17_Implementations/SP5WWP/gr-m17/examples/m17_streamer.py' - -Executing: /usr/bin/python3 -u .../M17_Implementations/SP5WWP/gr-m17/examples/m17_streamer.py - -new meta: helloworld -new SRC ID: 1 2 3 4 5 6 -new DST ID: 255 255 255 255 255 255 -New sampling rate: 8800.000000 -new type: 0 0 -got_lsf=1 -LSF -DST: #BCAST SRC: FPR-4U3F TYPE: 0000 META: 68656C6C6F776F726C6400000000 LSF_CRC_OK -FN: 0000 PLD: 00000000000000000000000000000000 -FN: 0001 PLD: 00000000000000000000000000000000 -FN: 0002 PLD: 00000000000000000000000000000000 -FN: 0003 PLD: 00000000000000000000000000000000 -FN: 0004 PLD: 00000000000000000000000000000000 -DST: #BCAST SRC: FPR-4U3F TYPE: 0000 META: 68656C6C6F776F726C6400000000 LSF_CRC_OK -FN: 0005 PLD: 00000000000000000000000000000000 -FN: 0006 PLD: 00000000000000000000000000000000 -FN: 0007 PLD: 00000000000000000000000000000000 -FN: 0008 PLD: 00000000000000000000000000000000 -FN: 0009 PLD: 00000000000000000000000000000000 -FN: 000A PLD: 00000000000000000000000000000000 -DST: #BCAST SRC: FPR-4U3F TYPE: 0000 META: 68656C6C6F776F726C6400000000 LSF_CRC_OK -FN: 000B PLD: 00000000000000000000000000000000 -FN: 000C PLD: 00000000000000000000000000000000 -FN: 000D PLD: 00000000000000000000000000000000 -FN: 000E PLD: 00000000000000000000000000000000 -FN: 000F PLD: 00000000000000000000000000000000 -``` - -Notice that due to the verbose output of gr-m17 and the slow console of GNU Radio Companion, I +Notice that due to the verbose output of ``gr-m17`` and the slow console of GNU Radio Companion, I would strongly advise generating the Python script from GNU Radio Companion and then execute ``python3 m17_streamer.py`` from a terminal to avoid waiting for a long time for GNU Radio Companion to flush all messages. diff --git a/examples/README.md b/examples/README.md index 1fe9a5f..b1d9f7f 100644 --- a/examples/README.md +++ b/examples/README.md @@ -2,6 +2,8 @@ ### m17_rx.grc + + This receiver testing example relies on ``../M17_Implementations/SP5WWP/m17-coder/m17-coder-sym`` to broadcast a signal. Following this unit testing example, run this flowchart along with ``` @@ -26,17 +28,56 @@ DST: ALL SRC: AB1CDE TYPE: 0005 META: 0000000000000000000000000000 LSF_ It would be wise to execute from a terminal rather than the GNU Radio Companion graphical interface to avoid flooding the console. +### m17_tx.grc + + + +This transmitter testing example relies on ``../M17_Implementations/SP5WWP/m17-decoder/m17-decoder-sym`` +to decode a signal. Following this unit testing example, run this flowchart along with +``` +mkfifo /tmp/fifo1 +mkfifo /tmp/fifo2 +../M17_Implementations/SP5WWP/m17-decoder/m17-decoder-sym < /tmp/fifo2 +``` + +and the output of ``python3 ./m17_tx.py`` should be +``` +DST: AB2CDE SRC: AB1CDE TYPE: 0005 META: 48656C6C6F210000000000000000 LSF_CRC_OK +FN: 0018 PLD: 01020304050600000000000000000000 e=0.0 +FN: 0019 PLD: 01020304050600000000000000000000 e=0.0 +FN: 001A PLD: 01020304050600000000000000000000 e=0.0 +FN: 001B PLD: 01020304050600000000000000000000 e=0.0 +FN: 001C PLD: 01020304050600000000000000000000 e=0.0 +FN: 001D PLD: 01020304050600000000000000000000 e=0.0 +DST: AB2CDE SRC: AB1CDE TYPE: 0005 META: 48656C6C6F210000000000000000 LSF_CRC_OK +FN: 001E PLD: 01020304050600000000000000000000 e=0.0 +``` + +### m17_streamer.grc + +Loopback demo with TX and RX both in GNU Radio. + + + +The output should be + +``` +DST: AB2CDE SRC: AB1CDE TYPE: 0005 META: 48656C6C6F210000000000000000 LSF_CRC_OK +DST: AB2CDE SRC: AB1CDE TYPE: 0005 META: 48656C6C6F210000000000000000 LSF_CRC_OK +DST: AB2CDE SRC: AB1CDE TYPE: 0005 META: 48656C6C6F210000000000000000 LSF_CRC_OK +DST: AB2CDE SRC: AB1CDE TYPE: 0005 META: 48656C6C6F210000000000000000 LSF_CRC_OK +DST: AB2CDE SRC: AB1CDE TYPE: 0005 META: 48656C6C6F210000000000000000 LSF_CRC_OK +DST: AB2CDE SRC: AB1CDE TYPE: 0005 META: 48656C6C6F210000000000000000 LSF_CRC_OK +``` + +## TO BE DEBUGGED AND VALIDATED + ### transmitterPLUTOSDR.grc M17 transmitter with ADALM Pluto SDR. ### receiverRTLSDR.grc M17 receiver with RTL SDR. Automatic Frequency Correction can be enabled as an option. -### m17_streamer.grc -Old loopback demo. - - - ### m17_loopback_noisychannel.grc Loopback demo with the addition of noise, no modulation/no channnel. diff --git a/examples/m17_rx.png b/examples/m17_rx.png new file mode 100644 index 0000000..5ea9b07 Binary files /dev/null and b/examples/m17_rx.png differ diff --git a/examples/m17_streamer.png b/examples/m17_streamer.png deleted file mode 100644 index 68288ec..0000000 Binary files a/examples/m17_streamer.png and /dev/null differ diff --git a/examples/m17_tx.grc b/examples/m17_tx.grc new file mode 100644 index 0000000..a72df4e --- /dev/null +++ b/examples/m17_tx.grc @@ -0,0 +1,215 @@ +options: + parameters: + author: Wojciech SP5WWP + catch_exceptions: 'True' + category: '[GRC Hier Blocks]' + cmake_opt: '' + comment: '' + copyright: M17 Project, Jan 2024 + description: '' + gen_cmake: 'On' + gen_linking: dynamic + generate_options: qt_gui + hier_block_src_path: '.:' + id: m17_tx + max_nouts: '0' + output_language: python + placement: (0,0) + qt_qss_theme: '' + realtime_scheduling: '' + run: 'True' + run_command: '{python} -u {filename}' + run_options: prompt + sizing_mode: fixed + thread_safe_setters: '' + title: M17 loopback demo + window_size: (1000,1000) + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 4.0] + rotation: 0 + state: enabled + +blocks: +- name: dst_str + id: variable_qtgui_entry + parameters: + comment: '' + entry_signal: editingFinished + gui_hint: '' + label: DST + type: string + value: AB2CDE + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [568, 12.0] + rotation: 0 + state: true +- name: meta_str + id: variable_qtgui_entry + parameters: + comment: '' + entry_signal: editingFinished + gui_hint: '' + label: META + type: string + value: Hello! + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [288, 12.0] + rotation: 0 + state: true +- name: samp_rate + id: variable + parameters: + comment: '' + value: '4800' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [192, 12.0] + rotation: 0 + state: true +- name: src_str + id: variable_qtgui_entry + parameters: + comment: '' + entry_signal: editingFinished + gui_hint: '' + label: SRC + type: string + value: AB1CDE + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [424, 12.0] + rotation: 0 + state: true +- name: type_val + id: variable_qtgui_entry + parameters: + comment: '' + entry_signal: editingFinished + gui_hint: '' + label: TYPE + type: int + value: '5' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [712, 12.0] + rotation: 0 + state: true +- name: blocks_file_sink_0 + id: blocks_file_sink + parameters: + affinity: '' + alias: '' + append: 'False' + comment: '/tmp/fifo2 was created with + + mkfifo /tmp/fifo2' + file: /tmp/fifo2 + type: float + unbuffered: 'False' + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [752, 144.0] + rotation: 0 + state: enabled +- name: blocks_throttle2_0 + id: blocks_throttle2 + parameters: + affinity: '' + alias: '' + comment: '' + ignoretag: 'True' + limit: auto + maximum: '0.1' + maxoutbuf: '0' + minoutbuf: '0' + samples_per_second: samp_rate + type: float + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [536, 152.0] + rotation: 0 + state: true +- name: blocks_vector_source_x_0_2 + id: blocks_vector_source_x + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + repeat: 'True' + tags: '[]' + type: byte + vector: (0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00) + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [16, 144.0] + rotation: 0 + state: true +- name: m17_m17_coder_0 + id: m17_m17_coder + parameters: + affinity: '' + alias: '' + comment: '' + debug: 'False' + dst_id: dst_str + maxoutbuf: '0' + meta: meta_str + minoutbuf: '0' + src_id: src_str + type: type_val + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [320, 128.0] + rotation: 0 + state: true +- name: note_0_2 + id: note + parameters: + alias: '' + comment: '' + note: DATA + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [200, 88.0] + rotation: 0 + state: true + +connections: +- [blocks_throttle2_0, '0', blocks_file_sink_0, '0'] +- [blocks_vector_source_x_0_2, '0', m17_m17_coder_0, '0'] +- [m17_m17_coder_0, '0', blocks_throttle2_0, '0'] + +metadata: + file_format: 1 + grc_version: 3.10.10.0 diff --git a/examples/m17_tx.png b/examples/m17_tx.png new file mode 100644 index 0000000..835e653 Binary files /dev/null and b/examples/m17_tx.png differ diff --git a/lib/m17_coder_impl.cc b/lib/m17_coder_impl.cc index 427896b..1228374 100644 --- a/lib/m17_coder_impl.cc +++ b/lib/m17_coder_impl.cc @@ -138,6 +138,8 @@ void m17_coder_impl::set_type(short type) int countin=0; uint32_t countout=0; + float frame_buff_tmp[192]; + uint32_t frame_buff_count_tmp; uint8_t enc_bits[SYM_PER_PLD*2]; //type-2 bits, unpacked uint8_t rf_bits[SYM_PER_PLD*2]; //type-4 bits, unpacked @@ -149,120 +151,30 @@ void m17_coder_impl::set_type(short type) while (countout<(uint32_t)noutput_items) { if (countin+16<=noutput_items) - {if(_got_lsf) //stream frames + {for (int i=0;i<16;i++) {data[i]=in[countin];countin++;} + if(_got_lsf) //stream frames { - //we could discard the data we already have - for (int i=0;i<16;i++) {data[i]=in[countin];countin++;} - //send stream frame syncword send_syncword(out,&countout,SYNC_STR); - //derive the LICH_CNT from the Frame Number - lich_cnt=_fn%6; - //extract LICH from the whole LSF - switch(lich_cnt) - { - case 0: - lich[0]=lsf.dst[0]; - lich[1]=lsf.dst[1]; - lich[2]=lsf.dst[2]; - lich[3]=lsf.dst[3]; - lich[4]=lsf.dst[4]; - break; - - case 1: - lich[0]=lsf.dst[5]; - lich[1]=lsf.src[0]; - lich[2]=lsf.src[1]; - lich[3]=lsf.src[2]; - lich[4]=lsf.src[3]; - break; - - case 2: - lich[0]=lsf.src[4]; - lich[1]=lsf.src[5]; - lich[2]=lsf.type[0]; - lich[3]=lsf.type[1]; - lich[4]=lsf.meta[0]; - break; - - case 3: - lich[0]=lsf.meta[1]; - lich[1]=lsf.meta[2]; - lich[2]=lsf.meta[3]; - lich[3]=lsf.meta[4]; - lich[4]=lsf.meta[5]; - break; - - case 4: - lich[0]=lsf.meta[6]; - lich[1]=lsf.meta[7]; - lich[2]=lsf.meta[8]; - lich[3]=lsf.meta[9]; - lich[4]=lsf.meta[10]; - break; - - case 5: - lich[0]=lsf.meta[11]; - lich[1]=lsf.meta[12]; - lich[2]=lsf.meta[13]; - lich[3]=lsf.crc[0]; - lich[4]=lsf.crc[1]; - break; - - default: - ; - break; - } - lich[5]=lich_cnt<<5; + extract_LICH(lich, lich_cnt, &lsf); //encode the LICH - uint32_t val; - - val=golay24_encode((lich[0]<<4)|(lich[1]>>4)); - lich_encoded[0]=(val>>16)&0xFF; - lich_encoded[1]=(val>>8)&0xFF; - lich_encoded[2]=(val>>0)&0xFF; - val=golay24_encode(((lich[1]&0x0F)<<8)|lich[2]); - lich_encoded[3]=(val>>16)&0xFF; - lich_encoded[4]=(val>>8)&0xFF; - lich_encoded[5]=(val>>0)&0xFF; - val=golay24_encode((lich[3]<<4)|(lich[4]>>4)); - lich_encoded[6]=(val>>16)&0xFF; - lich_encoded[7]=(val>>8)&0xFF; - lich_encoded[8]=(val>>0)&0xFF; - val=golay24_encode(((lich[4]&0x0F)<<8)|lich[5]); - lich_encoded[9]=(val>>16)&0xFF; - lich_encoded[10]=(val>>8)&0xFF; - lich_encoded[11]=(val>>0)&0xFF; + encode_LICH(lich_encoded, lich); //unpack LICH (12 bytes) - memset(enc_bits, 0, SYM_PER_PLD*2); - for(uint8_t i=0; i<12; i++) - { - for(uint8_t j=0; j<8; j++) - enc_bits[i*8+j]=(lich_encoded[i]>>(7-j))&1; - } + unpack_LICH(enc_bits, lich_encoded); - //encode the rest of the frame + //encode the rest of the frame (starting at bit 96 - 0..95 are filled with LICH) + // conv_encode_stream_frame(&enc_bits[96], data, finished ? (_fn | 0x8000) : _fn); JMF review conv_encode_stream_frame(&enc_bits[96], data, _fn); //reorder bits - for(uint16_t i=0; i>(7-(i%8)))&1) //flip bit if '1' - { - if(rf_bits[i]) - rf_bits[i]=0; - else - rf_bits[i]=1; - } - } + randomize_bits(rf_bits); //send dummy symbols (debug) /*float s=0.0; @@ -288,51 +200,41 @@ void m17_coder_impl::set_type(short type) } else //LSF { -// for (int i=0;i<6;i++) {lsf.dst[i]=in[countin];countin++;} -// for (int i=0;i<6;i++) {lsf.src[i]=in[countin];countin++;} -// for (int i=0;i<2;i++) {lsf.type[i]=in[countin];countin++;} -// for (int i=0;i<14;i++) {lsf.meta[i]=in[countin];countin++;} - for (int i=0;i<16;i++) {data[i]=in[countin];countin++;} - - //calculate LSF CRC -// uint16_t ccrc=LSF_CRC(&lsf); -// lsf.crc[0]=ccrc>>8; -// lsf.crc[1]=ccrc&0xFF; _got_lsf=1; // printf("got_lsf=1\n"); + //send out the preamble and LSF + send_preamble(frame_buff_tmp, &frame_buff_count_tmp, 0); //0 - LSF preamble, as opposed to 1 - BERT preamble + for(uint16_t i=0; i>(7-(i%8)))&1) //flip bit if '1' - { - if(rf_bits[i]) - rf_bits[i]=0; - else - rf_bits[i]=1; - } - } + randomize_bits(rf_bits); - float s; + //send LSF data + send_data(frame_buff_tmp, &frame_buff_count_tmp, rf_bits); + for(uint16_t i=0; i