GONEC_CONVERT/APP/main.c

270 lines
8.1 KiB
C

//
// Created by cfif on 09.09.2025.
//
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "cJSON.h"
#include "EraGlonassMsd.h"
#include "AsciiStringAssmeblingUtils.h"
char cConvertDecToMilliArcSec(double dec, int32_t *mArcs, double *gradus) {
int deg = 0, min = 0;
double sec = 0.0;
double _dec = dec;
deg = (int) (_dec / 100);
min = (int) (_dec) - (deg * 100);
sec = (double) (_dec - min - 100 * deg) * 60.0;
if (gradus != NULL) *gradus = deg + min / 60.0 + sec / 3600.0;
if (mArcs != NULL) *mArcs = (int) (deg * 3600 + min * 60) * 1000 + (int) (sec * 1000); // mArcseconds
return 0;
}
char cConvertDecToMilliArcSecFromDegMin(double deg, double min, int32_t *mArcs, double *gradus) {
double sec = 0.0;
if (gradus != NULL) *gradus = deg + min / 60.0 + sec / 3600.0;
if (mArcs != NULL) *mArcs = (int) (deg * 3600 + min * 60) * 1000 + (int) (sec * 1000); // mArcseconds
return 0;
}
int main(int argc, char *argv[]) {
// const char *json_string = "{\"timestamp\": \"2024-06-26T09:36:42+05:06\", \"coordinate\": \"56 33.13N 060 54.13E\", \"phone\": \"88312622039\", \"id\": \"00182\" }";
if (argc != 3) {
printf("Usage: conv fileIn fileOut\n");
fflush(stdout);
return 1;
}
FILE *input_file = fopen(argv[1], "r");
if (input_file == NULL) {
printf("Error: Failed to open file %s\n", argv[1]);
fflush(stdout);
return 1;
}
#define BUFFER_SIZE 4096
char json_string[BUFFER_SIZE] = {0};
size_t bytes_read = fread(json_string, 1, BUFFER_SIZE, input_file);
printf("Read from file: \"%s\", %zu bytes:\n", argv[1], bytes_read);
printf("%.*s\n", (int) bytes_read, json_string);
fclose(input_file);
tEraGlonassMsd msd;
EraGlonassMsdInit(&msd);
EraGlonassMsdSetDataEmergencySituationFlags(&msd, 1, MANUAL_ACTIVATION, EMERGENCY_CALL);
EraGlonassMsdSetVehicleType(&msd, 0);
EraGlonassMsdSetPassengersNumber(&msd, 1);
EraGlonassMsdSetPropulsionStorageType(&msd, 0);
cJSON *json = cJSON_Parse(json_string);
if (json == NULL) {
printf("Error parsing JSON\n");
fflush(stdout);
return 1;
}
cJSON *timestampJS = cJSON_GetObjectItemCaseSensitive(json, "timestamp");
cJSON *coordinateJS = cJSON_GetObjectItemCaseSensitive(json, "coordinate");
cJSON *phoneJS = cJSON_GetObjectItemCaseSensitive(json, "phone");
cJSON *idJS = cJSON_GetObjectItemCaseSensitive(json, "id");
if (cJSON_IsString(timestampJS) && (timestampJS->valuestring != NULL)) {
printf("timestamp (JSON): %s\n", timestampJS->valuestring);
struct tm timeinfo = {0};
int timezone_hour_offset;
int timezone_min_offset;
char timezone_sign;
int result = sscanf(timestampJS->valuestring, "%d-%d-%dT%d:%d:%d%c%d:%d",
&timeinfo.tm_year, &timeinfo.tm_mon, &timeinfo.tm_mday,
&timeinfo.tm_hour, &timeinfo.tm_min, &timeinfo.tm_sec,
&timezone_sign, &timezone_hour_offset, &timezone_min_offset);
if (result >= 6) {
timeinfo.tm_year -= 1900;
timeinfo.tm_mon -= 1;
time_t timestamp = mktime(&timeinfo);
if (result >= 9) {
int offset_seconds = timezone_hour_offset * 3600 + timezone_min_offset * 60;
if (timezone_sign == '-') {
timestamp += offset_seconds;
} else if (timezone_sign == '+') {
timestamp -= offset_seconds;
}
} else {
printf("Parsing timestamp (UTC) error");
fflush(stdout);
return 1;
}
EraGlonassMsdSetTimeStamp(&msd, timestamp);
printf("timestamp: %u\n", msd.MSD_Data.timestamp);
} else {
printf("Parsing timestamp error");
fflush(stdout);
return 1;
}
} else {
printf("Parsing JSON timestamp error");
fflush(stdout);
return 1;
}
if (cJSON_IsString(coordinateJS) && (coordinateJS->valuestring != NULL)) {
printf("coordinate (JSON): %s\n", coordinateJS->valuestring);
int lat_deg, lon_deg;
double lat_min, lon_min;
char lat_dir, lon_dir;
char tmp[1024] = {0};
int len = 0;
for (size_t i = 0; i < strlen(coordinateJS->valuestring); ++i) {
tmp[len] = coordinateJS->valuestring[i];
++len;
if ((coordinateJS->valuestring[i + 1] == 'N') || (coordinateJS->valuestring[i + 1] == 'S') ||
(coordinateJS->valuestring[i + 1] == 'W') || (coordinateJS->valuestring[i + 1] == 'E')) {
tmp[len] = ' ';
++len;
}
}
int result = sscanf(tmp,
"%d %lf %c %d %lf %c",
&lat_deg, &lat_min, &lat_dir,
&lon_deg, &lon_min, &lon_dir);
if (result == 6) {
double lat_decimal = 0;
double lon_decimal = 0;
cConvertDecToMilliArcSecFromDegMin(lat_deg, lat_min, &msd.MSD_Data.pos.lat, &lat_decimal);
cConvertDecToMilliArcSecFromDegMin(lon_deg, lon_min, &msd.MSD_Data.pos.lon, &lon_decimal);
if (lat_dir == 'S') {
lat_decimal = -lat_decimal;
msd.MSD_Data.pos.lat = -msd.MSD_Data.pos.lat;
}
if (lon_dir == 'W') {
lon_decimal = -lon_decimal;
msd.MSD_Data.pos.lon = -msd.MSD_Data.pos.lon;
}
printf("Latitude (degrees): %lf; dir: %c\n", lat_decimal, lat_dir);
printf("Longitude (degrees): %lf; dir: %c\n", lon_decimal, lon_dir);
printf("Latitude (mArcs): %d\n", msd.MSD_Data.pos.lat);
printf("Longitude (mArcs): %d\n", msd.MSD_Data.pos.lon);
EraGlonassMsdSetPositionValue(&msd, msd.MSD_Data.pos.lon, msd.MSD_Data.pos.lat, 0, 2);
} else {
printf("Parsing coordinate error");
fflush(stdout);
return 1;
}
} else {
printf("Parsing JSON coordinate error");
fflush(stdout);
return 1;
}
if (cJSON_IsString(phoneJS) && (phoneJS->valuestring != NULL)) {
printf("phone (JSON): %s\n", phoneJS->valuestring);
} else {
printf("Parsing JSON phone error");
fflush(stdout);
return 1;
}
if (cJSON_IsString(idJS) && (idJS->valuestring != NULL)) {
printf("id (JSON): %s\n", idJS->valuestring);
char VIN[18] = {0};
memset(VIN, '0', 17);
memcpy(&VIN[17 - 5], idJS->valuestring, 5);
// memcpy(&VIN[5], "1111111111", 10);
EraGlonassMsdSetVIN(&msd, VIN, sizeof(VIN));
printf("id (VIN): %s\n", VIN);
} else {
printf("Parsing JSON id error");
fflush(stdout);
return 1;
}
uint8_t msdEncoded[512] = {0};
msdEncoded[0] = 0;
msdEncoded[1] = 15;
memcpy(&msdEncoded[2], "000000000000000", 15);
msdEncoded[17] = strlen(phoneJS->valuestring);
memcpy(&msdEncoded[18], phoneJS->valuestring, strlen(phoneJS->valuestring));
msdEncoded[18 + strlen(phoneJS->valuestring)] = 0;
size_t msdEncodedSize = EraGlonassMsdEncode(&msd, MSD_V_2, &msdEncoded[20 + strlen(phoneJS->valuestring)]);
msdEncoded[19 + strlen(phoneJS->valuestring)] = msdEncodedSize;
char egtsHexStr[1024] = {0};
size_t egtsHexStrLen = 0;
vAsciiStringAddBytesAsHex(egtsHexStr, &egtsHexStrLen, msdEncoded, 20 + strlen(phoneJS->valuestring) + msdEncodedSize);
FILE *output_file = fopen(argv[2], "w");
if (output_file == NULL) {
printf("Error: Failed to open file %s\n", argv[2]);
fflush(stdout);
return 1;
}
size_t bytes_written = fwrite(egtsHexStr, 1, egtsHexStrLen, output_file);
if (bytes_written != egtsHexStrLen) {
printf("Error: Failed to write file %s\n", argv[2]);
fflush(stdout);
return 1;
}
printf("Write to file: \"%s\" %zu bytes: %.*s\n", argv[2], bytes_written, (int) bytes_written, egtsHexStr);
fclose(output_file);
fflush(stdout);
cJSON_Delete(json);
return 0;
}