void coap_decode_segment(const unsigned char *seg, size_t length, unsigned char *buf) { while (length--) { if (*seg == '%') { *buf = (hexchar_to_dec(seg[1]) << 4) + hexchar_to_dec(seg[2]); seg += 2; length -= 2; } else { *buf = *seg; } ++buf; ++seg; } }
/* Validates the checksum of the specified NMEA sentence * Returns 1 if calculated checksum matched the received checksum; * Returns 0 otherwise */ static uint8_t validate_checksum(char * s) { uint8_t checksum = 0; uint8_t s_cursor; // Calculate the checksum of the received characters in the sentence. // Note: only the characters between '$' and '*' are used for (s_cursor = 1; s_cursor < GPS_SENTENCE_BUFF_SZ; s_cursor++) { if (*(s + s_cursor) != '*') { checksum ^= *(s + s_cursor); } else { break; } } // Advance the cursor to the position of the checksum's first char s_cursor++; // Verify that there was no overflow by checking whether the cursor // went beyond the buffer limit, possibly due to not finding a '*' if (s_cursor + GPS_CHECKSUM_LENGTH >= GPS_SENTENCE_BUFF_SZ) { return 0; } // Convert the most significant and least significant nibbles of // the checksum byte uint8_t chk_upper = hexchar_to_dec(s[s_cursor]); uint8_t chk_lower = hexchar_to_dec(s[s_cursor + 1]); // Verify no error occurred during the conversion if (chk_upper == GPS_INVALID_HEX_CHAR || chk_lower == GPS_INVALID_HEX_CHAR) { return 0; } // Assemble the expected checksum provided by the GPS receiver uint8_t expected_checksum = (chk_upper << 4) | chk_lower; if (checksum == expected_checksum) { return 1; } return 0; }