Project

General

Profile

Statistics
| Revision:

root / branches / wireless / code / projects / libwireless / wireless_receive.c @ 1612

History | View | Annotate | Download (6.6 KB)

1
/**
2
 * Copyright (c) 2009 Colony Project
3
 *
4
 * Permission is hereby granted, free of charge, to any person
5
 * obtaining a copy of this software and associated documentation
6
 * files (the "Software"), to deal in the Software without
7
 * restriction, including without limitation the rights to use,
8
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9
 * copies of the Software, and to permit persons to whom the
10
 * Software is furnished to do so, subject to the following
11
 * conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be
14
 * included in all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
 * OTHER DEALINGS IN THE SOFTWARE.
24
 **/
25

    
26
/**
27
 * @file wireless_receive.c
28
 * @brief Wireless library receive functions
29
 *
30
 * Implementation of high level wireless communication.
31
 * This is the receive functions portion of the library.
32
 *
33
 * @author Colony Project, CMU Robotics Club
34
 **/
35

    
36
#include <string.h>
37
#include "wl_defs.h"
38
#include "wireless.h"
39
#include "xbee.h"
40

    
41
/**
42
 * Definition for wireless library receive packet structure
43
 *
44
 * Basic Buffer Packet:
45
 *   byte 1: length of data
46
 *   bytes 2-3: source
47
 *   bytes 4-n: data
48
 *
49
 * Other Buffer Packet:
50
 *   byte 1: length of data
51
 *   byte 2: group number
52
 *   bytes 3-4: source
53
 *   bytes 5-n: data
54
 *
55
 **/
56

    
57
extern uint8_t xbee_basic_buf[PACKET_BUFFER_SIZE];  // buffer for basic-group packets
58
extern uint8_t xbee_other_buf[PACKET_BUFFER_SIZE];  // buffer for non-basic-group packets
59
extern uint8_t basic_buf_first;        // beginning of first packet in basic buffer
60
extern uint8_t basic_buf_last;        // end of last packet in basic buffer
61
extern uint8_t other_buf_first; // beginning of first packet in other buffer
62
extern uint8_t other_buf_last;  // end of last packet in other buffer
63
extern void (*handlers[])(void);    // array of pointers to normal-priority packet handlers
64

    
65
/**
66
 * @addtogroup wireless Wireless
67
 * @{
68
 **/
69

    
70
/**
71
 * the main receive function (similar to wl_do)
72
 * 
73
 * when called, this function will receive the next packet on the default packet group
74
 * it will also dispatch registered packet handler functions for any other packet groups it has received
75
 *
76
 * @param data an already-initialized array to store the default group packet data in
77
 * @param length the length of the initialized data array
78
 *
79
 * @return the length of the used portion of data array or error (<0)
80
 **/
81
int8_t wl_get(char *data, uint8_t length) {
82
  int8_t return_code = wl_dispatch(); // run dispatch of other packet groups
83
  if (return_code != 0)
84
    return return_code; // error, so end early
85
  return wl_get_basic(data, length); // get a basic packet
86
}
87

    
88
/**
89
 * function to receive only packets on the default group
90
 * this function is only meant to receive packets sent using wl_send_basic()
91
 * 
92
 * @param data an already-initialized array to store the default group packet data in
93
 * @param length the length of the initialized data array
94
 * 
95
 * @return the length of the used portion of data array or error (<0)
96
 **/
97
int8_t wl_get_basic(char *data, uint8_t length) {
98
    uint8_t buf_pos = basic_buf_first;        // start at beginning of first (oldest) basic packet
99
    uint8_t data_length = xbee_basic_buf[buf_pos % PACKET_BUFFER_SIZE];  // get packet length
100

    
101
    if (data_length - 3 > length)   // not enough room for data in destination
102
        return WL_ERROR_TOO_SMALL;
103

    
104
    // packet has not fully arrived yet
105
    if (buf_pos + data_length > basic_buf_last        // length goes farther than end of buffer
106
            && !(buf_pos >= basic_buf_last && buf_pos + data_length > buf_pos))
107
        /* basic test is Beginning + Length > Buffer End means packet isn't all there yet
108
           if end counter overflows, a complete packet's end may still be greater than the buffer end index,
109
           but such a packet can be read from the buffer
110
         */
111
        return WL_SUCCESS;  // no data written
112

    
113
    buf_pos++;
114
    buf_pos++;        // ignore the source ID
115

    
116
    // copy data to destination, byte by byte to account for circular buffer
117
    // don't copy the 3 header bytes. nobody wants those.
118
    for (; buf_pos < basic_buf_first + data_length; buf_pos++)
119
        memcpy(data + buf_pos - 3, xbee_basic_buf + (buf_pos % PACKET_BUFFER_SIZE), 1);
120

    
121
    basic_buf_first += data_length; // "free up" this packet's buffer space
122

    
123
    return data_length;
124
}
125

    
126
/*
127
 * function to dispatch all registered packet handlers for received packets on non-default groups
128
 *
129
 * @return error codes (TBD)
130
 */
131
int8_t wl_dispatch(void) {
132
    uint8_t buf_pos = other_buf_first;        // current position in buffer
133
    uint8_t group;  // group of packet under consideration
134
    void (*handler)(uint8_t *data, uint8_t length, uint8_t source);  // handler for group of packet under consideration
135
    uint8_t length = xbee_other_buf[buf_pos % PACKET_BUFFER_SIZE];  // length of packet under consideration
136
    uint8_t source; // robot ID of sender of packet under consideration
137

    
138
    // consider packets one at a time until buffer contains no complete packets
139
    while (buf_pos + length <= other_buf_last        // length goes farther than end of buffer
140
            || (buf_pos >= other_buf_last && buf_pos + length > buf_pos)) {
141
        /* basic test is Beginning + Length > Buffer End means packet isn't all there yet
142
           if end counter overflows, a complete packet's end may still be greater than the buffer end index,
143
           but such a packet can be read from the buffer
144
         */
145
        buf_pos++;
146
        group = xbee_other_buf[buf_pos];    // get group from packet
147
        if (group >= WL_NUM_PACKET_GROUPS)  // invalid group number
148
            buf_pos += length - 1 + 1;        // go to first byte of next packet
149
        else {        // valid group number
150
            handler = handlers[group].FUNC;        // get function from handler array
151
            buf_pos++;
152
            buf_pos++;  // ignore 1st byte of ID (will be all 0s)
153
            source = xbee_other_buf[buf_pos];   // get sender ID from packet
154
            buf_pos++;  // now index of beginning of packet data (mod PACKET_BUFFER_SIZE)
155

    
156
            if (handler)        // check whether group is handled
157
                (*handler)(xbee_other_buf + (buf_pos & PACKET_BUFFER_SIZE), length - 4, source);
158

    
159
            // go to next packet
160
            buf_pos += length - 4 + 1;  // go to first byte of next packet
161
        }
162

    
163
        length = xbee_other_buf[buf_pos & PACKET_BUFFER_SIZE];        // get length of next packet
164
    }
165

    
166
    return WL_SUCCESS;
167
}
168

    
169

    
170
/**@} **/ //end defgroup
171

    
172

    
173
// Define all private functions down here
174

    
175

    
176