Root/fw/dispatch.c

1/*
2 * fw/dispatch.c - Wireless protocol dispatcher
3 *
4 * Written 2012 by Werner Almesberger
5 * Copyright 2012 Werner Almesberger
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13
14#include <stddef.h>
15#include <stdbool.h>
16#include <stdint.h>
17#include <string.h>
18
19#include "version.h"
20#include "rf.h"
21#include "proto.h"
22#include "dispatch.h"
23
24
25static uint8_t seq; /* last sequence number seen */
26static uint8_t type; /* type currently being processed */
27static uint8_t limit; /* last limit seen */
28static const struct handler *curr_proto = NULL;
29
30
31static void send_ack(const uint8_t *buf)
32{
33    uint8_t ack[3] = { buf[0]+1, buf[1], 0 };
34
35    rf_send(ack, sizeof(ack));
36}
37
38
39static bool answer_ping(const uint8_t *buf)
40{
41    char num[6]; /* let's hope we won't need more than 9999 versions */
42    char *num_end = num+sizeof(num);
43    int date_len = strlen(build_date);
44    int num_len;
45    uint8_t pong[3] = { PONG, 0, 0 };
46    uint8_t tmp[3+6+date_len+1];
47    char *s;
48    int n;
49    
50    if (buf[1])
51        return 0;
52    s = num_end-1;
53    *s = ' ';
54    for (n = build_number; n; n /= 10)
55        *--s = '0'+n % 10;
56    *--s = '#';
57    num_len = num_end-s;
58    memcpy(tmp, pong, 3);
59    memcpy(tmp+3, s, num_len);
60    memcpy(tmp+3+num_len, build_date, date_len);
61    rf_send(tmp, 3+num_len+date_len);
62    return 1;
63}
64
65
66bool dispatch(const uint8_t *buf, uint8_t len, const struct handler **protos)
67{
68    if (len == 3 && buf[0] == PING)
69        return answer_ping(buf);
70
71    if (len != 64+3)
72        return 0;
73
74    if (!buf[1]) {
75        while (*protos) {
76            if ((*protos)->type == buf[0])
77                break;
78            protos++;
79        }
80        if (!*protos)
81            return 0;
82        if (!(*protos)->first(buf[2], buf+3))
83            return 0;
84        curr_proto = *protos;
85        type = buf[0];
86        seq = 1;
87        limit = buf[2];
88        send_ack(buf);
89        return 1;
90    }
91
92    if (!curr_proto)
93        return 0;
94    if (buf[0] != type)
95        return 0;
96    if (buf[2] != limit)
97        return 0;
98    if (buf[1] > limit)
99        return 0;
100
101    if (buf[1]+1 == seq) {
102        send_ack(buf);
103        return 0;
104    }
105    if (buf[1] != seq)
106        return 0;
107
108    if (!curr_proto->more(seq, limit, buf+3))
109        return 0;
110    seq++;
111    send_ack(buf);
112    return 1;
113
114}
115

Archive Download this file

Branches:
master
tornado-v1



interactive