pocketbus.c
Go to the documentation of this file.00001
00079 #include "pocketbus.h"
00080
00081 #include "cfg/cfg_pocketbus.h"
00082
00083
00084 #define LOG_LEVEL POCKETBUS_LOG_LEVEL
00085 #define LOG_VERBOSITY POCKETBUS_LOG_FORMAT
00086 #include <cfg/log.h>
00087 #include <cfg/debug.h>
00088 #include <cfg/macros.h>
00089
00090 #include <kern/kfile.h>
00091
00092 #include <cpu/byteorder.h>
00093
00094 #include <string.h>
00095
00099 void pocketbus_putchar(struct PocketBusCtx *ctx, uint8_t c)
00100 {
00101
00102 rotating_update1(c, &ctx->out_cks);
00103
00104
00105 if (c == POCKETBUS_ESC || c == POCKETBUS_STX || c == POCKETBUS_ETX)
00106 kfile_putc(POCKETBUS_ESC, ctx->fd);
00107
00108 kfile_putc(c, ctx->fd);
00109 }
00110
00114 void pocketbus_begin(struct PocketBusCtx *ctx, pocketbus_addr_t addr)
00115 {
00116 PocketBusHdr hdr;
00117
00118 hdr.ver = POCKETBUS_VER;
00119 hdr.addr = cpu_to_be16(addr);
00120 rotating_init(&ctx->out_cks);
00121
00122
00123 kfile_putc(POCKETBUS_STX, ctx->fd);
00124
00125
00126 pocketbus_write(ctx, &hdr, sizeof(hdr));
00127 }
00128
00132 void pocketbus_write(struct PocketBusCtx *ctx, const void *_data, size_t len)
00133 {
00134 const uint8_t *data = (const uint8_t *)_data;
00135
00136 while (len--)
00137 pocketbus_putchar(ctx, *data++);
00138 }
00139
00143 void pocketbus_end(struct PocketBusCtx *ctx)
00144 {
00145
00146 rotating_t cks = cpu_to_be16(ctx->out_cks);
00147 pocketbus_write(ctx, &cks, sizeof(cks));
00148
00149
00150 kfile_putc(POCKETBUS_ETX, ctx->fd);
00151 }
00152
00156 void pocketbus_send(struct PocketBusCtx *ctx, pocketbus_addr_t addr, const void *data, size_t len)
00157 {
00158 pocketbus_begin(ctx, addr);
00159
00160
00161 pocketbus_write(ctx, data, len);
00162
00163 pocketbus_end(ctx);
00164 }
00165
00166
00171 bool pocketbus_recv(struct PocketBusCtx *ctx, struct PocketMsg *msg)
00172 {
00173 int c;
00174
00175
00176 while ((c = kfile_getc(ctx->fd)) != EOF)
00177 {
00178
00179 if (c == POCKETBUS_STX && !ctx->escape)
00180 {
00181
00182 if (ctx->sync)
00183 kprintf("pocketBus double sync!\n");
00184
00185 ctx->sync = true;
00186 ctx->len = 0;
00187 rotating_init(&ctx->in_cks);
00188 continue;
00189 }
00190
00191 if (ctx->sync)
00192 {
00193
00194 if (c == POCKETBUS_ESC && !ctx->escape)
00195 {
00196 ctx->escape = true;
00197 continue;
00198 }
00199
00200
00201 if (c == POCKETBUS_ETX && !ctx->escape)
00202 {
00203 ctx->sync = false;
00204
00205
00206 if (ctx->len < sizeof(PocketBusHdr) + sizeof(rotating_t))
00207 {
00208 kprintf("pocketBus short pkt!\n");
00209 continue;
00210 }
00211
00212
00213 ctx->len -= sizeof(rotating_t);
00214
00215
00216 rotating_update(ctx->buf, ctx->len, &ctx->in_cks);
00217 uint8_t cks_h = *(ctx->buf + ctx->len);
00218 uint8_t cks_l = *(ctx->buf + ctx->len + 1);
00219
00220 rotating_t recv_cks = (cks_h << 8) | cks_l;
00221
00222
00223 if (recv_cks == ctx->in_cks)
00224 {
00225 PocketBusHdr *hdr = (PocketBusHdr *)ctx;
00226
00227
00228 if (hdr->ver == POCKETBUS_VER)
00229 {
00230
00231 msg->payload = ctx->buf + sizeof(PocketBusHdr);
00232 msg->addr = be16_to_cpu(hdr->addr);
00233 msg->len = ctx->len - sizeof(PocketBusHdr);
00234 msg->ctx = ctx;
00235 return true;
00236 }
00237 else
00238 {
00239 kprintf("pocketBus version mismatch, here[%d], there[%d]\n", POCKETBUS_VER, hdr->ver);
00240 continue;
00241 }
00242 }
00243 else
00244 {
00245 kprintf("pocketBus cks error, here[%04X], there[%04X]\n", ctx->in_cks, recv_cks);
00246 continue;
00247 }
00248
00249 }
00250
00251 ctx->escape = false;
00252
00253
00254
00255 if (ctx->len >= CONFIG_POCKETBUS_BUFLEN)
00256 {
00257 kprintf("pocketBus buffer overflow\n");
00258 ctx->sync = false;
00259 continue;
00260 }
00261
00262
00263 ctx->buf[ctx->len] = c;
00264 ctx->len++;
00265 }
00266 }
00267
00268
00269
00270
00271 if (kfile_error(ctx->fd))
00272 {
00273 LOG_ERR("fd status[%04X]\n", kfile_error(ctx->fd));
00274 kfile_clearerr(ctx->fd);
00275 }
00276
00277 return false;
00278 }
00279
00280
00284 void pocketbus_init(struct PocketBusCtx *ctx, struct KFile *fd)
00285 {
00286 ASSERT(ctx);
00287 ASSERT(fd);
00288
00289 memset(ctx, 0, sizeof(*ctx));
00290 ctx->fd = fd;
00291 }