void build_packet(const char** parameters) { char* data = buffers[OPERATIONAL_BUFFER].data; // Fill D-PRS header memcpy(data, "$$CRCxxxx,", DPRS_SIGN_LENGTH); data += DPRS_SIGN_LENGTH; // Fill TNC-2 header data += build_aprs_call(data); memcpy(data, ">APD4XX,DSTAR*:", 15); data[5] = (software_version[1] % 10) + '0'; data[6] = (software_version[2] % 24) + 'A'; data += 15; // Fill APRS payload data += build_position_report(data, parameters); // Fill D-PRS/APRS-IS terminator and Slow Data filler memcpy(data, "\r\n", 2); data += 2; memset(data, 0x66, 5); // Update buffer attributes int length = data - buffers[OPERATIONAL_BUFFER].data; buffers[OPERATIONAL_BUFFER].length = length; buffers[OPERATIONAL_BUFFER].version ++; // Update CRC in D-PRS header data = buffers[OPERATIONAL_BUFFER].data; length -= TNC2_POSITION + 1; // Length from TNC-2 header to CR uint16_t sum = rx_dstar_crc_data(data + TNC2_POSITION, length); vdisp_i2s(data + CRC_POSITION, 4, 16, 1, sum); data[DPRS_SIGN_LENGTH - 1] = ','; }
static uint32_t get_crc(void) { return rx_dstar_crc_data( (uint8_t *) &settings, 504) | (SETTINGS_VERSION << 16); }
void slowdata_analyze_stream(void) { while (slowDataFIFOoutPtr != slowDataFIFOinPtr) { char d = (char) slowDataFIFO[slowDataFIFOoutPtr]; slowDataFIFOoutPtr++; if (slowDataFIFOoutPtr >= SLOWDATA_FIFO_BYTES) { slowDataFIFOoutPtr = 0; } switch (slowDataGPSA_state) { case 0: if (d == '$') { slowDataGPSA_state = 1; } break; case 1: if (d == '$') { slowDataGPSA_state = 2; } else { slowDataGPSA_state = 0; } break; case 2: if (d == 'C') { slowDataGPSA_state = 3; } else { slowDataGPSA_state = 0; } break; case 3: if (d == 'R') { slowDataGPSA_state = 4; } else { slowDataGPSA_state = 0; } break; case 4: if (d == 'C') { slowDataGPSA_state = 5; } else { slowDataGPSA_state = 0; } break; case 5: if (d > ' ') { slowDataGPSA_state = 6; crc[0] = d; } else { slowDataGPSA_state = 0; } break; case 6: if (d > ' ') { slowDataGPSA_state = 7; crc[1] = d; } else { slowDataGPSA_state = 0; } break; case 7: if (d > ' ') { slowDataGPSA_state = 8; crc[2] = d; } else { slowDataGPSA_state = 0; } break; case 8: if (d > ' ') { slowDataGPSA_state = 9; crc[3] = d; } else { slowDataGPSA_state = 0; } break; case 9: if (d == ',') { slowDataGPSA_state = 10; slowDataGPSA_ptr = 0; } else { slowDataGPSA_state = 0; } break; case 10: if (d >= ' ') // printable character { if (slowDataGPSA_ptr >= SLOWDATA_GPSA_BUFLEN) // buffer full, line too long { slowDataGPSA_state = 0; } else { slowDataGPSA[slowDataGPSA_ptr] = d; slowDataGPSA_ptr ++; } } else // everything else including CR { slowDataGPSA_state = 0; if (slowDataGPSA_ptr < SLOWDATA_GPSA_BUFLEN) // buffer not full { slowDataGPSA[slowDataGPSA_ptr] = d; // put last character at the end slowDataGPSA_ptr ++; // crc[4] = 0; // vd_prints_xy(VDISP_NODEINFO_LAYER, 80, 16, VDISP_FONT_6x8, 0, crc); unsigned short sum = rx_dstar_crc_data((unsigned char *) slowDataGPSA, slowDataGPSA_ptr); char buf[5]; vdisp_i2s(buf, 4, 16, 1, sum); // buf[4] = 0; // vd_prints_xy(VDISP_NODEINFO_LAYER, 80, 24, VDISP_FONT_6x8, 0, buf); if (memcmp(crc, buf, 4) == 0) { aprs_send_user_report((unsigned char *) slowDataGPSA, slowDataGPSA_ptr -1); // send GPS-A data without trailing CR } } } break; } // switch } // while }