/** * \file * * * \author Andrea Grandi * \author Daniele Basile * * \brief KeyTAG parser. * * This module parse TAG message that come from comunication channel, * and convert the tag value into string. * * TAG protocol is decribed in this way: *
 * ---------------------------------------------------
 * |STX (0x02)|data...(10 HEX chars)|CR|LF|ETX (0x03)|
 * ---------------------------------------------------
 * 
*/ #include "keytag.h" #include // Define log settings for cfg/log.h #define LOG_LEVEL CONFIG_KEYTAG_LOG_LEVEL #define LOG_FORMAT CONFIG_KEYTAG_LOG_FORMAT #include #include #include #include /** * Starting communication char (STX). */ #define TAG_STX 0x02 /** * Ending communication char (ETX). */ #define TAG_ETX 0x03 static void keytag_clearPkt(struct TagPacket *pkt) { pkt->sync = false; pkt->len = 0; } /** * DEPRECATED FUCNTIONS * To read the tag string from device you shoul use the keytag_recv * fuction, that return the string if we had received it. */ void keytag_poll(struct TagPacket *pkt) { uint8_t buf[CONFIG_TAG_MAX_LEN]; int len; if ((len = keytag_recv(pkt, buf, sizeof(buf))) != EOF) kfile_write(pkt->host, buf, len); } /** * Receive the tag message from channel, and if * the tag is good put the converted string into given buffer. * The fuction return the len of found tag string, otherwise EOF. */ int keytag_recv(struct TagPacket *pkt, uint8_t *tag, size_t len) { int c; /* Get all chars from buffer */ while ((c = kfile_getc(pkt->tag)) != EOF) { /* Search for STX char in received chars */ if (c == TAG_STX) { /* When STX is found a new packet begins */ if (pkt->sync) LOG_WARN("TAG double sync!\n"); keytag_clearPkt(pkt); pkt->sync = true; } else if (pkt->sync) { /* Check for end of packet */ if (c == TAG_ETX) { /* Terminate the tag string */ size_t tag_len = MIN(len, pkt->len); /* Save read tag */ memcpy(tag, pkt->buf, tag_len); pkt->sync = false; return tag_len; } else { /* Check for buffer overflow */ if (pkt->len >= CONFIG_TAG_MAX_LEN) { LOG_ERR("TAG buffer overflow\n"); pkt->sync = false; } else { /* Add every char after STX to tag reading buffer */ if (pkt->sync) { pkt->buf[pkt->len] = c; pkt->len++; } } } } } if (kfile_error(pkt->tag) != 0) { LOG_ERR("Error %04x\n", kfile_error(pkt->tag)); kfile_clearerr(pkt->tag); } return EOF; } /** * Init the keytag module. */ void keytag_init(struct TagPacket *pkt, struct KFile *comm, struct KFile *tag) { keytag_clearPkt(pkt); pkt->tag = tag; pkt->host = comm; }