diff --git a/README.md b/README.md index f2c96fd..2403ba9 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,9 @@ Packet encoding is available with `m17-packet-encoder`. Its input parameters are -S - source callsign (uppercase alphanumeric string) max. 9 characters -D - destination callsign (uppercase alphanumeric string) or ALL for broadcast -C - Channel Access Number (0..15, default - 0) --n - number of bytes (1 to 798) +-T - SMS Text Message (example: -T 'Hello World! This is a text message') +-R - Raw Hex Octets (example: -R 010203040506070809) +-n - number of bytes, only when pre-encoded data passed over stdin (1 to 798) -o - output file path/name -x - binary output (M17 baseband as a packed bitstream) -r - raw audio output - default (single channel, signed 16-bit LE, +7168 for the +1.0 symbol, 10 samples per symbol) @@ -87,7 +89,7 @@ Packet encoding is available with `m17-packet-encoder`. Its input parameters are -w - libsndfile wav audio output - default (single channel, signed 16-bit LE, +7168 for the +1.0 symbol, 10 samples per symbol) ``` -Input data is passed over stdin. Example command: +Input data can be pre-encoded and passed over stdin. Example command: `echo -en "\x05Testing M17 packet mode.\x00" | ./m17-packet-encode -S N0CALL -D ALL -C 0 -n 26 -f -o baseband.sym` @@ -97,16 +99,16 @@ Input data is passed over stdin. Example command: Output: ``` -DST: ALL FFFFFFFFFFFF -SRC: N0CALL 00004B13D106 -Data CRC: BFEC -LSF CRC: 432A +SMS: Testing M17 packet mode. +DST: ALL FFFFFFFFFFFF +SRC: N0CALL 00004B13D106 +CAN: 00 +Data CRC: BFEC +LSF CRC: 432A FN:00 (full frame) -0554657374696E67204D3137207061636B6574206D6F64652E00 FN:-- (ending frame) -00BFEC0000000000000000000000000000000000000000000084 -FULL: 0554657374696E67204D3137207061636B6574206D6F64652E00BFEC - SMS: Testing M17 packet mode. +PKT: 05 54 65 73 74 69 6E 67 20 4D 31 37 20 70 61 63 6B 65 74 20 6D 6F 64 65 2E + 00 BF EC 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ``` Decode packet created with above sample: @@ -117,26 +119,28 @@ Output: ``` DST: FFFFFFFFFFFF SRC: 00004B13D106 TYPE: 0002 META: 0000000000000000000000000000 LSF_CRC_OK -Testing M17 packet mode. +SMS: Testing M17 packet mode. ``` -Encode directly as wav format (skip sox): +Encode User Text String as wav format: -`echo -en "\x05Testing M17 packet mode.\x00" | ./m17-packet-encode -S N0CALL -D AB1CDE -C 7 -n 26 -w -o baseband.wav` +`./m17-packet-encode -S N0CALL -D AB1CDE -T 'This is an SMS Text Message Generated by m17-packet-encode' -C 7 -w -o baseband.wav` Output: ``` -DST: AB1CDE 00001F245D51 -SRC: N0CALL 00004B13D106 -Data CRC: BFEC -LSF CRC: F754 +SMS: This is an SMS Text Message Generated by m17-packet-encode +DST: AB1CDE 00001F245D51 +SRC: N0CALL 00004B13D106 +CAN: 07 +Data CRC: FD81 +LSF CRC: F754 FN:00 (full frame) -0554657374696E67204D3137207061636B6574206D6F64652E00 +FN:01 (full frame) FN:-- (ending frame) -00BFEC0000000000000000000000000000000000000000000084 -FULL: 0554657374696E67204D3137207061636B6574206D6F64652E00BFEC - SMS: Testing M17 packet mode. +PKT: 05 54 68 69 73 20 69 73 20 61 6E 20 53 4D 53 20 54 65 78 74 20 4D 65 73 73 + 61 67 65 20 47 65 6E 65 72 61 74 65 64 20 62 79 20 6D 31 37 2D 70 61 63 6B + 65 74 2D 65 6E 63 6F 64 65 00 FD 81 00 00 00 00 00 00 00 00 00 00 00 00 00 ``` Decode with M17-FME: @@ -147,26 +151,55 @@ Output: ``` M17 Project - Florida Man Edition -Build Version: 2024-1-g4f2c15c -Session Number: A4F5 +Build Version: 2024-10-g060dd21 +Session Number: A751 M17 Project RF Audio Frame Demodulator. SNDFile (.wav, .rrc) Input File: baseband.wav Payload Verbosity: 1; -M17 LSF Frame Sync (08:57:09): - DST: AB1CDE SRC: N0CALL CAN: 7; Data Packet +M17 LSF Frame Sync (16:12:34): + DST: AB1CDE SRC: N0CALL CAN: 7; Data Packet FT: 0382; ET: 0; ES: 0; LSF: 00 00 1F 24 5D 51 00 00 4B 13 D1 06 03 82 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F7 54 (CRC CHK) E: F754; C: F754; -M17 PKT Frame Sync (08:57:09): CNT: 00; PBC: 00; EOT: 0; - pkt: 0554657374696E67204D3137207061636B6574206D6F64652E00 -M17 PKT Frame Sync (08:57:09): CNT: 01; LST: 01; EOT: 1; - pkt: 00BFEC0000000000000000000000000000000000000000000084 Protocol: SMS; - SMS: Testing M17 packet mode. - PKT: 05 54 65 73 74 69 6E 67 20 4D 31 37 20 70 61 63 6B 65 74 20 6D 6F 64 65 2E - 00 BF EC 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - (CRC CHK) E: BFEC; C: BFEC; -M17 No Frame Sync (08:57:09): +M17 PKT Frame Sync (16:12:34): CNT: 00; PBC: 00; EOT: 0; + pkt: 055468697320697320616E20534D532054657874204D65737300 +M17 PKT Frame Sync (16:12:34): CNT: 01; PBC: 01; EOT: 0; + pkt: 6167652047656E657261746564206279206D31372D7061636B04 +M17 PKT Frame Sync (16:12:34): CNT: 02; LST: 12; EOT: 1; + pkt: 65742D656E636F646500FD8100000000000000000000000000B0 Protocol: SMS; + SMS: This is an SMS Text Message Generated by m17-packet-encode + PKT: 05 54 68 69 73 20 69 73 20 61 6E 20 53 4D 53 20 54 65 78 74 20 4D 65 73 73 + 61 67 65 20 47 65 6E 65 72 61 74 65 64 20 62 79 20 6D 31 37 2D 70 61 63 6B + 65 74 2D 65 6E 63 6F 64 65 00 FD 81 00 00 00 00 00 00 00 00 00 00 00 00 00 + (CRC CHK) E: FD81; C: FD81; +``` +Encode Raw Hex Octet String as float symbol format: + +`./m17-packet-encode -S N0CALL -D AB1CDE -R 010203040506070809 -C 7 -f -o float.sym` + +Output: + +``` +Raw Len: 9; Raw Octets: 01 02 03 04 05 06 07 08 09 +DST: AB1CDE 00001F245D51 +SRC: N0CALL 00004B13D106 +CAN: 07 +Data CRC: D7CE +LSF CRC: F754 +FN:-- (ending frame) +PKT: 01 02 03 04 05 06 07 08 09 D7 CE 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +``` + +Decode (rolling) packets created with above sample: + +`tail -f float.sym | ./m17-packet-decode` + +Output: + +``` +DST: 00001F245D51 SRC: 00004B13D106 TYPE: 0382 META: 0000000000000000000000000000 LSF_CRC_OK +PKT: 01 02 03 04 05 06 07 08 09 D7 CE ``` \ No newline at end of file diff --git a/SP5WWP/m17-packet/m17-packet-decode.c b/SP5WWP/m17-packet/m17-packet-decode.c index f0ba2c1..a4cf127 100644 --- a/SP5WWP/m17-packet/m17-packet-decode.c +++ b/SP5WWP/m17-packet/m17-packet-decode.c @@ -207,10 +207,10 @@ int main(int argc, char* argv[]) { uint16_t p_len=strlen((const char*)packet_data); uint16_t p_crc=CRC_M17(packet_data, p_len+1); - fprintf(stderr, "Data CRC: rx=%02X%02X calc=%04X\n ", packet_data[p_len+1], packet_data[p_len+2], p_crc); + fprintf(stderr, "Data CRC: rx=%02X%02X calc=%04X\n", packet_data[p_len+1], packet_data[p_len+2], p_crc); if(p_crc==(uint16_t)packet_data[p_len+1]*256+(uint16_t)packet_data[p_len+2]) { - fprintf(stderr, "%s\n", &packet_data[1]); + fprintf(stderr, "SMS: %s\n", &packet_data[1]); } } } @@ -218,10 +218,12 @@ int main(int argc, char* argv[]) { if(!text_only) { - fprintf(stderr, "PKT: "); - for(uint16_t i=0; i 797) len = 797; + + //set num_bytes to len + 1 + num_bytes = len + 0; //doing 0 instead, let user pass an extra 00 on the end if they want it there + + char octet_char[3]; + octet_char[2] = 0; + uint16_t k = 0; + uint16_t i = 0; + + //debug + fprintf (stderr, "\nRaw Len: %d; Raw Octets:", len); + + for (i = 0; i < len; i++) + { + strncpy (octet_char, input+k, 2); + octet_char[2] = 0; + sscanf (octet_char, "%hhX", &raw[i]); + + //debug + // fprintf (stderr, " (%s)", octet_char); + fprintf (stderr, " %02X", raw[i]); + + k += 2; + } + + fprintf (stderr, "\n"); +} + //main routine int main(int argc, char* argv[]) { //scan command line options for input data - //TODO: support for strings with spaces, the code below is NOT foolproof! - //the user has to provide a minimum of 2 parameters: number of bytes and output filename + //WIP: support for text strings with spaces and raw hex octet strings (still NOT foolproof) + //the user has to provide a minimum of 2 parameters: input string or num_bytes, output type, and output filename if(argc>=4) { for(uint8_t i=1; i0) + { + memset(text, 0, 800*sizeof(char)); + memcpy(text, &argv[i+1][0], strlen(argv[i+1])); + std_encode = 0; + sms_encode = 1; + raw_encode = 0; + } + } + else if(argv[i][1]=='R') //-R - Raw Octets + { + if(strlen(&argv[i+1][0])>0) + { + memset (raw, 0, sizeof(raw)); + parse_raw_user_string (argv[i+1]); + std_encode = 0; + sms_encode = 0; + raw_encode = 1; + } + } else if(argv[i][1]=='o') //-o - output filename { if(strlen(&argv[i+1][0])>0) @@ -187,7 +262,9 @@ int main(int argc, char* argv[]) fprintf(stderr, "-S - source callsign (uppercase alphanumeric string) max. 9 characters,\n"); fprintf(stderr, "-D - destination callsign (uppercase alphanumeric string) or ALL for broadcast,\n"); fprintf(stderr, "-C - Channel Access Number (0..15, default - 0),\n"); - fprintf(stderr, "-n - number of bytes (1 to 798),\n"); + fprintf(stderr, "-T - SMS Text Message (example: -T 'Hello World! This is a text message'),\n"); + fprintf(stderr, "-R - Raw Hex Octets (example: -R 010203040506070809),\n"); + fprintf(stderr, "-n - number of bytes, only when pre-encoded data passed over stdin (1 to 798),\n"); fprintf(stderr, "-o - output file path/name,\n"); fprintf(stderr, "Output formats:\n"); //fprintf(stderr, "-x - binary output (M17 baseband as a packed bitstream),\n"); @@ -199,13 +276,8 @@ int main(int argc, char* argv[]) return -1; } - //assert number of bytes and filename - if(num_bytes==0) - { - fprintf(stderr, "Number of bytes not set. Exiting...\n"); - return -1; - } - else if(strlen((const char*)fname)==0) + //assert filename and not binary output + if(strlen((const char*)fname)==0) { fprintf(stderr, "Filename not specified. Exiting...\n"); return -1; @@ -218,12 +290,43 @@ int main(int argc, char* argv[]) //obtain data and append with CRC memset(full_packet_data, 0, 32*25); - if(fread(full_packet_data, num_bytes, 1, stdin)<1) + + //SMS Encode (-T) ./m17-packet-encode -f -o float.sym -T 'This is a simple SMS text message sent over M17 Packet Data.' + if (sms_encode == 1) { - fprintf(stderr, "Packet data too short. Exiting...\n"); - return -1; + num_bytes = strlen((const char*)text); //No need to check for zero return, since the default text string is supplied + if (num_bytes > 796) num_bytes = 796; //not 798 because we have to manually add the 0x05 protocol byte and 0x00 terminator + full_packet_data[0] = 0x05; //SMS Protocol + memcpy (full_packet_data+1, text, num_bytes); + num_bytes+= 2; //add one for terminating byte and 1 for strlen fix + fprintf (stderr, "SMS: %s\n", full_packet_data+1); } - + + //RAW Encode (-R) ./m17-packet-encode -f -o float.sym -R 5B69001E135152397C0A0000005A45 + else if (raw_encode == 1) + { + memcpy (full_packet_data, raw, num_bytes); + } + + //Old Method pre-encoded data over stdin // echo -en "\x05Testing M17 packet mode.\x00" | ./m17-packet-encode -S N0CALL -D AB1CDE -C 7 -n 26 -f -o float.sym + else if (std_encode == 1) + { + //assert number of bytes + if(num_bytes==0) + { + fprintf(stderr, "Number of bytes not set. Exiting...\n"); + return -1; + } + + if(fread(full_packet_data, num_bytes, 1, stdin)<1) + { + fprintf(stderr, "Packet data too short. Exiting...\n"); + return -1; + } + fprintf(stderr, "SMS: %s\n", full_packet_data+1); + // + } + uint16_t packet_crc=CRC_M17(full_packet_data, num_bytes); full_packet_data[num_bytes] =packet_crc>>8; full_packet_data[num_bytes+1]=packet_crc&0xFF; @@ -244,8 +347,7 @@ int main(int argc, char* argv[]) #else fprintf(stderr, "DST: %s\t%012lX\nSRC: %s\t%012lX\n", dst_raw, dst_encoded, src_raw, src_encoded); #endif - //fprintf(stderr, "DST: %02X %02X %02X %02X %02X %02X\n", lsf.dst[0], lsf.dst[1], lsf.dst[2], lsf.dst[3], lsf.dst[4], lsf.dst[5]); - //fprintf(stderr, "SRC: %02X %02X %02X %02X %02X %02X\n", lsf.src[0], lsf.src[1], lsf.src[2], lsf.src[3], lsf.src[4], lsf.src[5]); + fprintf(stderr, "CAN: %02d\n", can); fprintf(stderr, "Data CRC:\t%04hX\n", packet_crc); type=((uint16_t)0x01<<1)|((uint16_t)can<<7); //packet mode, content: data lsf.type[0]=(uint16_t)type>>8; @@ -368,16 +470,16 @@ int main(int argc, char* argv[]) } num_bytes=tmp; //bring back the num_bytes value - - fprintf (stderr, "FULL: "); - for(uint8_t i=0; i