root / trunk / code / projects / libwireless / lib / xbee.c @ 203
History | View | Annotate | Download (16.1 KB)
1 | 17 | bcoltin | #include "xbee.h" |
---|---|---|---|
2 | #include "wl_defs.h" |
||
3 | |||
4 | #ifndef ROBOT
|
||
5 | |||
6 | #include <fcntl.h> |
||
7 | #include <unistd.h> |
||
8 | #include <pthread.h> |
||
9 | #include <errno.h> |
||
10 | |||
11 | #else
|
||
12 | |||
13 | #include <serial.h> |
||
14 | #include <avr/interrupt.h> |
||
15 | |||
16 | #endif
|
||
17 | |||
18 | #include <stdio.h> |
||
19 | #include <stdlib.h> |
||
20 | #include <string.h> |
||
21 | |||
22 | #include <queue.h> |
||
23 | |||
24 | #define XBEE_FRAME_START 0x7E |
||
25 | |||
26 | /*Frame Types*/
|
||
27 | #define XBEE_FRAME_STATUS 0x8A |
||
28 | #define XBEE_FRAME_AT_COMMAND 0x08 |
||
29 | #define XBEE_FRAME_AT_COMMAND_RESPONSE 0x88 |
||
30 | #define XBEE_FRAME_TX_REQUEST_64 0x00 |
||
31 | #define XBEE_FRAME_TX_REQUEST_16 0x01 |
||
32 | #define XBEE_FRAME_TX_STATUS XBEE_TX_STATUS
|
||
33 | #define XBEE_FRAME_RX_64 0x80 |
||
34 | #define XBEE_FRAME_RX_16 XBEE_RX
|
||
35 | |||
36 | /*Internal Function Prototypes*/
|
||
37 | |||
38 | /*I/O Functions*/
|
||
39 | void xbee_send(char* buf, int size); |
||
40 | void xbee_send_string(char* c); |
||
41 | |||
42 | #ifndef ROBOT
|
||
43 | void xbee_read(char* buf, int size); |
||
44 | #endif
|
||
45 | |||
46 | /*Command Mode Functions
|
||
47 | * Called during initialization.
|
||
48 | */
|
||
49 | void xbee_enter_command_mode(void); |
||
50 | void xbee_exit_command_mode(void); |
||
51 | void xbee_enter_api_mode(void); |
||
52 | void xbee_wait_for_string(char* s, int len); |
||
53 | void xbee_wait_for_ok(void); |
||
54 | |||
55 | /*API Mode Functions*/
|
||
56 | |||
57 | int xbee_handle_packet(char* packet, int len); |
||
58 | void xbee_handle_at_command_response(char* command, char result, |
||
59 | char* extra, int extraLen); |
||
60 | void xbee_handle_status(char status); |
||
61 | int xbee_verify_checksum(char* packet, int len); |
||
62 | char xbee_compute_checksum(char* packet, int len); |
||
63 | void xbee_send_frame(char* buf, int len); |
||
64 | void xbee_send_read_at_command(char* command); |
||
65 | void xbee_send_modify_at_command(char* command, char* value); |
||
66 | |||
67 | /*Global Variables*/
|
||
68 | |||
69 | #ifndef ROBOT
|
||
70 | 203 | justin | char* xbee_com_port;
|
71 | 17 | bcoltin | int xbee_stream;
|
72 | pthread_t* xbee_listen_thread; |
||
73 | #endif
|
||
74 | |||
75 | Queue* xbee_queue; |
||
76 | |||
77 | //used to store packets as they are read
|
||
78 | char xbee_buf[128]; |
||
79 | int currentBufPos = 0; |
||
80 | |||
81 | //XBee status
|
||
82 | unsigned int xbee_panID = XBEE_PAN_DEFAULT; |
||
83 | unsigned int xbee_pending_panID = XBEE_PAN_DEFAULT; |
||
84 | 60 | bcoltin | int xbee_channel = XBEE_CHANNEL_DEFAULT;
|
85 | int xbee_pending_channel = XBEE_CHANNEL_DEFAULT;
|
||
86 | 17 | bcoltin | unsigned int xbee_address = 0; |
87 | |||
88 | /*Function Implementations*/
|
||
89 | |||
90 | #ifdef ROBOT
|
||
91 | |||
92 | /**
|
||
93 | * Interrupt for the robot. Adds bytes received from the xbee
|
||
94 | * to the queue.
|
||
95 | **/
|
||
96 | 86 | bcoltin | #ifndef FIREFLY
|
97 | 17 | bcoltin | ISR(USART1_RX_vect) |
98 | { |
||
99 | char c = UDR1;
|
||
100 | queue_add(xbee_queue, (void*)(int)c); |
||
101 | } |
||
102 | 86 | bcoltin | #else
|
103 | SIGNAL(SIG_USART0_RECV) |
||
104 | { |
||
105 | char c = UDR0;
|
||
106 | queue_add(xbee_queue, (void*)(int)c); |
||
107 | } |
||
108 | #endif
|
||
109 | 17 | bcoltin | |
110 | #else
|
||
111 | |||
112 | /**
|
||
113 | * Thread that listens to the xbee.
|
||
114 | **/
|
||
115 | void* listen_to_xbee(void* x) |
||
116 | { |
||
117 | char c;
|
||
118 | while (1) |
||
119 | { |
||
120 | xbee_read(&c, 1);
|
||
121 | queue_add(xbee_queue, (void*)(int)c); |
||
122 | } |
||
123 | return 0; |
||
124 | } |
||
125 | |||
126 | #endif
|
||
127 | |||
128 | /**
|
||
129 | * Initializes the XBee library so that other functions may be used.
|
||
130 | *
|
||
131 | * @param pan_id the PAN to join initially. Use XBEE_PAN_DEFAULT
|
||
132 | * to leave the PAN as it is initially.
|
||
133 | **/
|
||
134 | 60 | bcoltin | void xbee_lib_init(void) |
135 | 17 | bcoltin | { |
136 | xbee_queue = queue_create(); |
||
137 | |||
138 | #ifdef ROBOT
|
||
139 | |||
140 | //enable the receiving interrupt
|
||
141 | 86 | bcoltin | #ifdef FIREFLY
|
142 | UCSR0B |= _BV(RXCIE) | _BV(RXEN); |
||
143 | #else
|
||
144 | 17 | bcoltin | UCSR1B |= _BV(RXCIE); |
145 | 86 | bcoltin | #endif
|
146 | 17 | bcoltin | sei(); |
147 | #else
|
||
148 | 203 | justin | xbee_stream = open(xbee_com_port, O_RDWR); |
149 | 17 | bcoltin | if (xbee_stream == -1 || lockf(xbee_stream, F_TEST, 0) != 0) |
150 | 113 | bcoltin | xbee_stream = open(XBEE_PORT2, O_RDWR); |
151 | 17 | bcoltin | if (xbee_stream == -1 || lockf(xbee_stream, F_TEST, 0) != 0) |
152 | { |
||
153 | 203 | justin | printf("Failed to open connection to XBee on port %s\r\n",xbee_com_port);
|
154 | 17 | bcoltin | exit(0);
|
155 | } |
||
156 | lockf(xbee_stream, F_LOCK, 0);
|
||
157 | |||
158 | xbee_listen_thread = |
||
159 | (pthread_t*)malloc(sizeof(pthread_t));
|
||
160 | |||
161 | int ret = pthread_create(xbee_listen_thread, NULL, |
||
162 | listen_to_xbee, NULL);
|
||
163 | if (ret)
|
||
164 | { |
||
165 | printf("Failed to create listener thread.\r\n");
|
||
166 | exit(0);
|
||
167 | } |
||
168 | #endif
|
||
169 | xbee_enter_command_mode(); |
||
170 | xbee_enter_api_mode(); |
||
171 | xbee_exit_command_mode(); |
||
172 | xbee_send_read_at_command("MY");
|
||
173 | |||
174 | //wait to return until the address is set
|
||
175 | while (xbee_address == 0) xbee_get_packet(NULL); |
||
176 | } |
||
177 | |||
178 | /**
|
||
179 | * Call when finished using the XBee library. This releases
|
||
180 | * all sued resources.
|
||
181 | **/
|
||
182 | void xbee_terminate()
|
||
183 | { |
||
184 | #ifndef ROBOT
|
||
185 | pthread_cancel(*xbee_listen_thread); |
||
186 | free(xbee_listen_thread); |
||
187 | lockf(xbee_stream, F_ULOCK, 0);
|
||
188 | close(xbee_stream); |
||
189 | #endif
|
||
190 | queue_destroy(xbee_queue); |
||
191 | } |
||
192 | |||
193 | /**
|
||
194 | * Send a buffer buf of size bytes to the XBee.
|
||
195 | *
|
||
196 | * @param buf the buffer of data to send
|
||
197 | * @param size the number of bytes to send
|
||
198 | **/
|
||
199 | void xbee_send(char* buf, int size) |
||
200 | { |
||
201 | #ifdef ROBOT
|
||
202 | int i;
|
||
203 | for (i = 0; i < size; i++) |
||
204 | xbee_putc(buf[i]); |
||
205 | #else
|
||
206 | int ret = write(xbee_stream, buf, size);
|
||
207 | //success
|
||
208 | if (ret == size)
|
||
209 | return;
|
||
210 | if (ret == -1) |
||
211 | { |
||
212 | //interrupted by system signal, probably timer interrupt.
|
||
213 | //just try again
|
||
214 | if (errno == 4) |
||
215 | { |
||
216 | xbee_send(buf, size); |
||
217 | return;
|
||
218 | } |
||
219 | printf("Failed to write to xbee, error %i.\r\n", errno);
|
||
220 | return;
|
||
221 | } |
||
222 | |||
223 | //write was interrupted after writing ret bytes
|
||
224 | xbee_send(buf + ret, size - ret); |
||
225 | #endif
|
||
226 | } |
||
227 | |||
228 | /**
|
||
229 | * Sends a string to the XBee.
|
||
230 | *
|
||
231 | * @param c the string to send to the XBEE
|
||
232 | **/
|
||
233 | void xbee_send_string(char* c) |
||
234 | { |
||
235 | xbee_send(c, strlen(c)); |
||
236 | } |
||
237 | |||
238 | #ifndef ROBOT
|
||
239 | void xbee_read(char* buf, int size) |
||
240 | { |
||
241 | if (read(xbee_stream, buf, size) == -1) |
||
242 | printf("Failed to read from xbee.\r\n");
|
||
243 | } |
||
244 | #endif
|
||
245 | |||
246 | /**
|
||
247 | * Enter into command mode.
|
||
248 | **/
|
||
249 | void xbee_enter_command_mode()
|
||
250 | { |
||
251 | xbee_send_string("+++");
|
||
252 | xbee_wait_for_ok(); |
||
253 | } |
||
254 | |||
255 | /**
|
||
256 | * Exit from command mode.
|
||
257 | **/
|
||
258 | void xbee_exit_command_mode()
|
||
259 | { |
||
260 | xbee_send_string("ATCN\r");
|
||
261 | xbee_wait_for_ok(); |
||
262 | } |
||
263 | |||
264 | /**
|
||
265 | * Enter API mode.
|
||
266 | **/
|
||
267 | void xbee_enter_api_mode()
|
||
268 | { |
||
269 | xbee_send_string("ATAP 1\r");
|
||
270 | xbee_wait_for_ok(); |
||
271 | } |
||
272 | |||
273 | /**
|
||
274 | * Wait until the string "OK\r" is received from the XBee.
|
||
275 | **/
|
||
276 | void xbee_wait_for_ok()
|
||
277 | { |
||
278 | xbee_wait_for_string("OK\r", 3); |
||
279 | } |
||
280 | |||
281 | /**
|
||
282 | * Delay until the specified string is received from
|
||
283 | * the XBee. Discards all other XBee data.
|
||
284 | *
|
||
285 | * @param s the string to receive
|
||
286 | * @param len the length of the string
|
||
287 | **/
|
||
288 | void xbee_wait_for_string(char* s, int len) |
||
289 | { |
||
290 | char* curr = s;
|
||
291 | while (curr - s < len)
|
||
292 | { |
||
293 | if (queue_is_empty(xbee_queue))
|
||
294 | continue;
|
||
295 | char c = (char)(int)queue_remove(xbee_queue); |
||
296 | if (c == *curr)
|
||
297 | curr++; |
||
298 | else
|
||
299 | curr = s; |
||
300 | } |
||
301 | } |
||
302 | |||
303 | /**
|
||
304 | * Verifies that the packets checksum is correct.
|
||
305 | * (If the checksum is correct, the sum of the bytes
|
||
306 | * is 0xFF.)
|
||
307 | *
|
||
308 | * @param packet the packet received. This includes the first
|
||
309 | * three bytes, which are header information from the XBee.
|
||
310 | *
|
||
311 | * @param len The length of the packet received from the XBee
|
||
312 | *
|
||
313 | * @return 0 if the checksum is incorrect, nonzero
|
||
314 | * otherwise
|
||
315 | **/
|
||
316 | int xbee_verify_checksum(char* packet, int len) |
||
317 | { |
||
318 | unsigned char sum = 0; |
||
319 | int i;
|
||
320 | for (i = 3; i < len; i++) |
||
321 | sum += (unsigned char)packet[i]; |
||
322 | return sum == 0xFF; |
||
323 | } |
||
324 | |||
325 | /**
|
||
326 | * Returns the checksum of the given packet.
|
||
327 | *
|
||
328 | * @param buf the data for the packet to send
|
||
329 | * @param len the length of the packet in bytes
|
||
330 | *
|
||
331 | * @return the checksum of the packet, which will
|
||
332 | * become the last byte sent in the packet
|
||
333 | **/
|
||
334 | char xbee_compute_checksum(char* buf, int len) |
||
335 | { |
||
336 | int i;
|
||
337 | unsigned char sum = 0; |
||
338 | for (i = 0; i < len; i++) |
||
339 | sum += (unsigned char)buf[i]; |
||
340 | return 0xFF - sum; |
||
341 | } |
||
342 | |||
343 | /**
|
||
344 | * Adds header information and checksum to the given
|
||
345 | * packet and sends it. Header information includes
|
||
346 | * XBEE_FRAME_START and the packet length, as two bytes.
|
||
347 | *
|
||
348 | * @param buf the packet data
|
||
349 | * @param len the size in bytes of the packet data
|
||
350 | *
|
||
351 | **/
|
||
352 | void xbee_send_frame(char* buf, int len) |
||
353 | { |
||
354 | char prefix[3]; |
||
355 | prefix[0] = XBEE_FRAME_START;
|
||
356 | prefix[1] = (len & 0xFF00) >> 8; |
||
357 | prefix[2] = len & 0xFF; |
||
358 | char checksum = xbee_compute_checksum(buf, len);
|
||
359 | xbee_send(prefix, 3);
|
||
360 | xbee_send(buf, len); |
||
361 | xbee_send(&checksum, 1);
|
||
362 | } |
||
363 | |||
364 | /**
|
||
365 | * Sends an AT command to read a parameter.
|
||
366 | *
|
||
367 | * @param command the AT command to send. For exmaple,
|
||
368 | * use ID to read the PAN ID and MY to return the XBee ID.
|
||
369 | * See the XBee reference guide for a complete listing.
|
||
370 | **/
|
||
371 | void xbee_send_read_at_command(char* command) |
||
372 | { |
||
373 | xbee_send_modify_at_command(command, NULL);
|
||
374 | } |
||
375 | |||
376 | /**
|
||
377 | * Sends the given AT command.
|
||
378 | *
|
||
379 | * @param command the AT command to send (e.g., MY, ID)
|
||
380 | * @param value the value to pass as a parameter
|
||
381 | * (or NULL if there is no parameter)
|
||
382 | **/
|
||
383 | void xbee_send_modify_at_command(char* command, char* value) |
||
384 | { |
||
385 | char buf[16]; |
||
386 | int i;
|
||
387 | |||
388 | buf[0] = XBEE_FRAME_AT_COMMAND;
|
||
389 | buf[1] = 1; |
||
390 | buf[2] = command[0]; |
||
391 | buf[3] = command[1]; |
||
392 | int valueLen = 0; |
||
393 | if (value != NULL) |
||
394 | { |
||
395 | valueLen = strlen(value); |
||
396 | if (valueLen > 8) |
||
397 | { |
||
398 | WL_DEBUG_PRINT("AT Command too large.\r\n");
|
||
399 | return;
|
||
400 | } |
||
401 | for (i = 0; i < valueLen; i++) |
||
402 | buf[4 + i] = value[i];
|
||
403 | } |
||
404 | xbee_send_frame(buf, 4 + valueLen);
|
||
405 | } |
||
406 | |||
407 | /**
|
||
408 | * Send the specified packet.
|
||
409 | *
|
||
410 | * @param packet the packet data to send
|
||
411 | * @param len the number of bytes in the packet
|
||
412 | *
|
||
413 | * @param dest the ID of the XBee to send the packet to,
|
||
414 | * or XBEE_BROADCAST to send the message to all robots
|
||
415 | * in the PAN.
|
||
416 | *
|
||
417 | * @param options a combination of the flags
|
||
418 | * XBEE_OPTIONS_NONE, XBEE_OPTIONS_DISABLE_RESPONSE and
|
||
419 | * XBEE_OPTIONS_BROADCAST_ALL_PANS
|
||
420 | *
|
||
421 | * @param frame the frame number to associate this packet
|
||
422 | * with. This will be used to identify the response when
|
||
423 | * the XBee alerts us as to whether or not our message
|
||
424 | * was received.
|
||
425 | **/
|
||
426 | void xbee_send_packet(char* packet, int len, int dest, |
||
427 | char options, char frame) |
||
428 | { |
||
429 | char buf[5]; |
||
430 | char prefix[3]; |
||
431 | int i;
|
||
432 | unsigned char checksum = 0; |
||
433 | |||
434 | if (len > 100) |
||
435 | { |
||
436 | WL_DEBUG_PRINT("Packet is too large.\r\n");
|
||
437 | return;
|
||
438 | } |
||
439 | |||
440 | //data for sending request
|
||
441 | buf[0] = XBEE_FRAME_TX_REQUEST_16;
|
||
442 | buf[1] = frame;
|
||
443 | buf[2] = (dest >> 8) & 0xFF; |
||
444 | buf[3] = dest & 0xFF; |
||
445 | buf[4] = options;
|
||
446 | |||
447 | //packet prefix, do this here so we don't need an extra buffer
|
||
448 | prefix[0] = XBEE_FRAME_START;
|
||
449 | prefix[1] = ((5 + len) & 0xFF00) >> 8; |
||
450 | prefix[2] = (5 + len) & 0xFF; |
||
451 | |||
452 | for (i = 0; i < 5; i++) |
||
453 | checksum += (unsigned char)buf[i]; |
||
454 | for (i = 0; i < len; i++) |
||
455 | checksum += (unsigned char)packet[i]; |
||
456 | checksum = 0xFF - checksum;
|
||
457 | xbee_send(prefix, 3);
|
||
458 | xbee_send(buf, 5);
|
||
459 | xbee_send(packet, len); |
||
460 | xbee_send((char*)&checksum, 1); |
||
461 | } |
||
462 | |||
463 | /**
|
||
464 | * Reads a packet received from the XBee. This function
|
||
465 | * is non-blocking. The resulting packet is stored in dest.
|
||
466 | * Only returns transmission response packets and
|
||
467 | * received packets. The returned packet does not include
|
||
468 | * header information or the checksum. This method also
|
||
469 | * handles special packets dealt with by the XBee library,
|
||
470 | * and so should be called frequently while the XBee is in
|
||
471 | * use.<br><br>
|
||
472 | *
|
||
473 | * The first byte of the packet will be either
|
||
474 | * XBEE_TX_STATUS or XBEE_RX to indicated
|
||
475 | * a response to a sent message or a received message,
|
||
476 | * respectively.<br><br>
|
||
477 | *
|
||
478 | * For a status response packet:<br>
|
||
479 | * The first byte will be XBEE_TX_STATUS.<br>
|
||
480 | * The second byte will be the frame number.<br>
|
||
481 | * The third byte will be the result. 0 indicates success,
|
||
482 | * and nonzero indicates that an error ocurred in
|
||
483 | * transmitting the packet.<br><br>
|
||
484 | *
|
||
485 | * For a received packet:<br>
|
||
486 | * The first byte will be XBEE_RX.<br>
|
||
487 | * The second and third bytes will be the 16-bit
|
||
488 | * address of the packet's sender.<br>
|
||
489 | * The fourth byte is the signal strength.<br>
|
||
490 | * The fifth byte is 1 if the packet were sent to
|
||
491 | * a specific address, and 2 if it is a broadcast packet.<br><br>
|
||
492 | *
|
||
493 | * @param dest set to the packet data
|
||
494 | * @return the length of the packet, or -1 if no packet
|
||
495 | * is available
|
||
496 | **/
|
||
497 | int xbee_get_packet(unsigned char* dest) |
||
498 | { |
||
499 | //start reading a packet with XBEE_FRAME_START
|
||
500 | if (currentBufPos == 0) |
||
501 | { |
||
502 | do
|
||
503 | if (queue_is_empty(xbee_queue))
|
||
504 | return -1; |
||
505 | while ((char)(int)queue_remove(xbee_queue) != XBEE_FRAME_START); |
||
506 | xbee_buf[0] = XBEE_FRAME_START;
|
||
507 | currentBufPos++; |
||
508 | } |
||
509 | |||
510 | int len = -1; |
||
511 | if (currentBufPos >= 3) |
||
512 | len = (int)xbee_buf[2] + ((int)xbee_buf[1] << 8); |
||
513 | |||
514 | while (len == -1 //packet length has not been read yet |
||
515 | || currentBufPos < len + 4)
|
||
516 | { |
||
517 | if (currentBufPos == 3) |
||
518 | 190 | bcoltin | { |
519 | 17 | bcoltin | len = (int)xbee_buf[2] + ((int)xbee_buf[1] << 8); |
520 | 190 | bcoltin | if (len > 120) |
521 | { |
||
522 | WL_DEBUG_PRINT("Packet too large. Probably error in XBee transmission.\n");
|
||
523 | currentBufPos = 0;
|
||
524 | return -1; |
||
525 | } |
||
526 | } |
||
527 | 17 | bcoltin | if (queue_is_empty(xbee_queue))
|
528 | return -1; |
||
529 | xbee_buf[currentBufPos++] = (char)(int)queue_remove(xbee_queue); |
||
530 | } |
||
531 | |||
532 | currentBufPos = 0;
|
||
533 | |||
534 | if (!xbee_verify_checksum(xbee_buf, len + 4)) |
||
535 | { |
||
536 | WL_DEBUG_PRINT("XBee checksum failed.\r\n");
|
||
537 | return -1; |
||
538 | } |
||
539 | |||
540 | //we will take care of the packet
|
||
541 | if (xbee_handle_packet(xbee_buf + 3, len)) |
||
542 | return -1; |
||
543 | |||
544 | if (dest == NULL) |
||
545 | return -1; |
||
546 | |||
547 | int i;
|
||
548 | for (i = 3; i < len + 3; i++) |
||
549 | dest[i - 3] = xbee_buf[i];
|
||
550 | return len;
|
||
551 | } |
||
552 | |||
553 | /**
|
||
554 | * Handles modem status packets.
|
||
555 | *
|
||
556 | * @param status the type of status packet received.
|
||
557 | **/
|
||
558 | void xbee_handle_status(char status) |
||
559 | { |
||
560 | switch (status)
|
||
561 | { |
||
562 | case 0: |
||
563 | WL_DEBUG_PRINT("XBee hardware reset.\r\n");
|
||
564 | break;
|
||
565 | case 1: |
||
566 | WL_DEBUG_PRINT("Watchdog timer reset.\r\n");
|
||
567 | break;
|
||
568 | case 2: |
||
569 | WL_DEBUG_PRINT("Associated.\r\n");
|
||
570 | break;
|
||
571 | case 3: |
||
572 | WL_DEBUG_PRINT("Disassociated.\r\n");
|
||
573 | break;
|
||
574 | case 4: |
||
575 | WL_DEBUG_PRINT("Synchronization lost.\r\n");
|
||
576 | break;
|
||
577 | case 5: |
||
578 | WL_DEBUG_PRINT("Coordinator realignment.\r\n");
|
||
579 | break;
|
||
580 | case 6: |
||
581 | WL_DEBUG_PRINT("Coordinator started.\r\n");
|
||
582 | break;
|
||
583 | } |
||
584 | } |
||
585 | |||
586 | /**
|
||
587 | * Handles AT command response packets.
|
||
588 | * @param command the two character AT command, e.g. MY or ID
|
||
589 | * @param result 0 for success, 1 for an error
|
||
590 | * @param extra the hex value of the requested register
|
||
591 | * @param extraLen the length in bytes of extra
|
||
592 | **/
|
||
593 | void xbee_handle_at_command_response(char* command, char result, |
||
594 | char* extra, int extraLen) |
||
595 | { |
||
596 | if (result == 1) |
||
597 | { |
||
598 | WL_DEBUG_PRINT("Error with AT");
|
||
599 | WL_DEBUG_PRINT(command); |
||
600 | WL_DEBUG_PRINT(" packet.\r\n");
|
||
601 | } |
||
602 | WL_DEBUG_PRINT("AT");
|
||
603 | WL_DEBUG_PRINT(command); |
||
604 | WL_DEBUG_PRINT(" command was successful.\r\n");
|
||
605 | |||
606 | if (command[0] == 'I' && command[1] == 'D') |
||
607 | { |
||
608 | xbee_panID = xbee_pending_panID; |
||
609 | WL_DEBUG_PRINT("PAN ID set to ");
|
||
610 | WL_DEBUG_PRINT_INT(xbee_panID); |
||
611 | WL_DEBUG_PRINT(".\r\n");
|
||
612 | return;
|
||
613 | } |
||
614 | 60 | bcoltin | |
615 | if (command[0] == 'C' && command[1] == 'H') |
||
616 | { |
||
617 | xbee_channel = xbee_pending_channel; |
||
618 | WL_DEBUG_PRINT("Channel set to ");
|
||
619 | WL_DEBUG_PRINT_INT(xbee_channel); |
||
620 | WL_DEBUG_PRINT(".\r\n");
|
||
621 | return;
|
||
622 | } |
||
623 | 17 | bcoltin | |
624 | if (command[0] == 'M' && command[1] == 'Y' && extraLen != 0) |
||
625 | { |
||
626 | xbee_address = 0;
|
||
627 | int i;
|
||
628 | for (i = 0; i < extraLen; i++) |
||
629 | xbee_address = (xbee_address << 8) + extra[i];
|
||
630 | |||
631 | WL_DEBUG_PRINT("XBee address is ");
|
||
632 | WL_DEBUG_PRINT_INT(xbee_address); |
||
633 | WL_DEBUG_PRINT(".\r\n");
|
||
634 | |||
635 | if (xbee_address == 0) |
||
636 | { |
||
637 | WL_DEBUG_PRINT("XBee 16-bit address must be set using ATMY.\r\n");
|
||
638 | exit(0);
|
||
639 | } |
||
640 | } |
||
641 | } |
||
642 | |||
643 | /**
|
||
644 | * Attempts to handle the packet if it is dealt with
|
||
645 | * by the library.
|
||
646 | * We will handle the following packet types:
|
||
647 | * Modem Status
|
||
648 | * AT Command Response
|
||
649 | *
|
||
650 | * @param packet the packet to handle
|
||
651 | * @param len the length of the packet
|
||
652 | *
|
||
653 | * @return 1 if we have handled the packet, 0 otherwise
|
||
654 | */
|
||
655 | int xbee_handle_packet(char* packet, int len) |
||
656 | { |
||
657 | char command[3] = {1, 2, 3}; |
||
658 | if (len <= 0) //this should not happend |
||
659 | { |
||
660 | WL_DEBUG_PRINT("Non-positive packet length.\r\n");
|
||
661 | return 0; |
||
662 | } |
||
663 | |||
664 | switch ((unsigned char)packet[0]) //packet type |
||
665 | { |
||
666 | case XBEE_FRAME_STATUS:
|
||
667 | xbee_handle_status(packet[1]);
|
||
668 | return 1; |
||
669 | case XBEE_FRAME_AT_COMMAND_RESPONSE:
|
||
670 | command[0] = packet[2]; |
||
671 | command[1] = packet[3]; |
||
672 | command[2] = 0; |
||
673 | xbee_handle_at_command_response(command, |
||
674 | packet[4], packet + 5, len - 5); |
||
675 | return 1; |
||
676 | } |
||
677 | return 0; |
||
678 | } |
||
679 | |||
680 | /**
|
||
681 | * Sets the personal area network id.
|
||
682 | *
|
||
683 | * @param id the new personal area network (PAN) id
|
||
684 | **/
|
||
685 | void xbee_set_pan_id(int id) |
||
686 | { |
||
687 | char s[3]; |
||
688 | s[0] = (id >> 8) & 0xFF; |
||
689 | s[1] = id & 0xFF; |
||
690 | s[2] = 0; |
||
691 | xbee_pending_panID = id; |
||
692 | xbee_send_modify_at_command("ID", s);
|
||
693 | } |
||
694 | |||
695 | /**
|
||
696 | * Get the PAN ID for the XBee.
|
||
697 | *
|
||
698 | * @return the personal area network id, or
|
||
699 | * XBEE_PAN_DEFAULT if it has not yet been set.
|
||
700 | **/
|
||
701 | unsigned int xbee_get_pan_id() |
||
702 | { |
||
703 | return xbee_panID;
|
||
704 | } |
||
705 | |||
706 | /**
|
||
707 | 60 | bcoltin | * Set the channel the XBee is using.
|
708 | *
|
||
709 | * @param channel the channel the XBee will not use,
|
||
710 | * between 0x0B and 0x1A
|
||
711 | *
|
||
712 | * @see xbee_get_channel
|
||
713 | **/
|
||
714 | void xbee_set_channel(int channel) |
||
715 | { |
||
716 | if (channel < 0x0B || channel > 0x1A) |
||
717 | { |
||
718 | WL_DEBUG_PRINT("Channel out of range.\r\n");
|
||
719 | return;
|
||
720 | } |
||
721 | char s[3]; |
||
722 | s[0] = channel & 0xFF; |
||
723 | s[1] = 0; |
||
724 | xbee_pending_channel = channel; |
||
725 | xbee_send_modify_at_command("CH", s);
|
||
726 | } |
||
727 | |||
728 | /**
|
||
729 | * Returns the channel which the XBee is currently using.
|
||
730 | *
|
||
731 | * @return the channel the XBee is using
|
||
732 | *
|
||
733 | * @see xbee_set_channel
|
||
734 | **/
|
||
735 | int xbee_get_channel(void) |
||
736 | { |
||
737 | return xbee_channel;
|
||
738 | } |
||
739 | |||
740 | /**
|
||
741 | 17 | bcoltin | * Get the 16-bit address of the XBee.
|
742 | * This is used to specify who to send messages to
|
||
743 | * and who messages are from.
|
||
744 | *
|
||
745 | * @return the 16-bit address of the XBee.
|
||
746 | **/
|
||
747 | unsigned int xbee_get_address() |
||
748 | { |
||
749 | return xbee_address;
|
||
750 | } |
||
751 | |||
752 | 203 | justin | #ifndef ROBOT
|
753 | void xbee_set_com_port(char* port){ |
||
754 | //printf("Port being passed is %s\n",port);
|
||
755 | xbee_com_port = malloc(strlen(port)); |
||
756 | strcpy(xbee_com_port,port); |
||
757 | } |
||
758 | #endif
|