Project

General

Profile

Statistics
| Revision:

root / branches / wireless / code / projects / libwireless / wireless_send.c @ 1600

History | View | Annotate | Download (7.73 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_send.c
28
 * @brief Wireless library send functions
29
 *
30
 * Implementation of high level wireless communication.
31
 * This is the send functions portion of the library.
32
 *
33
 * @author Colony Project, CMU Robotics Club
34
 **/
35

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

    
40

    
41
/**
42
 * Definition for wireless library send packet structure
43
 * byte 1: length of packet
44
 * byte 2: frame number
45
 * byte 3: group code 
46
 * bytes 4-n: data
47
 * (byte n+1: num retries - only saved locally in sending buffer)
48
 *
49
 * Definition for ack buffer
50
 * 2 bit system: 0=still sending
51
 *               1=OK
52
 *               2=ack failure
53
 *               3=CCA failure
54
 **/
55

    
56

    
57
/* global variables */
58
uint8_t nextframe = 1; // number of next frame
59
uint8_t ack_buf[64]; // ack buffer (holds 255 packet return codes)
60
uint8_t send_buf[PACKET_BUFFER_SIZE]; // sending buffer for retries
61
uint8_t send_buf_first = 0; // first byte of data on buffer
62
uint8_t send_buf_last = 0; // next free byte on buffer
63

    
64
/* private function prototypes */
65
void setack(uint8_t num,uint8_t val);
66

    
67

    
68
// the send functions
69

    
70
/**
71
 * @addtogroup wireless Wireless
72
 * @{
73
 **/
74

    
75

    
76
/**
77
 * The core send function. This will take all possible arguments and send all types of packets.
78
 * 
79
 * @param data pointer to the byte array of data to be included in the packet
80
 * @param length the length of the data array
81
 * @param group the packet group of the packet
82
 * @param scope flag for sending global packet or your current PAN
83
 * @param dest robot ID (for robot to robot packet)
84
 * @param mode flag for using FAST or RELIABLE sending
85
 *
86
 * @return positive packet number for tracking acks, or error code (TBD)
87
 **/
88
int16_t wl_send(uint8_t *data, uint8_t length, uint8_t group, uint8_t scope, uint16_t dest, uint8_t mode) {
89
  uint8_t packet[length+2];
90
  uint8_t options = XBEE_OPTIONS_NONE;
91
  int16_t ret_val = (int16_t)nextframe;
92
  
93
  // build packet
94
  packet[0] = nextframe;
95
  packet[1] = group;
96
  memcpy(packet+2,data,length);
97
  
98
  // set scope
99
  if (scope == GLOBAL)
100
    options &= XBEE_OPTIONS_BROADCAST_ALL_PANS;
101
    
102
  // set mode
103
  if (mode == FAST) {
104
    options &= XBEE_OPTIONS_DISABLE_RESPONSE;
105
    ret_val = 0;
106
  } else if (mode != RELIABLE) {
107
    WL_DEBUG_PRINT("Error - bad mode in core send function\r\n");
108
    return WL_ERROR_MODE;
109
  }
110

    
111
  // send the packet
112
  if (xbee_send_packet(packet,length,dest,options,(uint_8)ret_val) != 0) {
113
    WL_DEBUG_PRINT("Error sending packet from core send function\r\n");
114
    return WL_ERROR_SEND;
115
  }
116
  
117
  // save in ack system
118
  if (mode == FAST) {
119
    setack(nextframe,ACK_OK); // assume the send was successful
120
  } else if (mode == RELIABLE) {
121
    setack(nextframe,SENDING); // set status to SENDING
122
    // TODO: save packet on sending buffer
123
    /* if (buffer full) {
124
      WL_DEBUG_PRINT("Error: sending buffer full\r\n");
125
      return WL_ERROR_SENDING_BUFFER_FULL
126
    } */
127
  }
128
  
129
  // increment frame number
130
  nextframe = (nextframe == 0xFF)?1:nextframe+1;
131

    
132
  return ret_val; // return frame number for ack tracking
133
}
134

    
135
/**
136
 * Wrapper for core send function that will send a global packet across the current channel.
137
 *
138
 * @param data pointer to the byte array of data to be included in the packet
139
 * @param length the length of the data array
140
 * @param group the packet group of the packet
141
 *
142
 * @return positive packet number for tracking acks, or error code (TBD)
143
 **/
144
int16_t wl_send_global(char *data, uint8_t length, uint8_t group) {
145

    
146
  return 0;
147
}
148

    
149
/**
150
 * Wrapper for core send function that will send a packet across the current channel on the current pan.
151
 *
152
 * @param data pointer to the byte array of data to be included in the packet
153
 * @param length the length of the data array
154
 * @param group the packet group of the packet
155
 *
156
 * @return positive packet number for tracking acks, or error code (TBD)
157
 **/
158
int16_t wl_send_pan(char *data, uint8_t length, uint8_t group) {
159

    
160
  return 0;
161
}
162

    
163
/**
164
 * Wrapper for core send function that will send a packet across the current channel to a specific robot. 
165
 *
166
 * @param data pointer to the byte array of data to be included in the packet
167
 * @param length the length of the data array
168
 * @param group the packet group of the packet 
169
 * @param dest robot ID (for robot to robot packet)
170
 * @param mode flag for using FAST or RELIABLE sending
171
 *
172
 * @return positive packet number for tracking acks, or error code (TBD)
173
 **/
174
int16_t wl_send_robot(char *data, uint8_t length, uint8_t group, uint16_t dest, uint8_t mode) {
175

    
176
  return 0;
177
}
178

    
179
/**
180
 * Default (i.e. basic) send wrapper.
181
 *
182
 * @param data pointer to the byte array of data to be included in the packet
183
 * @param length the length of the data array
184
 *
185
 * @return positive packet number for tracking acks, or error code (TBD)
186
 **/
187
int16_t wl_send_basic(char *data, uint8_t length) {
188

    
189
  return 0;
190
}
191

    
192

    
193
/**
194
 * acknowledgment error
195
 * check if any of the packets you have sent have been lost.
196
 *
197
 * note that all other error checking will be handled by library, 
198
 * so your user behavior won't have to worry about it
199
 *
200
 * @return the # of packets lost (up to 255)
201
 **/
202
uint8_t wl_ack_error(void) {
203
  uint_8 val=0,i=1;
204
  
205
  while(1) {
206
    if (ack_buf[i/4]&(0x2<<(i%4)) != 0) // if the ack is in an error state
207
      val++;
208
    if (i==255)
209
      break;
210
    i++;
211
  }
212

    
213
  return val;
214
}
215

    
216
/**
217
 * acknowledgement error check
218
 * check if a specific packet has been lost
219
 * note: buffer will overflow every 255 packets
220
 * 
221
 * @param packet packet number
222
 *
223
 * @return {SENDING,ACK_OK,ACK_FAILURE,CCA_FAILURE}
224
 **/
225
int8_t wl_ack_check(uint8_t packet) {
226
  if (packet == 0) {
227
    // no ack information here
228
    WL_DEBIG_PRINT("packet number cannot be 0\r\n");
229
    return WL_ERROR_ARGUMENT;
230
  }
231
  
232
  // check ack
233
  return ack_buf[packet/4]&(0x3<<(packet%4));
234
}
235

    
236
/**
237
 * acknowledgement reset
238
 * reset the acknowledgement buffer
239
 **/
240
void wl_ack_reset(void) {
241
  memset(ack_buf,0,64);
242
}
243

    
244

    
245
/**@} **/ //end defgroup
246

    
247

    
248
// Define all private functions down here
249

    
250
/*
251
 * sets 2 bits in the ack_buf
252
 *
253
 * @param num the ack number
254
 * @param val {SENDING,ACK_OK,ACK_FAILURE,CCA_FAILURE}
255
 */
256
void setack(uint8_t num,uint8_t val) {
257
  switch(num%4) {
258
  case 0:
259
    ack_buf[num/4] &= (0xFC|val);
260
    break;
261
  case 1:
262
    ack_buf[num/4] &= (0xF3|(val<<2));
263
    break;
264
  case 2:
265
    ack_buf[num/4] &= (0xCF|(val<<4));
266
    break;
267
  case 3:
268
    ack_buf[num/4] &= (0x3F|(val<<6));
269
    break;
270
  }
271
}
272

    
273

    
274
/* ack handler */
275
void ackhandle(uint8_t num,uint8_t val) {
276
  switch(val) {
277
  case 0:
278
    // success
279
    setack(num,ACK_OK); // set status code
280
    // TODO: remove from sending buffer
281
    break;
282
  case 1:
283
    // no ack
284
    // TODO: check resend attempts
285
    setack(num,ACK_FAILURE);
286
    break;
287
  case 2:
288
    // CCA failure
289
    // TODO: check resend attempts
290
    setack(num,CCA_FAILURE);
291
    break;
292
}
293