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