Project

General

Profile

Statistics
| Revision:

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

History | View | Annotate | Download (7.81 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 source+data
46
 *   bytes 2-3: source
47
 *   bytes 4-n: data
48
 *
49
 * Other Buffer Packet:
50
 *   byte 1: length of group+source+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 uint8_t xbee_basic_buf_get(uint8_t *ptr); // get byte from basic buf
64
extern uint8_t xbee_other_buf_get(uint8_t *ptr); // get byte from other buf
65

    
66

    
67
/**
68
 * @addtogroup wireless Wireless
69
 * @{
70
 **/
71

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

    
90
/**
91
 * function to receive only packets on the default group
92
 * this function is only meant to receive packets sent using wl_send_basic()
93
 * 
94
 * @param data an already-initialized array to store the default group packet data in
95
 * @param length the length of the initialized data array
96
 * 
97
 * @return the length of the used portion of data array or error (<0)
98
 **/
99
int8_t wl_get_basic(char *data, uint8_t length) {
100
  uint8_t buf_pos = basic_buf_first;        // start at beginning of first (oldest) basic packet
101
  uint8_t data_length = 0xFF;
102
  while((data_length = xbee_basic_buf_get(&buf_pos)) == 0xFF) {  // get packet length
103
    if (buf_pos == basic_buf_last)
104
      break;
105
  }
106
  if (buf_pos == basic_buf_last)
107
      return WL_SUCCESS;
108
  if (data_length - 3 > length)   // not enough room for data in destination
109
    return WL_ERROR_TOO_SMALL;
110
  
111
  WL_DEBUG_PRINT_P("entered wl_get_basic\r\n");
112

    
113
  // packet has not fully arrived yet
114
  if (buf_pos + data_length >= PACKET_BUFFER_SIZE) {
115
    if ((buf_pos + data_length - PACKET_BUFFER_SIZE) > basic_buf_last)
116
      return WL_SUCCESS;
117
  } else {
118
    if ((buf_pos + data_length) > basic_buf_last)
119
      return WL_SUCCESS;
120
  }  
121
  WL_DEBUG_PRINT_P("wl_get_basic() - packet has arrived\r\n");
122
  
123
  // ignore the source ID
124
  xbee_basic_buf_get(&buf_pos);
125
  xbee_basic_buf_get(&buf_pos);
126
  
127
  // copy data to destination, byte by byte to account for circular buffer
128
  data_length-=2;
129
  uint8_t i;
130
  for(i=0;i<data_length;i++) {
131
    data[i] = xbee_basic_buf_get(&buf_pos);
132
  }
133
  WL_DEBUG_PRINT_P("we advanced ");
134
  WL_DEBUG_PRINT_INT(i+3);
135
  WL_DEBUG_PRINT_P(" bytes"); 
136
  WL_DEBUG_PRINT_P("|first=");
137
  WL_DEBUG_PRINT_INT(basic_buf_first);
138
  WL_DEBUG_PRINT_P("|last=");
139
  WL_DEBUG_PRINT_INT(basic_buf_last);
140
  
141
  // "free up" this packet's buffer space
142
  if (buf_pos == 0)
143
    basic_buf_first = PACKET_BUFFER_SIZE-1;
144
  else
145
    basic_buf_first = buf_pos-1;
146
    
147
  xbee_basic_buf[basic_buf_first] = 0xFF;
148
    
149
  WL_DEBUG_PRINT_P("|first=");
150
  WL_DEBUG_PRINT_INT(basic_buf_first);
151
  WL_DEBUG_PRINT_P("|last=");
152
  WL_DEBUG_PRINT_INT(basic_buf_last);
153
  WL_DEBUG_PRINT_P("\r\n");
154

    
155
  return data_length;
156
}
157

    
158
/*
159
 * function to dispatch all registered packet handlers for received packets on non-default groups
160
 *
161
 * @return error codes
162
 */
163
int8_t wl_dispatch(void) {
164
  uint8_t buf_pos = other_buf_first;        // start at beginning of first (oldest) basic packet
165
  uint8_t data_length = 0xFF;  
166
  uint8_t group;  // group of packet under consideration
167
  FNPTR; // pointer to handler
168
  uint8_t source=0; // robot ID of sender of packet under consideration
169
  
170
  WL_DEBUG_PRINT_P("entered wl_dispatch\r\n");
171
  
172
  while(1) {
173
    while((data_length = xbee_other_buf_get(&buf_pos)) == 0xFF) {  // get packet length
174
      WL_DEBUG_PRINT_P("|searching - data_length=");
175
      WL_DEBUG_PRINT_HEX(data_length);
176
      WL_DEBUG_PRINT_P(" on pos=");
177
      WL_DEBUG_PRINT_INT(buf_pos);
178
      if (buf_pos == other_buf_last)
179
        break;
180
    }
181
    if (buf_pos == other_buf_last) {
182
      WL_DEBUG_PRINT_P("|buf_pos=other_buf_last\r\n");
183
      return WL_SUCCESS;
184
    }       
185
    
186
    // packet has not fully arrived yet
187
    if (buf_pos + data_length >= PACKET_BUFFER_SIZE) {
188
      if ((buf_pos + data_length - PACKET_BUFFER_SIZE) > other_buf_last)
189
        break;
190
    } else {
191
      if ((buf_pos + data_length) > other_buf_last)
192
        break;
193
    }  
194
    WL_DEBUG_PRINT_P("wl_dispatch() - packet has arrived\r\n");
195
    
196
    // get group number
197
    group = xbee_other_buf_get(&buf_pos);
198
    if (group >= MAX_PACKET_GROUPS || wl_packet_handlers[group].FUNC == NULL) {
199
      // this is an invalid group, so go to next packet
200
      if (buf_pos + data_length - 2 >= PACKET_BUFFER_SIZE)
201
        buf_pos += data_length - 2 - PACKET_BUFFER_SIZE;
202
      else
203
        buf_pos += data_length - 2;
204
    } else {
205
      // this is a valid group number, so get handler
206
      FUNC = wl_packet_handlers[group].FUNC;
207
      xbee_other_buf_get(&buf_pos); // ignore first byte of source id
208
      source = xbee_other_buf_get(&buf_pos); // get low byte of source id
209
      
210
      // call handler
211
      (*FUNC)(xbee_other_buf+buf_pos,data_length-4,source);
212
      
213
      // go to next packet
214
      if (buf_pos + data_length - 4 >= PACKET_BUFFER_SIZE)
215
        buf_pos += data_length - 4 - PACKET_BUFFER_SIZE;
216
      else
217
        buf_pos += data_length - 4;
218
    }
219
  }
220
  
221
  WL_DEBUG_PRINT_P("other_buf_first=");
222
  WL_DEBUG_PRINT_INT(other_buf_first);
223
    
224
  
225
  // mark packets as read
226
  other_buf_first = (buf_pos==0)?(PACKET_BUFFER_SIZE-1):(buf_pos-1);
227
  xbee_other_buf[other_buf_first] = 0xFF;
228

    
229
  WL_DEBUG_PRINT_P("Exit wl dispatch\r\n");  
230
  WL_DEBUG_PRINT_P("other_buf_first=");
231
  WL_DEBUG_PRINT_INT(other_buf_first);
232
  WL_DEBUG_PRINT_P("\r\n");
233

    
234
  return WL_SUCCESS;
235
}
236

    
237

    
238
/**@} **/ //end defgroup
239

    
240

    
241
// Define all private functions down here
242

    
243

    
244