7#define crc_option crc_tbl4bit
9#if crc_option == crc_bbb
11#define crc_init crc_16_dnp_bbb_init
12#define crc_update crc_16_dnp_bbb_update
13#define crc_finalize crc_16_dnp_bbb_finalize
14#elif crc_option == crc_bbf
16#define crc_init crc_16_dnp_bbf_init
17#define crc_update crc_16_dnp_bbf_update
18#define crc_finalize crc_16_dnp_bbf_finalize
19#elif crc_option == crc_tbl4bit
21#define crc_init crc_16_dnp_tbl4bit_init
22#define crc_update crc_16_dnp_tbl4bit_update
23#define crc_finalize crc_16_dnp_tbl4bit_finalize
24#elif crc_option == crc_crcmod
27#error "crc_option not supported!"
35#define error_message_max_copy_data_len 9
36#define max_remove_unfinished_frames_tries 10
52 const char *data,
size_t dataLen) {
58 if (dataLen > MAXDATALEN) {
59 Throw(ASC_ERROR_DATA_TOO_LONG);
65 for (
size_t i = 0; i < dataLen; i++) {
69 char checksum[NCHARCHECKSUM];
71 for (
size_t i = 0; i < NCHARCHECKSUM; i++) {
80 char *command,
char *data,
82 char computeChecksum[NCHARCHECKSUM];
93 if (iEnd >= buf_size) {
102 if (iPeriod > iEnd) {
103 for (
size_t i = 0; i <= iEnd; i++) {
106 Throw(ASC_ERROR_INVALID_FRAME_PERIOD);
118 for (
size_t iData = 0; iData < iPeriod - 4; iData++) {
120 if (dataByte ==
'.') {
123 data[iData] = dataByte;
129 Throw(ASC_ERROR_INVALID_FRAME);
135 char receiveChecksum[NCHARCHECKSUM];
136 for (
size_t iChk = 0; iChk < NCHARCHECKSUM; iChk++) {
140 for (
size_t iChk = 0; iChk < NCHARCHECKSUM; iChk++) {
141 if (receiveChecksum[iChk] != computeChecksum[iChk]) {
188 if (iStart >= size) {
189 Throw(ASC_ERROR_INVALID_FRAME);
192 Throw(ASC_ERROR_INVALID_FRAME_PERIOD);
194 if (iStop >= MAXMESSAGELEN - NCHARCHECKSUM - 1) {
195 Throw(ASC_ERROR_CHECKSUM_PROBLEM);
197 if (iStop <= iStart || iStop - iStart < 4) {
198 Throw(ASC_ERROR_INVALID_FRAME_PERIOD);
201 size_t blocks_sizes[2];
203 circ_buf, iStart, iStop - iStart + 1, blocks, blocks_sizes);
204#if crc_option == crc_crcmod
205 uint16_t crc = 0xFFFF;
206 for (
size_t iBlock = 0; iBlock < nBlocks; iBlock++) {
207 crc = computeCRC_16_DNP(blocks[iBlock], blocks_sizes[iBlock], crc);
210 uint16_t crc = crc_init();
211 for (
size_t iBlock = 0; iBlock < nBlocks; iBlock++) {
212 crc = crc_update(crc, blocks[iBlock], blocks_sizes[iBlock]);
214 crc = crc_finalize(crc);
225 if (dataLen > MAXSPAYLOADEN) {
226 Throw(ASC_ERROR_DATA_TOO_LONG);
228 char outData[MAXDATALEN];
232 for (
size_t i = 0; i < dataLen && i < (MAXDATALEN - 3); i++) {
233 outData[i + 3] = data[i];
236 's', outData, dataLen + 3);
241 char appVersion,
char command,
242 char *data,
size_t dataLen,
244 char outData[error_message_max_copy_data_len + 5];
247 outData[3] = command;
249 size_t outDataLen = 5;
250 for (
size_t i = 0; i < dataLen && i < error_message_max_copy_data_len; i++) {
251 outData[i + 5] = data[i];
255 'e', outData, outDataLen);
269 for (uint8_t i = 0; i < 2; i++) {
270 uint8_t nibble = (num >> (4 * i)) & 0xF;
272 outstr[1 - i] = 0x30 + nibble;
274 outstr[1 - i] = 0x41 + nibble - 10;
276 outstr[1 - i] = 0x61 + nibble - 10;
282 for (uint8_t i = 0; i < 2; i++) {
288 for (uint8_t i = 0; i < 4; i++) {
295 for (uint8_t i = 0; i < 2; i++) {
296 char thischar = instr[1 - i];
297 if (thischar >= 0x30 && thischar <= 0x39) {
298 result |= (thischar - 0x30) << (i * 4);
299 }
else if (thischar >= 0x41 && thischar <= 0x46) {
300 result |= (thischar - 0x41 + 10) << (i * 4);
301 }
else if (thischar >= 0x61 && thischar <= 0x66) {
302 result |= (thischar - 0x61 + 10) << (i * 4);
306 Throw(ASC_ERROR_NOT_HEX_CHAR);
314 for (uint8_t i = 0; i < 2; i++) {
322 for (uint8_t i = 0; i < 4; i++) {
asc_exception
Exception type to be used with CException.
void convert_uint8_to_hex(uint8_t num, char *outstr, bool caps)
convert uint8 to hex string
circular_buffer_uint8 * ascii_serial_com_get_output_buffer(ascii_serial_com *asc)
ASCII Serial Com get output buffer.
void convert_uint16_to_hex(uint16_t num, char *outstr, bool caps)
convert uint16 to hex string
void ascii_serial_com_put_s_message_in_output_buffer(ascii_serial_com *asc, char ascVersion, char appVersion, const char *data, size_t dataLen)
ASCII Serial Com Pack and put 's' message in output buffer.
void ascii_serial_com_init(ascii_serial_com *asc)
ASCII Serial Com Interface init method.
uint16_t convert_hex_to_uint16(const char *instr)
convert hex string to uint16
void ascii_serial_com_put_message_in_output_buffer(ascii_serial_com *asc, char ascVersion, char appVersion, char command, const char *data, size_t dataLen)
ASCII Serial Com Pack and put message in output buffer.
void ascii_serial_com_get_message_from_input_buffer(ascii_serial_com *asc, char *ascVersion, char *appVersion, char *command, char *data, size_t *dataLen)
ASCII Serial Com pop message from input buffer and unpack.
uint8_t convert_hex_to_uint8(const char *instr)
convert hex string to uint8
uint32_t convert_hex_to_uint32(const char *instr)
convert hex string to uint32
void ascii_serial_com_put_error_in_output_buffer(ascii_serial_com *asc, char ascVersion, char appVersion, char command, char *data, size_t dataLen, enum asc_exception errorCode)
ASCII Serial Com put error message in out buffer.
void ascii_serial_com_compute_checksum(ascii_serial_com *asc, char *checksumOut, bool outputBuffer)
ASCII Serial Com compute checksum of message.
circular_buffer_uint8 * ascii_serial_com_get_input_buffer(ascii_serial_com *asc)
ASCII Serial Com get input buffer.
void convert_uint32_to_hex(uint32_t num, char *outstr, bool caps)
convert uint32 to hex string
size_t circular_buffer_get_size_uint8(const circular_buffer_uint8 *circ_buf)
circular buffer get number of elements
void circular_buffer_init_uint8(circular_buffer_uint8 *circ_buf, const size_t capacity, uint8_t *buffer)
circular buffer init method
size_t circular_buffer_remove_front_unfinished_frames_uint8(circular_buffer_uint8 *circ_buf, const char startChar, const char endChar)
circular buffer remove unfinished frames from front of buffer
size_t circular_buffer_get_blocks_uint8(circular_buffer_uint8 *circ_buf, size_t iStart, size_t nElem, uint8_t **blocks, size_t *blocks_sizes)
circular buffer access raw blocks of data for a given range of elements
uint8_t circular_buffer_get_element_uint8(const circular_buffer_uint8 *circ_buf, const size_t iElement)
circular buffer get element
size_t circular_buffer_find_first_uint8(const circular_buffer_uint8 *circ_buf, const uint8_t value)
circular buffer find index of first occurance of value
uint8_t circular_buffer_pop_front_uint8(circular_buffer_uint8 *circ_buf)
circular buffer pop front
size_t circular_buffer_find_last_uint8(const circular_buffer_uint8 *circ_buf, const uint8_t value)
circular buffer find index of last occurance of value
void circular_buffer_push_back_uint8(circular_buffer_uint8 *circ_buf, const uint8_t element)
circular buffer push back
ASCII Serial Com Interface State struct.
uint8_t receive_stream_frame_counter
circular_buffer_uint8 in_buf
uint8_t raw_buffer[2 *MAXMESSAGELEN]
bool receive_stream_frame_counter_initialized
uint8_t send_stream_frame_counter
circular_buffer_uint8 out_buf