Project

General

Profile

Statistics
| Revision:

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

History | View | Annotate | Download (7.02 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
 *
48
 * Definition for ack buffer
49
 * 2 bit system: 0=still sending
50
 *               1=OK
51
 *               2=ack failure
52
 *               3=CCA failure
53
 **/
54

    
55

    
56
/* global variables */
57
uint8_t nextframe = 1;
58
uint8_t ack_buf[64];
59

    
60
/* private function prototypes */
61
void setack(uint8_t num,uint8_t val);
62

    
63

    
64
// the send functions
65

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

    
71

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

    
109
  // send the packet
110
  if (xbee_send_packet(packet,length,dest,options,(uint_8)ret_val) != 0) {
111
    WL_DEBUG_PRINT("Error sending packet from core send function\r\n");
112
    return WL_ERROR_SEND;
113
  }
114
  
115
  // increment frame number
116
  nextframe = (nextframe == 0xFF)?1:nextframe+1;
117
    
118

    
119
  return ret_val; // return frame number for ack tracking
120
}
121

    
122
/**
123
 * Wrapper for core send function that will send a global packet across the current channel.
124
 *
125
 * @param data pointer to the byte array of data to be included in the packet
126
 * @param length the length of the data array
127
 * @param group the packet group of the packet
128
 *
129
 * @return positive packet number for tracking acks, or error code (TBD)
130
 **/
131
int16_t wl_send_global(char *data, uint8_t length, uint8_t group) {
132

    
133
  return 0;
134
}
135

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

    
147
  return 0;
148
}
149

    
150
/**
151
 * Wrapper for core send function that will send a packet across the current channel to a specific robot. 
152
 *
153
 * @param data pointer to the byte array of data to be included in the packet
154
 * @param length the length of the data array
155
 * @param group the packet group of the packet 
156
 * @param dest robot ID (for robot to robot packet)
157
 * @param mode flag for using FAST or RELIABLE sending
158
 *
159
 * @return positive packet number for tracking acks, or error code (TBD)
160
 **/
161
int16_t wl_send_robot(char *data, uint8_t length, uint8_t group, uint16_t dest, uint8_t mode) {
162

    
163
  return 0;
164
}
165

    
166
/**
167
 * Default (i.e. basic) send wrapper.
168
 *
169
 * @param data pointer to the byte array of data to be included in the packet
170
 * @param length the length of the data array
171
 *
172
 * @return positive packet number for tracking acks, or error code (TBD)
173
 **/
174
int16_t wl_send_basic(char *data, uint8_t length) {
175

    
176
  return 0;
177
}
178

    
179

    
180
/**
181
 * acknowledgment error
182
 * check if any of the packets you have sent have been lost.
183
 *
184
 * note that all other error checking will be handled by library, 
185
 * so your user behavior won't have to worry about it
186
 *
187
 * @return the # of packets lost (up to 255)
188
 **/
189
uint8_t wl_ack_error(void) {
190
  uint_8 val=0,i=1;
191
  
192
  while(1) {
193
    if (ack_buf[i/4]&(0x3<<(i%4)) != 0)
194
      val++;
195
    if (i==255)
196
      break;
197
    i++;
198
  }
199

    
200
  return val;
201
}
202

    
203
/**
204
 * acknowledgement error check
205
 * check if a specific packet has been lost
206
 * note: buffer will overflow every 255 packets
207
 * 
208
 * @param packet packet number
209
 *
210
 * @return {SENDING,ACK_OK,ACK_FAILURE,CCA_FAILURE}
211
 **/
212
int8_t wl_ack_check(uint8_t packet) {
213
  if (packet == 0) {
214
    // no ack information here
215
    WL_DEBIG_PRINT("packet number cannot be 0\r\n");
216
    return WL_ERROR_ARGUMENT;
217
  }
218
  
219
  // check ack
220
  return ack_buf[packet/4]&(0x3<<(packet%4));
221
}
222

    
223
/**
224
 * acknowledgement reset
225
 * reset the acknowledgement buffer
226
 **/
227
void wl_ack_reset(void) {
228
  memset(ack_buf,0,64);
229
}
230

    
231

    
232
/**@} **/ //end defgroup
233

    
234

    
235
// Define all private functions down here
236

    
237
/*
238
 * sets 2 bits in the ack_buf
239
 *
240
 * @param num the ack number
241
 * @param val {SENDING,ACK_OK,ACK_FAILURE,CCA_FAILURE}
242
 */
243
void setack(uint8_t num,uint8_t val) {
244
  switch(num%4) {
245
  case 0:
246
    ack_buf[num/4] &= (0xFC|val);
247
    break;
248
  case 1:
249
    ack_buf[num/4] &= (0xF3|(val<<2));
250
    break;
251
  case 2:
252
    ack_buf[num/4] &= (0xCF|(val<<4));
253
    break;
254
  case 3:
255
    ack_buf[num/4] &= (0x3F|(val<<6));
256
    break;
257
  }
258
}
259

    
260

    
261
/* ack handler */
262
void ackhandle(uint8_t num,uint8_t val) {
263
  switch(val) {
264
  case 0:
265
    // success
266
    setack(num,ACK_OK);
267
    break;
268
  case 1:
269
    // no ack
270
    setack(num,ACK_FAILURE);
271
    break;
272
  case 2:
273
    // CCA failure
274
    setack(num,CCA_FAILURE);
275
    break;
276
}
277