#include #include #include #include //libm17 #include float sample; //last raw sample from the stdin float last[8]; //look-back buffer for finding syncwords float dist; //Euclidean distance for finding syncwords in the symbol stream float pld[SYM_PER_PLD]; //raw frame symbols uint16_t soft_bit[2*SYM_PER_PLD]; //raw frame soft bits uint16_t d_soft_bit[2*SYM_PER_PLD]; //deinterleaved soft bits uint8_t lsf[30+1]; //complete LSF (one byte extra needed for the Viterbi decoder) uint8_t frame_data[26+1]; //decoded frame data, 206 bits, plus 4 flushing bits uint8_t packet_data[33*25]; //whole packet data uint8_t syncd=0; //syncword found? uint8_t fl=0; //Frame=0 of LSF=1 int8_t last_fn; //last received frame number (-1 when idle) uint8_t pushed; //counter for pushed symbols uint8_t skip_payload_crc_check=0; //skip payload CRC check uint8_t callsigns=0; //decode callsigns? uint8_t show_viterbi=0; //show Viterbi errors? uint8_t text_only=0; //display text only (for text message mode) int main(int argc, char* argv[]) { //scan command line options - if there are any //TODO: support for strings with spaces, the code below is NOT foolproof! if(argc>1) { for(uint8_t i=1; i=symbol_list[3]) { soft_bit[i*2+1]=0xFFFF; } else if(pld[i]>=symbol_list[2]) { soft_bit[i*2+1]=-(float)0xFFFF/(symbol_list[3]-symbol_list[2])*symbol_list[2]+pld[i]*(float)0xFFFF/(symbol_list[3]-symbol_list[2]); } else if(pld[i]>=symbol_list[1]) { soft_bit[i*2+1]=0x0000; } else if(pld[i]>=symbol_list[0]) { soft_bit[i*2+1]=(float)0xFFFF/(symbol_list[1]-symbol_list[0])*symbol_list[1]-pld[i]*(float)0xFFFF/(symbol_list[1]-symbol_list[0]); } else { soft_bit[i*2+1]=0xFFFF; } //bit 1 if(pld[i]>=symbol_list[2]) { soft_bit[i*2]=0x0000; } else if(pld[i]>=symbol_list[1]) { soft_bit[i*2]=0x7FFF-pld[i]*(float)0xFFFF/(symbol_list[2]-symbol_list[1]); } else { soft_bit[i*2]=0xFFFF; } } //derandomize for(uint16_t i=0; i>(7-(i%8)))&1) //soft XOR. flip soft bit if "1" soft_bit[i]=0xFFFF-soft_bit[i]; } //deinterleave for(uint16_t i=0; i>2)&0x1F; uint8_t rx_last=frame_data[26]>>7; //fprintf(stderr, "FN%d, (%d)\n", rx_fn, rx_last); //copy data - might require some fixing if(rx_fn<=31 && rx_fn==last_fn+1 && !rx_last) { memcpy(&packet_data[rx_fn*25], &frame_data[1], 25); last_fn++; } else if(rx_last) { memcpy(&packet_data[(last_fn+1)*25], &frame_data[1], rx_fn); //dump data if(packet_data[0]==0x05) //if a text message { if(skip_payload_crc_check) { fprintf(stderr, "%s\n", &packet_data[1]); } else { uint16_t p_len=strlen((const char*)packet_data); uint16_t p_crc=CRC_M17(packet_data, p_len+1); //fprintf(stderr, "rx=%02X%02X calc=%04X", 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]); } } } else { if(!text_only) { fprintf(stderr, "PKT: "); for(uint16_t i=0; i