Project

General

Profile

Revision 346

Undid Jason's style changes. I like tabs.

View differences:

trunk/code/projects/libwireless/lib/wl_token_ring.c
67 67
void wl_token_ring_timeout_handler(void);
68 68
void wl_token_ring_response_handler(int frame, int received);
69 69
void wl_token_ring_receive_handler(char type, int source, unsigned char* packet,
70
				   int length);
70
							int length);
71 71
void wl_token_ring_cleanup(void);
72 72

  
73 73
/*Helper Functions*/
......
127 127
#endif
128 128

  
129 129
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};
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 133

  
134 134
/**
135 135
 * Initialize the token ring packet group and register it with the
136 136
 * wireless library. The robot will not join a token ring.
137 137
 **/
138
void wl_token_ring_register() {
139
  if (wl_get_xbee_id() > 0xFF) {
140
    //Note: if this becomes an issue (unlikely), we could limit sensor information
141
    //to half a byte and use 12 bits for the id
142
    WL_DEBUG_PRINT("XBee ID must be single byte for token ring, is ");
143
    WL_DEBUG_PRINT_INT(wl_get_xbee_id());
144
    WL_DEBUG_PRINT(".\r\n");
145
    return;
146
  }
138
void wl_token_ring_register()
139
{
140
	if (wl_get_xbee_id() > 0xFF)
141
	{
142
		//Note: if this becomes an issue (unlikely), we could limit sensor information
143
		//to half a byte and use 12 bits for the id
144
		WL_DEBUG_PRINT("XBee ID must be single byte for token ring, is ");
145
		WL_DEBUG_PRINT_INT(wl_get_xbee_id());
146
		WL_DEBUG_PRINT(".\r\n");
147
		return;
148
	}
147 149
	
148
  sensorMatrix = sensor_matrix_create();
149
  //add ourselves to the sensor matrix
150
  sensor_matrix_set_in_ring(sensorMatrix, wl_get_xbee_id(), 0);
150
	sensorMatrix = sensor_matrix_create();
151
	//add ourselves to the sensor matrix
152
	sensor_matrix_set_in_ring(sensorMatrix, wl_get_xbee_id(), 0);
151 153

  
152
  wl_register_packet_group(&wl_token_ring_handler);
154
	wl_register_packet_group(&wl_token_ring_handler);
153 155
}
154 156

  
155 157
/**
156 158
 * Removes the packet group from the wireless library.
157 159
 **/
158
void wl_token_ring_unregister() {
159
  wl_unregister_packet_group(&wl_token_ring_handler);
160
void wl_token_ring_unregister()
161
{
162
	wl_unregister_packet_group(&wl_token_ring_handler);
160 163
}
161 164

  
162 165
/**
......
172 175
 * measurement of the maximum BOM reading is needed.
173 176
 **/
174 177
void wl_token_ring_set_bom_functions(void (*on_function) (void),
175
				     void (*off_function) (void), int (*max_bom_function) (void)) {
176
  bom_on_function = on_function;
177
  bom_off_function = off_function;
178
  get_max_bom_function = max_bom_function;
178
	void (*off_function) (void), int (*max_bom_function) (void))
179
{
180
	bom_on_function = on_function;
181
	bom_off_function = off_function;
182
	get_max_bom_function = max_bom_function;
179 183
}
180 184

  
181 185
/**
182 186
 * Called to cleanup the token ring packet group.
183 187
 **/
184
void wl_token_ring_cleanup() {
185
  sensor_matrix_destroy(sensorMatrix);
188
void wl_token_ring_cleanup()
189
{
190
	sensor_matrix_destroy(sensorMatrix);
186 191
}
187 192

  
188 193
/**
189 194
 * Called approximately every quarter second by the wireless library.
190 195
 **/
191
void wl_token_ring_timeout_handler() {
192
  //someone is not responding, assume they are dead
193
  if (deathDelay == 0) {
194
    //pass the token to the next robot if we think someone has died
195
    //also, declare that person dead, as long as it isn't us
196
    if (wl_token_next_robot != wl_get_xbee_id()) {
197
      sensor_matrix_set_in_ring(sensorMatrix, wl_token_next_robot, 0);
198
      WL_DEBUG_PRINT("Robot ");
199
      WL_DEBUG_PRINT_INT(wl_token_next_robot);
200
      WL_DEBUG_PRINT(" has died.\r\n");
201
      wl_token_next_robot = -1;
202
      deathDelay = DEATH_DELAY;
203
    }
196
void wl_token_ring_timeout_handler()
197
{
198
	//someone is not responding, assume they are dead
199
	if (deathDelay == 0)
200
	{
201
		//pass the token to the next robot if we think someone has died
202
		//also, declare that person dead, as long as it isn't us
203
		if (wl_token_next_robot != wl_get_xbee_id())
204
		{
205
			sensor_matrix_set_in_ring(sensorMatrix, wl_token_next_robot, 0);
206
			WL_DEBUG_PRINT("Robot ");
207
			WL_DEBUG_PRINT_INT(wl_token_next_robot);
208
			WL_DEBUG_PRINT(" has died.\r\n");
209
			wl_token_next_robot = -1;
210
			deathDelay = DEATH_DELAY;
211
		}
204 212
		
205
    // we may have been dropped from the ring when this is received
206
    if (ringState == MEMBER)
207
      wl_token_pass_token();
208
  }
213
		// we may have been dropped from the ring when this is received
214
		if (ringState == MEMBER)
215
			wl_token_pass_token();
216
	}
209 217

  
210
  //we must start our own token ring, no one is responding to us
211
  if (joinDelay == 0) {
212
    if (sensor_matrix_get_joined(sensorMatrix) == 0) {
213
      WL_DEBUG_PRINT("Creating our own token ring, no robots seem to exist.\r\n");
214
      sensor_matrix_set_in_ring(sensorMatrix, wl_get_xbee_id(), 1);
215
      ringState = MEMBER;
216
      //this will make us pass the token to ourself
217
      //repeatedly, and other robots when they join
218
      deathDelay = DEATH_DELAY;
219
      wl_token_next_robot = wl_get_xbee_id();
220
    } else {
221
      WL_DEBUG_PRINT("Attempting to join the token ring again.\r\n");
222
      //attempt to rejoin with a random delay
223
      wl_token_ring_join();
224
      joinDelay = rand() / (RAND_MAX / JOIN_DELAY) + 1;
225
    }
226
  }
218
	//we must start our own token ring, no one is responding to us
219
	if (joinDelay == 0)
220
	{
221
		if (sensor_matrix_get_joined(sensorMatrix) == 0)
222
		{
223
			WL_DEBUG_PRINT("Creating our own token ring, no robots seem to exist.\r\n");
224
			sensor_matrix_set_in_ring(sensorMatrix, wl_get_xbee_id(), 1);
225
			ringState = MEMBER;
226
			//this will make us pass the token to ourself
227
			//repeatedly, and other robots when they join
228
			deathDelay = DEATH_DELAY;
229
			wl_token_next_robot = wl_get_xbee_id();
230
		}
231
		else
232
		{
233
			WL_DEBUG_PRINT("Attempting to join the token ring again.\r\n");
234
			//attempt to rejoin with a random delay
235
			wl_token_ring_join();
236
			joinDelay = rand() / (RAND_MAX / JOIN_DELAY) + 1;
237
		}
238
	}
227 239

  
228
  if (deathDelay >= 0)
229
    deathDelay--;
230
  if (joinDelay >= 0)
231
    joinDelay--;
232
  if (bom_on_count >= 0)
233
    bom_on_count++;
240
	if (deathDelay >= 0)
241
		deathDelay--;
242
	if (joinDelay >= 0)
243
		joinDelay--;
244
	if (bom_on_count >= 0)
245
		bom_on_count++;
234 246
}
235 247

  
236 248
/**
......
239 251
 * @param frame the frame number assigned when the packet was sent
240 252
 * @param received 1 if the packet was received, 0 otherwise
241 253
 **/
242
void wl_token_ring_response_handler(int frame, int received) {
243
  if (!received) {
244
    WL_DEBUG_PRINT("FAILED.\r\n");
245
  }
254
void wl_token_ring_response_handler(int frame, int received)
255
{
256
	if (!received)
257
	{
258
		WL_DEBUG_PRINT("FAILED.\r\n");
259
	}
246 260
}
247 261

  
248 262
/**
......
253 267
 * @param length the length of the packet in bytes
254 268
 **/
255 269
void wl_token_ring_receive_handler(char type, int source, unsigned char* packet,
256
				   int length) {
257
  switch (type) {
258
  case WL_TOKEN_PASS:
259
    if (length < 1) {
260
      WL_DEBUG_PRINT("Malformed Token Pass packet received.\r\n");
261
      return;
262
    }
263
    wl_token_pass_receive(source, packet[0], packet + 1, length - 1);
264
    break;
265
  case WL_TOKEN_BOM_ON:
266
    //add the robot to the sensor matrix if it is not already there
267
    wl_token_bom_on_receive(source);
268
    break;
269
  case WL_TOKEN_JOIN:
270
    wl_token_join_receive(source);
271
    break;
272
  case WL_TOKEN_JOIN_ACCEPT:
273
    wl_token_join_accept_receive(source);
274
    break;
275
  default:
276
    WL_DEBUG_PRINT("Unimplemented token ring packet received.\r\n");
277
    break;
278
  }
270
							int length)
271
{
272
	switch (type)
273
	{
274
		case WL_TOKEN_PASS:
275
			if (length < 1)
276
			{
277
				WL_DEBUG_PRINT("Malformed Token Pass packet received.\r\n");
278
				return;
279
			}
280
			wl_token_pass_receive(source, packet[0], packet + 1, length - 1);
281
			break;
282
		case WL_TOKEN_BOM_ON:
283
			//add the robot to the sensor matrix if it is not already there
284
			wl_token_bom_on_receive(source);
285
			break;
286
		case WL_TOKEN_JOIN:
287
			wl_token_join_receive(source);
288
			break;
289
		case WL_TOKEN_JOIN_ACCEPT:
290
			wl_token_join_accept_receive(source);
291
			break;
292
		default:
293
			WL_DEBUG_PRINT("Unimplemented token ring packet received.\r\n");
294
			break;
295
	}
279 296
}
280 297

  
281 298
/**
......
283 300
 * if no token ring exists. The token ring uses global and robot to robot
284 301
 * packets, and does not rely on any PAN.
285 302
 **/
286
void wl_token_ring_join() {
287
  WL_DEBUG_PRINT("Joining the token ring.\r\n");
288
  ringState = JOINING;
289
  joinDelay = DEATH_DELAY * 2;
290
  wl_send_global_packet(WL_TOKEN_RING_GROUP, WL_TOKEN_JOIN,
291
			NULL, 0, 0);
303
void wl_token_ring_join()
304
{
305
	WL_DEBUG_PRINT("Joining the token ring.\r\n");
306
	ringState = JOINING;
307
	joinDelay = DEATH_DELAY * 2;
308
	wl_send_global_packet(WL_TOKEN_RING_GROUP, WL_TOKEN_JOIN,
309
		NULL, 0, 0);
292 310
}
293 311

  
294 312
/**
......
296 314
 * alerting others of its location, but continues storing the
297 315
 * locations of other robots.
298 316
 **/
299
void wl_token_ring_leave() {
300
  ringState = LEAVING;
317
void wl_token_ring_leave()
318
{
319
	ringState = LEAVING;
301 320
}
302 321

  
303 322
/**
......
309 328
 * @return a BOM reading from robot source to robot dest,
310 329
 * in the range 0-15, or -1 if it is unknown
311 330
 **/
312
int wl_token_get_sensor_reading(int source, int dest) {
313
  if (wl_token_is_robot_in_ring(dest) &&
314
      (source == wl_get_xbee_id() || wl_token_is_robot_in_ring(source)))
315
    return sensor_matrix_get_reading(sensorMatrix, source, dest);
316
  return -1;
331
int wl_token_get_sensor_reading(int source, int dest)
332
{
333
	if (wl_token_is_robot_in_ring(dest) &&
334
			(source == wl_get_xbee_id() || wl_token_is_robot_in_ring(source)))
335
		return sensor_matrix_get_reading(sensorMatrix, source, dest);
336
	return -1;
317 337
}
318 338

  
319 339
/**
......
324 344
 * @return a BOM reading from us to robot dest, in the range
325 345
 * 0-15, or -1 if it is unkown
326 346
 **/
327
int wl_token_get_my_sensor_reading(int dest) {
328
  return wl_token_get_sensor_reading(wl_get_xbee_id(), dest);
347
int wl_token_get_my_sensor_reading(int dest)
348
{
349
	return wl_token_get_sensor_reading(wl_get_xbee_id(), dest);
329 350
}
330 351

  
331 352
/**
......
336 357
 *		reading for that robot, repeated for sensorDataLength bytes
337 358
 * @param sensorDataLength the length in bytes of sensorData
338 359
 */
339
void wl_token_pass_receive(int source, char nextRobot, unsigned char* sensorData, int sensorDataLength) {
340
  int i, j;
360
void wl_token_pass_receive(int source, char nextRobot, unsigned char* sensorData, int sensorDataLength)
361
{
362
	int i, j;
341 363

  
342
  // this prevents two tokens from being passed around at a time (second clause is in case we are joining)
343
  if (source != wl_token_next_robot && bom_on_count <= DEATH_DELAY / 2 &&
344
      ringState != ACCEPTED) {
345
    WL_DEBUG_PRINT("Received token pass when a robot should not have died yet.\n");
346
    WL_DEBUG_PRINT("There are probably two tokens going around, packet ignored.\n");
347
    return;
348
  }
364
	// this prevents two tokens from being passed around at a time (second clause is in case we are joining)
365
	if (source != wl_token_next_robot && bom_on_count <= DEATH_DELAY / 2 &&
366
		ringState != ACCEPTED)
367
	{
368
		WL_DEBUG_PRINT("Received token pass when a robot should not have died yet.\n");
369
		WL_DEBUG_PRINT("There are probably two tokens going around, packet ignored.\n");
370
		return;
371
	}
349 372

  
350
  bom_on_count = -1;
351
  deathDelay = -1;
352
  WL_DEBUG_PRINT("Received the token from robot");
353
  WL_DEBUG_PRINT_INT(source);
354
  WL_DEBUG_PRINT(", next robot is ");
355
  WL_DEBUG_PRINT_INT((int)nextRobot);
356
  WL_DEBUG_PRINT(" \r\n");
357
  sensor_matrix_set_in_ring(sensorMatrix, source, 1);
373
	bom_on_count = -1;
374
	deathDelay = -1;
375
	WL_DEBUG_PRINT("Received the token from robot");
376
	WL_DEBUG_PRINT_INT(source);
377
	WL_DEBUG_PRINT(", next robot is ");
378
	WL_DEBUG_PRINT_INT((int)nextRobot);
379
	WL_DEBUG_PRINT(" \r\n");
380
	sensor_matrix_set_in_ring(sensorMatrix, source, 1);
358 381

  
359
  //with this packet, we are passed the id of the next robot in the ring
360
  //and the sensor matrix, a list of id and sensor reading pairs (two bytes for both)
361
  j = 0;
362
  for (i = 0; i < sensor_matrix_get_size(sensorMatrix); i++) {
363
    if (i == source)
364
      continue;
382
	//with this packet, we are passed the id of the next robot in the ring
383
	//and the sensor matrix, a list of id and sensor reading pairs (two bytes for both)
384
	j = 0;
385
	for (i = 0; i < sensor_matrix_get_size(sensorMatrix); i++)
386
	{
387
		if (i == source)
388
			continue;
365 389
		
366
    //set the sensor information we receive
367
    if (j < sensorDataLength / 2 && sensorData[2 * j] == i) {
368
      //the robot we were going to accept has already been accepted
369
      if (accepted == i) {
370
	accepted = -1;
371
	WL_DEBUG_PRINT("Someone accepted the robot we did.\r\n");
372
      }
373
      sensor_matrix_set_reading(sensorMatrix, source, i,
374
				sensorData[2 * j + 1]);
375
      sensor_matrix_set_in_ring(sensorMatrix, i, 1);
376
      j++;
377
    } else {
378
      if (sensor_matrix_get_in_ring(sensorMatrix, i)) {
379
	WL_DEBUG_PRINT("Robot ");
380
	WL_DEBUG_PRINT_INT(i);
381
	WL_DEBUG_PRINT(" has been removed from the sensor matrix of robot ");
382
	WL_DEBUG_PRINT_INT(wl_get_xbee_id());
383
	WL_DEBUG_PRINT(" due to a packet from robot ");
384
	WL_DEBUG_PRINT_INT(source);
385
	WL_DEBUG_PRINT(".\r\n");
386
	sensor_matrix_set_in_ring(sensorMatrix, i, 0);
387
      }
390
		//set the sensor information we receive
391
		if (j < sensorDataLength / 2 && sensorData[2 * j] == i)
392
		{
393
			//the robot we were going to accept has already been accepted
394
			if (accepted == i)
395
			{
396
				accepted = -1;
397
				WL_DEBUG_PRINT("Someone accepted the robot we did.\r\n");
398
			}
399
			sensor_matrix_set_reading(sensorMatrix, source, i,
400
						sensorData[2 * j + 1]);
401
			sensor_matrix_set_in_ring(sensorMatrix, i, 1);
402
			j++;
403
		}
404
		else
405
		{
406
			if (sensor_matrix_get_in_ring(sensorMatrix, i))
407
			{
408
				WL_DEBUG_PRINT("Robot ");
409
				WL_DEBUG_PRINT_INT(i);
410
				WL_DEBUG_PRINT(" has been removed from the sensor matrix of robot ");
411
				WL_DEBUG_PRINT_INT(wl_get_xbee_id());
412
				WL_DEBUG_PRINT(" due to a packet from robot ");
413
				WL_DEBUG_PRINT_INT(source);
414
				WL_DEBUG_PRINT(".\r\n");
415
				sensor_matrix_set_in_ring(sensorMatrix, i, 0);
416
			}
388 417

  
389
      if (i == wl_get_xbee_id() && ringState == MEMBER) {
390
	ringState = NONMEMBER;
391
	wl_token_ring_join();
418
			if (i == wl_get_xbee_id() && ringState == MEMBER)
419
			{
420
				ringState = NONMEMBER;
421
				wl_token_ring_join();
392 422
				
393
	WL_DEBUG_PRINT("We have been removed from the ring ");
394
	WL_DEBUG_PRINT("and are rejoining.\r\n");
395
      }
423
				WL_DEBUG_PRINT("We have been removed from the ring ");
424
				WL_DEBUG_PRINT("and are rejoining.\r\n");
425
			}
396 426
			
397
      //the person who accepted us is dead... let's ask again
398
      if (i == acceptor) {
399
	sensor_matrix_set_in_ring(sensorMatrix,
400
				  wl_get_xbee_id(), 1);
401
	ringState = NONMEMBER;
402
	acceptor = -1;
403
	wl_token_ring_join();
404
      }
405
    }
406
  }
427
			//the person who accepted us is dead... let's ask again
428
			if (i == acceptor)
429
			{
430
				sensor_matrix_set_in_ring(sensorMatrix,
431
						wl_get_xbee_id(), 1);
432
				ringState = NONMEMBER;
433
				acceptor = -1;
434
				wl_token_ring_join();
435
			}
436
		}
437
	}
407 438

  
408
  wl_token_next_robot = nextRobot;
439
	wl_token_next_robot = nextRobot;
409 440
	
410
  deathDelay = get_token_distance(wl_get_xbee_id(), nextRobot) * DEATH_DELAY;
441
	deathDelay = get_token_distance(wl_get_xbee_id(), nextRobot) * DEATH_DELAY;
411 442
	
412
  //we have the token
413
  if (wl_token_next_robot == wl_get_xbee_id())
414
    wl_token_get_token();
443
	//we have the token
444
	if (wl_token_next_robot == wl_get_xbee_id())
445
		wl_token_get_token();
415 446
}
416 447

  
417 448
/**
......
423 454
 * @return the number of passes before the token is expected
424 455
 * to reach robot2 from robot1
425 456
 **/
426
int get_token_distance(int robot1, int robot2) {
427
  int curr = robot1 + 1;
428
  int count = 1;
429
  while (1) {
430
    if (curr == sensor_matrix_get_size(sensorMatrix))
431
      curr = 0;
432
    if (curr == robot2)
433
      break;
434
    if (sensor_matrix_get_in_ring(sensorMatrix, curr))
435
      count++;
436
    curr++;
437
  }
438
  return count;
457
int get_token_distance(int robot1, int robot2)
458
{
459
	int curr = robot1 + 1;
460
	int count = 1;
461
	while (1)
462
	{
463
		if (curr == sensor_matrix_get_size(sensorMatrix))
464
			curr = 0;
465
		if (curr == robot2)
466
			break;
467
		if (sensor_matrix_get_in_ring(sensorMatrix, curr))
468
			count++;
469
		curr++;
470
	}
471
	return count;
439 472
}
440 473

  
441 474
/**
442 475
 * Passes the token to the next robot in the token ring.
443 476
 **/
444
void wl_token_pass_token() {
445
  char nextRobot;
446
  int i = wl_get_xbee_id() + 1;
447
  if (accepted == -1) {
448
    while (1) {
449
      if (i == sensor_matrix_get_size(sensorMatrix))
450
	i = 0;
451
      if (sensor_matrix_get_in_ring(sensorMatrix, i)) {
452
	nextRobot = (char)i;
453
	break;
454
      }
455
      i++;
456
    }
457
  } else {
458
    WL_DEBUG_PRINT("Accepting new robot, sending it the token.\r\n");
459
    //add a new robot to the token ring
460
    sensor_matrix_set_in_ring(sensorMatrix, accepted, 1);
461
    nextRobot = accepted;
462
    accepted = -1;
463
  }
477
void wl_token_pass_token()
478
{
479
	char nextRobot;
480
	int i = wl_get_xbee_id() + 1;
481
	if (accepted == -1)
482
	{
483
		while (1)
484
		{
485
			if (i == sensor_matrix_get_size(sensorMatrix))
486
				i = 0;
487
			if (sensor_matrix_get_in_ring(sensorMatrix, i))
488
			{
489
				nextRobot = (char)i;
490
				break;
491
			}
492
			i++;
493
		}
494
	}
495
	else
496
	{
497
		WL_DEBUG_PRINT("Accepting new robot, sending it the token.\r\n");
498
		//add a new robot to the token ring
499
		sensor_matrix_set_in_ring(sensorMatrix, accepted, 1);
500
		nextRobot = accepted;
501
		accepted = -1;
502
	}
464 503

  
465
  //we don't include ourself
466
  int packetSize = 1 + 2 * (sensor_matrix_get_joined(sensorMatrix) - 1);
467
  char* buf = (char*)malloc(packetSize * sizeof(char));
468
  if (!buf) {
469
    WL_DEBUG_PRINT_INT(packetSize);
470
    WL_DEBUG_PRINT("Out of memory - pass token.\r\n");
471
    return;
472
  }
473
  buf[0] = nextRobot;
504
	//we don't include ourself
505
	int packetSize = 1 + 2 * (sensor_matrix_get_joined(sensorMatrix) - 1);
506
	char* buf = (char*)malloc(packetSize * sizeof(char));
507
	if (!buf)
508
	{
509
		WL_DEBUG_PRINT_INT(packetSize);
510
		WL_DEBUG_PRINT("Out of memory - pass token.\r\n");
511
		return;
512
	}
513
	buf[0] = nextRobot;
474 514

  
475
  int j = 0;
476
  for (i = 0; i < sensor_matrix_get_size(sensorMatrix); i++)
477
    if (sensor_matrix_get_in_ring(sensorMatrix, i) && i != wl_get_xbee_id()) {
478
      buf[2*j + 1] = i;
479
      buf[2*j + 2] = sensor_matrix_get_reading(sensorMatrix, wl_get_xbee_id(), i);
480
      j++;
481
    }
515
	int j = 0;
516
	for (i = 0; i < sensor_matrix_get_size(sensorMatrix); i++)
517
		if (sensor_matrix_get_in_ring(sensorMatrix, i) && i != wl_get_xbee_id())
518
		{
519
			buf[2*j + 1] = i;
520
			buf[2*j + 2] = sensor_matrix_get_reading(sensorMatrix, wl_get_xbee_id(), i);
521
			j++;
522
		}
482 523
	
483
  WL_DEBUG_PRINT("Passing the token to robot ");
484
  WL_DEBUG_PRINT_INT(buf[0]);
485
  WL_DEBUG_PRINT(".\r\n");
486
  wl_send_global_packet(WL_TOKEN_RING_GROUP, WL_TOKEN_PASS,
487
			buf, packetSize, 3);
524
	WL_DEBUG_PRINT("Passing the token to robot ");
525
	WL_DEBUG_PRINT_INT(buf[0]);
526
	WL_DEBUG_PRINT(".\r\n");
527
	wl_send_global_packet(WL_TOKEN_RING_GROUP, WL_TOKEN_PASS,
528
		buf, packetSize, 3);
488 529

  
489
  wl_token_next_robot = nextRobot;
490
  deathDelay = DEATH_DELAY;
491
  free(buf);
530
	wl_token_next_robot = nextRobot;
531
	deathDelay = DEATH_DELAY;
532
	free(buf);
492 533
}
493 534

  
494 535
/**
......
498 539
 *
499 540
 * @param source the robot whose BOM is on
500 541
 **/
501
void wl_token_bom_on_receive(int source) {
502
  WL_DEBUG_PRINT("Robot ");
503
  WL_DEBUG_PRINT_INT(source);
504
  WL_DEBUG_PRINT(" has flashed its bom.\r\n");
542
void wl_token_bom_on_receive(int source)
543
{
544
	WL_DEBUG_PRINT("Robot ");
545
	WL_DEBUG_PRINT_INT(source);
546
	WL_DEBUG_PRINT(" has flashed its bom.\r\n");
505 547
	
506
  bom_on_count = 0;
548
	bom_on_count = 0;
507 549

  
508
  sensor_matrix_set_reading(sensorMatrix, wl_get_xbee_id(), 
509
			    source, get_max_bom_function());
550
	sensor_matrix_set_reading(sensorMatrix, wl_get_xbee_id(), 
551
		source, get_max_bom_function());
510 552
}
511 553

  
512 554
/**
......
516 558
 * 
517 559
 * If there is a pending request for the token, this is processed first.
518 560
 **/
519
void wl_token_get_token() {
520
  WL_DEBUG_PRINT("We have the token.\r\n");
521
  if (ringState == ACCEPTED) {
522
    sensor_matrix_set_in_ring(sensorMatrix,
523
			      wl_get_xbee_id(), 1);
524
    WL_DEBUG_PRINT("Now a member of the token ring.\r\n");
525
    ringState = MEMBER;
526
    joinDelay = -1;
527
  }
561
void wl_token_get_token()
562
{
563
	WL_DEBUG_PRINT("We have the token.\r\n");
564
	if (ringState == ACCEPTED)
565
	{
566
		sensor_matrix_set_in_ring(sensorMatrix,
567
			wl_get_xbee_id(), 1);
568
		WL_DEBUG_PRINT("Now a member of the token ring.\r\n");
569
		ringState = MEMBER;
570
		joinDelay = -1;
571
	}
528 572

  
529
  if (ringState == LEAVING || ringState == NONMEMBER) {
530
    sensor_matrix_set_in_ring(sensorMatrix, wl_get_xbee_id(), 0);
531
    if (ringState == NONMEMBER) {
532
      WL_DEBUG_PRINT("We should have left the token ring, but didn't.\r\n");
533
    }
534
    return;
535
  }
573
	if (ringState == LEAVING || ringState == NONMEMBER)
574
	{
575
		sensor_matrix_set_in_ring(sensorMatrix, wl_get_xbee_id(), 0);
576
		if (ringState == NONMEMBER)
577
		{
578
			WL_DEBUG_PRINT("We should have left the token ring, but didn't.\r\n");
579
		}
580
		return;
581
	}
536 582
	
537
  WL_DEBUG_PRINT("Our BOM has been flashed.\r\n");
538
  wl_send_global_packet(WL_TOKEN_RING_GROUP, WL_TOKEN_BOM_ON,
539
			NULL, 0, 0);
583
	WL_DEBUG_PRINT("Our BOM has been flashed.\r\n");
584
	wl_send_global_packet(WL_TOKEN_RING_GROUP, WL_TOKEN_BOM_ON,
585
		NULL, 0, 0);
540 586

  
541
  bom_on_function();
542
#ifdef ROBOT
543
  delay_ms(BOM_DELAY);
544
#endif
545
  bom_off_function();
587
	bom_on_function();
588
	#ifdef ROBOT
589
	delay_ms(BOM_DELAY);
590
	#endif
591
	bom_off_function();
546 592
	
547
  if (!sensor_matrix_get_in_ring(sensorMatrix, wl_get_xbee_id())) {
548
    WL_DEBUG_PRINT("Removed from sensor matrix while flashing BOM.\r\n");
549
    return;
550
  }
593
	if (!sensor_matrix_get_in_ring(sensorMatrix, wl_get_xbee_id()))
594
	{
595
		WL_DEBUG_PRINT("Removed from sensor matrix while flashing BOM.\r\n");
596
		return;
597
	}
551 598
	
552
  wl_token_pass_token();
599
	wl_token_pass_token();
553 600
}
554 601

  
555 602
/**
......
560 607
 *
561 608
 * @param source the robot who requested to join
562 609
 **/
563
void wl_token_join_receive(int source) {
564
  WL_DEBUG_PRINT("Received joining request from robot ");
565
  WL_DEBUG_PRINT_INT(source);
566
  WL_DEBUG_PRINT(".\r\n");
610
void wl_token_join_receive(int source)
611
{
612
	WL_DEBUG_PRINT("Received joining request from robot ");
613
	WL_DEBUG_PRINT_INT(source);
614
	WL_DEBUG_PRINT(".\r\n");
567 615

  
568
  //we cannot accept the request if we are not a member
569
  if (ringState != MEMBER)
570
    return;
571
  //if they didn't get our response, see if we should respond again
572
  if (accepted == source)
573
    accepted = -1;
574
  //we can only accept one request at a time
575
  if (accepted != -1)
576
    return;
616
	//we cannot accept the request if we are not a member
617
	if (ringState != MEMBER)
618
		return;
619
	//if they didn't get our response, see if we should respond again
620
	if (accepted == source)
621
		accepted = -1;
622
	//we can only accept one request at a time
623
	if (accepted != -1)
624
		return;
577 625
	
578
  //check if we are the preceding robot in the token ring
579
  int i = source - 1;
580
  while (1) {
581
    if (i < 0)
582
      i = sensor_matrix_get_size(sensorMatrix) - 1;
583
    //we must send a join acceptance
584
    if (i == wl_get_xbee_id())
585
      break;
626
	//check if we are the preceding robot in the token ring
627
	int i = source - 1;
628
	while (1)
629
	{
630
		if (i < 0)
631
			i = sensor_matrix_get_size(sensorMatrix) - 1;
632
		//we must send a join acceptance
633
		if (i == wl_get_xbee_id())
634
			break;
586 635

  
587
    //another robot will handle it
588
    if (sensor_matrix_get_in_ring(sensorMatrix, i))
589
      return;
590
    i--;
591
  }
636
		//another robot will handle it
637
		if (sensor_matrix_get_in_ring(sensorMatrix, i))
638
			return;
639
		i--;
640
	}
592 641

  
593
  accepted = source;
594
  wl_send_robot_to_robot_global_packet(WL_TOKEN_RING_GROUP, WL_TOKEN_JOIN_ACCEPT,
595
				       NULL, 0, source, TOKEN_JOIN_ACCEPT_FRAME);
642
	accepted = source;
643
	wl_send_robot_to_robot_global_packet(WL_TOKEN_RING_GROUP, WL_TOKEN_JOIN_ACCEPT,
644
		NULL, 0, source, TOKEN_JOIN_ACCEPT_FRAME);
596 645
	
597
  WL_DEBUG_PRINT("Accepting robot ");
598
  WL_DEBUG_PRINT_INT(source);
599
  WL_DEBUG_PRINT(" into the token ring.\r\n");
646
	WL_DEBUG_PRINT("Accepting robot ");
647
	WL_DEBUG_PRINT_INT(source);
648
	WL_DEBUG_PRINT(" into the token ring.\r\n");
600 649

  
601
  // the token ring has not started yet
602
  if (sensor_matrix_get_joined(sensorMatrix) == 1)
603
    wl_token_pass_token();
650
	// the token ring has not started yet
651
	if (sensor_matrix_get_joined(sensorMatrix) == 1)
652
		wl_token_pass_token();
604 653
}
605 654

  
606 655
/**
......
610 659
 *
611 660
 * @param source the robot who accepted us
612 661
 **/
613
void wl_token_join_accept_receive(int source) {
614
  WL_DEBUG_PRINT("Accepted into the token ring by robot ");
615
  WL_DEBUG_PRINT_INT(source);
616
  WL_DEBUG_PRINT(".\r\n");
617
  joinDelay = JOIN_DELAY;
618
  ringState = ACCEPTED;
619
  acceptor = source;
662
void wl_token_join_accept_receive(int source)
663
{
664
	WL_DEBUG_PRINT("Accepted into the token ring by robot ");
665
	WL_DEBUG_PRINT_INT(source);
666
	WL_DEBUG_PRINT(".\r\n");
667
	joinDelay = JOIN_DELAY;
668
	ringState = ACCEPTED;
669
	acceptor = source;
620 670

  
621
  //add ourselves to the token ring
622
  sensor_matrix_set_in_ring(sensorMatrix, wl_get_xbee_id(), 1);
671
	//add ourselves to the token ring
672
	sensor_matrix_set_in_ring(sensorMatrix, wl_get_xbee_id(), 1);
623 673
}
624 674

  
625 675
/**
......
627 677
 *
628 678
 * @return the number of robots in the token ring
629 679
 **/
630
int wl_token_get_robots_in_ring(void) {
631
  return sensor_matrix_get_joined(sensorMatrix);
680
int wl_token_get_robots_in_ring(void)
681
{
682
	return sensor_matrix_get_joined(sensorMatrix);
632 683
}
633 684

  
634 685
/**
......
638 689
 * @param robot the robot to check for whether it is in the token ring
639 690
 * @return nonzero if the robot is in the token ring, zero otherwise
640 691
 **/
641
int wl_token_is_robot_in_ring(int robot) {
642
  return sensor_matrix_get_in_ring(sensorMatrix, robot);
692
int wl_token_is_robot_in_ring(int robot)
693
{
694
	return sensor_matrix_get_in_ring(sensorMatrix, robot);
643 695
}
644 696

  
645 697
/**
......
647 699
 *
648 700
 * @see wl_token_iterator_has_next, wl_token_iterator_next
649 701
 **/
650
void wl_token_iterator_begin(void) {
651
  int i = 0;
652
  iteratorCount = 0;
653
  while (!sensor_matrix_get_in_ring(sensorMatrix, i) &&
654
	 i < sensor_matrix_get_size(sensorMatrix))
655
    i++;
656
  if (i == sensor_matrix_get_size(sensorMatrix))
657
    i = -1;
658
  iteratorCount = i;
702
void wl_token_iterator_begin(void)
703
{
704
	int i = 0;
705
	iteratorCount = 0;
706
	while (!sensor_matrix_get_in_ring(sensorMatrix, i) &&
707
			i < sensor_matrix_get_size(sensorMatrix))
708
		i++;
709
	if (i == sensor_matrix_get_size(sensorMatrix))
710
		i = -1;
711
	iteratorCount = i;
659 712
}
660 713

  
661 714
/**
......
667 720
 *
668 721
 * @see wl_token_iterator_begin, wl_token_iterator_next
669 722
 **/
670
int wl_token_iterator_has_next(void) {
671
  return iteratorCount != -1;
723
int wl_token_iterator_has_next(void)
724
{
725
	return iteratorCount != -1;
672 726
}
673 727

  
674 728
/**
......
678 732
 *
679 733
 * @see wl_token_iterator_begin, wl_token_iterator_has_next
680 734
 **/
681
int wl_token_iterator_next(void) {
682
  int result = iteratorCount;
683
  if (result < 0)
684
    return result;
735
int wl_token_iterator_next(void)
736
{
737
	int result = iteratorCount;
738
	if (result < 0)
739
		return result;
685 740

  
686
  iteratorCount++;
687
  while (!sensor_matrix_get_in_ring(sensorMatrix, iteratorCount) &&
688
	 iteratorCount < sensor_matrix_get_size(sensorMatrix))
689
    iteratorCount++;
690
  if (iteratorCount == sensor_matrix_get_size(sensorMatrix))
691
    iteratorCount = -1;
692
  return result;
741
	iteratorCount++;
742
	while (!sensor_matrix_get_in_ring(sensorMatrix, iteratorCount) &&
743
		iteratorCount < sensor_matrix_get_size(sensorMatrix))
744
		iteratorCount++;
745
	if (iteratorCount == sensor_matrix_get_size(sensorMatrix))
746
		iteratorCount = -1;
747
	return result;
693 748
}
694 749

  
695 750
/**
......
697 752
 *
698 753
 * @return the number of robots in the token ring
699 754
 **/
700
int wl_token_get_num_robots(void) {
701
  return sensor_matrix_get_joined(sensorMatrix);
755
int wl_token_get_num_robots(void)
756
{
757
	return sensor_matrix_get_joined(sensorMatrix);
702 758
}
703 759

  
704 760
/**
......
706 762
 *
707 763
 * @return the number of robots in the sensor matrix
708 764
 **/
709
int wl_token_get_matrix_size(void) {
710
  return sensor_matrix_get_size(sensorMatrix);
765
int wl_token_get_matrix_size(void)
766
{
767
	return sensor_matrix_get_size(sensorMatrix);
711 768
}
769

  
trunk/code/projects/libwireless/lib/sensor_matrix.h
51 51
 *
52 52
 * A sensor matrix.
53 53
 **/
54
typedef struct {
55
  /**
56
   * The size of the sensor matrix.
57
   **/
58
  int size;
59
  /**
60
   * The matrix. Each row represents the readings of one
61
   * robot.
62
   **/
63
  int** matrix;
64
  /**
65
   * The element representing a robot is true if that robot
66
   * is in the token ring and false otherwise.
67
   **/
68
  int* joined;
69
  /**
70
   * The number of robots in the token ring.
71
   **/
72
  int numJoined;
54
typedef struct
55
{
56
	/**
57
	 * The size of the sensor matrix.
58
	**/
59
	int size;
60
	/**
61
	 * The matrix. Each row represents the readings of one
62
	 * robot.
63
	 **/
64
	int** matrix;
65
	/**
66
	 * The element representing a robot is true if that robot
67
	 * is in the token ring and false otherwise.
68
	 **/
69
	int* joined;
70
	/**
71
	 * The number of robots in the token ring.
72
	 **/
73
	int numJoined;
73 74
} SensorMatrix;
74 75

  
75 76
/**@brief Create a sensor matrix **/
trunk/code/projects/libwireless/lib/wireless.h
72 72
 * handlers for various events which can occur related to a packet
73 73
 * group.
74 74
 **/
75
typedef struct {
75
typedef struct
76
{
76 77
	/**
77 78
	 * The group code for this packet group. This number
78 79
	 * must be unique. The maximum number of packet groups
trunk/code/projects/libwireless/lib/xbee.c
90 90

  
91 91
int xbee_handle_packet(char* packet, int len);
92 92
void xbee_handle_at_command_response(char* command, char result,
93
				     char* extra, int extraLen);
93
	char* extra, int extraLen);
94 94
void xbee_handle_status(char status);
95 95
int xbee_verify_checksum(char* packet, int len);
96 96
char xbee_compute_checksum(char* packet, int len);
......
136 136
 * to the buffer.
137 137
 **/
138 138
#ifndef FIREFLY
139
ISR(USART1_RX_vect) {
140
  char c = UDR1;
141
  arrival_buf[buffer_last] = c;
142
  int t = buffer_last + 1;
143
  if (t == XBEE_BUFFER_SIZE)
144
    t = 0;
145
  if (t == buffer_first) {
146
    WL_DEBUG_PRINT("Out of space in buffer.\n");
147
  }
148
  buffer_last = t;
139
ISR(USART1_RX_vect)
140
{
141
	char c = UDR1;
142
	arrival_buf[buffer_last] = c;
143
	int t = buffer_last + 1;
144
	if (t == XBEE_BUFFER_SIZE)
145
		t = 0;
146
	if (t == buffer_first)
147
	{
148
		WL_DEBUG_PRINT("Out of space in buffer.\n");
149
	}
150
	buffer_last = t;
149 151
}
150 152
#else
151
SIGNAL(SIG_USART0_RECV) {
152
  char c = UDR0;
153
  arrival_buf[buffer_last] = c;
154
  int t = buffer_last + 1;
155
  if (t == XBEE_BUFFER_SIZE)
156
    t = 0;
157
  if (t == buffer_first) {
158
    WL_DEBUG_PRINT("Out of space in buffer.\n");
159
  }
160
  buffer_last = t;
153
SIGNAL(SIG_USART0_RECV)
154
{
155
	char c = UDR0;
156
	arrival_buf[buffer_last] = c;
157
	int t = buffer_last + 1;
158
	if (t == XBEE_BUFFER_SIZE)
159
		t = 0;
160
	if (t == buffer_first)
161
	{
162
		WL_DEBUG_PRINT("Out of space in buffer.\n");
163
	}
164
	buffer_last = t;
161 165
}
162 166
#endif
163 167

  
......
166 170
/**
167 171
 * Thread that listens to the xbee.
168 172
 **/
169
void* listen_to_xbee(void* x) {
170
  char c;
171
  while (1) {
172
    xbee_read(&c, 1);
173
    arrival_buf[buffer_last] = c;
174
    int t = buffer_last + 1;
175
    if (t == XBEE_BUFFER_SIZE)
176
      t = 0;
177
    if (t == buffer_first) {
178
      WL_DEBUG_PRINT("Out of space in buffer.\n");
179
    }
180
    buffer_last = t;
181
  }
182
  return 0;
173
void* listen_to_xbee(void* x)
174
{
175
	char c;
176
	while (1)
177
	{
178
		xbee_read(&c, 1);
179
		arrival_buf[buffer_last] = c;
180
		int t = buffer_last + 1;
181
		if (t == XBEE_BUFFER_SIZE)
182
			t = 0;
183
		if (t == buffer_first)
184
		{
185
			WL_DEBUG_PRINT("Out of space in buffer.\n");
186
		}
187
		buffer_last = t;
188
	}
189
	return 0;
183 190
}
184 191

  
185 192
#endif
......
187 194
/**
188 195
 * Initializes the XBee library so that other functions may be used.
189 196
 **/
190
int xbee_lib_init(void) {
191
  arrival_buf[0] = 'A';
192
  arrival_buf[1] = 'A';
193
  arrival_buf[2] = 'A';
194
#ifdef ROBOT
197
int xbee_lib_init(void)
198
{
199
	arrival_buf[0] = 'A';
200
	arrival_buf[1] = 'A';
201
	arrival_buf[2] = 'A';
202
	#ifdef ROBOT
195 203

  
196
  //enable the receiving interrupt
197
#ifdef FIREFLY
198
  UCSR0B |= _BV(RXCIE) | _BV(RXEN);
199
#else
200
  UCSR1B |= _BV(RXCIE);
201
#endif
202
  sei();
203
#else
204
  printf("Connecting to port %s.\n", xbee_com_port);
205
  xbee_stream = open(xbee_com_port, O_RDWR);
206
  if (xbee_stream == -1/* || lockf(xbee_stream, F_TEST, 0) != 0*/) {
207
    printf("Failed to open connection to XBee on port %s\r\n", xbee_com_port);
208
    return -1;
209
  }
204
	//enable the receiving interrupt
205
	#ifdef FIREFLY
206
	UCSR0B |= _BV(RXCIE) | _BV(RXEN);
207
	#else
208
	UCSR1B |= _BV(RXCIE);
209
	#endif
210
	sei();
211
	#else
212
	printf("Connecting to port %s.\n", xbee_com_port);
213
	xbee_stream = open(xbee_com_port, O_RDWR);
214
	if (xbee_stream == -1/* || lockf(xbee_stream, F_TEST, 0) != 0*/)
215
	{
216
		printf("Failed to open connection to XBee on port %s\r\n", xbee_com_port);
217
		return -1;
218
	}
210 219
	
211
  // set baud rate, etc. correctly
212
  struct termios options;
220
	// set baud rate, etc. correctly
221
	struct termios options;
213 222

  
214
  tcgetattr(xbee_stream, &options);
215
  cfsetispeed(&options, B9600);
216
  cfsetospeed(&options, B9600);
217
  options.c_iflag &= ~ICRNL;
218
  options.c_oflag &= ~OCRNL;
219
  options.c_cflag |= (CLOCAL | CREAD);
220
  options.c_cflag &= ~PARENB;
221
  options.c_cflag &= ~CSTOPB;
222
  options.c_cflag &= ~CSIZE;
223
  options.c_cflag |= CS8;
224
  options.c_lflag &= ~ICANON;
225
  options.c_cc[VMIN] = 1;
226
  options.c_cc[VTIME] = 50;
223
	tcgetattr(xbee_stream, &options);
224
	cfsetispeed(&options, B9600);
225
	cfsetospeed(&options, B9600);
226
	options.c_iflag &= ~ICRNL;
227
	options.c_oflag &= ~OCRNL;
228
	options.c_cflag |= (CLOCAL | CREAD);
229
	options.c_cflag &= ~PARENB;
230
	options.c_cflag &= ~CSTOPB;
231
	options.c_cflag &= ~CSIZE;
232
	options.c_cflag |= CS8;
233
	options.c_lflag &= ~ICANON;
234
	options.c_cc[VMIN] = 1;
235
	options.c_cc[VTIME] = 50;
227 236

  
228
  if (tcsetattr(xbee_stream, TCSANOW, &options)) {
229
    fprintf(stderr, "Error setting attributes.\n");
230
    return -1;
231
  }
237
	if (tcsetattr(xbee_stream, TCSANOW, &options))
238
	{
239
		fprintf(stderr, "Error setting attributes.\n");
240
		return -1;
241
	}
232 242

  
233
  //lockf(xbee_stream, F_LOCK, 0);
243
	//lockf(xbee_stream, F_LOCK, 0);
234 244
	
235
  xbee_listen_thread =
236
    (pthread_t*)malloc(sizeof(pthread_t));
237
  if (xbee_listen_thread == NULL) {
238
    fprintf(stderr, "%s: Malloc failed.\n", __FUNCTION__);
239
    return -1;
240
  }
245
	xbee_listen_thread =
246
		(pthread_t*)malloc(sizeof(pthread_t));
247
	if (xbee_listen_thread == NULL)
248
	{
249
		fprintf(stderr, "%s: Malloc failed.\n", __FUNCTION__);
250
		return -1;
251
	}
241 252
	
242
  int ret = pthread_create(xbee_listen_thread, NULL,
243
			   listen_to_xbee, NULL);
244
  if (ret) {
245
    fprintf(stderr, "Failed to create listener thread.\r\n");
246
    return -1;
247
  }
253
	int ret = pthread_create(xbee_listen_thread, NULL,
254
		listen_to_xbee, NULL);
255
	if (ret)
256
	{
257
		fprintf(stderr, "Failed to create listener thread.\r\n");
258
		return -1;
259
	}
248 260
	
249
#endif
250
  xbee_enter_command_mode();
251
  xbee_enter_api_mode();
252
  xbee_exit_command_mode();
253
  xbee_send_read_at_command("MY");
261
	#endif
262
	xbee_enter_command_mode();
263
	xbee_enter_api_mode();
264
	xbee_exit_command_mode();
265
	xbee_send_read_at_command("MY");
254 266
	
255
  //wait to return until the address is set
256
  while (xbee_address == 0) xbee_get_packet(NULL);
267
	//wait to return until the address is set
268
	while (xbee_address == 0) xbee_get_packet(NULL);
257 269

  
258
  return 0;
270

  
271
	return 0;
259 272
}
260 273

  
261 274
/**
262 275
 * Call when finished using the XBee library. This releases
263 276
 * all sued resources.
264 277
 **/
265
void xbee_terminate() {
266
#ifndef ROBOT
267
  pthread_cancel(*xbee_listen_thread);
268
  free(xbee_listen_thread);
269
  lockf(xbee_stream, F_ULOCK, 0);
270
  close(xbee_stream);
271
#endif
278
void xbee_terminate()
279
{
280
	#ifndef ROBOT
281
	pthread_cancel(*xbee_listen_thread);
282
	free(xbee_listen_thread);
283
	lockf(xbee_stream, F_ULOCK, 0);
284
	close(xbee_stream);
285
	#endif
272 286
}
273 287

  
274 288
/**
......
277 291
 * @param buf the buffer of data to send
278 292
 * @param size the number of bytes to send
279 293
 **/
280
void xbee_send(char* buf, int size) {
281
#ifdef ROBOT
282
  int i;
283
  for (i = 0; i < size; i++)
284
    xbee_putc(buf[i]);
285
#else
286
  int ret = write(xbee_stream, buf, size);
287
  //success
288
  if (ret == size)
289
    return;
290
  if (ret == -1) {
291
    //interrupted by system signal, probably timer interrupt.
292
    //just try again
293
    if (errno == 4) {
294
      xbee_send(buf, size);
295
      return;
296
    }
297
    printf("Failed to write to xbee, error %i.\r\n", errno);
298
    return;
299
  }
294
void xbee_send(char* buf, int size)
295
{
296
	#ifdef ROBOT
297
	int i;
298
	for (i = 0; i < size; i++)
299
		xbee_putc(buf[i]);
300
	#else
301
	int ret = write(xbee_stream, buf, size);
302
	//success
303
	if (ret == size)
304
		return;
305
	if (ret == -1)
306
	{
307
		//interrupted by system signal, probably timer interrupt.
308
		//just try again
309
		if (errno == 4)
310
		{
311
			xbee_send(buf, size);
312
			return;
313
		}
314
		printf("Failed to write to xbee, error %i.\r\n", errno);
315
		return;
316
	}
300 317

  
301
  //write was interrupted after writing ret bytes
302
  xbee_send(buf + ret, size - ret);
303
#endif
318
	//write was interrupted after writing ret bytes
319
	xbee_send(buf + ret, size - ret);
320
	#endif
304 321
}
305 322

  
306 323
/**
......
308 325
 *
309 326
 * @param c the string to send to the XBEE
310 327
 **/
311
void xbee_send_string(char* c) {
312
  xbee_send(c, strlen(c));
328
void xbee_send_string(char* c)
329
{
330
	xbee_send(c, strlen(c));
313 331
}
314 332

  
315 333
#ifndef ROBOT
316
void xbee_read(char* buf, int size) {
317
  if (read(xbee_stream, buf, size) == -1)
318
    printf("Failed to read from xbee.\r\n");
334
void xbee_read(char* buf, int size)
335
{
336
	if (read(xbee_stream, buf, size) == -1)
337
		printf("Failed to read from xbee.\r\n");
319 338
}
320 339
#endif
321 340

  
322 341
/**
323 342
 * Enter into command mode.
324 343
 **/
325
void xbee_enter_command_mode() {
326
  xbee_send_string("+++");
327
  xbee_wait_for_ok();
344
void xbee_enter_command_mode()
345
{
346
	xbee_send_string("+++");
347
	xbee_wait_for_ok();
328 348
}
329 349

  
330 350
/**
331 351
 * Exit from command mode.
332 352
 **/
333
void xbee_exit_command_mode() {
334
  xbee_send_string("ATCN\r");
335
  xbee_wait_for_ok();
353
void xbee_exit_command_mode()
354
{
355
	xbee_send_string("ATCN\r");
356
	xbee_wait_for_ok();
336 357
}
337 358

  
338 359
/**
339 360
 * Enter API mode.
340 361
 **/
341
void xbee_enter_api_mode() {
342
  xbee_send_string("ATAP 1\r");
343
  xbee_wait_for_ok();
362
void xbee_enter_api_mode()
363
{
364
	xbee_send_string("ATAP 1\r");
365
	xbee_wait_for_ok();
344 366
}
345 367

  
346 368
/**
347 369
 * Exit API mode. (warning - does not check for response)
348 370
 **/
349
void xbee_exit_api_mode() {
350
  xbee_send_string("ATAP 0\r");
371
void xbee_exit_api_mode()
372
{
373
	xbee_send_string("ATAP 0\r");
351 374
}
352 375

  
353 376
/**
354 377
 * Wait until the string "OK\r" is received from the XBee.
355 378
 **/
356
void xbee_wait_for_ok() {
357
  xbee_wait_for_string("OK\r", 3);
379
void xbee_wait_for_ok()
380
{
381
	xbee_wait_for_string("OK\r", 3);
358 382
}
359 383

  
360 384
/**
......
364 388
 * @param s the string to receive
365 389
 * @param len the length of the string
366 390
 **/
367
void xbee_wait_for_string(char* s, int len) {
368
  char* curr = s;
369
  while (curr - s < len) {
370
    // check if buffer is empty
371
    if (buffer_last == buffer_first)
372
      continue;
373
    char c = arrival_buf[buffer_first++];
374
    if (buffer_first == XBEE_BUFFER_SIZE)
375
      buffer_first = 0;
376
    if (c == *curr)
377
      curr++;
378
    else
379
      curr = s;
380
  }
391
void xbee_wait_for_string(char* s, int len)
392
{
393
	char* curr = s;
394
	while (curr - s < len)
395
	{
396
		// check if buffer is empty
397
		if (buffer_last == buffer_first)
398
			continue;
399
		char c = arrival_buf[buffer_first++];
400
		if (buffer_first == XBEE_BUFFER_SIZE)
401
			buffer_first = 0;
402
		if (c == *curr)
403
			curr++;
404
		else
405
			curr = s;
406
	}
381 407
}
382 408

  
383 409
/**
......
393 419
 * @return 0 if the checksum is incorrect, nonzero
394 420
 * otherwise
395 421
 **/
396
int xbee_verify_checksum(char* packet, int len) {
397
  unsigned char sum = 0;
398
  int i;
399
  for (i = 3; i < len; i++)
400
    sum += (unsigned char)packet[i];
401
  return sum == 0xFF;
422
int xbee_verify_checksum(char* packet, int len)
423
{
424
	unsigned char sum = 0;
425
	int i;
426
	for (i = 3; i < len; i++)
427
		sum += (unsigned char)packet[i];
428
	return sum == 0xFF;
402 429
}
403 430

  
404 431
/**
......
410 437
 * @return the checksum of the packet, which will
411 438
 * become the last byte sent in the packet
412 439
 **/
413
char xbee_compute_checksum(char* buf, int len) {
414
  int i;
415
  unsigned char sum = 0;
416
  for (i = 0; i < len; i++)
417
    sum += (unsigned char)buf[i];
418
  return 0xFF - sum;
440
char xbee_compute_checksum(char* buf, int len)
441
{
442
	int i;
443
	unsigned char sum = 0;
444
	for (i = 0; i < len; i++)
445
		sum += (unsigned char)buf[i];
446
	return 0xFF - sum;
419 447
}
420 448

  
421 449
/**
......
427 455
 * @param len the size in bytes of the packet data
428 456
 *
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff