1
0
mirror of git://projects.qi-hardware.com/antorcha.git synced 2024-11-01 11:28:26 +02:00
antorcha/fw/dispatch.c
Werner Almesberger 56476539cf fw/: addition of boot loader (WIP) and assorted cleanup and improvements
The boot loader currently uses the protocol switch intended for the
application. This makes it too big to fit in the very limiting
constraints the ATmega168 poses - and there's not even cryptographic
authentication yet. We'll have to dumb it down quite a bit.
2012-06-18 10:56:43 -03:00

105 lines
1.8 KiB
C

/*
* fw/dispatch.c - Wireless protocol dispatcher
*
* Written 2012 by Werner Almesberger
* Copyright 2012 Werner Almesberger
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#define F_CPU 8000000UL
#include <util/delay.h>
#include "rf.h"
#include "proto.h"
#include "dispatch.h"
#include "io.h"
static uint8_t seq; /* last sequence number seen */
static uint8_t type; /* type currently being processed */
static uint8_t limit; /* last limit seen */
static const struct handler *curr_proto = NULL;
static void send_ack(const uint8_t *buf)
{
uint8_t ack[3] = { buf[0]+1, buf[1], 0 };
SET(LED_B6);
_delay_ms(1);
rf_send(ack, sizeof(ack));
CLR(LED_B6);
}
static bool answer_ping(const uint8_t *buf)
{
uint8_t pong[] = { PONG, 0, 0 };
if (buf[1])
return 0;
rf_send(pong, sizeof(pong));
return 1;
}
bool dispatch(const uint8_t *buf, uint8_t len, const struct handler **protos)
{
SET(LED_B7);
CLR(LED_B7);
if (len == 3 && buf[0] == PING)
return answer_ping(buf);
if (len != 64+3)
return 0;
if (!buf[1]) {
while (*protos) {
if ((*protos)->type == buf[0])
break;
protos++;
}
if (!*protos)
return 0;
if (!(*protos)->first(buf+3))
return 0;
curr_proto = *protos;
type = buf[0];
seq = 0;
limit = buf[2];
send_ack(buf);
return 1;
}
if (!curr_proto)
return 0;
if (buf[0] != type)
return 0;
if (buf[1] > limit)
return 0;
if (buf[2] != limit)
return 0;
if (buf[1] == seq) {
send_ack(buf);
return 0;
}
if (buf[1] != seq+1)
return 0;
if (!curr_proto->more(buf[1], limit, buf+3))
return 0;
seq++;
send_ack(buf);
return 1;
}