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 rotating_t recv_cks = be16_to_cpu(*((rotating_t *)(ctx->buf + ctx->len)));
00212
00213
00214 if (recv_cks == ctx->in_cks)
00215 {
00216 PocketBusHdr *hdr = (PocketBusHdr *)(ctx->buf);
00217
00218 if (hdr->ver == POCKETBUS_VER)
00219 {
00220
00221 msg->payload = ctx->buf + sizeof(PocketBusHdr);
00222 msg->addr = be16_to_cpu(hdr->addr);
00223 msg->len = ctx->len - sizeof(PocketBusHdr);
00224 msg->ctx = ctx;
00225 return true;
00226 }
00227 else
00228 {
00229 kprintf("pocketBus version mismatch, here[%d], there[%d]\n", POCKETBUS_VER, hdr->ver);
00230 continue;
00231 }
00232 }
00233 else
00234 {
00235 kprintf("pocketBus cks error, here[%04X], there[%04X]\n", ctx->in_cks, recv_cks);
00236 continue;
00237 }
00238
00239 }
00240
00241 ctx->escape = false;
00242
00243
00244
00245 if (ctx->len >= CONFIG_POCKETBUS_BUFLEN)
00246 {
00247 kprintf("pocketBus buffer overflow\n");
00248 ctx->sync = false;
00249 continue;
00250 }
00251
00252
00253 ctx->buf[ctx->len] = c;
00254 ctx->len++;
00255 }
00256 }
00257
00258
00259
00260
00261 if (kfile_error(ctx->fd))
00262 {
00263 TRACEMSG("fd status[%04X]", kfile_error(ctx->fd));
00264 kfile_clearerr(ctx->fd);
00265 }
00266
00267 return false;
00268 }
00269
00270
00274 void pocketbus_init(struct PocketBusCtx *ctx, struct KFile *fd)
00275 {
00276 ASSERT(ctx);
00277 ASSERT(fd);
00278
00279 memset(ctx, 0, sizeof(*ctx));
00280 ctx->fd = fd;
00281 }