root / branches / wireless / code / projects / libwireless / wireless_send.c @ 1587
History | View | Annotate | Download (6.71 KB)
1 | 1576 | dsschult | /**
|
---|---|---|---|
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 | 1587 | dsschult | #include <string.h> |
39 | 1576 | dsschult | |
40 | |||
41 | 1587 | dsschult | /* Definition for wireless library packet structure
|
42 | * byte 1: frame number
|
||
43 | * byte 2: group code
|
||
44 | * bytes 3-n: data
|
||
45 | *
|
||
46 | * Definition for ack buffer
|
||
47 | * 2 bit system: 0=still sending
|
||
48 | * 1=OK
|
||
49 | * 2=ack failure
|
||
50 | * 3=CCA failure
|
||
51 | */
|
||
52 | |||
53 | |||
54 | /* global variables */
|
||
55 | uint8_t nextframe = 1;
|
||
56 | uint8_t ack_buf[64];
|
||
57 | |||
58 | /* private function prototypes */
|
||
59 | void setack(uint8_t num,uint8_t val);
|
||
60 | |||
61 | |||
62 | 1576 | dsschult | // the send functions
|
63 | 1577 | dsschult | |
64 | /**
|
||
65 | * @addtogroup wireless Wireless
|
||
66 | * @{
|
||
67 | **/
|
||
68 | |||
69 | |||
70 | /**
|
||
71 | * The core send function. This will take all possible arguments and send all types of packets.
|
||
72 | *
|
||
73 | * @param data pointer to the byte array of data to be included in the packet
|
||
74 | * @param length the length of the data array
|
||
75 | * @param group the packet group of the packet
|
||
76 | 1581 | dsschult | * @param scope flag for sending global packet or your current PAN
|
77 | 1577 | dsschult | * @param dest robot ID (for robot to robot packet)
|
78 | 1581 | dsschult | * @param mode flag for using FAST or RELIABLE sending
|
79 | 1577 | dsschult | *
|
80 | 1581 | dsschult | * @return positive packet number for tracking acks, or error code (TBD)
|
81 | 1577 | dsschult | **/
|
82 | 1587 | dsschult | int16_t wl_send(uint8_t *data, uint8_t length, uint8_t group, uint8_t scope, uint16_t dest, uint8_t mode) { |
83 | uint8_t packet[length+2];
|
||
84 | uint8_t options = XBEE_OPTIONS_NONE; |
||
85 | int16_t ret_val = (int16_t)nextframe; |
||
86 | |||
87 | // build packet
|
||
88 | packet[0] = nextframe;
|
||
89 | packet[1] = group;
|
||
90 | memcpy(packet+2,data,length);
|
||
91 | |||
92 | // set options
|
||
93 | if (scope == GLOBAL)
|
||
94 | options &= XBEE_OPTIONS_BROADCAST_ALL_PANS; |
||
95 | if (mode == FAST) {
|
||
96 | options &= XBEE_OPTIONS_DISABLE_RESPONSE; |
||
97 | ret_val = 0;
|
||
98 | setack(nextframe,ACK_OK); // save in ack system
|
||
99 | } else if (mode == RELIABLE) { |
||
100 | // save in ack system
|
||
101 | setack(nextframe,SENDING); // save in ack system
|
||
102 | } else {
|
||
103 | WL_DEBUG_PRINT("Error - bad mode in core send function\r\n");
|
||
104 | return WL_ERROR_MODE;
|
||
105 | } |
||
106 | 1576 | dsschult | |
107 | 1587 | dsschult | // send the packet
|
108 | if (xbee_send_packet(packet,length,dest,options,(uint_8)ret_val) != 0) { |
||
109 | WL_DEBUG_PRINT("Error sending packet from core send function\r\n");
|
||
110 | return WL_ERROR_SEND;
|
||
111 | } |
||
112 | |||
113 | // increment frame number
|
||
114 | nextframe = (nextframe == 0xFF)?1:nextframe+1; |
||
115 | |||
116 | |||
117 | return ret_val; // return frame number for ack tracking |
||
118 | 1576 | dsschult | } |
119 | |||
120 | 1577 | dsschult | /**
|
121 | * Wrapper for core send function that will send a global packet across the current channel.
|
||
122 | *
|
||
123 | * @param data pointer to the byte array of data to be included in the packet
|
||
124 | * @param length the length of the data array
|
||
125 | * @param group the packet group of the packet
|
||
126 | *
|
||
127 | 1581 | dsschult | * @return positive packet number for tracking acks, or error code (TBD)
|
128 | 1577 | dsschult | **/
|
129 | 1581 | dsschult | int16_t wl_send_global(char *data, uint8_t length, uint8_t group) {
|
130 | 1576 | dsschult | |
131 | return 0; |
||
132 | } |
||
133 | |||
134 | 1577 | dsschult | /**
|
135 | * Wrapper for core send function that will send a packet across the current channel on the current pan.
|
||
136 | *
|
||
137 | * @param data pointer to the byte array of data to be included in the packet
|
||
138 | * @param length the length of the data array
|
||
139 | * @param group the packet group of the packet
|
||
140 | *
|
||
141 | 1581 | dsschult | * @return positive packet number for tracking acks, or error code (TBD)
|
142 | 1577 | dsschult | **/
|
143 | 1581 | dsschult | int16_t wl_send_pan(char *data, uint8_t length, uint8_t group) {
|
144 | 1576 | dsschult | |
145 | return 0; |
||
146 | } |
||
147 | |||
148 | 1577 | dsschult | /**
|
149 | * Wrapper for core send function that will send a packet across the current channel to a specific robot.
|
||
150 | *
|
||
151 | * @param data pointer to the byte array of data to be included in the packet
|
||
152 | * @param length the length of the data array
|
||
153 | * @param group the packet group of the packet
|
||
154 | * @param dest robot ID (for robot to robot packet)
|
||
155 | 1581 | dsschult | * @param mode flag for using FAST or RELIABLE sending
|
156 | 1577 | dsschult | *
|
157 | 1581 | dsschult | * @return positive packet number for tracking acks, or error code (TBD)
|
158 | 1577 | dsschult | **/
|
159 | 1581 | dsschult | int16_t wl_send_robot(char *data, uint8_t length, uint8_t group, uint16_t dest, uint8_t mode) {
|
160 | 1576 | dsschult | |
161 | return 0; |
||
162 | } |
||
163 | |||
164 | 1577 | dsschult | /**
|
165 | * Default (i.e. basic) send wrapper.
|
||
166 | *
|
||
167 | * @param data pointer to the byte array of data to be included in the packet
|
||
168 | * @param length the length of the data array
|
||
169 | *
|
||
170 | 1581 | dsschult | * @return positive packet number for tracking acks, or error code (TBD)
|
171 | 1577 | dsschult | **/
|
172 | 1581 | dsschult | int16_t wl_send_basic(char *data, uint8_t length) {
|
173 | 1576 | dsschult | |
174 | return 0; |
||
175 | } |
||
176 | |||
177 | |||
178 | 1577 | dsschult | /**
|
179 | * acknowledgment error
|
||
180 | 1581 | dsschult | * check if any of the packets you have sent have been lost.
|
181 | 1577 | dsschult | *
|
182 | 1581 | dsschult | * note that all other error checking will be handled by library,
|
183 | * so your user behavior won't have to worry about it
|
||
184 | 1577 | dsschult | *
|
185 | 1581 | dsschult | * @return the # of packets lost (up to 255)
|
186 | 1577 | dsschult | **/
|
187 | 1587 | dsschult | uint8_t wl_ack_error(void) {
|
188 | uint_8 val=0,i=1; |
||
189 | |||
190 | while(1) { |
||
191 | if (ack_buf[i/4]&(0x3<<(i%4)) != 0) |
||
192 | val++; |
||
193 | if (i==255) |
||
194 | break;
|
||
195 | i++; |
||
196 | } |
||
197 | 1576 | dsschult | |
198 | 1587 | dsschult | return val;
|
199 | 1576 | dsschult | } |
200 | |||
201 | 1581 | dsschult | /**
|
202 | * acknowledgement error check
|
||
203 | * check if a specific packet has been lost
|
||
204 | 1587 | dsschult | * note: buffer will overflow every 255 packets
|
205 | 1581 | dsschult | *
|
206 | 1587 | dsschult | * @param packet packet number
|
207 | 1581 | dsschult | *
|
208 | 1587 | dsschult | * @return {SENDING,ACK_OK,ACK_FAILURE,CCA_FAILURE}
|
209 | 1581 | dsschult | **/
|
210 | int8_t wl_ack_check(uint8_t packet) { |
||
211 | 1587 | dsschult | if (packet == 0) { |
212 | // no ack information here
|
||
213 | WL_DEBIG_PRINT("packet number cannot be 0\r\n");
|
||
214 | return WL_ERROR_ARGUMENT;
|
||
215 | } |
||
216 | |||
217 | // check ack
|
||
218 | return ack_buf[packet/4]&(0x3<<(packet%4)); |
||
219 | 1581 | dsschult | } |
220 | |||
221 | /**
|
||
222 | * acknowledgement reset
|
||
223 | * reset the acknowledgement buffer
|
||
224 | **/
|
||
225 | void wl_ack_reset(void) { |
||
226 | 1587 | dsschult | memset(ack_buf,0,64); |
227 | 1581 | dsschult | } |
228 | |||
229 | |||
230 | 1577 | dsschult | /**@} **/ //end defgroup |
231 | |||
232 | |||
233 | // Define all private functions down here
|
||
234 | |||
235 | 1587 | dsschult | /*
|
236 | * sets 2 bits in the ack_buf
|
||
237 | *
|
||
238 | * @param num the ack number
|
||
239 | * @param val {SENDING,ACK_OK,ACK_FAILURE,CCA_FAILURE}
|
||
240 | */
|
||
241 | void setack(uint8_t num,uint8_t val) {
|
||
242 | switch(num%4) { |
||
243 | case 0: |
||
244 | ack_buf[num/4] &= (0xFC|val); |
||
245 | break;
|
||
246 | case 1: |
||
247 | ack_buf[num/4] &= (0xF3|(val<<2)); |
||
248 | break;
|
||
249 | case 2: |
||
250 | ack_buf[num/4] &= (0xCF|(val<<4)); |
||
251 | break;
|
||
252 | case 3: |
||
253 | ack_buf[num/4] &= (0x3F|(val<<6)); |
||
254 | break;
|
||
255 | } |
||
256 | } |