// // Created by cfif on 09.09.2025. // #include #include #include #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\n"); fflush(stdout); return 1; } EraGlonassMsdSetTimeStamp(&msd, timestamp); printf("timestamp: %u\n", msd.MSD_Data.timestamp); } else { printf("Parsing timestamp error\n"); fflush(stdout); return 1; } } else { printf("Parsing JSON timestamp error\n"); 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\n"); fflush(stdout); return 1; } } else { printf("Parsing JSON coordinate error\n"); fflush(stdout); return 1; } if (cJSON_IsString(phoneJS) && (phoneJS->valuestring != NULL)) { printf("phone (JSON): %s\n", phoneJS->valuestring); } else { printf("Parsing JSON phone error\n"); fflush(stdout); return 1; } if (cJSON_IsString(idJS) && (idJS->valuestring != NULL)) { printf("id (JSON): %s\n", idJS->valuestring); char VIN[18] = {0}; if (strlen(idJS->valuestring) > (sizeof(VIN) - 1)) { printf("Length error id\n"); fflush(stdout); return 1; } memset(VIN, '0', sizeof(VIN) - 1); memcpy(&VIN[sizeof(VIN) - 1 - strlen(idJS->valuestring)], idJS->valuestring, strlen(idJS->valuestring)); // memcpy(&VIN[5], "1111111111", 10); EraGlonassMsdSetVIN(&msd, VIN, sizeof(VIN) - 1); printf("id (VIN): %s\n", VIN); } else { printf("Parsing JSON id error\n"); fflush(stdout); return 1; } uint8_t msdEncoded[512] = {0}; msdEncoded[0] = 0; // msdEncoded[1] = 15; memcpy(&msdEncoded[1], "000000000000000", 15); msdEncoded[16] = strlen(phoneJS->valuestring); memcpy(&msdEncoded[17], phoneJS->valuestring, strlen(phoneJS->valuestring)); msdEncoded[17 + strlen(phoneJS->valuestring)] = 0; size_t msdEncodedSize = EraGlonassMsdEncode(&msd, MSD_V_2, &msdEncoded[19 + strlen(phoneJS->valuestring)]); msdEncoded[18 + strlen(phoneJS->valuestring)] = msdEncodedSize; char egtsHexStr[1024] = {0}; size_t egtsHexStrLen = 0; vAsciiStringAddBytesAsHex(egtsHexStr, &egtsHexStrLen, msdEncoded, 19 + strlen(phoneJS->valuestring) + msdEncodedSize); size_t egtsBinStrLen = 19 + 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(msdEncoded, 1, egtsBinStrLen, output_file); if (bytes_written != egtsBinStrLen) { 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; }