pocketbus.c
Go to the documentation of this file.00001
00058 #include "pocketbus.h"
00059
00060 #include <cfg/macros.h>
00061 #include <cfg/debug.h>
00062
00063 #include <kern/kfile.h>
00064
00065 #include <mware/byteorder.h>
00066
00067 #include <string.h>
00068
00072 void pocketbus_putchar(struct PocketBusCtx *ctx, uint8_t c)
00073 {
00074
00075 rotating_update1(c, &ctx->out_cks);
00076
00077
00078 if (c == POCKETBUS_ESC || c == POCKETBUS_STX || c == POCKETBUS_ETX)
00079 kfile_putc(POCKETBUS_ESC, ctx->fd);
00080
00081 kfile_putc(c, ctx->fd);
00082 }
00083
00087 void pocketbus_begin(struct PocketBusCtx *ctx, pocketbus_addr_t addr)
00088 {
00089 PocketBusHdr hdr;
00090
00091 hdr.ver = POCKETBUS_VER;
00092 hdr.addr = cpu_to_be16(addr);
00093 rotating_init(&ctx->out_cks);
00094
00095
00096 kfile_putc(POCKETBUS_STX, ctx->fd);
00097
00098
00099 pocketbus_write(ctx, &hdr, sizeof(hdr));
00100 }
00101
00105 void pocketbus_write(struct PocketBusCtx *ctx, const void *_data, size_t len)
00106 {
00107 const uint8_t *data = (const uint8_t *)_data;
00108
00109 while (len--)
00110 pocketbus_putchar(ctx, *data++);
00111 }
00112
00116 void pocketbus_end(struct PocketBusCtx *ctx)
00117 {
00118
00119 rotating_t cks = cpu_to_be16(ctx->out_cks);
00120 pocketbus_write(ctx, &cks, sizeof(cks));
00121
00122
00123 kfile_putc(POCKETBUS_ETX, ctx->fd);
00124 }
00125
00129 void pocketbus_send(struct PocketBusCtx *ctx, pocketbus_addr_t addr, const void *data, size_t len)
00130 {
00131 pocketbus_begin(ctx, addr);
00132
00133
00134 pocketbus_write(ctx, data, len);
00135
00136 pocketbus_end(ctx);
00137 }
00138
00139
00144 bool pocketbus_recv(struct PocketBusCtx *ctx, struct PocketMsg *msg)
00145 {
00146 int c;
00147
00148
00149 while ((c = kfile_getc(ctx->fd)) != EOF)
00150 {
00151
00152 if (c == POCKETBUS_STX && !ctx->escape)
00153 {
00154
00155 if (ctx->sync)
00156 kprintf("pocketBus double sync!\n");
00157
00158 ctx->sync = true;
00159 ctx->len = 0;
00160 rotating_init(&ctx->in_cks);
00161 continue;
00162 }
00163
00164 if (ctx->sync)
00165 {
00166
00167 if (c == POCKETBUS_ESC && !ctx->escape)
00168 {
00169 ctx->escape = true;
00170 continue;
00171 }
00172
00173
00174 if (c == POCKETBUS_ETX && !ctx->escape)
00175 {
00176 ctx->sync = false;
00177
00178
00179 if (ctx->len < sizeof(PocketBusHdr) + sizeof(rotating_t))
00180 {
00181 kprintf("pocketBus short pkt!\n");
00182 continue;
00183 }
00184
00185
00186 ctx->len -= sizeof(rotating_t);
00187
00188
00189 rotating_update(ctx->buf, ctx->len, &ctx->in_cks);
00190 rotating_t recv_cks = be16_to_cpu(*((rotating_t *)(ctx->buf + ctx->len)));
00191
00192
00193 if (recv_cks == ctx->in_cks)
00194 {
00195 PocketBusHdr *hdr = (PocketBusHdr *)(ctx->buf);
00196
00197 if (hdr->ver == POCKETBUS_VER)
00198 {
00199
00200 msg->payload = ctx->buf + sizeof(PocketBusHdr);
00201 msg->addr = be16_to_cpu(hdr->addr);
00202 msg->len = ctx->len - sizeof(PocketBusHdr);
00203 msg->ctx = ctx;
00204 return true;
00205 }
00206 else
00207 {
00208 kprintf("pocketBus version mismatch, here[%d], there[%d]\n", POCKETBUS_VER, hdr->ver);
00209 continue;
00210 }
00211 }
00212 else
00213 {
00214 kprintf("pocketBus cks error, here[%04X], there[%04X]\n", ctx->in_cks, recv_cks);
00215 continue;
00216 }
00217
00218 }
00219
00220 ctx->escape = false;
00221
00222
00223
00224 if (ctx->len >= CONFIG_POCKETBUS_BUFLEN)
00225 {
00226 kprintf("pocketBus buffer overflow\n");
00227 ctx->sync = false;
00228 continue;
00229 }
00230
00231
00232 ctx->buf[ctx->len] = c;
00233 ctx->len++;
00234 }
00235 }
00236
00237
00238
00239
00240 if (kfile_error(ctx->fd))
00241 {
00242 TRACEMSG("fd status[%04X]", kfile_error(ctx->fd));
00243 kfile_clearerr(ctx->fd);
00244 }
00245
00246 return false;
00247 }
00248
00249
00253 void pocketbus_init(struct PocketBusCtx *ctx, struct KFile *fd)
00254 {
00255 ASSERT(ctx);
00256 ASSERT(fd);
00257
00258 memset(ctx, 0, sizeof(*ctx));
00259 ctx->fd = fd;
00260 }