X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=net%2Fpocketbus.c;h=61d4d2b44261432885e33fa0bb81050a5c8d7330;hb=HEAD;hp=e793f95df54b26886ee5bc62edb0951b7d85c0eb;hpb=07382ad480794063a2d5be63547eb288034d9832;p=bertos.git diff --git a/net/pocketbus.c b/net/pocketbus.c deleted file mode 100644 index e793f95d..00000000 --- a/net/pocketbus.c +++ /dev/null @@ -1,260 +0,0 @@ -/** - * \file - * - * - * \version $Id: pocketbus.c 20131 2007-12-13 17:39:55Z batt $ - * - * \author Francesco Sacchi - * - * \brief pocketBus protocol implementation. - * - * pocketBus protocol is a simple strictly master-slave protocol, usable - * in embedded systems. - * pocketBus frame is as follows: - *
- * +----------------------------------------+
- * | STX | VER | ADDR | PAYLOAD | CKS | ETX |
- * +----------------------------------------+
- * |     |     |      |         |     |     |
- * + 1B  + 1B  +  2B  + N Byte  + 2B  + 1B  +
- * 
- * - * - STX, 1 byte (0x02), packet start - * - VER, 1 byte, packet version - * - ADDR, 2 byte, slave address - * - PAYLOAD, N byte, data field - * - CKS, 2 byte, checksum - * - ETX, 1 byte, (0x03) packet end - * - * Protocol parsing start on STX reception. When the receiving routine - * finds an STX char, it starts to read characters from the bus - * until an ETX is received. Once a packet is received, - * the parser checks packet correctness and checksum. If all is OK - * the payload is returned. - * - * STX (0x02), ETX(0x03) and ESC(0x1B) are special characters and cannot be - * transmitted inside payload without escaping them. - * To escape a character you must precede it by the ESC char. - * E.G. STX -> ESC + STX - * ETX -> ESC + ETX - * ESC -> ESC + ESC - * - * In the ADDR field is always specified the slave address. - * In the case of master trasmitting, ADDR contains the slave destination - * address. - * In case of slave replying, ADDR contains the slave address itself. - * Thus, the master device does not have an address. Packet must be routed to - * master by hardware bus design. - * - * The checksum algorithm used is rotating hash algortihm, quite simple but more - * reliable than simple checksum. - * The checksum in computed on all fields excluding STX, ETX and CHK fields itself. - * Checksum is computed on the packet *before* escaping. - * Escape sequence counts for 1 character only (the escaped one). - */ - -#include "pocketbus.h" - -#include -#include - -#include - -#include - -#include - -/** - * Send a character over pocketBus channel stream, handling escape mode. - */ -void pocketbus_putchar(struct PocketBusCtx *ctx, uint8_t c) -{ - /* Update checksum */ - rotating_update1(c, &ctx->out_cks); - - /* Escape characters with special meaning */ - if (c == POCKETBUS_ESC || c == POCKETBUS_STX || c == POCKETBUS_ETX) - kfile_putc(POCKETBUS_ESC, ctx->fd); - - kfile_putc(c, ctx->fd); -} - -/** - * Send pocketBus packet header. - */ -void pocketbus_begin(struct PocketBusCtx *ctx, pocketbus_addr_t addr) -{ - PocketBusHdr hdr; - - hdr.ver = POCKETBUS_VER; - hdr.addr = cpu_to_be16(addr); - rotating_init(&ctx->out_cks); - - /* Send STX */ - kfile_putc(POCKETBUS_STX, ctx->fd); - - /* Send header */ - pocketbus_write(ctx, &hdr, sizeof(hdr)); -} - -/** - * Send buffer \a _data over bus, handling escape. - */ -void pocketbus_write(struct PocketBusCtx *ctx, const void *_data, size_t len) -{ - const uint8_t *data = (const uint8_t *)_data; - - while (len--) - pocketbus_putchar(ctx, *data++); -} - -/** - * Send pocketBus packet tail. - */ -void pocketbus_end(struct PocketBusCtx *ctx) -{ - /* Send checksum */ - rotating_t cks = cpu_to_be16(ctx->out_cks); - pocketbus_write(ctx, &cks, sizeof(cks)); - - /* Send ETX */ - kfile_putc(POCKETBUS_ETX, ctx->fd); -} - -/** - * Send buffer of \a data to address \a addr with a pocketBus packet over channel stream. - */ -void pocketbus_send(struct PocketBusCtx *ctx, pocketbus_addr_t addr, const void *data, size_t len) -{ - pocketbus_begin(ctx, addr); - - /* Send data */ - pocketbus_write(ctx, data, len); - - pocketbus_end(ctx); -} - - -/** - * Try to read a packet from the pocketBus. - * \return true if a packet is received, false otherwise. - */ -bool pocketbus_recv(struct PocketBusCtx *ctx, struct PocketMsg *msg) -{ - int c; - - /* Process incoming characters until buffer is not empty */ - while ((c = kfile_getc(ctx->fd)) != EOF) - { - /* Look for STX char */ - if (c == POCKETBUS_STX && !ctx->escape) - { - /* When an STX is found, inconditionally start a new packet */ - if (ctx->sync) - kprintf("pocketBus double sync!\n"); - - ctx->sync = true; - ctx->len = 0; - rotating_init(&ctx->in_cks); - continue; - } - - if (ctx->sync) - { - /* Handle escape mode */ - if (c == POCKETBUS_ESC && !ctx->escape) - { - ctx->escape = true; - continue; - } - - /* Handle message end */ - if (c == POCKETBUS_ETX && !ctx->escape) - { - ctx->sync = false; - - /* Check minimum size */ - if (ctx->len < sizeof(PocketBusHdr) + sizeof(rotating_t)) - { - kprintf("pocketBus short pkt!\n"); - continue; - } - - /* Remove checksum bytes from packet len */ - ctx->len -= sizeof(rotating_t); - - /* Compute checksum */ - rotating_update(ctx->buf, ctx->len, &ctx->in_cks); - rotating_t recv_cks = be16_to_cpu(*((rotating_t *)(ctx->buf + ctx->len))); - - /* Checksum check */ - if (recv_cks == ctx->in_cks) - { - PocketBusHdr *hdr = (PocketBusHdr *)(ctx->buf); - /* Check packet version */ - if (hdr->ver == POCKETBUS_VER) - { - /* Packet received, set msg fields */ - msg->payload = ctx->buf + sizeof(PocketBusHdr); - msg->addr = be16_to_cpu(hdr->addr); - msg->len = ctx->len - sizeof(PocketBusHdr); - msg->ctx = ctx; - return true; - } - else - { - kprintf("pocketBus version mismatch, here[%d], there[%d]\n", POCKETBUS_VER, hdr->ver); - continue; - } - } - else - { - kprintf("pocketBus cks error, here[%04X], there[%04X]\n", ctx->in_cks, recv_cks); - continue; - } - - } - - ctx->escape = false; - - /* Check buffer overflow: simply ignore - received data and go to unsynced state. */ - if (ctx->len >= CONFIG_POCKETBUS_BUFLEN) - { - kprintf("pocketBus buffer overflow\n"); - ctx->sync = false; - continue; - } - - /* Put received data in the buffer */ - ctx->buf[ctx->len] = c; - ctx->len++; - } - } - - /* - * Check stream status. - */ - if (kfile_error(ctx->fd)) - { - TRACEMSG("fd status[%04X]", kfile_error(ctx->fd)); - kfile_clearerr(ctx->fd); - } - - return false; -} - - -/** - * Initialize pocketBus protocol handler. - */ -void pocketbus_init(struct PocketBusCtx *ctx, struct KFile *fd) -{ - ASSERT(ctx); - ASSERT(fd); - - memset(ctx, 0, sizeof(*ctx)); - ctx->fd = fd; -}