I am trying to write a program to find and decrypt messages in RTCM 2.3 format from a file. But all my attempts end up not quite successful. If you have already dealt with RTCM, you can explain the decryption algorithm or point out the error.
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
unsigned char* full_message1;
typedef struct {
uint8_t preamble : 8;
uint8_t frame_id : 6;
uint16_t r_station_id : 10;
uint8_t paryty1 : 6;
uint16_t modified_Z_count : 13;
uint8_t sequence : 3;
uint8_t number_of_data_words : 5;
uint8_t station_health : 3;
uint8_t paryty2 : 6;
} Message_header;
Message_header RTCM_decoder(unsigned char* data) {
Message_header msg;
int i = 0;
printf("Передал:n");
for (int i=0; i < 10; i++) {
printf("%02x ", data[i]);
}
printf("n");
msg.preamble = ((data[0] & 0x3f) << 2) | ((data[1] & 0x30) >> 4);
if (!(msg.preamble == 0x66) & !(msg.preamble == 0x19)) {
printf("Preamble incorrect: %xn", msg.preamble);
}
msg.frame_id = ((data[1] & 0x0f) << 2) | ((data[2] & 0x30) >> 4);
msg.r_station_id = ((data[2] & 0x0f) << 6) | data[3] & 0x3f;
msg.paryty1 = data[4] & 0x3f;
msg.modified_Z_count = ((data[5] & 0x3f) << 7) | ((data[6] & 0x3f) << 1) | ((data[7] & 0x20) >> 5);
msg.sequence = ((data[7] & 0x1c) >> 2);
msg.number_of_data_words = ((data[7] & 0x03) << 3) | ((data[8] & 0x38) >> 3);
msg.station_health = data[8] & 0x07;
if (msg.station_health != 0) {
printf("Ststion errorn");
}
msg.paryty2 = data[9] & 0x3f;
return msg;
}
typedef struct {
int search_result;
unsigned char cuted_bits[2];
} search1;
search1 RTCM_searcher1(unsigned char *buffer) {
static uint16_t preamble;
search1 srch;
srch.search_result = 0;
int i;
preamble = ((preamble << 6) & 0xffc0) | (*buffer & 0x3f);
for (i=0; i<16; i++) {
uint16_t preamble_s = (preamble << i) & 0xff00;
srch.cuted_bits[0] = preamble_s >> 10;
srch.cuted_bits[1] = ((preamble << i) & 0x03f0) >> 4;
if (preamble_s == 0x6600 || preamble_s == 0x1900) {
srch.search_result = 1;
break;
}
}
return srch;
}
int main() {
FILE *file = fopen("1.cor", "rb");
if (file == NULL) {
printf("Не удалось открыть файлn");
};
Message_header msg;
int inv;
while (1) {
unsigned char ubuffer, buffer_roll, kadr[5], full_header1[10];
char buffer;
fread(&buffer, sizeof (buffer), 1, file);
ubuffer = (char)buffer;
for (int i=0; i < 8; i++) {
uint8_t bit = (ubuffer >> 7-i) & 0x01;
buffer_roll |= bit << i;
}
buffer = 0;
search1 srch = RTCM_searcher1(&buffer_roll);
buffer_roll = 0;
if (srch.search_result == true) {
printf("nПреамбула найдена!n");
memcpy(&kadr[0], &srch.cuted_bits[0], sizeof(srch.cuted_bits));
inv = 0;
if (inv == 0) {
for (int j=2; j<5; j++) {
fread(&buffer, sizeof (buffer), 1, file);
ubuffer = (char)buffer;
for (int i=0; i < 8; i++) {
uint8_t bit = (ubuffer >> 7-i) & 0x01;
buffer_roll |= bit << i;
}
buffer = 0;
memcpy(&kadr[j], &buffer_roll, sizeof(buffer_roll));
buffer_roll = 0;
}
} else {
for (int j=2; j<5; j++) {
fread(&buffer, sizeof (buffer), 1, file);
ubuffer = (char)buffer;
for (int i=0; i < 8; i++) {
uint8_t bit = (ubuffer >> 7-i) & 0x01;
buffer_roll |= bit << i;
}
buffer = 0;
memcpy(&kadr[j], &buffer_roll, sizeof(buffer_roll));
buffer_roll = 0;
}
}
if ((kadr[4] & 0x01) == 0x01) {
inv = 1;
} else {
inv = 0;
}
memcpy(&full_header1[0], kadr, sizeof(kadr));
memset(kadr, 0, sizeof(kadr));
if (inv == 0) {
for (int j=0; j<5; j++) {
fread(&buffer, sizeof (buffer), 1, file);
ubuffer = (char)buffer;
for (int i=0; i < 8; i++) {
uint8_t bit = (ubuffer >> 7-i) & 0x01;
buffer_roll |= bit << i;
}
buffer = 0;
memcpy(&kadr[j], &buffer_roll, sizeof(buffer_roll));
buffer_roll = 0;
}
} else {
for (int j=0; j<5; j++) {
fread(&buffer, sizeof (buffer), 1, file);
ubuffer = (char)buffer;
for (int i=0; i < 8; i++) {
uint8_t bit = (ubuffer >> 7-i) & 0x01;
buffer_roll |= bit << i;
}
buffer = 0;
memcpy(&kadr[j], &buffer_roll, sizeof(buffer_roll));
buffer_roll = 0;
}
}
if ((kadr[4] & 0x01) == 0x01) {
inv = 1;
} else {
inv = 0;
}
memcpy(&full_header1[5], kadr, sizeof(kadr));
memset(kadr, 0, sizeof(kadr));
Message_header read1 = RTCM_decoder(full_header1);
printf("Nomer kadra: %dnZ-count: %dnChislo kadrov: %dnSostoyanie stancii: %dnnn", read1.frame_id, read1.modified_Z_count, read1.number_of_data_words, read1.station_health);
getchar();
}
}
fclose(file);
getchar();
return 0;
}
As I understood the algorithm is as follows: take 1 byte, make 8 -> 6, and roll those 6 bits and so on with each subsequent bit. We also take into account 30 bits of each word, if it is equal to 1, the next word is inverted. Maybe it would help: https://github.com/tomojitakasu/RTKLIB/tree/master?tab=readme-ov-file#readme
I’ve tried almost everything, but I can’t figure out where the error is. Different methods and different sources, nothing helped(
vkosmose03 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.