Project

General

Profile

Revision 1730

demos: fixing template lib folder

View differences:

demos/template/lib/src/libwireless/sensor_matrix.h
1
/**
2
 * Copyright (c) 2007 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 sensor_matrix.h
28
 * @brief Definitions for sensor matrices
29
 *
30
 * Contains functions and declarations for using sensor matrices.
31
 *
32
 * @author Brian Coltin, Colony Project, CMU Robotics Club
33
 **/
34

  
35
#ifndef SENSOR_MATRIX_H
36
#define SENSOR_MATRIX_H
37

  
38

  
39
/**
40
 * @defgroup sensormatrix Sensor Matrix
41
 * @brief the robot sensor matrix
42
 *
43
 * These functions and structures are used for localization
44
 * to determine the relative directions of robots.
45
 *
46
 * @{
47
 **/
48

  
49
#define MAXIMUM_XBEE_ID		0x10
50
#define READING_UNKNOWN		0xFF
51

  
52
/**
53
 * @struct SensorMatrix
54
 *
55
 * A sensor matrix.
56
 **/
57
//TODO: the order of member variables in this struct should be changed in case the compile packs the struct
58
// In order to achieve the best packing, the variables should be listed in order of decreasing memory size.
59
// Thus, pointers should be first, followed by int, followed by char.
60
typedef struct
61
{
62
	/**
63
	 * The number of robots in the token ring.
64
	 **/
65
	int numJoined;
66
	/**
67
	 * The element representing a robot is true if that robot
68
	 * is in the token ring and false otherwise.
69
	 **/
70
	unsigned char joined[MAXIMUM_XBEE_ID];
71

  
72
	// on the bayboard, we don't include the matrix to save memory.
73
#ifndef BAYBOARD
74
	/**
75
	 * The matrix. Each row represents the readings of one
76
	 * robot.
77
	 **/
78
	unsigned char matrix[MAXIMUM_XBEE_ID][MAXIMUM_XBEE_ID];
79
#endif
80
} SensorMatrix;
81

  
82
/**@brief Create a sensor matrix **/
83
void sensor_matrix_create(void);
84
/**@brief Set a reading in a sensor matrix **/
85
void sensor_matrix_set_reading(int observer, int robot, int reading);
86
/**@brief Get a reading in a sensor matrix **/
87
int sensor_matrix_get_reading(int observer, int robot);
88
/**@brief Set whether the robot is in the token ring **/
89
void sensor_matrix_set_in_ring(int robot, int in);
90
/**@brief Get whether the robot is in the sensor ring **/
91
int sensor_matrix_get_in_ring(int robot);
92
/**@brief Get the number of robots which have joined the token ring **/
93
int sensor_matrix_get_joined(void);
94
/**@brief Get the maximum size of the sensor matrix **/
95
int sensor_matrix_get_size(void);
96

  
97
/** @} **/ //end defgroup
98

  
99

  
100
#endif
101

  
demos/template/lib/src/libwireless/xbee.h
1
/**
2
 * Copyright (c) 2007 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 xbee.h
28
 * @brief Contains definitions for using the XBee
29
 *
30
 * Contains definitions for interfacing with the 
31
 * XBee module, from either a robot or a computer.
32
 * To use a robot, define ROBOT in wl_defs.h, and
33
 * to use a computer, don't define ROBOT.
34
 *
35
 * @author Brian Coltin, Colony Project, CMU Robotics Club
36
 **/
37

  
38
#ifndef XBEE_H
39
#define XBEE_H
40

  
41
/**
42
 * The port to use the XBee from on the computer.
43
 * Also, a backup port if the other is used.
44
 **/
45
#ifndef ROBOT
46
#define XBEE_PORT_DEFAULT "/dev/ttyUSB1"
47
#endif
48

  
49
/**
50
 * @defgroup xbee XBee
51
 * @brief Interface with the XBee module
52
 *
53
 * Interface with the XBee module.
54
 *
55
 * @{
56
 **/
57

  
58
/*Definitions*/
59
/**@brief Unset PAN, uses XBee default **/
60
#define XBEE_PAN_DEFAULT 0xFFFF
61
/**@brief Unset channel, uses XBee default **/
62
#define XBEE_CHANNEL_DEFAULT 0
63
/**@brief Broadcast to all robots in the PAN **/
64
#define XBEE_BROADCAST 0xFFFF
65
/**@brief No special options **/
66
#define XBEE_OPTIONS_NONE 0x00
67
/**@brief Do not receive a TX_STATUS message from this packet **/
68
#define XBEE_OPTIONS_DISABLE_RESPONSE 0x01
69
/**@brief Send the packet to all PANS **/
70
#define XBEE_OPTIONS_BROADCAST_ALL_PANS 0x04
71
/**@brief A transmit status packet **/
72
#define XBEE_TX_STATUS 0x89
73
/**@brief A packet received from another XBee **/
74
#define XBEE_RX 0x81
75

  
76
/**@brief Initialize the XBee library **/
77
int xbee_lib_init(void);
78
/**@brief Uninitialize the XBee library **/
79
void xbee_terminate(void);
80
/**@brief Get a packet from the XBee **/
81
int xbee_get_packet(unsigned char* packet);
82
/**@brief Send a packet to the XBee **/
83
int xbee_send_packet(char* packet, int len, int dest, char options, char frame);
84
/**@brief Set the PAN ID for the XBee **/
85
int xbee_set_pan_id(int id);
86
/**@brief Get the XBee's PAN ID **/
87
unsigned int xbee_get_pan_id(void);
88
/**@brief Set the channel the XBee is currently using **/
89
int xbee_set_channel(int channel);
90
/**@brief Get the channel the XBee is currently using **/
91
int xbee_get_channel(void);
92
/**@brief Get the XBee's 16-bit address **/
93
unsigned int xbee_get_address(void);
94
/**@brief Set the com port on a computer, undefined on the robot**/
95
void xbee_set_com_port(char* port);
96
/**@brief Reset XBee **/
97
int xbee_reset(void);
98

  
99
/**@}**/ //end defgroup
100

  
101
#endif
demos/template/lib/src/libwireless/wl_basic.h
1
/**
2
 * @file wl_basic.h
3
 * @brief High Level Wireless Packet Sending-Receiving Functions
4
 *
5
 * Abstracted wireless functionality for sending and receiving packets
6
 *
7
 * @author Christopher Mar, Colony Project, CMU Robotics Club
8
 **/
9

  
10
/**
11
 * @defgroup wl_basic Wireless Basic
12
 * @brief Wireless abstraction for easily sending and receing packets.
13
 *
14
 * A high level abstraction of the wireless library.
15
 *
16
 * This will allow you to easily send and receive packets.
17
 *
18
 * @{
19
 **/
20

  
21
#ifndef WL_BASIC_H
22
#define WL_BASIC_H
23

  
24
#include "wireless.h"
25

  
26
/** @brief default wireless group for basic sending and receiving packets **/
27
#define WL_BASIC_GROUP 8
28

  
29
/** @brief PacketGroupHandler struct for Basic Group **/
30
PacketGroupHandler wl_basic_group_handler;
31

  
32
/**
33
 * @brief struct that contains relevant packet information
34
 **/
35
struct PacketInfo {
36
    char new_flag;
37
    char type;
38
    int source;
39
    unsigned char* data;
40
    int length;
41
};
42

  
43
/**
44
 * @brief current packet information, correct after wl_basic_do()
45
 **/
46
struct PacketInfo current_packet;
47

  
48
/** @brief init wireless for Basic Group **/
49
int wl_basic_init( void (*handle_receive) (char type, int source, unsigned char* packet, int length) );
50
/** @brief init wireless for Basic Group with default packet handling **/
51
int wl_basic_init_default( void );
52
/** @brief internal function to register a packet handler function **/
53
void wl_basic_register_handler( void (*handle_receive) (char type, int source, unsigned char* packet, int length) );
54
/** @brief send a packet to a single robot in Basic Group **/
55
void wl_basic_send_robot_packet( char type, char* data, int len, int dest );
56
/** @brief send a packet to all robots in Basic Group **/
57
void wl_basic_send_global_packet( char type, char* data, int len );
58
/** @brief internal default packet handler if none is specified on init **/
59
void wl_basic_packet_receive_handler( char type, int source, unsigned char* packet, int length );
60
/** @brief wrapper for wl_do() to return packet data buffer **/
61
unsigned char* wl_basic_do_default( int *length );
62
/** @} **/ // end defgroup
63

  
64
#endif
65

  
demos/template/lib/src/libwireless/wl_token_ring.c
1
/**
2
 * Copyright (c) 2007 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 wl_token_ring.c
28
 * @brief Token Ring Implementation
29
 *
30
 * Implementation of the token ring packet group.
31
 *
32
 * @author Brian Coltin, Colony Project, CMU Robotics Club
33
 **/
34

  
35
#include <wl_token_ring.h>
36

  
37
#include <stdlib.h>
38

  
39
#include <wl_defs.h>
40
#include <wireless.h>
41
#include <sensor_matrix.h>
42

  
43
#ifdef ROBOT
44
#ifndef FIREFLY
45
#include <bom.h>
46
#endif
47
#include <time.h>
48
#endif
49

  
50

  
51
//#define DEFAULT_SENSOR_MATRIX_SIZE 20
52

  
53
/*Ring States*/
54

  
55
#define NONMEMBER 0
56
#define MEMBER 1
57
#define JOINING 2
58
#define ACCEPTED 3
59
#define LEAVING 4
60

  
61
/*Frame Types*/
62
#define TOKEN_JOIN_ACCEPT_FRAME	1
63
#define WL_TOKEN_PASS_FRAME	2
64

  
65
/*Function Prototypes*/
66

  
67
/*Wireless Library Prototypes*/
68
static void wl_token_ring_timeout_handler(void);
69
static void wl_token_ring_response_handler(int frame, int received);
70
static void wl_token_ring_receive_handler(char type, int source, unsigned char* packet, int length);
71
static void wl_token_ring_cleanup(void);
72

  
73
/*Helper Functions*/
74
static int wl_token_pass_token(void);
75
static int get_token_distance(int robot1, int robot2);
76
static void wl_token_get_token(void);
77

  
78
/*Packet Handling Routines*/
79
static void wl_token_pass_receive(int source);
80
static void wl_token_sensor_matrix_receive(int source, unsigned char* sensorData, int sensorDataLength);
81
static void wl_token_bom_on_receive(int source);
82
static void wl_token_join_receive(int source);
83
static void wl_token_join_accept_receive(int source);
84

  
85
/*Global Variables*/
86

  
87
//the robot we are waiting to say it has received the token. -1 if unspecified
88
static int wl_token_next_robot = -1;
89

  
90
//true if the robot should be in the token ring, 0 otherwise
91
static int ringState = NONMEMBER;
92
//the id of the robot who accepted us into the token ring, only used in ACCEPTED state
93
static int acceptor = -1;
94
//id of the robot we are accepting
95
static int accepted = -1;
96

  
97
//the counter for when we assume a robot is dead
98
static int deathDelay = -1;
99
//the counter for joining, before we form our own token ring
100
static int joinDelay = -1;
101

  
102
//current robot to check in the iterator
103
static int iteratorCount = 0;
104

  
105
// the amount of time a robot has had its BOM on for
106
static int bom_on_count = 0;
107

  
108
#ifndef ROBOT
109
static void do_nothing(void) {}
110
static int get_nothing(void) {return -1;}
111
#endif
112

  
113
#ifdef ROBOT
114
#ifndef FIREFLY
115
static void (*bom_on_function) (void) = bom_on;
116
static void (*bom_off_function) (void) = bom_off;
117
static int (*get_max_bom_function) (void) = get_max_bom;
118
#else
119
static void (*bom_on_function) (void) = do_nothing;
120
static void (*bom_off_function) (void) = do_nothing;
121
static int (*get_max_bom_function) (void) = get_nothing;
122
#endif
123
#else
124
static void (*bom_on_function) (void) = do_nothing;
125
static void (*bom_off_function) (void) = do_nothing;
126
static int (*get_max_bom_function) (void) = get_nothing;
127
#endif
128

  
129
static PacketGroupHandler wl_token_ring_handler =
130
	{WL_TOKEN_RING_GROUP, wl_token_ring_timeout_handler,
131
		wl_token_ring_response_handler, wl_token_ring_receive_handler,
132
		wl_token_ring_cleanup};
133

  
134
/**
135
 * Causes the robot to join an existing token ring, or create one
136
 * if no token ring exists. The token ring uses global and robot to robot
137
 * packets, and does not rely on any PAN.
138
 **/
139
int wl_token_ring_join()
140
{
141
	WL_DEBUG_PRINT("Joining the token ring.\r\n");
142

  
143
	ringState = JOINING;
144
	joinDelay = DEATH_DELAY * 2;
145
	if (wl_send_global_packet(WL_TOKEN_RING_GROUP, WL_TOKEN_JOIN, NULL, 0, 0) != 0) {
146
		return -1;
147
	}
148

  
149
	return 0;
150
}
151

  
152
/**
153
 * Causes the robot to leave the token ring. The robot stops
154
 * alerting others of its location, but continues storing the
155
 * locations of other robots.
156
 **/
157
void wl_token_ring_leave()
158
{
159
	ringState = LEAVING;
160
}
161

  
162
/**
163
 * Initialize the token ring packet group and register it with the
164
 * wireless library. The robot will not join a token ring.
165
 **/
166
int wl_token_ring_register()
167
{
168
	if (wl_get_xbee_id() > 0xFF)
169
	{
170
		//Note: if this becomes an issue (unlikely), we could limit sensor information
171
		//to half a byte and use 12 bits for the id
172
		WL_DEBUG_PRINT("XBee ID must be single byte for token ring, is ");
173
		WL_DEBUG_PRINT_INT(wl_get_xbee_id());
174
		WL_DEBUG_PRINT(".\r\n");
175
		return -1;
176
	}
177

  
178
	sensor_matrix_create();
179
	//add ourselves to the sensor matrix
180
	sensor_matrix_set_in_ring(wl_get_xbee_id(), 0);
181

  
182
	wl_register_packet_group(&wl_token_ring_handler);
183

  
184
	return 0;
185
}
186

  
187
/**
188
 * Removes the packet group from the wireless library.
189
 **/
190
void wl_token_ring_unregister()
191
{
192
	wl_unregister_packet_group(&wl_token_ring_handler);
193
}
194

  
195
/**
196
 * Sets the functions that are called when the BOM ought to be
197
 * turned on or off. This could be used for things such as
198
 * charging stations, which have multiple BOMs.
199
 *
200
 * @param on_function the function to be called when the BOM
201
 * should be turned on
202
 * @param off_function the function to be called when the BOM
203
 * should be turned off
204
 * @param max_bom_function the function to be called when a
205
 * measurement of the maximum BOM reading is needed.
206
 **/
207
void wl_token_ring_set_bom_functions(void (*on_function) (void),
208
	void (*off_function) (void), int (*max_bom_function) (void))
209
{
210
	bom_on_function = on_function;
211
	bom_off_function = off_function;
212
	get_max_bom_function = max_bom_function;
213
}
214

  
215
/**
216
 * Called to cleanup the token ring packet group.
217
 **/
218
static void wl_token_ring_cleanup()
219
{
220
}
221

  
222
/**
223
 * Called approximately every quarter second by the wireless library.
224
 **/
225
static void wl_token_ring_timeout_handler()
226
{
227
	//someone is not responding, assume they are dead
228
	if (deathDelay == 0)
229
	{
230
		//pass the token to the next robot if we think someone has died
231
		//also, declare that person dead, as long as it isn't us
232
		if (wl_token_next_robot != wl_get_xbee_id())
233
		{
234
			sensor_matrix_set_in_ring(wl_token_next_robot, 0);
235
			WL_DEBUG_PRINT("Robot ");
236
			WL_DEBUG_PRINT_INT(wl_token_next_robot);
237
			WL_DEBUG_PRINT(" has died.\r\n");
238
			wl_token_next_robot = -1;
239
			deathDelay = DEATH_DELAY;
240
		}
241

  
242
		// we may have been dropped from the ring when this is received
243
		if (ringState == MEMBER) {
244
			wl_token_pass_token();
245
		}
246
	}
247

  
248
	//we must start our own token ring, no one is responding to us
249
	if (joinDelay == 0)
250
	{
251
		if (sensor_matrix_get_joined() == 0)
252
		{
253
			WL_DEBUG_PRINT("Creating our own token ring, no robots seem to exist.\r\n");
254
			sensor_matrix_set_in_ring(wl_get_xbee_id(), 1);
255
			ringState = MEMBER;
256
			//this will make us pass the token to ourself
257
			//repeatedly, and other robots when they join
258
			deathDelay = DEATH_DELAY;
259
			wl_token_next_robot = wl_get_xbee_id();
260
		}
261
		else
262
		{
263
			WL_DEBUG_PRINT("Attempting to join the token ring again.\r\n");
264
			//attempt to rejoin with a random delay
265
      //TODO: should we use the constant JOIN_DELAY ?
266
			wl_token_ring_join();
267
			joinDelay = rand() / (RAND_MAX / JOIN_DELAY) + 1;
268
		}
269
	}
270

  
271
	if (deathDelay >= 0) {
272
		deathDelay--;
273
	}
274

  
275
	if (joinDelay >= 0) {
276
		joinDelay--;
277
	}
278

  
279
	if (bom_on_count >= 0) {
280
		bom_on_count++;
281
	}
282
}
283

  
284
/**
285
 * Called when the XBee tells us if a packet we sent has been received.
286
 *
287
 * @param frame the frame number assigned when the packet was sent
288
 * @param received 1 if the packet was received, 0 otherwise
289
 **/
290
static void wl_token_ring_response_handler(int frame, int received)
291
{
292
	if (!received)
293
	{
294
		WL_DEBUG_PRINT("FAILED.\r\n");
295
	}
296
}
297

  
298
/**
299
 * Called when we recieve a token ring packet.
300
 * @param type the type of the packet
301
 * @param source the id of the robot who sent the packet
302
 * @param packet the data in the packet
303
 * @param length the length of the packet in bytes
304
 **/
305
static void wl_token_ring_receive_handler(char type, int source, unsigned char* packet, int length)
306
{
307
	switch (type)
308
	{
309
		case WL_TOKEN_PASS:
310
			wl_token_pass_receive(source);
311
			break;
312
		case WL_TOKEN_SENSOR_MATRIX:
313
			wl_token_sensor_matrix_receive(source, packet, length);
314
			break;
315
		case WL_TOKEN_BOM_ON:
316
			//add the robot to the sensor matrix if it is not already there
317
			wl_token_bom_on_receive(source);
318
			break;
319
		case WL_TOKEN_JOIN:
320
			wl_token_join_receive(source);
321
			break;
322
		case WL_TOKEN_JOIN_ACCEPT:
323
			wl_token_join_accept_receive(source);
324
			break;
325
		default:
326
			WL_DEBUG_PRINT("Unimplemented token ring packet received.\r\n");
327
			break;
328
	}
329
}
330

  
331
/**
332
 * Returns the BOM reading robot source has for robot dest.
333
 *
334
 * @param source the robot that made the BOM reading
335
 * @param dest the robot whose relative location is returned
336
 *
337
 * @return a BOM reading from robot source to robot dest,
338
 * in the range 0-15, or -1 if it is unknown
339
 **/
340
int wl_token_get_sensor_reading(int source, int dest)
341
{
342
	if (wl_token_is_robot_in_ring(dest) &&
343
			(source == wl_get_xbee_id() || wl_token_is_robot_in_ring(source))) {
344
		return sensor_matrix_get_reading(source, dest);
345
	}
346

  
347
	return -1;
348
}
349

  
350
/**
351
 * Returns the BOM reading we have for robot dest.
352
 *
353
 * @param dest the robot whose relative location is returned
354
 *
355
 * @return a BOM reading from us to robot dest, in the range
356
 * 0-15, or -1 if it is unkown
357
 **/
358
int wl_token_get_my_sensor_reading(int dest)
359
{
360
	return wl_token_get_sensor_reading(wl_get_xbee_id(), dest);
361
}
362

  
363

  
364
/**
365
 * Returns the number of robots in the token ring.
366
 *
367
 * @return the number of robots in the token ring
368
 **/
369
int wl_token_get_robots_in_ring(void)
370
{
371
	return sensor_matrix_get_joined();
372
}
373

  
374
/**
375
 * Returns true if the specified robot is in the token ring, false
376
 * otherwise.
377
 *
378
 * @param robot the robot to check for whether it is in the token ring
379
 * @return nonzero if the robot is in the token ring, zero otherwise
380
 **/
381
int wl_token_is_robot_in_ring(int robot)
382
{
383
	return sensor_matrix_get_in_ring(robot);
384
}
385

  
386
/**
387
 * Begins iterating through the robots in the token ring.
388
 *
389
 * @see wl_token_iterator_has_next, wl_token_iterator_next
390
 **/
391
void wl_token_iterator_begin(void)
392
{
393
	int i = 0;
394
  //TODO: the compiler may or may not optimize this such that my comment is useless:
395
  // instead of calling sensor_matrix_get_size every iteration of the while loop and incurring
396
  // the overhead of a function call each iteration, call it only once before the loop and store
397
  // the value in a variable and check against that variable in the loop condition
398
	while (!sensor_matrix_get_in_ring(i) && i < sensor_matrix_get_size()) {
399
		i++;
400
	}
401

  
402
  //TODO: if you do the above comment, then you can compare this to the variable also
403
	if (i == sensor_matrix_get_size()) {
404
		i = -1;
405
	}
406

  
407
	iteratorCount = i;
408
}
409

  
410
/**
411
 * Returns true if there are more robots in the token ring
412
 * to iterate through, and false otherwise.
413
 *
414
 * @return nonzero if there are more robots to iterate through,
415
 * zero otherwise
416
 *
417
 * @see wl_token_iterator_begin, wl_token_iterator_next
418
 **/
419
int wl_token_iterator_has_next(void)
420
{
421
	return iteratorCount != -1;
422
}
423

  
424
/**
425
 * Returns the next robot ID in the token ring.
426
 *
427
 * @return the next robot ID in the token ring, or -1 if none exists
428
 *
429
 * @see wl_token_iterator_begin, wl_token_iterator_has_next
430
 **/
431
int wl_token_iterator_next(void)
432
{
433
	int result = iteratorCount;
434
	if (result < 0) {
435
		return result;
436
	}
437

  
438
  //TODO: the compiler may or may not optimize this such that my comment is useless:
439
  // instead of calling sensor_matrix_get_size every iteration of the while loop and incurring
440
  // the overhead of a function call each iteration, call it only once before the loop and store
441
  // the value in a variable and check against that variable in the loop condition
442
	iteratorCount++;
443
	while (!sensor_matrix_get_in_ring(iteratorCount)
444
		&& iteratorCount < sensor_matrix_get_size()) {
445
		iteratorCount++;
446
	}
447

  
448
  //TODO: if you do the above comment, then you can compare this to the variable also
449
	if (iteratorCount == sensor_matrix_get_size()) {
450
		iteratorCount = -1;
451
	}
452

  
453
	return result;
454
}
455

  
456
/**
457
 * Returns the number of robots currently in the token ring.
458
 *
459
 * @return the number of robots in the token ring
460
 **/
461
int wl_token_get_num_robots(void)
462
{
463
	return sensor_matrix_get_joined();
464
}
465

  
466
/**
467
 * Returns the number of robots in the sensor matrix.
468
 *
469
 * @return the number of robots in the sensor matrix
470
 **/
471
int wl_token_get_matrix_size(void)
472
{
473
	return sensor_matrix_get_size();
474
}
475

  
476
/**
477
 * This method is called when we receive a token pass packet.
478
 *
479
 * @param source the robot who passed the token to us.
480
 **/
481
static void wl_token_pass_receive(int source)
482
{
483
	WL_DEBUG_PRINT("Received token from ");
484
	WL_DEBUG_PRINT_INT(source);
485
	WL_DEBUG_PRINT(", expected ");
486
	WL_DEBUG_PRINT_INT(wl_token_next_robot);
487
	WL_DEBUG_PRINT(".\n");
488
	// this prevents two tokens from being passed around at a time (second clause is in case we are joining)
489
	if ((source != wl_token_next_robot && wl_get_xbee_id() != wl_token_next_robot) && bom_on_count <= DEATH_DELAY / 2 &&
490
		ringState != ACCEPTED)
491
	{
492
		WL_DEBUG_PRINT("Received token pass when a robot should not have died yet.\n");
493
		WL_DEBUG_PRINT("There are probably two tokens going around, packet ignored.\n");
494
		return;
495
	}
496
	bom_on_count = -1;
497
	deathDelay = -1;
498
	sensor_matrix_set_in_ring(source, 1);
499
	wl_token_get_token();
500
}
501

  
502
/**
503
 * This method is called when we receive a token pass packet.
504
 * @param source is the robot it came from
505
 * @param nextRobot is the robot the token was passed to
506
 * @param sensorData a char with an id followed by a char with the sensor
507
 *		reading for that robot, repeated for sensorDataLength bytes
508
 * @param sensorDataLength the length in bytes of sensorData
509
 */
510
static void wl_token_sensor_matrix_receive(int source, unsigned char* sensorData, int sensorDataLength)
511
{
512
	int i, j;
513
	char nextRobot;
514

  
515
	bom_on_count = -1;
516
	deathDelay = -1;
517
	sensor_matrix_set_in_ring(source, 1);
518

  
519
	//with this packet, we are passed the id of the next robot in the ring
520
	//and the sensor matrix, a list of id and sensor reading pairs (two bytes for both)
521
	j = 0;
522
  //TODO: the compiler may or may not optimize this such that my comment is useless:
523
  // instead of calling sensor_matrix_get_size every iteration of the while loop and incurring
524
  // the overhead of a function call each iteration, call it only once before the loop and store
525
  // the value in a variable and check against that variable in the loop condition
526
	for (i = 0; i < sensor_matrix_get_size(); i++)
527
	{
528
		if (i == source) {
529
			continue;
530
		}
531

  
532
		//set the sensor information we receive
533
		if (j < sensorDataLength / 2 && sensorData[2 * j] == i)
534
		{
535
			//the robot we were going to accept has already been accepted
536
			if (accepted == i)
537
			{
538
				accepted = -1;
539
				WL_DEBUG_PRINT("Someone accepted the robot we did.\r\n");
540
			}
541
			sensor_matrix_set_reading(source, i,
542
						sensorData[2 * j + 1]);
543
			if (!sensor_matrix_get_in_ring(i))
544
			{
545
				WL_DEBUG_PRINT("Robot ");
546
				WL_DEBUG_PRINT_INT(i);
547
				WL_DEBUG_PRINT(" has been added to the sensor matrix of robot ");
548
				WL_DEBUG_PRINT_INT(wl_get_xbee_id());
549
				WL_DEBUG_PRINT(" due to a packet from robot ");
550
				WL_DEBUG_PRINT_INT(source);
551
				WL_DEBUG_PRINT(".\r\n");
552
			}
553
			sensor_matrix_set_in_ring(i, 1);
554
			j++;
555
		}
556
		else
557
		{
558
			if (sensor_matrix_get_in_ring(i))
559
			{
560
				WL_DEBUG_PRINT("Robot ");
561
				WL_DEBUG_PRINT_INT(i);
562
				WL_DEBUG_PRINT(" has been removed from the sensor matrix of robot ");
563
				WL_DEBUG_PRINT_INT(wl_get_xbee_id());
564
				WL_DEBUG_PRINT(" due to a packet from robot ");
565
				WL_DEBUG_PRINT_INT(source);
566
				WL_DEBUG_PRINT(".\r\n");
567
				sensor_matrix_set_in_ring(i, 0);
568
			}
569

  
570
			if (i == wl_get_xbee_id() && ringState == MEMBER)
571
			{
572
				ringState = NONMEMBER;
573
				wl_token_ring_join();
574

  
575
				WL_DEBUG_PRINT("We have been removed from the ring ");
576
				WL_DEBUG_PRINT("and are rejoining.\r\n");
577
			}
578

  
579
			//the person who accepted us is dead... let's ask again
580
			if (i == acceptor)
581
			{
582
				sensor_matrix_set_in_ring(wl_get_xbee_id(), 0);
583
				ringState = NONMEMBER;
584
				acceptor = -1;
585
				wl_token_ring_join();
586
			}
587
		}
588
	}
589
	
590
	// get the next robot in the token ring
591
	i = source + 1;
592
	while (1)
593
	{
594
		if (i == sensor_matrix_get_size()) {
595
			i = 0;
596
		}
597

  
598
		if (sensor_matrix_get_in_ring(i) || i == source)
599
		{
600
			nextRobot = (char)i;
601
			break;
602
		}
603

  
604
		i++;
605
	}
606

  
607
	if (nextRobot != wl_get_xbee_id())
608
		wl_token_next_robot = nextRobot;
609

  
610
	deathDelay = get_token_distance(wl_get_xbee_id(), nextRobot) * DEATH_DELAY;
611

  
612
	if (sensor_matrix_get_joined() == 0 && ringState == JOINING)
613
		wl_send_robot_to_robot_global_packet(WL_TOKEN_RING_GROUP, WL_TOKEN_PASS, NULL, 0, nextRobot, WL_TOKEN_PASS_FRAME);
614
}
615

  
616
/**
617
 * Gets the distance in the token ring between two robots.
618
 *
619
 * @param robot1 the first robot
620
 * @param robot2 the second robot
621
 *
622
 * @return the number of passes before the token is expected
623
 * to reach robot2 from robot1
624
 **/
625
static int get_token_distance(int robot1, int robot2)
626
{
627
	int curr = robot1 + 1;
628
	int count = 1;
629
	while (1)
630
	{
631
    //TODO: the compiler may or may not optimize this such that my comment is useless:
632
    // instead of calling sensor_matrix_get_size every iteration of the while loop and incurring
633
    // the overhead of a function call each iteration, call it only once before the loop and store
634
    // the value in a variable and check against that variable in the loop condition
635
		if (curr == sensor_matrix_get_size())
636
			curr = 0;
637
		if (curr == robot2)
638
			break;
639
		if (sensor_matrix_get_in_ring(curr))
640
			count++;
641
		curr++;
642
	}
643
	return count;
644
}
645

  
646
/**
647
 * Passes the token to the next robot in the token ring.
648
 **/
649
static int wl_token_pass_token()
650
{
651
	char nextRobot = 0xFF;
652
	int i = wl_get_xbee_id() + 1;
653
	char buf[2 * sensor_matrix_get_size()];
654
	if (accepted == -1)
655
	{
656
		while (1)
657
		{
658
      //TODO: the compiler may or may not optimize this such that my comment is useless:
659
      // instead of calling sensor_matrix_get_size every iteration of the while loop and incurring
660
      // the overhead of a function call each iteration, call it only once before the loop and store
661
      // the value in a variable and check against that variable in the loop condition
662
			if (i == sensor_matrix_get_size()) {
663
				i = 0;
664
			}
665

  
666
			if (sensor_matrix_get_in_ring(i))
667
			{
668
				nextRobot = (char)i;
669
				break;
670
			}
671

  
672
			i++;
673
		}
674
	}
675
	else
676
	{
677
		WL_DEBUG_PRINT("Accepting new robot, sending it the token.\r\n");
678
		//add a new robot to the token ring
679
		sensor_matrix_set_in_ring(accepted, 1);
680
		nextRobot = accepted;
681
		accepted = -1;
682
	}
683

  
684
	int j = 0;
685
  //TODO: the compiler may or may not optimize this such that my comment is useless:
686
  // instead of calling sensor_matrix_get_size every iteration of the while loop and incurring
687
  // the overhead of a function call each iteration, call it only once before the loop and store
688
  // the value in a variable and check against that variable in the loop condition
689
	for (i = 0; i < sensor_matrix_get_size(); i++) {
690
		if (sensor_matrix_get_in_ring(i) && i != wl_get_xbee_id())
691
		{
692
			buf[2*j] = i;
693
			buf[2*j + 1] = sensor_matrix_get_reading(wl_get_xbee_id(), i);
694
			j++;
695
		}
696
	}
697

  
698
	int packetSize = 2 * j * sizeof(char);
699
	WL_DEBUG_PRINT("Passing the token to robot ");
700
	WL_DEBUG_PRINT_INT(nextRobot);
701
	WL_DEBUG_PRINT(".\r\n");
702
	if (wl_send_global_packet(WL_TOKEN_RING_GROUP, WL_TOKEN_SENSOR_MATRIX, buf, packetSize, 0) != 0)
703
		return -1;
704
	if (wl_send_robot_to_robot_global_packet(WL_TOKEN_RING_GROUP, WL_TOKEN_PASS, NULL, 0, nextRobot, WL_TOKEN_PASS_FRAME))
705
		return -1;
706

  
707
	wl_token_next_robot = nextRobot;
708
	deathDelay = DEATH_DELAY;
709

  
710
	return 0;
711
}
712

  
713
/**
714
 * Called when a packet is received stating that another robot has turned
715
 * its BOM on. Our BOM is then read, and the data is added to the sensor
716
 * matrix.
717
 *
718
 * @param source the robot whose BOM is on
719
 **/
720
static void wl_token_bom_on_receive(int source)
721
{
722
	int max;
723

  
724
	WL_DEBUG_PRINT("Robot ");
725
	WL_DEBUG_PRINT_INT(source);
726
	WL_DEBUG_PRINT(" has flashed its bom.\r\n");
727

  
728
	bom_on_count = 0;
729

  
730
	max = get_max_bom_function();
731
	sensor_matrix_set_reading(wl_get_xbee_id(),
732
		source, max);
733

  
734
	WL_DEBUG_PRINT("Max: ");
735
	WL_DEBUG_PRINT_INT(max);
736
	WL_DEBUG_PRINT("\n\n");
737
}
738

  
739
/**
740
 * This method is called when we receive the token. Upon receiving
741
 * the token, we must send a BOM_ON packet, flash the BOM, and send
742
 * the token to the next robot.
743
 *
744
 * If there is a pending request for the token, this is processed first.
745
 **/
746
static void wl_token_get_token()
747
{
748
	WL_DEBUG_PRINT("We have the token.\r\n");
749
	if (ringState == ACCEPTED)
750
	{
751
		sensor_matrix_set_in_ring(wl_get_xbee_id(), 1);
752
		WL_DEBUG_PRINT("Now a member of the token ring.\r\n");
753
		ringState = MEMBER;
754
		joinDelay = -1;
755
	}
756

  
757
	if (ringState == LEAVING || ringState == NONMEMBER)
758
	{
759
		sensor_matrix_set_in_ring(wl_get_xbee_id(), 0);
760
		if (ringState == NONMEMBER)
761
		{
762
			WL_DEBUG_PRINT("We should have left the token ring, but didn't.\r\n");
763
		}
764
		return;
765
	}
766

  
767
	WL_DEBUG_PRINT("Our BOM has been flashed.\r\n");
768
	wl_send_global_packet(WL_TOKEN_RING_GROUP, WL_TOKEN_BOM_ON, NULL, 0, 0);
769

  
770
	bom_on_function();
771
	#ifdef ROBOT
772
	delay_ms(BOM_DELAY);
773
	#endif
774
	bom_off_function();
775

  
776
	if (!sensor_matrix_get_in_ring(wl_get_xbee_id()))
777
	{
778
		WL_DEBUG_PRINT("Removed from sensor matrix while flashing BOM.\r\n");
779
		return;
780
	}
781

  
782
	wl_token_pass_token();
783
}
784

  
785
/**
786
 * Called when a request to join the token ring is received.
787
 * If we are the robot preceding the requester in the ring,
788
 * we respond with a JOIN_ACCEPT packet and pass the token to
789
 * this robot when we receive the token.
790
 *
791
 * @param source the robot who requested to join
792
 **/
793
static void wl_token_join_receive(int source)
794
{
795
	WL_DEBUG_PRINT("Received joining request from robot ");
796
	WL_DEBUG_PRINT_INT(source);
797
	WL_DEBUG_PRINT(".\r\n");
798

  
799
	//we cannot accept the request if we are not a member
800
	if (ringState != MEMBER)
801
		return;
802
	//if they didn't get our response, see if we should respond again
803
	if (accepted == source)
804
		accepted = -1;
805
	//we can only accept one request at a time
806
	if (accepted != -1)
807
		return;
808

  
809
	//check if we are the preceding robot in the token ring
810
	int i = source - 1;
811
	while (1)
812
	{
813
		if (i < 0)
814
			i = sensor_matrix_get_size() - 1;
815

  
816
		//we must send a join acceptance
817
		if (i == wl_get_xbee_id())
818
			break;
819

  
820
		//another robot will handle it
821
		if (sensor_matrix_get_in_ring(i))
822
			return;
823

  
824
		i--;
825
	}
826

  
827
	accepted = source;
828
	wl_send_robot_to_robot_global_packet(WL_TOKEN_RING_GROUP, WL_TOKEN_JOIN_ACCEPT,
829
		NULL, 0, source, TOKEN_JOIN_ACCEPT_FRAME);
830

  
831
	WL_DEBUG_PRINT("Accepting robot ");
832
	WL_DEBUG_PRINT_INT(source);
833
	WL_DEBUG_PRINT(" into the token ring.\r\n");
834

  
835
	// the token ring has not started yet
836
	if (sensor_matrix_get_joined() == 1)
837
		wl_token_pass_token();
838
}
839

  
840
/**
841
 * Called when we receive a JOIN_ACCEPT packet in attempting to join
842
 * the token ring.
843
 * Our attempt to join the ring is stopped, and we wait for the token.
844
 *
845
 * @param source the robot who accepted us
846
 **/
847
static void wl_token_join_accept_receive(int source)
848
{
849
	WL_DEBUG_PRINT("Accepted into the token ring by robot ");
850
	WL_DEBUG_PRINT_INT(source);
851
	WL_DEBUG_PRINT(".\r\n");
852
	joinDelay = JOIN_DELAY;
853
	ringState = ACCEPTED;
854
	acceptor = source;
855

  
856
	//add ourselves to the token ring
857
	sensor_matrix_set_in_ring(wl_get_xbee_id(), 1);
858
}
demos/template/lib/src/libwireless/wl_error_group.c
1
/**
2
 * Copyright (c) 2007 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 wl_error_group.h
28
 * @brief Error Packets
29
 *
30
 * A wireless group for sending error packets.
31
 *
32
 * @author Brian Coltin, Colony Project, CMU Robotics Club
33
 **/
34

  
35
#include "wl_error_group.h"
36
#include "wireless.h"
37
#include "wl_defs.h"
38

  
39
#include <string.h>
40

  
41

  
42

  
43
void wl_error_response_receive(int frame, int received);
44
void wl_error_handle_receive(char type, int source, unsigned char* packet,
45
							int length);
46

  
47
PacketGroupHandler wl_error_handler =
48
		{WL_ERROR_GROUP, NULL,
49
		wl_error_response_receive, wl_error_handle_receive, NULL};
50

  
51
void wl_error_response_receive(int frame, int received)
52
{
53
	WL_DEBUG_PRINT("Response received.\r\n");
54
	if (!received)
55
	{
56
		WL_DEBUG_PRINT("FAILED.\r\n");
57
	}
58
}
59
/**
60
 * Register this packet group with the wireless library.
61
 * This function must be called before any other wl_error
62
 * function.
63
 **/
64
void wl_error_register(void)
65
{
66
	wl_register_packet_group(&wl_error_handler);
67
}
68

  
69
/**
70
 * Unregister this packet group with the wireless library.
71
 * This function must be called after wl_error_register.
72
 *
73
 * @see wl_error_register
74
 **/
75
void wl_error_unregister(void)
76
{
77
	wl_unregister_packet_group(&wl_error_handler);
78
}
79

  
80
/**
81
 * Handles receiving an error packet.
82
 *
83
 * @param type the packet type
84
 * @param source the 16-bit address of the packet's sender
85
 * @param packet the packet data
86
 * @param length the length in bytes of the packet
87
 **/
88
void wl_error_handle_receive(char type, int source, unsigned char* packet,
89
							int length)
90
{
91
	switch (type)
92
	{
93
		case WL_ERROR_STRING_TYPE:
94
			if (packet[length - 1] != 0)
95
			{
96
				WL_DEBUG_PRINT(
97
					"Error packet string should be null terminated.\r\n");
98
				break;
99
			}
100
			WL_DEBUG_PRINT("Error packet received from robot ");
101
			WL_DEBUG_PRINT_INT(source);
102
			WL_DEBUG_PRINT(":\r\n");
103
			WL_DEBUG_PRINT((char*)packet);
104
			WL_DEBUG_PRINT("\r\n");
105
			break;
106
		default:
107
			WL_DEBUG_PRINT("Error packet of unknown type received.\r\n");
108
			break;
109
	}
110
}
111

  
112
/**
113
 * Send an error message as a string.
114
 *
115
 * @param str the error message to send
116
 **/
117
void wl_error_send_string(char* str)
118
{
119
	wl_send_global_packet(WL_ERROR_GROUP, WL_ERROR_STRING_TYPE,
120
		str, strlen(str) + 1, 1);
121
}
122

  
demos/template/lib/src/libwireless/wl_error_group.h
1
/**
2
 * Copyright (c) 2007 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 wl_error_group.h
28
 * @brief Error Packets
29
 *
30
 * A packet group for sending error packets.
31
 *
32
 * @author Brian Coltin, Colony Project, CMU Robotics Club
33
 **/
34

  
35
#ifndef WL_ERROR_GROUP_H
36
#define WL_ERROR_GROUP_H
37

  
38
/**
39
 * @file wl_error_group.h
40
 * @brief A packet group for error messages.
41
 *
42
 * A packet group for sending and receiving error
43
 * messages.
44
 *
45
 * @author Brian Coltin, Colony Project, CMU Robotics Club
46
 **/
47

  
48
/**
49
 * @defgroup wlerror Error Packets
50
 * @brief Functions for sending and receiving error packets
51
 * 
52
 * Functions for sending and receiving error packets.
53
 * 
54
 * @{
55
 **/
56

  
57
/**@brief Register this packet group with the wireless library **/
58
void wl_error_register(void);
59
/**@brief Unregister this packet group with the wireless library **/
60
void wl_error_unregister(void);
61
/**@brief Send a string in an error packet **/
62
void wl_error_send_string(char* str);
63

  
64
/** @} **/ // end defgroup
65

  
66
#endif
demos/template/lib/src/libwireless/wireless.c
1
/**
2
 * Copyright (c) 2007 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.c
28
 * @brief Wireless Library Implementation
29
 *
30
 * Implementation of the wireless library.
31
 *
32
 * @author Brian Coltin, Colony Project, CMU Robotics Club
33
 **/
34

  
35
#include "wireless.h"
36
#include "xbee.h"
37

  
38
#include <stddef.h>
39

  
40
#ifdef WL_DEBUG
41
#include <stdio.h>
42
#endif
43

  
44
#include "wl_defs.h"
45

  
46
#ifndef ROBOT
47
	#include <sys/time.h>
48
	#include <signal.h>
49
#else
50
	#include <time.h>
51
	#include <bom.h>
52
#endif
53

  
54
/*Function Prototypes*/
55

  
56
static void wl_do_timeout(void);
57

  
58
//Note: the actual frame sent has group as the first four bits and
59
//frame as the last four.
60
static int wl_send_packet(char group, char type, char* data, int len, int dest, char options, char frame);
61

  
62
/*Data Members*/
63

  
64
//used to store incoming and outgoing packets
65
//TODO: does this need to be 128?  can it be smaller to save memory?
66
//TODO: this shouldn't be hardcoded as 128.  it should be a define.
67
static unsigned char wl_buf[128];
68
//1 if we have timed out since we last checked, 0 otherwise.
69
static int wl_timeout = 0;
70

  
71
static PacketGroupHandler* wl_packet_groups[WL_MAX_PACKET_GROUPS];
72

  
73
#ifndef ROBOT
74

  
75
//called when we time out, or receive interrupt
76
static void sig_handler(int signo)
77
{
78
	switch (signo)
79
	{
80
		case SIGALRM:
81
			wl_timeout = 1;
82
			break;
83
		case SIGINT:
84
			wl_terminate();
85
			exit(1);
86
			break;
87
	}
88
	return;
89
}
90
#else
91

  
92
//called when the timer ticks
93
static void timer_handler(void)
94
{
95
	wl_timeout = 1;
96
}
97

  
98
#endif
99

  
100
/**
101
 * Initializes the wireless library. Must be called before any
102
 * other function.
103
 *
104
 * @param wl_port File descriptor for wireless port, or NULL for default.
105
 **/
106
int wl_init()
107
{
108
	int i;
109
  //TODO: using memset here instead of this loop, *might* be less instructions and *might* reduce code size but not sure
110
	for (i = 0; i < WL_MAX_PACKET_GROUPS; i++)
111
		wl_packet_groups[i] = NULL;
112

  
113
	if (xbee_lib_init() == -1) {
114
		return -1;
115
	}
116

  
117
	//begin timeout timer
118
#ifdef ROBOT
119
#ifdef FIREFLY
120
	rtc_init(PRESCALE_DIV_256, 32, &timer_handler);
121
#else
122
	//TODO: FIX THIS
123
	#ifdef BAYBOARD
124
	rtc_init(10 * HALF_SECOND, &timer_handler);
125
	#else
126
	rtc_init(HALF_SECOND, &timer_handler);
127
	#endif
128
#endif
129
#else
130

  
131
	//create our timer
132
	struct itimerval timer_val;
133
	struct timeval interval;
134
	interval.tv_sec = 0;
135
	interval.tv_usec = 500000;
136
	struct timeval first_time;
137
	first_time.tv_sec = 0;
138
	first_time.tv_usec = 500000;
139
	timer_val.it_interval = interval;
140
	timer_val.it_value = first_time;
141
	if(setitimer(ITIMER_REAL,&timer_val,NULL)==-1)
142
	{
143
		WL_DEBUG_PRINT("Error creating a timer.\r\n");
144
		perror("Failure's cause");
145
		exit(1);
146
	}
147

  
148
	//create signal handler
149
	struct sigaction wl_sig_act;
150
	wl_sig_act.sa_handler = sig_handler;
151
	wl_sig_act.sa_flags = 0;
152
	sigemptyset(&wl_sig_act.sa_mask);
153
	sigaction(SIGALRM, &wl_sig_act, 0);
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff