1 |
1 |
/**
|
2 |
2 |
* Copyright (c) 2007 Colony Project
|
3 |
|
*
|
|
3 |
*
|
4 |
4 |
* Permission is hereby granted, free of charge, to any person
|
5 |
5 |
* obtaining a copy of this software and associated documentation
|
6 |
6 |
* files (the "Software"), to deal in the Software without
|
... | ... | |
9 |
9 |
* copies of the Software, and to permit persons to whom the
|
10 |
10 |
* Software is furnished to do so, subject to the following
|
11 |
11 |
* conditions:
|
12 |
|
*
|
|
12 |
*
|
13 |
13 |
* The above copyright notice and this permission notice shall be
|
14 |
14 |
* included in all copies or substantial portions of the Software.
|
15 |
|
*
|
|
15 |
*
|
16 |
16 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17 |
17 |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
18 |
18 |
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
... | ... | |
79 |
79 |
/*Command Mode Functions
|
80 |
80 |
* Called during initialization.
|
81 |
81 |
*/
|
82 |
|
void xbee_enter_command_mode(void);
|
83 |
|
void xbee_exit_command_mode(void);
|
84 |
|
void xbee_enter_api_mode(void);
|
85 |
|
void xbee_exit_api_mode(void);
|
86 |
|
void xbee_wait_for_string(char* s, int len);
|
87 |
|
void xbee_wait_for_ok(void);
|
|
82 |
static void xbee_enter_command_mode(void);
|
|
83 |
static void xbee_exit_command_mode(void);
|
|
84 |
static void xbee_enter_api_mode(void);
|
|
85 |
static void xbee_exit_api_mode(void);
|
|
86 |
static void xbee_wait_for_string(char* s, int len);
|
|
87 |
static void xbee_wait_for_ok(void);
|
88 |
88 |
|
89 |
89 |
/*API Mode Functions*/
|
90 |
90 |
|
... | ... | |
184 |
184 |
WL_DEBUG_PRINT("Out of space in buffer.\n");
|
185 |
185 |
}
|
186 |
186 |
buffer_last = t;
|
|
187 |
|
|
188 |
usleep(1000);
|
187 |
189 |
}
|
188 |
190 |
return 0;
|
189 |
191 |
}
|
... | ... | |
215 |
217 |
printf("Failed to open connection to XBee on port %s\r\n", xbee_com_port);
|
216 |
218 |
return -1;
|
217 |
219 |
}
|
218 |
|
|
|
220 |
|
219 |
221 |
// set baud rate, etc. correctly
|
220 |
222 |
struct termios options;
|
221 |
223 |
|
... | ... | |
240 |
242 |
}
|
241 |
243 |
|
242 |
244 |
//lockf(xbee_stream, F_LOCK, 0);
|
243 |
|
|
244 |
|
xbee_listen_thread =
|
245 |
|
(pthread_t*)malloc(sizeof(pthread_t));
|
|
245 |
|
|
246 |
xbee_listen_thread = (pthread_t*)malloc(sizeof(pthread_t));
|
246 |
247 |
if (xbee_listen_thread == NULL)
|
247 |
248 |
{
|
248 |
249 |
fprintf(stderr, "%s: Malloc failed.\n", __FUNCTION__);
|
249 |
250 |
return -1;
|
250 |
251 |
}
|
251 |
|
|
252 |
|
int ret = pthread_create(xbee_listen_thread, NULL,
|
253 |
|
listen_to_xbee, NULL);
|
|
252 |
|
|
253 |
int ret = pthread_create(xbee_listen_thread, NULL, listen_to_xbee, NULL);
|
254 |
254 |
if (ret)
|
255 |
255 |
{
|
256 |
256 |
fprintf(stderr, "Failed to create listener thread.\r\n");
|
257 |
257 |
return -1;
|
258 |
258 |
}
|
259 |
|
|
|
259 |
|
260 |
260 |
#endif
|
261 |
261 |
xbee_enter_command_mode();
|
262 |
262 |
xbee_enter_api_mode();
|
263 |
263 |
xbee_exit_command_mode();
|
264 |
264 |
xbee_send_read_at_command("MY");
|
265 |
|
|
|
265 |
|
266 |
266 |
//wait to return until the address is set
|
267 |
267 |
while (xbee_address == 0) xbee_get_packet(NULL);
|
268 |
268 |
|
... | ... | |
286 |
286 |
|
287 |
287 |
/**
|
288 |
288 |
* Send a buffer buf of size bytes to the XBee.
|
289 |
|
*
|
|
289 |
*
|
290 |
290 |
* @param buf the buffer of data to send
|
291 |
291 |
* @param size the number of bytes to send
|
292 |
292 |
**/
|
... | ... | |
341 |
341 |
/**
|
342 |
342 |
* Enter into command mode.
|
343 |
343 |
**/
|
344 |
|
void xbee_enter_command_mode()
|
|
344 |
static void xbee_enter_command_mode()
|
345 |
345 |
{
|
346 |
346 |
xbee_send_string("+++");
|
347 |
347 |
xbee_wait_for_ok();
|
... | ... | |
350 |
350 |
/**
|
351 |
351 |
* Exit from command mode.
|
352 |
352 |
**/
|
353 |
|
void xbee_exit_command_mode()
|
|
353 |
static void xbee_exit_command_mode()
|
354 |
354 |
{
|
355 |
355 |
xbee_send_string("ATCN\r");
|
356 |
356 |
xbee_wait_for_ok();
|
... | ... | |
359 |
359 |
/**
|
360 |
360 |
* Enter API mode.
|
361 |
361 |
**/
|
362 |
|
void xbee_enter_api_mode()
|
|
362 |
static void xbee_enter_api_mode()
|
363 |
363 |
{
|
364 |
364 |
xbee_send_string("ATAP 1\r");
|
365 |
365 |
xbee_wait_for_ok();
|
... | ... | |
368 |
368 |
/**
|
369 |
369 |
* Exit API mode. (warning - does not check for response)
|
370 |
370 |
**/
|
371 |
|
void xbee_exit_api_mode()
|
|
371 |
static void xbee_exit_api_mode()
|
372 |
372 |
{
|
373 |
373 |
xbee_send_string("ATAP 0\r");
|
374 |
374 |
}
|
... | ... | |
376 |
376 |
/**
|
377 |
377 |
* Wait until the string "OK\r" is received from the XBee.
|
378 |
378 |
**/
|
379 |
|
void xbee_wait_for_ok()
|
|
379 |
static void xbee_wait_for_ok()
|
380 |
380 |
{
|
381 |
381 |
xbee_wait_for_string("OK\r", 3);
|
382 |
382 |
}
|
... | ... | |
388 |
388 |
* @param s the string to receive
|
389 |
389 |
* @param len the length of the string
|
390 |
390 |
**/
|
391 |
|
void xbee_wait_for_string(char* s, int len)
|
|
391 |
static void xbee_wait_for_string(char* s, int len)
|
392 |
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 |
|
}
|
|
393 |
char* curr = s;
|
|
394 |
while (curr - s < len) {
|
|
395 |
// check if buffer is empty
|
|
396 |
if (buffer_last != buffer_first) {
|
|
397 |
char c = arrival_buf[buffer_first++];
|
|
398 |
if (buffer_first == XBEE_BUFFER_SIZE) {
|
|
399 |
buffer_first = 0;
|
|
400 |
}
|
|
401 |
|
|
402 |
if (c == *curr) {
|
|
403 |
curr++;
|
|
404 |
} else {
|
|
405 |
curr = s;
|
|
406 |
}
|
|
407 |
}
|
|
408 |
|
|
409 |
usleep(1000);
|
|
410 |
}
|
407 |
411 |
}
|
408 |
412 |
|
409 |
413 |
/**
|
... | ... | |
490 |
494 |
{
|
491 |
495 |
char buf[16];
|
492 |
496 |
int i;
|
493 |
|
|
|
497 |
|
494 |
498 |
buf[0] = XBEE_FRAME_AT_COMMAND;
|
495 |
499 |
buf[1] = 1;
|
496 |
500 |
buf[2] = command[0];
|
... | ... | |
512 |
516 |
|
513 |
517 |
/**
|
514 |
518 |
* Send the specified packet.
|
515 |
|
*
|
|
519 |
*
|
516 |
520 |
* @param packet the packet data to send
|
517 |
521 |
* @param len the number of bytes in the packet
|
518 |
|
*
|
|
522 |
*
|
519 |
523 |
* @param dest the ID of the XBee to send the packet to,
|
520 |
524 |
* or XBEE_BROADCAST to send the message to all robots
|
521 |
525 |
* in the PAN.
|
522 |
|
*
|
|
526 |
*
|
523 |
527 |
* @param options a combination of the flags
|
524 |
|
* XBEE_OPTIONS_NONE, XBEE_OPTIONS_DISABLE_RESPONSE and
|
|
528 |
* XBEE_OPTIONS_NONE, XBEE_OPTIONS_DISABLE_RESPONSE and
|
525 |
529 |
* XBEE_OPTIONS_BROADCAST_ALL_PANS
|
526 |
530 |
*
|
527 |
531 |
* @param frame the frame number to associate this packet
|
... | ... | |
591 |
595 |
*
|
592 |
596 |
* The first byte of the packet will be either
|
593 |
597 |
* XBEE_TX_STATUS or XBEE_RX to indicated
|
594 |
|
* a response to a sent message or a received message,
|
|
598 |
* a response to a sent message or a received message,
|
595 |
599 |
* respectively.<br><br>
|
596 |
600 |
*
|
597 |
601 |
* For a status response packet:<br>
|
598 |
602 |
* The first byte will be XBEE_TX_STATUS.<br>
|
599 |
603 |
* The second byte will be the frame number.<br>
|
600 |
604 |
* The third byte will be the result. 0 indicates success,
|
601 |
|
* and nonzero indicates that an error ocurred in
|
|
605 |
* and nonzero indicates that an error ocurred in
|
602 |
606 |
* transmitting the packet.<br><br>
|
603 |
607 |
*
|
604 |
608 |
* For a received packet:<br>
|
... | ... | |
608 |
612 |
* The fourth byte is the signal strength.<br>
|
609 |
613 |
* The fifth byte is 1 if the packet were sent to
|
610 |
614 |
* a specific address, and 2 if it is a broadcast packet.<br><br>
|
611 |
|
*
|
|
615 |
*
|
612 |
616 |
* @param dest set to the packet data
|
613 |
617 |
* @return the length of the packet, or -1 if no packet
|
614 |
618 |
* is available
|
... | ... | |
636 |
640 |
int len = -1;
|
637 |
641 |
if (currentBufPos >= 3)
|
638 |
642 |
len = (int)xbee_buf[2] + ((int)xbee_buf[1] << 8);
|
639 |
|
|
|
643 |
|
640 |
644 |
while (len == -1 //packet length has not been read yet
|
641 |
645 |
|| currentBufPos < len + 4)
|
642 |
646 |
{
|
... | ... | |
657 |
661 |
if (buffer_first == XBEE_BUFFER_SIZE)
|
658 |
662 |
buffer_first = 0;
|
659 |
663 |
}
|
660 |
|
|
|
664 |
|
661 |
665 |
currentBufPos = 0;
|
662 |
|
|
|
666 |
|
663 |
667 |
if (!xbee_verify_checksum(xbee_buf, len + 4))
|
664 |
668 |
{
|
665 |
669 |
WL_DEBUG_PRINT("XBee checksum failed.\r\n");
|
... | ... | |
669 |
673 |
//we will take care of the packet
|
670 |
674 |
if (xbee_handle_packet(xbee_buf + 3, len))
|
671 |
675 |
return -1;
|
672 |
|
|
|
676 |
|
673 |
677 |
if (dest == NULL)
|
674 |
678 |
return -1;
|
675 |
|
|
|
679 |
|
676 |
680 |
int i;
|
677 |
681 |
for (i = 3; i < len + 3; i++)
|
678 |
682 |
dest[i - 3] = xbee_buf[i];
|
... | ... | |
731 |
735 |
WL_DEBUG_PRINT("AT");
|
732 |
736 |
WL_DEBUG_PRINT(command);
|
733 |
737 |
WL_DEBUG_PRINT(" command was successful.\r\n");
|
734 |
|
|
|
738 |
|
735 |
739 |
if (command[0] == 'I' && command[1] == 'D')
|
736 |
740 |
{
|
737 |
741 |
xbee_panID = xbee_pending_panID;
|
... | ... | |
749 |
753 |
WL_DEBUG_PRINT(".\r\n");
|
750 |
754 |
return;
|
751 |
755 |
}
|
752 |
|
|
|
756 |
|
753 |
757 |
if (command[0] == 'M' && command[1] == 'Y' && extraLen != 0)
|
754 |
758 |
{
|
755 |
759 |
xbee_address = 0;
|
... | ... | |
778 |
782 |
*
|
779 |
783 |
* @param packet the packet to handle
|
780 |
784 |
* @param len the length of the packet
|
781 |
|
*
|
|
785 |
*
|
782 |
786 |
* @return 1 if we have handled the packet, 0 otherwise
|
783 |
787 |
*/
|
784 |
788 |
int xbee_handle_packet(char* packet, int len)
|
... | ... | |
789 |
793 |
WL_DEBUG_PRINT("Non-positive packet length.\r\n");
|
790 |
794 |
return 0;
|
791 |
795 |
}
|
792 |
|
|
|
796 |
|
793 |
797 |
switch ((unsigned char)packet[0]) //packet type
|
794 |
798 |
{
|
795 |
799 |
case XBEE_FRAME_STATUS:
|
... | ... | |
823 |
827 |
|
824 |
828 |
/**
|
825 |
829 |
* Get the PAN ID for the XBee.
|
826 |
|
*
|
|
830 |
*
|
827 |
831 |
* @return the personal area network id, or
|
828 |
832 |
* XBEE_PAN_DEFAULT if it has not yet been set.
|
829 |
833 |
**/
|
... | ... | |
835 |
839 |
/**
|
836 |
840 |
* Set the channel the XBee is using.
|
837 |
841 |
*
|
838 |
|
* @param channel the channel the XBee will not use,
|
|
842 |
* @param channel the channel the XBee will not use,
|
839 |
843 |
* between 0x0B and 0x1A
|
840 |
844 |
*
|
841 |
845 |
* @see xbee_get_channel
|