Project

General

Profile

Statistics
| Revision:

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

History | View | Annotate | Download (6.51 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

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

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

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

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

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

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

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

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

    
122
    return data_length;
123
}
124

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

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

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

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

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

    
165
    return WL_SUCCESS;
166
}
167

    
168

    
169
/**@} **/ //end defgroup
170

    
171

    
172
// Define all private functions down here
173

    
174

    
175