Первый коммит
This commit is contained in:
commit
8567a5bb2a
|
|
@ -0,0 +1,149 @@
|
||||||
|
//
|
||||||
|
// Created by xemon on 06.09.22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <memory.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "AsciiStringAssmeblingUtils.h"
|
||||||
|
|
||||||
|
static const char ASCII_STRING_HEX_CHAR[] = "0123456789ABCDEF";
|
||||||
|
|
||||||
|
static const uint64_t ASCII_STRING_DEC_POW[] = {
|
||||||
|
1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000, 100000000000
|
||||||
|
};
|
||||||
|
static const uint8_t ASCII_STRING_DEC_POW_LEN = (sizeof(ASCII_STRING_DEC_POW) / sizeof(uint64_t));
|
||||||
|
|
||||||
|
uint8_t vAsciiStringDecimalIntToChar(uint8_t number_0_9) {
|
||||||
|
number_0_9 = number_0_9 % 10; //cutoff digits more 1 (numbers between 0 and 9)
|
||||||
|
return ('0' + number_0_9); //return char of number('0' is base number in ascii)
|
||||||
|
}
|
||||||
|
|
||||||
|
void vAsciiStringAdd(char *string, size_t *stringLen, char *addString, size_t addStringLen) {
|
||||||
|
memcpy(string + (*stringLen), addString, addStringLen);
|
||||||
|
*stringLen += addStringLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vAsciiStringAddChar(char *string, size_t *stringLen, uint8_t singleChar) {
|
||||||
|
string[*stringLen] = singleChar;
|
||||||
|
++(*stringLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vAsciiStringInit(char *string, size_t *stringLen, size_t fullLen) {
|
||||||
|
memset(string, 0, fullLen);
|
||||||
|
*stringLen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vAsciiStringClean(char *string, size_t *stringLen) {
|
||||||
|
if (*stringLen == 0)return;
|
||||||
|
memset(string, 0, *stringLen);
|
||||||
|
*stringLen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vAsciiStringAddDecimalInt(char *string, size_t *stringLen, uint8_t number, uint8_t digits) {
|
||||||
|
for (uint8_t reverse_digit = 1; reverse_digit <= digits; ++reverse_digit) {
|
||||||
|
string[*stringLen + digits - reverse_digit] = vAsciiStringDecimalIntToChar(number);
|
||||||
|
number /= 10;
|
||||||
|
}
|
||||||
|
*stringLen += digits;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vAsciiStringAddDecimalInt64(char *string, size_t *stringLen, uint64_t number, uint8_t digits) {
|
||||||
|
for (uint8_t reverse_digit = 1; reverse_digit <= digits; ++reverse_digit) {
|
||||||
|
string[*stringLen + digits - reverse_digit] = vAsciiStringDecimalIntToChar(number % 10);
|
||||||
|
number /= 10;
|
||||||
|
}
|
||||||
|
*stringLen += digits;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vAsciiStringSpitChars(char *one, char *two) {
|
||||||
|
char tmp;
|
||||||
|
tmp = *one;
|
||||||
|
*one = *two;
|
||||||
|
*two = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vAsciiStringAddDecimalIntWithLimit(char *string, size_t *stringLen, int64_t number, uint8_t digitsLimit) {
|
||||||
|
|
||||||
|
if (number < 0) {
|
||||||
|
*(string + (*stringLen)) = '-';
|
||||||
|
++(*stringLen);
|
||||||
|
number = -number;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t cutoffNumber = 1;
|
||||||
|
|
||||||
|
for (uint8_t scale = 0; scale < digitsLimit; ++scale) {
|
||||||
|
cutoffNumber *= 10;
|
||||||
|
}
|
||||||
|
number = number % cutoffNumber;
|
||||||
|
|
||||||
|
if (number == 0) {
|
||||||
|
string[*stringLen] = '0';
|
||||||
|
(*stringLen) += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t digits = 0;
|
||||||
|
|
||||||
|
for (; (digits < digitsLimit) && (number != 0); ++digits) {
|
||||||
|
string[(*stringLen) + digits] = vAsciiStringDecimalIntToChar(number % 10);
|
||||||
|
number /= 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t reverses = digits / 2;
|
||||||
|
|
||||||
|
for (uint8_t reverse_digit = 0; reverse_digit < reverses; ++reverse_digit) {
|
||||||
|
vAsciiStringSpitChars(string + *stringLen + reverse_digit, string + *stringLen + digits - 1 - reverse_digit);
|
||||||
|
}
|
||||||
|
|
||||||
|
*stringLen += digits;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vAsciiStringAddByteAsHex(char *str, size_t *stringLen, uint8_t number) {
|
||||||
|
str[*stringLen + 0] = ASCII_STRING_HEX_CHAR[(number >> 4) & 0xF];
|
||||||
|
str[*stringLen + 1] = ASCII_STRING_HEX_CHAR[(number & 0xF)];
|
||||||
|
*stringLen += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vAsciiStringAddBytesAsHex(char *str, size_t *stringLen, uint8_t *bytesData, size_t bytesCount) {
|
||||||
|
uint8_t *end = bytesData + bytesCount;
|
||||||
|
while (end > bytesData) {
|
||||||
|
vAsciiStringAddByteAsHex(str, stringLen, *bytesData);
|
||||||
|
++bytesData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint64_t get_dec_pow(uint8_t value) {
|
||||||
|
if (value < ASCII_STRING_DEC_POW_LEN) {
|
||||||
|
return ASCII_STRING_DEC_POW[value];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t mux = ASCII_STRING_DEC_POW[ASCII_STRING_DEC_POW_LEN - 1];
|
||||||
|
|
||||||
|
for (uint8_t scale = ASCII_STRING_DEC_POW_LEN; scale < value; ++scale) {
|
||||||
|
mux *= 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mux;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void vAsciiStringAddDecimalFloatWithLimit(
|
||||||
|
char *string,
|
||||||
|
size_t *stringLen,
|
||||||
|
double number,
|
||||||
|
uint8_t intDigits,
|
||||||
|
uint8_t fractionalDigits
|
||||||
|
) {
|
||||||
|
uint64_t dec_mux = get_dec_pow(fractionalDigits);
|
||||||
|
|
||||||
|
uint64_t intPart = (uint64_t) number;
|
||||||
|
double fractional = round(number * dec_mux) / dec_mux - intPart;
|
||||||
|
uint64_t fractionalPartInInteger = (uint64_t) (fractional * dec_mux);
|
||||||
|
|
||||||
|
|
||||||
|
vAsciiStringAddDecimalIntWithLimit(string, stringLen, intPart, intDigits);
|
||||||
|
vAsciiStringAddChar(string, stringLen, '.');
|
||||||
|
vAsciiStringAddDecimalInt64(string, stringLen, fractionalPartInInteger, fractionalDigits);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
//
|
||||||
|
// Created by xemon on 06.09.22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef ASCIISTRINGASSMEBLINGUTILS_ASCIISTRINGASSMEBLINGUTILS_H
|
||||||
|
#define ASCIISTRINGASSMEBLINGUTILS_ASCIISTRINGASSMEBLINGUTILS_H
|
||||||
|
|
||||||
|
#include "stdint.h"
|
||||||
|
#include "stddef.h"
|
||||||
|
|
||||||
|
void vAsciiStringAdd(char *string, size_t *stringLen, char *addString, size_t addStringLen);
|
||||||
|
|
||||||
|
uint8_t vAsciiStringDecimalIntToChar(uint8_t number_0_9);
|
||||||
|
|
||||||
|
void vAsciiStringAddChar(char *string, size_t *stringLen, uint8_t singleChar);
|
||||||
|
|
||||||
|
#define vAsciiStringAddStatic(string, stringLen, staticString)\
|
||||||
|
vAsciiStringAdd(string, stringLen, staticString, sizeof(staticString)-1)
|
||||||
|
|
||||||
|
void vAsciiStringClean(char *string, size_t *stringLen);
|
||||||
|
|
||||||
|
void vAsciiStringInit(char *string, size_t *stringLen, size_t fullLen);
|
||||||
|
|
||||||
|
void vAsciiStringAddDecimalInt(char *string, size_t *stringLen, uint8_t number, uint8_t digits);
|
||||||
|
|
||||||
|
void vAsciiStringAddDecimalInt64(char *string, size_t *stringLen, uint64_t number, uint8_t digits);
|
||||||
|
|
||||||
|
void vAsciiStringAddDecimalIntWithLimit(char *string, size_t *stringLen, int64_t number, uint8_t digitsLimit);
|
||||||
|
|
||||||
|
void vAsciiStringAddByteAsHex(char *str, size_t *stringLen, uint8_t number);
|
||||||
|
|
||||||
|
void vAsciiStringAddBytesAsHex(char *str, size_t *stringLen, uint8_t *bytesData, size_t bytesCount);
|
||||||
|
|
||||||
|
void vAsciiStringAddDecimalFloatWithLimit(
|
||||||
|
char *string,
|
||||||
|
size_t *stringLen,
|
||||||
|
double number,
|
||||||
|
uint8_t intDigits,
|
||||||
|
uint8_t fractionalDigits
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif //ASCIISTRINGASSMEBLINGUTILS_ASCIISTRINGASSMEBLINGUTILS_H
|
||||||
|
|
@ -0,0 +1,128 @@
|
||||||
|
/*
|
||||||
|
* BitOps.c
|
||||||
|
*
|
||||||
|
* Created on: Apr 13, 2021
|
||||||
|
* Author: zemon
|
||||||
|
*/
|
||||||
|
#include "BitBuffer.h"
|
||||||
|
|
||||||
|
|
||||||
|
void vBitBufferAppendDataByteBitsCountWithBitsOffset(
|
||||||
|
uint8_t *destinationBitSequence,
|
||||||
|
uint16_t offsetOfFirstBit,
|
||||||
|
uint8_t appendableByte,
|
||||||
|
uint8_t countOfAppendableBits
|
||||||
|
) {
|
||||||
|
|
||||||
|
uint16_t fullBytesOffset = offsetOfFirstBit / 8;
|
||||||
|
uint8_t bitsOffsetInFirstByte = offsetOfFirstBit % 8;
|
||||||
|
uint8_t bitsWritedToSecondByte = bitsOffsetInFirstByte + countOfAppendableBits - 8;
|
||||||
|
|
||||||
|
uint8_t firstByteCut = appendableByte << (8 - countOfAppendableBits);
|
||||||
|
|
||||||
|
destinationBitSequence[fullBytesOffset] |= firstByteCut >> bitsOffsetInFirstByte;
|
||||||
|
|
||||||
|
if (bitsWritedToSecondByte > 0) {
|
||||||
|
destinationBitSequence[fullBytesOffset + 1] |= appendableByte << (8 - bitsWritedToSecondByte);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t vBitBufferAppendByte(
|
||||||
|
uint8_t *destinationBitSequence,
|
||||||
|
uint16_t offsetOfFirstBit,
|
||||||
|
uint8_t appendableByte,
|
||||||
|
uint8_t countOfAppendableBits
|
||||||
|
) {
|
||||||
|
vBitBufferAppendDataByteBitsCountWithBitsOffset(
|
||||||
|
destinationBitSequence,
|
||||||
|
offsetOfFirstBit,
|
||||||
|
appendableByte,
|
||||||
|
countOfAppendableBits
|
||||||
|
);
|
||||||
|
return countOfAppendableBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t vBitBufferAppendBits(
|
||||||
|
uint8_t *destinationBitSequence,
|
||||||
|
uint16_t offsetOfFirstBit,
|
||||||
|
uint8_t *appendableData,
|
||||||
|
uint8_t countOfAppendableBits
|
||||||
|
) {
|
||||||
|
|
||||||
|
uint16_t fullBytes = countOfAppendableBits / 8;
|
||||||
|
uint16_t notFullByteBits = countOfAppendableBits % 8;
|
||||||
|
|
||||||
|
uint16_t i = 0;
|
||||||
|
for (; i < fullBytes; ++i) {
|
||||||
|
vBitBufferAppendDataByteBitsCountWithBitsOffset(
|
||||||
|
destinationBitSequence,
|
||||||
|
offsetOfFirstBit,
|
||||||
|
appendableData[i], 8
|
||||||
|
);
|
||||||
|
offsetOfFirstBit += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (notFullByteBits > 0) {
|
||||||
|
vBitBufferAppendDataByteBitsCountWithBitsOffset(
|
||||||
|
destinationBitSequence,
|
||||||
|
offsetOfFirstBit,
|
||||||
|
appendableData[i],
|
||||||
|
notFullByteBits
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return countOfAppendableBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t vBitBufferAppendBitsReverseBytes(
|
||||||
|
uint8_t *destinationBitSequence,
|
||||||
|
uint16_t offsetOfFirstBit,
|
||||||
|
uint8_t *appendableData,
|
||||||
|
uint8_t countOfAppendableBits
|
||||||
|
) {
|
||||||
|
|
||||||
|
uint16_t fullBytes = countOfAppendableBits / 8;
|
||||||
|
uint16_t notFullByteBits = countOfAppendableBits % 8;
|
||||||
|
|
||||||
|
uint16_t totalBytes = fullBytes + (notFullByteBits > 0 ? 1 : 0);
|
||||||
|
|
||||||
|
uint16_t i = 0;
|
||||||
|
for (; i < fullBytes; ++i) {
|
||||||
|
vBitBufferAppendDataByteBitsCountWithBitsOffset(
|
||||||
|
destinationBitSequence,
|
||||||
|
offsetOfFirstBit,
|
||||||
|
appendableData[(totalBytes - 1) - i],
|
||||||
|
8
|
||||||
|
);
|
||||||
|
offsetOfFirstBit += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (notFullByteBits > 0) {
|
||||||
|
vBitBufferAppendDataByteBitsCountWithBitsOffset(
|
||||||
|
destinationBitSequence,
|
||||||
|
offsetOfFirstBit,
|
||||||
|
appendableData[(totalBytes - 1) - i],
|
||||||
|
notFullByteBits
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return countOfAppendableBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t vBitBufferAppendBytesReverse(
|
||||||
|
uint8_t *destinationBitSequence,
|
||||||
|
uint16_t offsetOfFirstBit,
|
||||||
|
uint8_t *appendableData,
|
||||||
|
uint8_t countOfAppendableBytes
|
||||||
|
) {
|
||||||
|
for (int i = countOfAppendableBytes - 1; i > -1; --i) {
|
||||||
|
vBitBufferAppendDataByteBitsCountWithBitsOffset(
|
||||||
|
destinationBitSequence,
|
||||||
|
offsetOfFirstBit,
|
||||||
|
appendableData[i], 8
|
||||||
|
);
|
||||||
|
offsetOfFirstBit += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
return countOfAppendableBytes * 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* BitOps.h
|
||||||
|
*
|
||||||
|
* Created on: Apr 13, 2021
|
||||||
|
* Author: zemon
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BITOPS_INC_BITOPS_H_
|
||||||
|
#define BITOPS_INC_BITOPS_H_
|
||||||
|
|
||||||
|
#include "stdint.h"
|
||||||
|
|
||||||
|
|
||||||
|
void vBitBufferAppendDataByteBitsCountWithBitsOffset(
|
||||||
|
uint8_t *destinationBitSequence,
|
||||||
|
uint16_t offsetOfFirstBit,
|
||||||
|
uint8_t appendableByte,
|
||||||
|
uint8_t countOfAppendableBits
|
||||||
|
);
|
||||||
|
|
||||||
|
uint8_t vBitBufferAppendByte(
|
||||||
|
uint8_t *destinationBitSequence,
|
||||||
|
uint16_t offsetOfFirstBit,
|
||||||
|
uint8_t appendableByte,
|
||||||
|
uint8_t countOfAppendableBits
|
||||||
|
);
|
||||||
|
|
||||||
|
uint8_t vBitBufferAppendBits(
|
||||||
|
uint8_t *destinationBitSequence,
|
||||||
|
uint16_t offsetOfFirstBit,
|
||||||
|
uint8_t *appendableData,
|
||||||
|
uint8_t countOfAppendableBits
|
||||||
|
);
|
||||||
|
|
||||||
|
uint8_t vBitBufferAppendBitsReverseBytes(
|
||||||
|
uint8_t *destinationBitSequence,
|
||||||
|
uint16_t offsetOfFirstBit,
|
||||||
|
uint8_t *appendableData,
|
||||||
|
uint8_t countOfAppendableBits
|
||||||
|
);
|
||||||
|
|
||||||
|
uint8_t vBitBufferAppendBytesReverse(
|
||||||
|
uint8_t *destinationBitSequence,
|
||||||
|
uint16_t offsetOfFirstBit,
|
||||||
|
uint8_t *appendableData,
|
||||||
|
uint8_t countOfAppendableBytes
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* BITOPS_INC_BITOPS_H_ */
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
//
|
||||||
|
// Created by xemon on 8/23/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef MODULE_ECALLTYPES_H
|
||||||
|
#define MODULE_ECALLTYPES_H
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
AUTOMATIC_ACTIVATION = 1,
|
||||||
|
MANUAL_ACTIVATION = 0
|
||||||
|
} eEcallActivationType;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
TEST_CALL = 1,
|
||||||
|
EMERGENCY_CALL = 0
|
||||||
|
} eEcallTestMode;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
NOT_CHANGE_TIME = 2,
|
||||||
|
GNSS_TIME_SOURSE = 1,
|
||||||
|
RTC_TIME_SOURSE = 0
|
||||||
|
} eEcallTimeSourse;
|
||||||
|
|
||||||
|
#endif //MODULE_ECALLTYPES_H
|
||||||
|
|
@ -0,0 +1,534 @@
|
||||||
|
/*
|
||||||
|
* msd.c
|
||||||
|
*
|
||||||
|
* Created on: OCT 21, 2020
|
||||||
|
* Author: FICOM-IT LTD
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "EraGlonassMsd.h"
|
||||||
|
#include "BitBuffer.h"
|
||||||
|
#include <memory.h>
|
||||||
|
|
||||||
|
|
||||||
|
void EraGlonassMsdInit(tEraGlonassMsd *env) {
|
||||||
|
|
||||||
|
// env->lastPos = (tEraGlonassMsd_GpsPos) {512, 512};
|
||||||
|
|
||||||
|
//init not changeable fields
|
||||||
|
env->MSD_Data.msgId = 0;
|
||||||
|
|
||||||
|
env->MSD_Data.msdId = MSD_V_2; // MSD format version
|
||||||
|
|
||||||
|
env->MSD_Data.MSD_Control.extraData = 0x00; // Additional information not included
|
||||||
|
|
||||||
|
// aGpsStatus
|
||||||
|
env->MSD_Data.MSD_Control.recentPos1 = 0x01; // Recent vehicle position 1 available
|
||||||
|
env->MSD_Data.MSD_Control.recentPos2 = 0x01; // Recent vehicle position 2 available
|
||||||
|
|
||||||
|
env->MSD_Data.additionalData.coordSystem = ERA_GLONASS_MSD_COORDINATE_SYSTEM_TYPE_WGS84;
|
||||||
|
env->MSD_Data.additionalData.diagnosticResult = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EraGlonassMsd_ClearDiagnostic(tMSD_DiagnosticResult *env) {
|
||||||
|
memset(env, 0, sizeof(tMSD_DiagnosticResult));
|
||||||
|
}
|
||||||
|
|
||||||
|
// In case we don't have valid GPS data set defaults as described in EN15722
|
||||||
|
void EraGlonassMsdNoGnssSetDefaults(tEraGlonassMsd *env) {
|
||||||
|
env->MSD_Data.timestamp = 0x00;
|
||||||
|
env->MSD_Data.pos.lat = 0xFFFFFFFF;
|
||||||
|
env->MSD_Data.pos.lon = 0xFFFFFFFF;
|
||||||
|
// env->MSD_Data.pos.lat = 0xFFFFFFF;
|
||||||
|
// env->MSD_Data.pos.lon = 0xFFFFFFF;
|
||||||
|
env->MSD_Data.direction = 0xFF;
|
||||||
|
|
||||||
|
env->MSD_Data.MSD_PosDelta[0].lat = 512;
|
||||||
|
env->MSD_Data.MSD_PosDelta[0].lon = 512;
|
||||||
|
|
||||||
|
env->MSD_Data.MSD_PosDelta[1].lat = 512;
|
||||||
|
env->MSD_Data.MSD_PosDelta[1].lon = 512;
|
||||||
|
|
||||||
|
// aGpsStatus
|
||||||
|
env->MSD_Data.MSD_Control.recentPos1 = 0x00; // Recent vehicle position 1 available
|
||||||
|
env->MSD_Data.MSD_Control.recentPos2 = 0x00; // Recent vehicle position 2 available
|
||||||
|
}
|
||||||
|
|
||||||
|
void EraGlonassMsdSetDataEmergencySituationFlags(
|
||||||
|
tEraGlonassMsd *env,
|
||||||
|
int MSD_MSG_ID,
|
||||||
|
eEcallActivationType eCallType,
|
||||||
|
eEcallTestMode eCallTestMode
|
||||||
|
) {
|
||||||
|
// Message ID
|
||||||
|
env->MSD_Data.msgId = MSD_MSG_ID;
|
||||||
|
|
||||||
|
// Automatic or manual eCall activation
|
||||||
|
if (eCallType == AUTOMATIC_ACTIVATION) {
|
||||||
|
env->MSD_Data.MSD_Control.activation = 1;
|
||||||
|
}
|
||||||
|
if (eCallType == MANUAL_ACTIVATION) {
|
||||||
|
env->MSD_Data.MSD_Control.activation = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test eCall
|
||||||
|
if (eCallTestMode == TEST_CALL) {
|
||||||
|
env->MSD_Data.MSD_Control.testCall = 1;
|
||||||
|
}
|
||||||
|
if (eCallTestMode == EMERGENCY_CALL) {
|
||||||
|
env->MSD_Data.MSD_Control.testCall = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void EraGlonassMsdCalcPosDelta(tEraGlonassMsd *env, tEraGlonassMsd_GpsPos lastPos) {
|
||||||
|
int16_t deltaLat = 0, deltaLon = 0;
|
||||||
|
|
||||||
|
deltaLat = (lastPos.lat - env->MSD_Data.pos.lat) / 100;
|
||||||
|
deltaLon = (lastPos.lon - env->MSD_Data.pos.lon) / 100;
|
||||||
|
|
||||||
|
if (deltaLat <= -512) {
|
||||||
|
deltaLat = -512;
|
||||||
|
} else if (deltaLat >= 511) {
|
||||||
|
deltaLat = 511;
|
||||||
|
}
|
||||||
|
deltaLat += 512; // Make offset
|
||||||
|
|
||||||
|
if (deltaLon <= -512) {
|
||||||
|
deltaLon = -512;
|
||||||
|
} else if (deltaLon >= 511) {
|
||||||
|
deltaLon = 511;
|
||||||
|
}
|
||||||
|
deltaLon += 512;
|
||||||
|
|
||||||
|
|
||||||
|
env->MSD_Data.MSD_PosDelta[1].lat = env->MSD_Data.MSD_PosDelta[0].lat;
|
||||||
|
env->MSD_Data.MSD_PosDelta[1].lon = env->MSD_Data.MSD_PosDelta[0].lon;
|
||||||
|
env->MSD_Data.MSD_Control.recentPos2 = env->MSD_Data.MSD_Control.recentPos1;
|
||||||
|
|
||||||
|
env->MSD_Data.MSD_PosDelta[0].lat = deltaLat;
|
||||||
|
env->MSD_Data.MSD_PosDelta[0].lon = deltaLon;
|
||||||
|
env->MSD_Data.MSD_Control.recentPos1 = 0x01;
|
||||||
|
|
||||||
|
//Update to the latest position in order to calculate
|
||||||
|
//correctly the deltas on the next iteration
|
||||||
|
// env->lastPos.lat = env->MSD_Data.pos.lat;
|
||||||
|
// env->lastPos.lon = env->MSD_Data.pos.lon;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EraGlonassMsdSetTimeStamp(tEraGlonassMsd *env, uint32_t timestamp) {
|
||||||
|
env->MSD_Data.timestamp = timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EraGlonassMsdSetPositionValue(
|
||||||
|
tEraGlonassMsd *env,
|
||||||
|
int32_t lonArc,
|
||||||
|
int32_t latArc,
|
||||||
|
uint16_t track,
|
||||||
|
uint8_t valid
|
||||||
|
) {
|
||||||
|
|
||||||
|
tEraGlonassMsd_GpsPos lastPos = env->MSD_Data.pos;
|
||||||
|
|
||||||
|
env->MSD_Data.pos.lat = latArc;
|
||||||
|
env->MSD_Data.pos.lon = lonArc;
|
||||||
|
|
||||||
|
if (valid == 0) {
|
||||||
|
env->MSD_Data.MSD_Control.posStatus = 0x00; // False if position is not valid
|
||||||
|
env->MSD_Data.direction = 0xFF;
|
||||||
|
} else if (valid == 1){
|
||||||
|
EraGlonassMsdCalcPosDelta(env, lastPos);
|
||||||
|
env->MSD_Data.MSD_Control.posStatus = 0x00;
|
||||||
|
env->MSD_Data.direction = 0xFF;
|
||||||
|
} else if (valid == 2){
|
||||||
|
EraGlonassMsdCalcPosDelta(env, lastPos);
|
||||||
|
env->MSD_Data.MSD_Control.posStatus = 0x01;
|
||||||
|
// env->MSD_Data.direction = (track / 2); //(*255)/2
|
||||||
|
env->MSD_Data.direction = track; //(*255)/2
|
||||||
|
}
|
||||||
|
|
||||||
|
env->MSD_Data.pos.lat += 0x80000000; // Make offset
|
||||||
|
env->MSD_Data.pos.lon += 0x80000000;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void EraGlonassMsdSetPassengersNumber(tEraGlonassMsd *env, uint16_t value) {
|
||||||
|
// Check passengers number
|
||||||
|
if (value >= 1) {
|
||||||
|
env->MSD_Data.MSD_Control.passengers = value; // Passengers number available
|
||||||
|
} else {
|
||||||
|
env->MSD_Data.MSD_Control.passengers = 0x00; // Passengers number not available
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EraGlonassMsdSetVehicleType(tEraGlonassMsd *env, eUveosGostVehicleType value) {
|
||||||
|
env->MSD_Data.MSD_Control.vehicleType = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EraGlonassMsdSetVIN(tEraGlonassMsd *env, char *vin, uint8_t vinLen) {
|
||||||
|
unsigned char ch = 0, i = 0;
|
||||||
|
// Set VIN
|
||||||
|
for (i = 0; i < 17; i++) {
|
||||||
|
|
||||||
|
if (i < vinLen) {
|
||||||
|
ch = vin[i];
|
||||||
|
} else {
|
||||||
|
ch = '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ch >= '0' && ch <= '9') {
|
||||||
|
ch -= 0x30; // Numbers are encoded with valuese 0x00 to 0x09
|
||||||
|
} else if (ch >= 'A' && ch <= 'H') {
|
||||||
|
ch -= 0x37;
|
||||||
|
} else if (ch >= 'J' && ch <= 'N') {
|
||||||
|
ch -= 0x38;
|
||||||
|
} else if (ch == 'P') {
|
||||||
|
ch = 0x17;
|
||||||
|
} else if (ch >= 'R' && ch <= 'Z') {
|
||||||
|
ch -= 0x3A;
|
||||||
|
} else {
|
||||||
|
ch = '0' - 0x30;
|
||||||
|
}
|
||||||
|
|
||||||
|
env->MSD_Data.vin[i] = ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EraGlonassMsdSetPropulsionStorageType(
|
||||||
|
tEraGlonassMsd *env,
|
||||||
|
eUveosGostVehiclePropulsionStorageType value
|
||||||
|
) {
|
||||||
|
env->MSD_Data.MSD_Control.includedTanks = 0b01111111; // Enable all tank type to be transmitted
|
||||||
|
|
||||||
|
// Set propulsion system storage
|
||||||
|
env->MSD_Data.propulsion = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t sEraGlonassMsdEncodeOfControl(tEraGlonassMsd_DataTypedef *data, unsigned char *raw, uint16_t lastBit) {
|
||||||
|
lastBit += vBitBufferAppendByte(raw, lastBit, data->msgId, 8);
|
||||||
|
|
||||||
|
lastBit += vBitBufferAppendByte(raw, lastBit, data->MSD_Control.activation ? 0x01 : 0x00, 1);
|
||||||
|
lastBit += vBitBufferAppendByte(raw, lastBit, data->MSD_Control.testCall ? 0x01 : 0x00, 1);
|
||||||
|
lastBit += vBitBufferAppendByte(raw, lastBit, data->MSD_Control.posStatus ? 0x01 : 0x00, 1);
|
||||||
|
|
||||||
|
lastBit += vBitBufferAppendByte(raw, lastBit, data->MSD_Control.vehicleType, 5);
|
||||||
|
|
||||||
|
return lastBit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t sEraGlonassMsdEncodeOfVin(tEraGlonassMsd_DataTypedef *data, unsigned char *raw, uint16_t lastBit) {
|
||||||
|
for (int i = 0; i < 17; ++i) {
|
||||||
|
lastBit += vBitBufferAppendByte(raw, lastBit, ((uint8_t) data->vin[i]), 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
return lastBit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t sEraGlonassMsdEncodeOfPropulsion(tEraGlonassMsd_DataTypedef *data, unsigned char *raw, uint16_t lastBit) {
|
||||||
|
|
||||||
|
uint8_t maxCountOfTanks;
|
||||||
|
|
||||||
|
if (data->msdId == MSD_V_1) {
|
||||||
|
maxCountOfTanks = 6;
|
||||||
|
} else if (data->msdId == MSD_V_2) {
|
||||||
|
maxCountOfTanks = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t tanksInfoIncluded = !(data->MSD_Control.includedTanks >> maxCountOfTanks) && 0x1;
|
||||||
|
|
||||||
|
if (tanksInfoIncluded) {
|
||||||
|
lastBit += vBitBufferAppendByte(raw, lastBit, data->MSD_Control.includedTanks, maxCountOfTanks + 1);
|
||||||
|
|
||||||
|
for (int i = 0; i < maxCountOfTanks; ++i) {
|
||||||
|
if ((data->MSD_Control.includedTanks >> i) && 0x1) {
|
||||||
|
lastBit += vBitBufferAppendByte(raw, lastBit, (data->propulsion >> i), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lastBit += vBitBufferAppendByte(raw, lastBit, 0x1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return lastBit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t sEraGlonassMsdEncodeOfTimestamp(tEraGlonassMsd_DataTypedef *data, unsigned char *raw, uint16_t lastBit) {
|
||||||
|
lastBit += vBitBufferAppendBitsReverseBytes(raw, lastBit, (uint8_t *) &data->timestamp, 32);
|
||||||
|
|
||||||
|
return lastBit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t sEraGlonassMsdEncodeOfLocation(tEraGlonassMsd_DataTypedef *data, unsigned char *raw, uint16_t lastBit) {
|
||||||
|
|
||||||
|
lastBit += vBitBufferAppendBitsReverseBytes(raw, lastBit, (uint8_t *) &data->pos.lat, 32);
|
||||||
|
lastBit += vBitBufferAppendBitsReverseBytes(raw, lastBit, (uint8_t *) &data->pos.lon, 32);
|
||||||
|
|
||||||
|
return lastBit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t sEraGlonassMsdEncodeOfDirection(tEraGlonassMsd_DataTypedef *data, unsigned char *raw, uint16_t lastBit) {
|
||||||
|
\
|
||||||
|
lastBit += vBitBufferAppendByte(raw, lastBit, data->direction, 8);
|
||||||
|
|
||||||
|
return lastBit;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t sEraGlonassMsdEncodeOfRecentPositions(tEraGlonassMsd_DataTypedef *data, unsigned char *raw, uint16_t lastBit) {
|
||||||
|
\
|
||||||
|
if (data->MSD_Control.recentPos1) {
|
||||||
|
lastBit += vBitBufferAppendBits(raw, lastBit, (uint8_t *) &data->MSD_PosDelta[0].lat, 10);
|
||||||
|
lastBit += vBitBufferAppendBits(raw, lastBit, (uint8_t *) &data->MSD_PosDelta[0].lon, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->MSD_Control.recentPos2) {
|
||||||
|
lastBit += vBitBufferAppendBits(raw, lastBit, (uint8_t *) &data->MSD_PosDelta[1].lat, 10);
|
||||||
|
lastBit += vBitBufferAppendBits(raw, lastBit, (uint8_t *) &data->MSD_PosDelta[1].lon, 10);
|
||||||
|
}
|
||||||
|
return lastBit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t sEraGlonassMsdEncodeOfPassengersCount(tEraGlonassMsd_DataTypedef *data, unsigned char *raw, uint16_t lastBit) {
|
||||||
|
|
||||||
|
if (data->MSD_Control.passengers) {
|
||||||
|
lastBit += vBitBufferAppendBits(raw, lastBit, (uint8_t *) &data->MSD_Control.passengers, 8);
|
||||||
|
}
|
||||||
|
return lastBit;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t sEraGlonassMsdEncodeOfV1FreeSpaceFix(tEraGlonassMsd_DataTypedef *data, unsigned char *raw, uint16_t lastBit) {
|
||||||
|
|
||||||
|
if (data->msdId == MSD_V_1) {
|
||||||
|
lastBit += vBitBufferAppendByte(raw, lastBit, 0x00, 8);
|
||||||
|
}
|
||||||
|
return lastBit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t
|
||||||
|
sEraGlonassMsdEncodeOfAdditionalDataOID(tEraGlonassMsd_DataTypedef *data, unsigned char *raw, uint16_t lastBit) {
|
||||||
|
lastBit += vBitBufferAppendByte(raw, lastBit, 0x03, 8);//lent of OID
|
||||||
|
|
||||||
|
lastBit += vBitBufferAppendByte(raw, lastBit, 0x01, 8);//OID 1
|
||||||
|
lastBit += vBitBufferAppendByte(raw, lastBit, 0x04, 8);//OID 2
|
||||||
|
|
||||||
|
if (data->msdId == MSD_V_1) {
|
||||||
|
lastBit += vBitBufferAppendByte(raw, lastBit, 0x01, 8);//OID 3
|
||||||
|
} else if (data->msdId == MSD_V_2) {
|
||||||
|
lastBit += vBitBufferAppendByte(raw, lastBit, 0x02, 8);//OID 3
|
||||||
|
}
|
||||||
|
|
||||||
|
return lastBit;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MSD_TO_RAW_ADD_OPTIONAL_FLAG_PRESENT(FLAG) lastBit += vBitBufferAppendByte(raw, lastBit, (FLAG) == ERA_GLONASS_MSD_OPTIONAL_FLAG_ABSENT ? 0b0 : 0b1, 1);
|
||||||
|
|
||||||
|
#define MSD_TO_RAW_ADD_OPTIONAL_FLAG_VALUE(FLAG) \
|
||||||
|
if((FLAG) == ERA_GLONASS_MSD_OPTIONAL_FLAG_PRESENT_TRUE) { lastBit += vBitBufferAppendByte(raw, lastBit, 0b1 , 1);} \
|
||||||
|
else if((FLAG) == ERA_GLONASS_MSD_OPTIONAL_FLAG_PRESENT_FALSE) { lastBit += vBitBufferAppendByte(raw, lastBit, 0b0, 1);}
|
||||||
|
|
||||||
|
uint16_t sEraGlonassMsdEncodeOfAdditionalDataPayload(
|
||||||
|
tEraGlonassMsd_DataTypedef *data, unsigned char *raw, uint16_t lastBit
|
||||||
|
) {
|
||||||
|
|
||||||
|
lastBit += vBitBufferAppendByte(raw, lastBit, 0b0, 1); // enable extendable
|
||||||
|
//enable what present
|
||||||
|
lastBit += vBitBufferAppendByte(raw, lastBit, data->additionalData.asi15Present ? 0b1 : 0b0, 1);
|
||||||
|
lastBit += vBitBufferAppendByte(raw, lastBit, data->additionalData.diagnosticResult ? 0b1 : 0b0, 1);
|
||||||
|
lastBit += vBitBufferAppendByte(raw, lastBit, data->additionalData.crashInfoPresent ? 0b1 : 0b0, 1);
|
||||||
|
|
||||||
|
if (data->msdId == MSD_V_2) {
|
||||||
|
lastBit += vBitBufferAppendByte(raw, lastBit, data->additionalData.coordSystem ? 0b1 : 0b0,
|
||||||
|
1); // enable extendable
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->additionalData.asi15Present) {
|
||||||
|
lastBit += vBitBufferAppendByte(raw, lastBit, ((uint8_t *) &data->additionalData.asi15)[1], 3);
|
||||||
|
lastBit += vBitBufferAppendByte(raw, lastBit, ((uint8_t *) &data->additionalData.asi15)[0], 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->additionalData.diagnosticResult) {
|
||||||
|
tMSD_DiagnosticResult *diagRes = data->additionalData.diagnosticResult;
|
||||||
|
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_PRESENT(diagRes->micConnectionFailure);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_PRESENT(diagRes->micFailure);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_PRESENT(diagRes->rightSpeakerFailure);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_PRESENT(diagRes->leftSpeakerFailure);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_PRESENT(diagRes->speakersFailure);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_PRESENT(diagRes->ignitionLineFailure);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_PRESENT(diagRes->uimFailure);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_PRESENT(diagRes->statusIndicatorFailure);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_PRESENT(diagRes->batteryFailure);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_PRESENT(diagRes->batteryVoltageLow);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_PRESENT(diagRes->crashSensorFailure);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_PRESENT(diagRes->firmwareImageCorruption);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_PRESENT(diagRes->commModuleInterfaceFailure);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_PRESENT(diagRes->gnssReceiverFailure);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_PRESENT(diagRes->raimProblem);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_PRESENT(diagRes->gnssAntennaFailure);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_PRESENT(diagRes->commModuleFailure);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_PRESENT(diagRes->eventsMemoryOverflow);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_PRESENT(diagRes->crashProfileMemoryOverflow);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_PRESENT(diagRes->otherCriticalFailures);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_PRESENT(diagRes->otherNotCriticalFailures);
|
||||||
|
|
||||||
|
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_VALUE(diagRes->micConnectionFailure);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_VALUE(diagRes->micFailure);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_VALUE(diagRes->rightSpeakerFailure);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_VALUE(diagRes->leftSpeakerFailure);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_VALUE(diagRes->speakersFailure);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_VALUE(diagRes->ignitionLineFailure);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_VALUE(diagRes->uimFailure);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_VALUE(diagRes->statusIndicatorFailure);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_VALUE(diagRes->batteryFailure);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_VALUE(diagRes->batteryVoltageLow);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_VALUE(diagRes->crashSensorFailure);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_VALUE(diagRes->firmwareImageCorruption);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_VALUE(diagRes->commModuleInterfaceFailure);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_VALUE(diagRes->gnssReceiverFailure);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_VALUE(diagRes->raimProblem);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_VALUE(diagRes->gnssAntennaFailure);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_VALUE(diagRes->commModuleFailure);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_VALUE(diagRes->eventsMemoryOverflow);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_VALUE(diagRes->crashProfileMemoryOverflow);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_VALUE(diagRes->otherCriticalFailures);
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_VALUE(diagRes->otherNotCriticalFailures);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->additionalData.crashInfoPresent) {
|
||||||
|
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_PRESENT(data->additionalData.crashInfo.CrashFront)
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_PRESENT(data->additionalData.crashInfo.CrashLeftSide)
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_PRESENT(data->additionalData.crashInfo.CrashRightSide)
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_PRESENT(data->additionalData.crashInfo.CrashRear)
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_PRESENT(data->additionalData.crashInfo.CrashWithRollover)
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_PRESENT(data->additionalData.crashInfo.CrashSide)
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_PRESENT(data->additionalData.crashInfo.CrashFrontOrSide)
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_PRESENT(data->additionalData.crashInfo.CrashOtherType)
|
||||||
|
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_VALUE(data->additionalData.crashInfo.CrashFront)
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_VALUE(data->additionalData.crashInfo.CrashLeftSide)
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_VALUE(data->additionalData.crashInfo.CrashRightSide)
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_VALUE(data->additionalData.crashInfo.CrashRear)
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_VALUE(data->additionalData.crashInfo.CrashWithRollover)
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_VALUE(data->additionalData.crashInfo.CrashSide)
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_VALUE(data->additionalData.crashInfo.CrashFrontOrSide)
|
||||||
|
MSD_TO_RAW_ADD_OPTIONAL_FLAG_VALUE(data->additionalData.crashInfo.CrashOtherType)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->msdId == MSD_V_2) {
|
||||||
|
lastBit += vBitBufferAppendByte(raw, lastBit, data->additionalData.coordSystem, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return lastBit;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t sEraGlonassMsdEncodeOfAdditionalDataOctetString(
|
||||||
|
tEraGlonassMsd_DataTypedef *data, unsigned char *raw, uint16_t lastBit
|
||||||
|
) {
|
||||||
|
|
||||||
|
uint16_t octetStringOffset = lastBit + 8;
|
||||||
|
|
||||||
|
uint16_t octetStringBitsLength =
|
||||||
|
sEraGlonassMsdEncodeOfAdditionalDataPayload(data, raw, octetStringOffset) - (octetStringOffset);
|
||||||
|
|
||||||
|
uint8_t octetsCount = octetStringBitsLength / 8 + (octetStringBitsLength % 8 ? 1 : 0);
|
||||||
|
|
||||||
|
lastBit += vBitBufferAppendByte(raw, lastBit, octetsCount, 8);
|
||||||
|
lastBit += octetsCount * 8;
|
||||||
|
|
||||||
|
return lastBit;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t sEraGlonassMsdEncodeOfAdditionalData(tEraGlonassMsd_DataTypedef *data, unsigned char *raw, uint16_t lastBit) {
|
||||||
|
|
||||||
|
lastBit = sEraGlonassMsdEncodeOfAdditionalDataOID(data, raw, lastBit);
|
||||||
|
lastBit = sEraGlonassMsdEncodeOfAdditionalDataOctetString(data, raw, lastBit);
|
||||||
|
|
||||||
|
return lastBit;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t sEraGlonassMsdEncodeOfMsdMainBody(tEraGlonassMsd_DataTypedef *data, unsigned char *raw, uint16_t lastBit) {
|
||||||
|
|
||||||
|
lastBit += vBitBufferAppendByte(raw, lastBit, 0b0, 1);
|
||||||
|
lastBit += vBitBufferAppendByte(raw, lastBit, data->additionalDataPresent ? 0b1 : 0b0, 1);
|
||||||
|
lastBit += vBitBufferAppendByte(raw, lastBit, 0b0, 1);
|
||||||
|
// lastBit+= vBitBufferAppendByte(raw,lastBit,data->MSD_Control.extraData,3);
|
||||||
|
lastBit += vBitBufferAppendByte(raw, lastBit, data->MSD_Control.recentPos1 ? 0x01 : 0x00, 1);
|
||||||
|
lastBit += vBitBufferAppendByte(raw, lastBit, data->MSD_Control.recentPos2 ? 0x01 : 0x00, 1);
|
||||||
|
lastBit += vBitBufferAppendByte(raw, lastBit, data->MSD_Control.passengers ? 0x01 : 0x00, 1);
|
||||||
|
|
||||||
|
lastBit = sEraGlonassMsdEncodeOfControl(data, raw, lastBit);
|
||||||
|
lastBit = sEraGlonassMsdEncodeOfVin(data, raw, lastBit);
|
||||||
|
lastBit = sEraGlonassMsdEncodeOfPropulsion(data, raw, lastBit);
|
||||||
|
|
||||||
|
lastBit = sEraGlonassMsdEncodeOfV1FreeSpaceFix(data, raw, lastBit);
|
||||||
|
|
||||||
|
lastBit = sEraGlonassMsdEncodeOfTimestamp(data, raw, lastBit);
|
||||||
|
lastBit = sEraGlonassMsdEncodeOfLocation(data, raw, lastBit);
|
||||||
|
lastBit = sEraGlonassMsdEncodeOfDirection(data, raw, lastBit);
|
||||||
|
lastBit = sEraGlonassMsdEncodeOfRecentPositions(data, raw, lastBit);
|
||||||
|
lastBit = sEraGlonassMsdEncodeOfPassengersCount(data, raw, lastBit);
|
||||||
|
|
||||||
|
if (data->additionalDataPresent) {
|
||||||
|
lastBit = sEraGlonassMsdEncodeOfAdditionalData(data, raw, lastBit);
|
||||||
|
}
|
||||||
|
|
||||||
|
return lastBit;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t sEraGlonassMsdEncodeV2BodyOctetString(tEraGlonassMsd_DataTypedef *data, unsigned char *raw, uint16_t lastBit) {
|
||||||
|
|
||||||
|
//length of msd block
|
||||||
|
uint16_t octetStringOffset = lastBit + 8;
|
||||||
|
uint16_t octetStringBitsLength =
|
||||||
|
sEraGlonassMsdEncodeOfMsdMainBody(data, raw, octetStringOffset) - (octetStringOffset);
|
||||||
|
uint8_t octetsCount = octetStringBitsLength / 8 + (octetStringBitsLength % 8 ? 1 : 0);
|
||||||
|
|
||||||
|
lastBit += vBitBufferAppendByte(raw, lastBit, octetsCount, 8);
|
||||||
|
|
||||||
|
lastBit += octetsCount * 8;
|
||||||
|
|
||||||
|
return lastBit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t EraGlonassMsdEncode(tEraGlonassMsd *env, eEraGlonassMsd_Version msdVersion, uint8_t *encoded) {
|
||||||
|
env->MSD_Data.msdId = msdVersion;
|
||||||
|
|
||||||
|
memset(encoded, '\0', ERA_GLONASS_MSD_ENCODED_BUFFER_LENGTH); // Clear
|
||||||
|
|
||||||
|
uint16_t lastBit = 0;
|
||||||
|
|
||||||
|
lastBit += vBitBufferAppendByte(encoded, lastBit, env->MSD_Data.msdId, 8);
|
||||||
|
|
||||||
|
if (env->MSD_Data.msdId == MSD_V_1) {
|
||||||
|
lastBit = sEraGlonassMsdEncodeOfMsdMainBody(&env->MSD_Data, encoded, lastBit);
|
||||||
|
} else if (env->MSD_Data.msdId == MSD_V_2) {
|
||||||
|
lastBit = sEraGlonassMsdEncodeV2BodyOctetString(&env->MSD_Data, encoded, lastBit);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t byteLength = lastBit / 8 + (lastBit % 8 ? 1 : 0);
|
||||||
|
return byteLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,177 @@
|
||||||
|
/*
|
||||||
|
* msd.h
|
||||||
|
*
|
||||||
|
* Created on: Oct 20, 2020
|
||||||
|
* Author: FICOM-IT LTD
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INC_MSD_H_
|
||||||
|
#define INC_MSD_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <UveosGostSettingsTypes.h>
|
||||||
|
#include "EcallTypes.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define ERA_GLONASS_MSD_ENCODED_BUFFER_LENGTH 128
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MSD_V_1 = 1,
|
||||||
|
MSD_V_2 = 2,
|
||||||
|
} eEraGlonassMsd_Version;
|
||||||
|
|
||||||
|
|
||||||
|
// @brief Control and status data
|
||||||
|
typedef struct {
|
||||||
|
uint16_t extraData; // 000 - additional data excluded, 010 - additional data included
|
||||||
|
uint16_t recentPos1; // True if previous location is available
|
||||||
|
uint16_t recentPos2; // True if previous location is available
|
||||||
|
uint16_t passengers; // True if passangers' number is available
|
||||||
|
uint16_t activation; // True if Automatic, False if manual eCall activation
|
||||||
|
uint16_t testCall; // True if test eCall, Flase if not test eCall
|
||||||
|
uint16_t posStatus; // True if GPS position can be trusted
|
||||||
|
uint16_t vehicleType; // Vehicle identification according to 2007/46/EC, 2002/24/EC
|
||||||
|
uint16_t includedTanks; // if True include status data (present/not present) for the relevant tank
|
||||||
|
} tEraGlonassMsd_Control;
|
||||||
|
|
||||||
|
// @brief Vehicle location stored in milli-arc-second
|
||||||
|
typedef struct {
|
||||||
|
int32_t lat; // Position latitude
|
||||||
|
int32_t lon; // Position longitude
|
||||||
|
} tEraGlonassMsd_GpsPos;
|
||||||
|
|
||||||
|
// @brief Vehicle location difference with the previous location stored in milli-arc-second
|
||||||
|
typedef struct {
|
||||||
|
uint16_t lat;
|
||||||
|
uint16_t lon;
|
||||||
|
} tEraGlonassMsd_PosDelta;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
ERA_GLONASS_MSD_OPTIONAL_FLAG_ABSENT = 0,
|
||||||
|
ERA_GLONASS_MSD_OPTIONAL_FLAG_PRESENT_TRUE = 1,
|
||||||
|
ERA_GLONASS_MSD_OPTIONAL_FLAG_PRESENT_FALSE = 2,
|
||||||
|
} tEraGlonassMsd_OptionalFlagState;
|
||||||
|
|
||||||
|
typedef uint8_t tEraGlonassMsd_OptionalFlag;
|
||||||
|
|
||||||
|
#define EraGlonassMsd_OptionalFlagClear(FLAG) (GLAG) = ERA_GLONASS_MSD_OPTIONAL_FLAG_ABSENT
|
||||||
|
#define EraGlonassMsd_OptionalFlagSet(FLAG, VALUE) (FLAG) = (VALUE) ? ERA_GLONASS_MSD_OPTIONAL_FLAG_PRESENT_TRUE : ERA_GLONASS_MSD_OPTIONAL_FLAG_PRESENT_FALSE
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
tEraGlonassMsd_OptionalFlag CrashFront;
|
||||||
|
tEraGlonassMsd_OptionalFlag CrashLeftSide;
|
||||||
|
tEraGlonassMsd_OptionalFlag CrashRightSide;
|
||||||
|
tEraGlonassMsd_OptionalFlag CrashRear;
|
||||||
|
tEraGlonassMsd_OptionalFlag CrashWithRollover;
|
||||||
|
tEraGlonassMsd_OptionalFlag CrashSide;
|
||||||
|
tEraGlonassMsd_OptionalFlag CrashFrontOrSide;
|
||||||
|
tEraGlonassMsd_OptionalFlag CrashOtherType;
|
||||||
|
} tMSD_CrashInfo;
|
||||||
|
|
||||||
|
#define EraGlonassMsd_CrashInfoClear(ENV) memset(ENV, 0, sizeof(tMSD_CrashInfo))
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
tEraGlonassMsd_OptionalFlag micConnectionFailure;
|
||||||
|
tEraGlonassMsd_OptionalFlag micFailure;
|
||||||
|
tEraGlonassMsd_OptionalFlag rightSpeakerFailure;
|
||||||
|
tEraGlonassMsd_OptionalFlag leftSpeakerFailure;
|
||||||
|
tEraGlonassMsd_OptionalFlag speakersFailure;
|
||||||
|
tEraGlonassMsd_OptionalFlag ignitionLineFailure;
|
||||||
|
tEraGlonassMsd_OptionalFlag uimFailure;
|
||||||
|
tEraGlonassMsd_OptionalFlag statusIndicatorFailure;
|
||||||
|
tEraGlonassMsd_OptionalFlag batteryFailure;
|
||||||
|
tEraGlonassMsd_OptionalFlag batteryVoltageLow;
|
||||||
|
tEraGlonassMsd_OptionalFlag crashSensorFailure;
|
||||||
|
tEraGlonassMsd_OptionalFlag firmwareImageCorruption;
|
||||||
|
tEraGlonassMsd_OptionalFlag commModuleInterfaceFailure;
|
||||||
|
tEraGlonassMsd_OptionalFlag gnssReceiverFailure;
|
||||||
|
tEraGlonassMsd_OptionalFlag raimProblem;
|
||||||
|
tEraGlonassMsd_OptionalFlag gnssAntennaFailure;
|
||||||
|
tEraGlonassMsd_OptionalFlag commModuleFailure;
|
||||||
|
tEraGlonassMsd_OptionalFlag eventsMemoryOverflow;
|
||||||
|
tEraGlonassMsd_OptionalFlag crashProfileMemoryOverflow;
|
||||||
|
tEraGlonassMsd_OptionalFlag otherCriticalFailures;
|
||||||
|
tEraGlonassMsd_OptionalFlag otherNotCriticalFailures;
|
||||||
|
} tMSD_DiagnosticResult;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
ERA_GLONASS_MSD_COORDINATE_SYSTEM_TYPE_WGS84 = 0x01,
|
||||||
|
ERA_GLONASS_MSD_COORDINATE_SYSTEM_TYPE_PZ90 = 0x02,
|
||||||
|
} eEraGlonassMsd_CoordinateSystemType;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool asi15Present;
|
||||||
|
bool crashInfoPresent;
|
||||||
|
|
||||||
|
uint16_t asi15;
|
||||||
|
tMSD_CrashInfo crashInfo;
|
||||||
|
eEraGlonassMsd_CoordinateSystemType coordSystem;
|
||||||
|
tMSD_DiagnosticResult *diagnosticResult;
|
||||||
|
} tEraGlonassMsd_AdditionalData;
|
||||||
|
|
||||||
|
|
||||||
|
// @brief MSD data structure
|
||||||
|
typedef struct {
|
||||||
|
uint16_t msdId; // MSD format version set to 1
|
||||||
|
uint16_t msgId; // Message identifier, starting with 1 for each new eCall session
|
||||||
|
tEraGlonassMsd_Control MSD_Control; // Control flags and data
|
||||||
|
uint16_t vin[18]; // VIN
|
||||||
|
uint16_t propulsion; // Vehicle propulsion storage type
|
||||||
|
uint32_t timestamp; // Timestamp
|
||||||
|
tEraGlonassMsd_GpsPos pos; // Vehicle position
|
||||||
|
uint8_t direction; // Vehicle heading, course over ground, course over north
|
||||||
|
tEraGlonassMsd_PosDelta MSD_PosDelta[2]; // Previous position delta
|
||||||
|
|
||||||
|
bool additionalDataPresent;
|
||||||
|
tEraGlonassMsd_AdditionalData additionalData; // Additional data
|
||||||
|
} tEraGlonassMsd_DataTypedef;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
tEraGlonassMsd_DataTypedef MSD_Data;
|
||||||
|
// tEraGlonassMsd_GpsPos lastPos;
|
||||||
|
} tEraGlonassMsd;
|
||||||
|
|
||||||
|
|
||||||
|
//Must be called on create
|
||||||
|
void EraGlonassMsdInit(tEraGlonassMsd *env);
|
||||||
|
|
||||||
|
void EraGlonassMsd_ClearDiagnostic(tMSD_DiagnosticResult *env);
|
||||||
|
|
||||||
|
//Must be called when settings changed
|
||||||
|
void EraGlonassMsdSetPassengersNumber(tEraGlonassMsd *env, uint16_t value);
|
||||||
|
|
||||||
|
void EraGlonassMsdSetVehicleType(tEraGlonassMsd *env, eUveosGostVehicleType value);
|
||||||
|
|
||||||
|
void EraGlonassMsdSetVIN(tEraGlonassMsd *env, char *vin, uint8_t vinLen);
|
||||||
|
|
||||||
|
void EraGlonassMsdSetPropulsionStorageType(tEraGlonassMsd *env, eUveosGostVehiclePropulsionStorageType value);
|
||||||
|
|
||||||
|
//Must be called when gnss data changed
|
||||||
|
void EraGlonassMsdSetTimeStamp(tEraGlonassMsd *env, uint32_t timestamp);
|
||||||
|
|
||||||
|
void EraGlonassMsdSetPositionValue(
|
||||||
|
tEraGlonassMsd *env,
|
||||||
|
int32_t lonArc,
|
||||||
|
int32_t latArc,
|
||||||
|
uint16_t track,
|
||||||
|
uint8_t valid
|
||||||
|
);
|
||||||
|
|
||||||
|
void EraGlonassMsdNoGnssSetDefaults(tEraGlonassMsd *env);
|
||||||
|
|
||||||
|
|
||||||
|
//Called on emergency situation
|
||||||
|
void EraGlonassMsdSetDataEmergencySituationFlags(
|
||||||
|
tEraGlonassMsd *env,
|
||||||
|
int MSD_MSG_ID,
|
||||||
|
eEcallActivationType eCallType,
|
||||||
|
eEcallTestMode eCallTestMode
|
||||||
|
);
|
||||||
|
|
||||||
|
uint16_t EraGlonassMsdEncode(tEraGlonassMsd *env, eEraGlonassMsd_Version msdVersion, uint8_t *encoded);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* INC_MSD_H_ */
|
||||||
|
|
@ -0,0 +1,104 @@
|
||||||
|
/*
|
||||||
|
* UVEOS_GOST_Settings.h
|
||||||
|
*
|
||||||
|
* Created on: Apr 12, 2021
|
||||||
|
* Author: zemon
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INC_UVEOS_GOST_SETTINGS_H_
|
||||||
|
#define INC_UVEOS_GOST_SETTINGS_H_
|
||||||
|
|
||||||
|
#include "stdint.h"
|
||||||
|
#include "stdbool.h"
|
||||||
|
#include "BaseTypes.h"
|
||||||
|
#include <UveosGostSettingsTypes.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool ECALL_TEST_MODE; //совершать все вызовы на тестовый номер
|
||||||
|
uint8_t FULL_POWER_OFF_TIME;
|
||||||
|
uint16_t BIP_BACKLIGHT_MODE;
|
||||||
|
uint16_t BIP_GREEN_LED_POWER_MODE;
|
||||||
|
uint16_t BIP_RED_LED_POWER_MODE;
|
||||||
|
} tUveosNotGostSettings;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
|
||||||
|
//Radio settings
|
||||||
|
uint16_t RADIO_MUTE_DELAY; //*(МС) Задержка между установкой сигнала «радио mute» и началом проигрывания звука
|
||||||
|
uint16_t RADIO_UNMUTE_DELAY; //*(МС) Задержка между снятием сигнала «радио mute» и окончанием проигрывания звукае
|
||||||
|
|
||||||
|
//настройки сробатывания
|
||||||
|
uint8_t CRASH_SIGNAL_INTERNAL; //* Только транспортные средства категорий М1 и N1 — для определения события аварии используется встроенный измеритель ускорения
|
||||||
|
uint8_t CRASH_SIGNAL_EXTERNAL; //* Только транспортные средства категорий М1 и N1 — для определения факта ДТП используется внешний датчик в транспортном средстве
|
||||||
|
float ASI15_TRESHOLD; //* Только транспортные средства категорий М1 и N1 — порог срабатывания датчика автоматической идентификации события ДТП
|
||||||
|
uint16_t SOS_BUTTON_TIME; //* (МС) Время нажатия на кнопку «Экстренный вызов» для активации режима «Экстренный вызов»
|
||||||
|
uint8_t ECALL_NO_AUTOMATIC_TRIGGERING; //Параметр используется для отмены функции автоматической инициации экстренного вызова
|
||||||
|
|
||||||
|
//Параметры дозвона
|
||||||
|
tString16 ECALL_TEST_NUMBER; //номер для тестового вызова
|
||||||
|
uint16_t CCFT; //(МИН) Длительность счетчика автоматического прекращения звонка (60 м)
|
||||||
|
uint16_t ECALL_DIAL_DURATION; //(МИН) Общая продолжительность дозвона при инициации экстренного вызова
|
||||||
|
uint64_t MSD_MAX_TRANSMISSION_TIME; //(CEK) Максимальная длительность передачи MSD (20 с)
|
||||||
|
uint8_t ECALL_MANUAL_CAN_CANCEL; //TRUE — экстренный вызов, инициированный вручную, может быть прекращен со стороны пользователя
|
||||||
|
|
||||||
|
//Ожидание
|
||||||
|
uint64_t CALL_AUTO_ANSWER_TIME; //(МИН)Промежуток времени после завершения экстренного вызова, в течение которого УСВ автоматически отвечает на входящие звонки
|
||||||
|
|
||||||
|
//Веремя регестрации в сети
|
||||||
|
uint64_t NAD_DEREGISTRATION_TIME; //(МИН) Время, после которого коммуникационный модуль GSM и UMTS прекращает регистрацию в сети
|
||||||
|
uint64_t POST_TEST_REGISTRATION_TIME; //Промежуток времени, в течение которого УСВ остается зарегистрированной в сети после передачи результатов тестирования оператору системы
|
||||||
|
|
||||||
|
//Оптравка экстренных ситуаций из памяти
|
||||||
|
tString16 ECALL_SMS_FALLBACK_NUMBER; //Номер, по которому УСВ посылает SMS с МНД при ошибке передачи МНД посредством in-band модема и по запросу от оператора системы. Определяется оператором национальной системы реагирования на аварии
|
||||||
|
uint64_t INT_MEM_TRANSMIT_INTERVAL; //интервал времени между повторными попытками отправки мнд из памяти
|
||||||
|
uint16_t INT_MEM_TRANSMIT_ATTEMPTS; //количество попыток отпкравки мнд из памяти
|
||||||
|
|
||||||
|
//Попытки дозвона
|
||||||
|
uint16_t ECALL_AUTO_DIAL_ATTEMPTS; //Только транспортные средства категорий М1 и N1 — число попыток дозвона при автоматически инициированном экстренном вызове. Не может быть установлено в «0»
|
||||||
|
uint16_t ECALL_MANUAL_DIAL_ATTEMPTS; //Число попыток дозвона при экстренном вызове, инициированном вручную. Значение не может устанавливаться в «0»
|
||||||
|
|
||||||
|
|
||||||
|
//Testing settings - тестирование и гараж
|
||||||
|
// Если УСВ была зарегистрирована в сети посредством нажатия на кнопку «Дополнительные функции»,
|
||||||
|
// то последующая регистрация УСВ в сети при нажатии на кнопку «Дополнительные функции» возможна
|
||||||
|
// не ранее чем через данный промежуток времени. Если значение установлено в «0»,
|
||||||
|
// то ограничений на последующую регистрацию УСВ в сети не накладывается
|
||||||
|
uint16_t TEST_REGISTRATION_PERIOD;
|
||||||
|
uint16_t TEST_MODE_END_DISTANCE; //(Метры)Дистанция, на которой режим тестирования выключается автоматически
|
||||||
|
uint16_t GARAGE_MODE_END_DISTANCE; //*(Метры) Дистанция, на которой режим «Автосервис» выключается автоматически
|
||||||
|
|
||||||
|
|
||||||
|
//Emergence acceleration profile - полностью используеться в коплектации доп оборудования
|
||||||
|
uint16_t IGNITION_OFF_FOLLOW_UP_TIME1; //* Промежуток времени, в течение которого осуществляется запись профиля ускорения при ДТП при выключенном зажигании
|
||||||
|
uint16_t IGNITION_OFF_FOLLOW_UP_TIME2; //* Промежуток времени, в течение которого осуществляется определение события аварии при выключенном зажигании
|
||||||
|
uint16_t CRASH_RECORD_TIME; //* Время записи информации о профиле ускорения при ДТП
|
||||||
|
uint16_t CRASH_RECORD_RESOLUTION; //* Дискретность записи профиля ускорения при ДТП
|
||||||
|
uint16_t CRASH_PRE_RECORD_TIME; //* Время записи информации о профиле ускорения до того, как событие ДТП наступило
|
||||||
|
uint16_t CRASH_PRE_RECORD_RESOLUTION; //* Продолжительность одного отсчета при записи профиля ускорения до того, как событие ДТП наступило
|
||||||
|
|
||||||
|
|
||||||
|
//Other settings - параметры навигацонного приемника - используються при инициализации приемника, а так же записываются в него после их изменения (все без участия УВЕОС,платформозависомо)
|
||||||
|
uint16_t GNSS_POWER_OFF_TIME; //* Промежуток времени, через который отключается питание приемника ГНСС после выключения зажигания
|
||||||
|
uint16_t GNSS_DATA_RATE; //Темп выдачи данных приемником ГНСС
|
||||||
|
uint16_t GNSS_MIN_ELEVATION; //* Минимальное значение угла возвышения (угла отсечки) навигационных космических аппаратов
|
||||||
|
|
||||||
|
|
||||||
|
//Vehicle parameters - Параметры транспортного средства, записываються в МНД
|
||||||
|
tString32 VIN; //18
|
||||||
|
|
||||||
|
uint16_t VEHICLE_TYPE; //Категория транспортного средства
|
||||||
|
uint8_t VEHICLE_PROPULSION_STORAGE_TYPE; //Тип энергоносителя
|
||||||
|
uint8_t VEHICLE_PASSENGERS_NUMBER; //Количество пасажиров
|
||||||
|
|
||||||
|
|
||||||
|
//неиспользуються, у нас пины определены заранее
|
||||||
|
uint16_t GARAGE_MODE_PIN; //*номер пина на котором поднимаеться сигнал в случае прехода в режим гараж
|
||||||
|
uint16_t ECALL_MODE_PIN; //*номер пина на котором поднимаеться сигнал в случае прехода в режим ecall
|
||||||
|
|
||||||
|
tUveosNotGostSettings notGost;
|
||||||
|
|
||||||
|
} tUveosGostSettings;
|
||||||
|
|
||||||
|
void vUveosGostSettingsInitDefaults(tUveosGostSettings *gostSettings);
|
||||||
|
|
||||||
|
#endif /* INC_UVEOS_GOST_SETTINGS_H_ */
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* UVEOS_GOST_SettingsEnums.h
|
||||||
|
*
|
||||||
|
* Created on: Apr 12, 2021
|
||||||
|
* Author: zemon
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INC_UVEOS_GOST_SETTINGSENUMS_H_
|
||||||
|
#define INC_UVEOS_GOST_SETTINGSENUMS_H_
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
UVEOS_GOST_NONE,
|
||||||
|
UVEOS_GOST_PIN_1,
|
||||||
|
UVEOS_GOST_PIN_2,
|
||||||
|
UVEOS_GOST_PIN_3,
|
||||||
|
UVEOS_GOST_PIN_4,
|
||||||
|
UVEOS_GOST_PIN_5,
|
||||||
|
UVEOS_GOST_PIN_6,
|
||||||
|
UVEOS_GOST_PIN_7,
|
||||||
|
UVEOS_GOST_PIN_8
|
||||||
|
} eUveosGostPin;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
UVEOS_GOST_PASSENGER_VEHICLE_CLASS_M1 = 1,
|
||||||
|
UVEOS_GOST_BUSES_AND_COACHES_CLASS_M2 = 2,
|
||||||
|
UVEOS_GOST_BUSES_AND_COACHES_CLASS_M3 = 3,
|
||||||
|
UVEOS_GOST_LIGHT_COMMERCIAL_VEHICLES_CLASS_N1 = 4,
|
||||||
|
UVEOS_GOST_HEAVY_DUTY_VEHICLES_CLASS_N2 = 5,
|
||||||
|
UVEOS_GOST_HEAVY_DUTY_VEHICLES_CLASS_N3 = 6,
|
||||||
|
UVEOS_GOST_MOTORCYCLE_CLASS_L1E = 7,
|
||||||
|
UVEOS_GOST_MOTORCYCLE_CLASS_L2E = 8,
|
||||||
|
UVEOS_GOST_MOTORCYCLE_CLASS_L3E = 9,
|
||||||
|
UVEOS_GOST_MOTORCYCLE_CLASS_L4E = 10,
|
||||||
|
UVEOS_GOST_MOTORCYCLE_CLASS_L5E = 11,
|
||||||
|
UVEOS_GOST_MOTORCYCLE_CLASS_L6E = 12,
|
||||||
|
UVEOS_GOST_MOTORCYCLE_CLASS_L7E = 13
|
||||||
|
} eUveosGostVehicleType;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
UVEOS_GOST_GASOLINE_TANK_PRESENT = 32,
|
||||||
|
UVEOS_GOST_DIESEL_TANK_PRESENT = 16,
|
||||||
|
UVEOS_GOST_COMPRESSED_NATURAL_GAS = 8,
|
||||||
|
UVEOS_GOST_LIQUID_PROPANE_GAS = 4,
|
||||||
|
UVEOS_GOST_ELECTRIC_ENERGY_STORAGE = 2,
|
||||||
|
UVEOS_GOST_HYDROGEN_STORAGE = 1
|
||||||
|
} eUveosGostVehiclePropulsionStorageType;
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* INC_UVEOS_GOST_SETTINGSENUMS_H_ */
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,306 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef cJSON__h
|
||||||
|
#define cJSON__h
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
|
||||||
|
#define __WINDOWS__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __WINDOWS__
|
||||||
|
|
||||||
|
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options:
|
||||||
|
|
||||||
|
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
|
||||||
|
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
|
||||||
|
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
|
||||||
|
|
||||||
|
For *nix builds that support visibility attribute, you can define similar behavior by
|
||||||
|
|
||||||
|
setting default visibility to hidden by adding
|
||||||
|
-fvisibility=hidden (for gcc)
|
||||||
|
or
|
||||||
|
-xldscope=hidden (for sun cc)
|
||||||
|
to CFLAGS
|
||||||
|
|
||||||
|
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define CJSON_CDECL __cdecl
|
||||||
|
#define CJSON_STDCALL __stdcall
|
||||||
|
|
||||||
|
/* export symbols by default, this is necessary for copy pasting the C and header file */
|
||||||
|
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
|
||||||
|
#define CJSON_EXPORT_SYMBOLS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CJSON_HIDE_SYMBOLS)
|
||||||
|
#define CJSON_PUBLIC(type) type CJSON_STDCALL
|
||||||
|
#elif defined(CJSON_EXPORT_SYMBOLS)
|
||||||
|
#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL
|
||||||
|
#elif defined(CJSON_IMPORT_SYMBOLS)
|
||||||
|
#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL
|
||||||
|
#endif
|
||||||
|
#else /* !__WINDOWS__ */
|
||||||
|
#define CJSON_CDECL
|
||||||
|
#define CJSON_STDCALL
|
||||||
|
|
||||||
|
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
|
||||||
|
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
|
||||||
|
#else
|
||||||
|
#define CJSON_PUBLIC(type) type
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* project version */
|
||||||
|
#define CJSON_VERSION_MAJOR 1
|
||||||
|
#define CJSON_VERSION_MINOR 7
|
||||||
|
#define CJSON_VERSION_PATCH 18
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
/* cJSON Types: */
|
||||||
|
#define cJSON_Invalid (0)
|
||||||
|
#define cJSON_False (1 << 0)
|
||||||
|
#define cJSON_True (1 << 1)
|
||||||
|
#define cJSON_NULL (1 << 2)
|
||||||
|
#define cJSON_Number (1 << 3)
|
||||||
|
#define cJSON_String (1 << 4)
|
||||||
|
#define cJSON_Array (1 << 5)
|
||||||
|
#define cJSON_Object (1 << 6)
|
||||||
|
#define cJSON_Raw (1 << 7) /* raw json */
|
||||||
|
|
||||||
|
#define cJSON_IsReference 256
|
||||||
|
#define cJSON_StringIsConst 512
|
||||||
|
|
||||||
|
/* The cJSON structure: */
|
||||||
|
typedef struct cJSON
|
||||||
|
{
|
||||||
|
/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
|
||||||
|
struct cJSON *next;
|
||||||
|
struct cJSON *prev;
|
||||||
|
/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
|
||||||
|
struct cJSON *child;
|
||||||
|
|
||||||
|
/* The type of the item, as above. */
|
||||||
|
int type;
|
||||||
|
|
||||||
|
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
|
||||||
|
char *valuestring;
|
||||||
|
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
|
||||||
|
int valueint;
|
||||||
|
/* The item's number, if type==cJSON_Number */
|
||||||
|
double valuedouble;
|
||||||
|
|
||||||
|
/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
|
||||||
|
char *string;
|
||||||
|
} cJSON;
|
||||||
|
|
||||||
|
typedef struct cJSON_Hooks
|
||||||
|
{
|
||||||
|
/* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */
|
||||||
|
void *(CJSON_CDECL *malloc_fn)(size_t sz);
|
||||||
|
void (CJSON_CDECL *free_fn)(void *ptr);
|
||||||
|
} cJSON_Hooks;
|
||||||
|
|
||||||
|
typedef int cJSON_bool;
|
||||||
|
|
||||||
|
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
|
||||||
|
* This is to prevent stack overflows. */
|
||||||
|
#ifndef CJSON_NESTING_LIMIT
|
||||||
|
#define CJSON_NESTING_LIMIT 1000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Limits the length of circular references can be before cJSON rejects to parse them.
|
||||||
|
* This is to prevent stack overflows. */
|
||||||
|
#ifndef CJSON_CIRCULAR_LIMIT
|
||||||
|
#define CJSON_CIRCULAR_LIMIT 10000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* returns the version of cJSON as a string */
|
||||||
|
CJSON_PUBLIC(const char*) cJSON_Version(void);
|
||||||
|
|
||||||
|
/* Supply malloc, realloc and free functions to cJSON */
|
||||||
|
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
|
||||||
|
|
||||||
|
/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
|
||||||
|
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length);
|
||||||
|
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
|
||||||
|
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated);
|
||||||
|
|
||||||
|
/* Render a cJSON entity to text for transfer/storage. */
|
||||||
|
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
|
||||||
|
/* Render a cJSON entity to text for transfer/storage without any formatting. */
|
||||||
|
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
|
||||||
|
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
|
||||||
|
CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
|
||||||
|
/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
|
||||||
|
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
|
||||||
|
/* Delete a cJSON entity and all subentities. */
|
||||||
|
CJSON_PUBLIC(void) cJSON_Delete(cJSON *item);
|
||||||
|
|
||||||
|
/* Returns the number of items in an array (or object). */
|
||||||
|
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
|
||||||
|
/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
|
||||||
|
/* Get item "string" from object. Case insensitive. */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
|
||||||
|
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
|
||||||
|
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
|
||||||
|
|
||||||
|
/* Check item type and return its value */
|
||||||
|
CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item);
|
||||||
|
|
||||||
|
/* These functions check the type of an item */
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
|
||||||
|
|
||||||
|
/* These calls create a cJSON item of the appropriate type. */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
|
||||||
|
/* raw json */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
|
||||||
|
|
||||||
|
/* Create a string where valuestring references a string so
|
||||||
|
* it will not be freed by cJSON_Delete */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
|
||||||
|
/* Create an object/array that only references it's elements so
|
||||||
|
* they will not be freed by cJSON_Delete */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
|
||||||
|
|
||||||
|
/* These utilities create an Array of count items.
|
||||||
|
* The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count);
|
||||||
|
|
||||||
|
/* Append item to the specified array/object. */
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
|
||||||
|
/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
|
||||||
|
* WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
|
||||||
|
* writing to `item->string` */
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
|
||||||
|
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
|
||||||
|
|
||||||
|
/* Remove/Detach items from Arrays/Objects. */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
|
||||||
|
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||||
|
CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
|
||||||
|
CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||||
|
|
||||||
|
/* Update array items. */
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
|
||||||
|
|
||||||
|
/* Duplicate a cJSON item */
|
||||||
|
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
|
||||||
|
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
|
||||||
|
* need to be released. With recurse!=0, it will duplicate any children connected to the item.
|
||||||
|
* The item->next and ->prev pointers are always zero on return from Duplicate. */
|
||||||
|
/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
|
||||||
|
* case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
|
||||||
|
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
|
||||||
|
|
||||||
|
/* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings.
|
||||||
|
* The input pointer json cannot point to a read-only address area, such as a string constant,
|
||||||
|
* but should point to a readable and writable address area. */
|
||||||
|
CJSON_PUBLIC(void) cJSON_Minify(char *json);
|
||||||
|
|
||||||
|
/* Helper functions for creating and adding items to an object at the same time.
|
||||||
|
* They return the added item or NULL on failure. */
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
|
||||||
|
CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
|
||||||
|
|
||||||
|
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
|
||||||
|
#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
|
||||||
|
/* helper for the cJSON_SetNumberValue macro */
|
||||||
|
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
|
||||||
|
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
|
||||||
|
/* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */
|
||||||
|
CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring);
|
||||||
|
|
||||||
|
/* If the object is not a boolean type this does nothing and returns cJSON_Invalid else it returns the new type*/
|
||||||
|
#define cJSON_SetBoolValue(object, boolValue) ( \
|
||||||
|
(object != NULL && ((object)->type & (cJSON_False|cJSON_True))) ? \
|
||||||
|
(object)->type=((object)->type &(~(cJSON_False|cJSON_True)))|((boolValue)?cJSON_True:cJSON_False) : \
|
||||||
|
cJSON_Invalid\
|
||||||
|
)
|
||||||
|
|
||||||
|
/* Macro for iterating over an array or object */
|
||||||
|
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
|
||||||
|
|
||||||
|
/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
|
||||||
|
CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
|
||||||
|
CJSON_PUBLIC(void) cJSON_free(void *object);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,243 @@
|
||||||
|
//
|
||||||
|
// 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");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *input_file = fopen(argv[1], "r");
|
||||||
|
if (input_file == NULL) {
|
||||||
|
printf("Error: Failed to open file %s\n", argv[1]);
|
||||||
|
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 %zu bytes:\n", 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");
|
||||||
|
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");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
EraGlonassMsdSetTimeStamp(&msd, timestamp);
|
||||||
|
|
||||||
|
printf("timestamp: %u\n", msd.MSD_Data.timestamp);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
printf("Parsing timestamp error");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
printf("Parsing JSON timestamp error");
|
||||||
|
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 (int i = 0; i < strlen(coordinateJS->valuestring); ++i) {
|
||||||
|
|
||||||
|
if ((coordinateJS->valuestring[i + 1] == 'N') || (coordinateJS->valuestring[i + 1] == 'S') ||
|
||||||
|
(coordinateJS->valuestring[i + 1] == 'W') || (coordinateJS->valuestring[i + 1] == 'E')) {
|
||||||
|
tmp[len] = coordinateJS->valuestring[i];
|
||||||
|
++len;
|
||||||
|
tmp[len] = ' ';
|
||||||
|
++len;
|
||||||
|
} else {
|
||||||
|
tmp[len] = coordinateJS->valuestring[i];
|
||||||
|
++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 (1)");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf("Parsing JSON coordinate error");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cJSON_IsString(phoneJS) && (phoneJS->valuestring != NULL)) {
|
||||||
|
printf("phone (JSON): %s\n", phoneJS->valuestring);
|
||||||
|
} else {
|
||||||
|
printf("Parsing JSON phone error");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cJSON_IsString(idJS) && (idJS->valuestring != NULL)) {
|
||||||
|
printf("id (JSON): %s\n", idJS->valuestring);
|
||||||
|
|
||||||
|
char VIN[17] = {0};
|
||||||
|
|
||||||
|
memcpy(VIN, 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");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON_Delete(json);
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t msdEncoded[512] = {0};
|
||||||
|
size_t msdEncodedSize = EraGlonassMsdEncode(&msd, MSD_V_2, msdEncoded);
|
||||||
|
|
||||||
|
char egtsHexStr[1024] = {0};
|
||||||
|
size_t egtsHexStrLen = 0;
|
||||||
|
vAsciiStringAddBytesAsHex(egtsHexStr, &egtsHexStrLen, msdEncoded, msdEncodedSize);
|
||||||
|
|
||||||
|
|
||||||
|
FILE *output_file = fopen(argv[2], "w");
|
||||||
|
if (output_file == NULL) {
|
||||||
|
printf("Error: Failed to open file %s\n", argv[1]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t bytes_written = fwrite(egtsHexStr, 1, egtsHexStrLen, output_file);
|
||||||
|
|
||||||
|
printf("Write %zu bytes:\n", bytes_written);
|
||||||
|
printf("%.*s\n", (int)bytes_written, egtsHexStr);
|
||||||
|
|
||||||
|
fclose(output_file);
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
|
||||||
|
"cmake": {
|
||||||
|
"inc_dirs": [
|
||||||
|
"./"
|
||||||
|
],
|
||||||
|
"srcs": [
|
||||||
|
"./ert_main.c",
|
||||||
|
"./*.c"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
cmake_minimum_required(VERSION 3.17)
|
||||||
|
project(simulink)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
|
||||||
|
include(modular.cmake)
|
||||||
|
|
||||||
|
#link_directories(/usr/local/opt/libpq/lib/)
|
||||||
|
#include_directories(/usr/local/opt/libpq/include)
|
||||||
|
#link_directories(/usr/lib/x86_64-linux-gnu/)
|
||||||
|
#include_directories(/usr/include/postgresql)
|
||||||
|
|
||||||
|
#link_libraries(pq)
|
||||||
|
#link_libraries(tcp)
|
||||||
|
#link_libraries(pthread)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -funsigned-char -pipe -Wl,-O0 -std=gnu++2a -Wall -Wextra")
|
||||||
|
|
||||||
|
add_executable(conv ${SOURCES})
|
||||||
|
target_link_libraries(conv PRIVATE m)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
function(add_sources FILE_LIST FILES_PATH)
|
||||||
|
file(GLOB_RECURSE ADD_FILES_LIST ${FILES_PATH})
|
||||||
|
list(APPEND ${FILE_LIST} ${ADD_FILES_LIST})
|
||||||
|
set(${FILE_LIST} ${${FILE_LIST}} PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
include_directories("APP/")
|
||||||
|
|
||||||
|
add_sources(SOURCES "APP/ert_main.c")
|
||||||
|
add_sources(SOURCES "APP/*.c")
|
||||||
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"dep": [
|
||||||
|
{
|
||||||
|
"type": "local",
|
||||||
|
"dir": "APP"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"cmake": {
|
||||||
|
"inc_dirs": [
|
||||||
|
],
|
||||||
|
"srcs": [
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue