Project

General

Profile

Statistics
| Revision:

root / trunk / code / lib / src / libwireless / xbee.c @ 294

History | View | Annotate | Download (17.3 KB)

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.c
28
 * @brief XBee Interface
29
 *
30
 * Implementation of low level communication with the XBee in API mode.
31
 *
32
 * @author Brian Coltin, Colony Project, CMU Robotics Club
33
 **/
34

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

    
38
#ifndef ROBOT
39

    
40
#include <fcntl.h>
41
#include <unistd.h>
42
#include <pthread.h>
43
#include <errno.h>
44

    
45
#else
46

    
47
#include <serial.h>
48
#include <avr/interrupt.h>
49

    
50
#endif
51

    
52
#include <stdio.h>
53
#include <stdlib.h>
54
#include <string.h>
55

    
56
#include <queue.h>
57

    
58
#define XBEE_FRAME_START 0x7E
59

    
60
/*Frame Types*/
61
#define XBEE_FRAME_STATUS 0x8A
62
#define XBEE_FRAME_AT_COMMAND 0x08
63
#define XBEE_FRAME_AT_COMMAND_RESPONSE 0x88
64
#define XBEE_FRAME_TX_REQUEST_64 0x00
65
#define XBEE_FRAME_TX_REQUEST_16 0x01
66
#define XBEE_FRAME_TX_STATUS XBEE_TX_STATUS
67
#define XBEE_FRAME_RX_64 0x80
68
#define XBEE_FRAME_RX_16 XBEE_RX
69

    
70
/*Internal Function Prototypes*/
71

    
72
/*I/O Functions*/
73
void xbee_send(char* buf, int size);
74
void xbee_send_string(char* c);
75

    
76
#ifndef ROBOT
77
void xbee_read(char* buf, int size);
78
#endif
79

    
80
/*Command Mode Functions
81
 * Called during initialization.
82
 */
83
void xbee_enter_command_mode(void);
84
void xbee_exit_command_mode(void);
85
void xbee_enter_api_mode(void);
86
void xbee_wait_for_string(char* s, int len);
87
void xbee_wait_for_ok(void);
88

    
89
/*API Mode Functions*/
90

    
91
int xbee_handle_packet(char* packet, int len);
92
void xbee_handle_at_command_response(char* command, char result,
93
        char* extra, int extraLen);
94
void xbee_handle_status(char status);
95
int xbee_verify_checksum(char* packet, int len);
96
char xbee_compute_checksum(char* packet, int len);
97
void xbee_send_frame(char* buf, int len);
98
void xbee_send_read_at_command(char* command);
99
void xbee_send_modify_at_command(char* command, char* value);
100

    
101
/*Global Variables*/
102

    
103
#ifndef ROBOT
104
char* xbee_com_port;
105
int xbee_stream;
106
pthread_t* xbee_listen_thread;
107
#endif
108

    
109
Queue* xbee_queue;
110

    
111
//used to store packets as they are read
112
char xbee_buf[128];
113
int currentBufPos = 0;
114

    
115
//XBee status
116
unsigned int xbee_panID = XBEE_PAN_DEFAULT;
117
unsigned int xbee_pending_panID = XBEE_PAN_DEFAULT;
118
int xbee_channel = XBEE_CHANNEL_DEFAULT;
119
int xbee_pending_channel = XBEE_CHANNEL_DEFAULT;
120
unsigned int xbee_address = 0;
121

    
122
/*Function Implementations*/
123

    
124
#ifdef ROBOT
125

    
126
/**
127
 * Interrupt for the robot. Adds bytes received from the xbee
128
 * to the queue.
129
 **/
130
#ifndef FIREFLY
131
ISR(USART1_RX_vect)
132
{
133
        char c = UDR1;
134
        queue_add(xbee_queue, (void*)(int)c);
135
}
136
#else
137
SIGNAL(SIG_USART0_RECV)
138
{
139
        char c = UDR0;
140
        queue_add(xbee_queue, (void*)(int)c);
141
}
142
#endif
143

    
144
#else
145

    
146
/**
147
 * Thread that listens to the xbee.
148
 **/
149
void* listen_to_xbee(void* x)
150
{
151
        char c;
152
        while (1)
153
        {
154
                xbee_read(&c, 1);
155
                queue_add(xbee_queue, (void*)(int)c);
156
        }
157
        return 0;
158
}
159

    
160
#endif
161

    
162
/**
163
 * Initializes the XBee library so that other functions may be used.
164
 **/
165
void xbee_lib_init(void)
166
{
167
        xbee_queue = queue_create();
168
        
169
        #ifdef ROBOT
170

    
171
        //enable the receiving interrupt
172
        #ifdef FIREFLY
173
        UCSR0B |= _BV(RXCIE) | _BV(RXEN);
174
        #else
175
        UCSR1B |= _BV(RXCIE);
176
        #endif
177
        sei();
178
        #else
179
        xbee_stream = open(xbee_com_port, O_RDWR);
180
        if (xbee_stream == -1 || lockf(xbee_stream, F_TEST, 0) != 0)
181
                xbee_stream = open(XBEE_PORT2, O_RDWR);
182
        if (xbee_stream == -1 || lockf(xbee_stream, F_TEST, 0) != 0)
183
        {
184
                printf("Failed to open connection to XBee on port %s\r\n",xbee_com_port);
185
                exit(0);
186
        }
187
        lockf(xbee_stream, F_LOCK, 0);
188
        
189
        xbee_listen_thread =
190
                (pthread_t*)malloc(sizeof(pthread_t));
191
        
192
        int ret = pthread_create(xbee_listen_thread, NULL, 
193
                listen_to_xbee, NULL);
194
        if (ret)
195
        {
196
                printf("Failed to create listener thread.\r\n");
197
                exit(0);
198
        }
199
        #endif
200
        xbee_enter_command_mode();
201
        xbee_enter_api_mode();
202
        xbee_exit_command_mode();
203
        xbee_send_read_at_command("MY");
204
        
205
        //wait to return until the address is set
206
        while (xbee_address == 0) xbee_get_packet(NULL);
207
}
208

    
209
/**
210
 * Call when finished using the XBee library. This releases
211
 * all sued resources.
212
 **/
213
void xbee_terminate()
214
{
215
        #ifndef ROBOT
216
        pthread_cancel(*xbee_listen_thread);
217
        free(xbee_listen_thread);
218
        lockf(xbee_stream, F_ULOCK, 0);
219
        close(xbee_stream);
220
        #endif
221
        queue_destroy(xbee_queue);
222
}
223

    
224
/**
225
 * Send a buffer buf of size bytes to the XBee.
226
 * 
227
 * @param buf the buffer of data to send
228
 * @param size the number of bytes to send
229
 **/
230
void xbee_send(char* buf, int size)
231
{
232
        #ifdef ROBOT
233
        int i;
234
        for (i = 0; i < size; i++)
235
                xbee_putc(buf[i]);
236
        #else
237
        int ret = write(xbee_stream, buf, size);
238
        //success
239
        if (ret == size)
240
                return;
241
        if (ret == -1)
242
        {
243
                //interrupted by system signal, probably timer interrupt.
244
                //just try again
245
                if (errno == 4)
246
                {
247
                        xbee_send(buf, size);
248
                        return;
249
                }
250
                printf("Failed to write to xbee, error %i.\r\n", errno);
251
                return;
252
        }
253

    
254
        //write was interrupted after writing ret bytes
255
        xbee_send(buf + ret, size - ret);
256
        #endif
257
}
258

    
259
/**
260
 * Sends a string to the XBee.
261
 *
262
 * @param c the string to send to the XBEE
263
 **/
264
void xbee_send_string(char* c)
265
{
266
        xbee_send(c, strlen(c));
267
}
268

    
269
#ifndef ROBOT
270
void xbee_read(char* buf, int size)
271
{
272
        if (read(xbee_stream, buf, size) == -1)
273
                printf("Failed to read from xbee.\r\n");
274
}
275
#endif
276

    
277
/**
278
 * Enter into command mode.
279
 **/
280
void xbee_enter_command_mode()
281
{
282
        xbee_send_string("+++");
283
        xbee_wait_for_ok();
284
}
285

    
286
/**
287
 * Exit from command mode.
288
 **/
289
void xbee_exit_command_mode()
290
{
291
        xbee_send_string("ATCN\r");
292
        xbee_wait_for_ok();
293
}
294

    
295
/**
296
 * Enter API mode.
297
 **/
298
void xbee_enter_api_mode()
299
{
300
        xbee_send_string("ATAP 1\r");
301
        xbee_wait_for_ok();
302
}
303

    
304
/**
305
 * Wait until the string "OK\r" is received from the XBee.
306
 **/
307
void xbee_wait_for_ok()
308
{
309
        xbee_wait_for_string("OK\r", 3);
310
}
311

    
312
/**
313
 * Delay until the specified string is received from
314
 * the XBee. Discards all other XBee data.
315
 *
316
 * @param s the string to receive
317
 * @param len the length of the string
318
 **/
319
void xbee_wait_for_string(char* s, int len)
320
{
321
        char* curr = s;
322
        while (curr - s < len)
323
        {
324
                if (queue_is_empty(xbee_queue))
325
                        continue;
326
                char c = (char)(int)queue_remove(xbee_queue);
327
                if (c == *curr)
328
                        curr++;
329
                else
330
                        curr = s;
331
        }
332
}
333

    
334
/**
335
 * Verifies that the packets checksum is correct.
336
 * (If the checksum is correct, the sum of the bytes
337
 * is 0xFF.)
338
 *
339
 * @param packet the packet received. This includes the first
340
 * three bytes, which are header information from the XBee.
341
 *
342
 * @param len The length of the packet received from the XBee
343
 *
344
 * @return 0 if the checksum is incorrect, nonzero
345
 * otherwise
346
 **/
347
int xbee_verify_checksum(char* packet, int len)
348
{
349
        unsigned char sum = 0;
350
        int i;
351
        for (i = 3; i < len; i++)
352
                sum += (unsigned char)packet[i];
353
        return sum == 0xFF;
354
}
355

    
356
/**
357
 * Returns the checksum of the given packet.
358
 *
359
 * @param buf the data for the packet to send
360
 * @param len the length of the packet in bytes
361
 *
362
 * @return the checksum of the packet, which will
363
 * become the last byte sent in the packet
364
 **/
365
char xbee_compute_checksum(char* buf, int len)
366
{
367
        int i;
368
        unsigned char sum = 0;
369
        for (i = 0; i < len; i++)
370
                sum += (unsigned char)buf[i];
371
        return 0xFF - sum;
372
}
373

    
374
/**
375
 * Adds header information and checksum to the given
376
 * packet and sends it. Header information includes
377
 * XBEE_FRAME_START and the packet length, as two bytes.
378
 *
379
 * @param buf the packet data
380
 * @param len the size in bytes of the packet data
381
 *
382
 **/
383
void xbee_send_frame(char* buf, int len)
384
{
385
        char prefix[3];
386
        prefix[0] = XBEE_FRAME_START;
387
        prefix[1] = (len & 0xFF00) >> 8;
388
        prefix[2] = len & 0xFF;
389
        char checksum = xbee_compute_checksum(buf, len);
390
        xbee_send(prefix, 3);
391
        xbee_send(buf, len);
392
        xbee_send(&checksum, 1);
393
}
394

    
395
/**
396
 * Sends an AT command to read a parameter.
397
 *
398
 * @param command the AT command to send. For exmaple,
399
 * use ID to read the PAN ID and MY to return the XBee ID.
400
 * See the XBee reference guide for a complete listing.
401
 **/
402
void xbee_send_read_at_command(char* command)
403
{
404
        xbee_send_modify_at_command(command, NULL);
405
}
406

    
407
/**
408
 * Sends the given AT command.
409
 *
410
 * @param command the AT command to send (e.g., MY, ID)
411
 * @param value the value to pass as a parameter
412
 * (or NULL if there is no parameter)
413
 **/
414
void xbee_send_modify_at_command(char* command, char* value)
415
{
416
        char buf[16];
417
        int i;
418
        
419
        buf[0] = XBEE_FRAME_AT_COMMAND;
420
        buf[1] = 1;
421
        buf[2] = command[0];
422
        buf[3] = command[1];
423
        int valueLen = 0;
424
        if (value != NULL)
425
        {
426
                valueLen = strlen(value);
427
                if (valueLen > 8)
428
                {
429
                        WL_DEBUG_PRINT("AT Command too large.\r\n");
430
                        return;
431
                }
432
                for (i = 0; i < valueLen; i++)
433
                        buf[4 + i] = value[i];
434
        }
435
        xbee_send_frame(buf, 4 + valueLen);
436
}
437

    
438
/**
439
 * Send the specified packet.
440
 * 
441
 * @param packet the packet data to send
442
 * @param len the number of bytes in the packet
443
 * 
444
 * @param dest the ID of the XBee to send the packet to,
445
 * or XBEE_BROADCAST to send the message to all robots
446
 * in the PAN.
447
 * 
448
 * @param options a combination of the flags
449
 * XBEE_OPTIONS_NONE, XBEE_OPTIONS_DISABLE_RESPONSE and 
450
 * XBEE_OPTIONS_BROADCAST_ALL_PANS
451
 *
452
 * @param frame the frame number to associate this packet
453
 * with. This will be used to identify the response when
454
 * the XBee alerts us as to whether or not our message
455
 * was received.
456
 **/
457
void xbee_send_packet(char* packet, int len, int dest,
458
        char options, char frame)
459
{
460
        char buf[5];
461
        char prefix[3];
462
        int i;
463
        unsigned char checksum = 0;
464

    
465
        if (len > 100)
466
        {
467
                WL_DEBUG_PRINT("Packet is too large.\r\n");
468
                return;
469
        }
470

    
471
        //data for sending request
472
        buf[0] = XBEE_FRAME_TX_REQUEST_16;
473
        buf[1] = frame;
474
        buf[2] = (dest >> 8) & 0xFF;
475
        buf[3] = dest & 0xFF;
476
        buf[4] = options;
477

    
478
        //packet prefix, do this here so we don't need an extra buffer
479
        prefix[0] = XBEE_FRAME_START;
480
        prefix[1] = ((5 + len) & 0xFF00) >> 8;
481
        prefix[2] = (5 + len) & 0xFF;
482

    
483
        for (i = 0; i < 5; i++)
484
                checksum += (unsigned char)buf[i];
485
        for (i = 0; i < len; i++)
486
                checksum += (unsigned char)packet[i];
487
        checksum = 0xFF - checksum;
488
        xbee_send(prefix, 3);
489
        xbee_send(buf, 5);
490
        xbee_send(packet, len);
491
        xbee_send((char*)&checksum, 1);
492
}
493

    
494
/**
495
 * Reads a packet received from the XBee. This function
496
 * is non-blocking. The resulting packet is stored in dest.
497
 * Only returns transmission response packets and
498
 * received packets. The returned packet does not include
499
 * header information or the checksum. This method also
500
 * handles special packets dealt with by the XBee library,
501
 * and so should be called frequently while the XBee is in
502
 * use.<br><br>
503
 *
504
 * The first byte of the packet will be either
505
 * XBEE_TX_STATUS or XBEE_RX to indicated
506
 * a response to a sent message or a received message, 
507
 * respectively.<br><br>
508
 *
509
 * For a status response packet:<br>
510
 * The first byte will be XBEE_TX_STATUS.<br>
511
 * The second byte will be the frame number.<br>
512
 * The third byte will be the result. 0 indicates success,
513
 * and nonzero indicates that an error ocurred in 
514
 * transmitting the packet.<br><br>
515
 *
516
 * For a received packet:<br>
517
 * The first byte will be XBEE_RX.<br>
518
 * The second and third bytes will be the 16-bit
519
 * address of the packet's sender.<br>
520
 * The fourth byte is the signal strength.<br>
521
 * The fifth byte is 1 if the packet were sent to
522
 * a specific address, and 2 if it is a broadcast packet.<br><br>
523
 * 
524
 * @param dest set to the packet data
525
 * @return the length of the packet, or -1 if no packet
526
 * is available
527
 **/
528
int xbee_get_packet(unsigned char* dest)
529
{
530
        //start reading a packet with XBEE_FRAME_START
531
        if (currentBufPos == 0)
532
        {
533
                do
534
                        if (queue_is_empty(xbee_queue))
535
                                return -1;
536
                while ((char)(int)queue_remove(xbee_queue) != XBEE_FRAME_START);
537
                xbee_buf[0] = XBEE_FRAME_START;
538
                currentBufPos++;
539
        }
540

    
541
        int len = -1;
542
        if (currentBufPos >= 3)
543
                len = (int)xbee_buf[2] + ((int)xbee_buf[1] << 8);
544
                
545
        while (len == -1 //packet length has not been read yet
546
                        || currentBufPos < len + 4)
547
        {
548
                if (currentBufPos == 3)
549
                {
550
                        len = (int)xbee_buf[2] + ((int)xbee_buf[1] << 8);
551
                        if (len > 120)
552
                        {
553
                                WL_DEBUG_PRINT("Packet too large. Probably error in XBee transmission.\n");
554
                                currentBufPos = 0;
555
                                return -1;
556
                        }
557
                }
558
                if (queue_is_empty(xbee_queue))
559
                        return -1;
560
                xbee_buf[currentBufPos++] = (char)(int)queue_remove(xbee_queue);
561
        }
562
        
563
        currentBufPos = 0;
564
        
565
        if (!xbee_verify_checksum(xbee_buf, len + 4))
566
        {
567
                WL_DEBUG_PRINT("XBee checksum failed.\r\n");
568
                return -1;
569
        }
570

    
571
        //we will take care of the packet
572
        if (xbee_handle_packet(xbee_buf + 3, len))
573
                return -1;
574
        
575
        if (dest == NULL)
576
                return -1;
577
        
578
        int i;
579
        for (i = 3; i < len + 3; i++)
580
                dest[i - 3] = xbee_buf[i];
581
        return len;
582
}
583

    
584
/**
585
 * Handles modem status packets.
586
 *
587
 * @param status the type of status packet received.
588
 **/
589
void xbee_handle_status(char status)
590
{
591
        switch (status)
592
        {
593
                case 0:
594
                        WL_DEBUG_PRINT("XBee hardware reset.\r\n");
595
                        break;
596
                case 1:
597
                        WL_DEBUG_PRINT("Watchdog timer reset.\r\n");
598
                        break;
599
                case 2:
600
                        WL_DEBUG_PRINT("Associated.\r\n");
601
                        break;
602
                case 3:
603
                        WL_DEBUG_PRINT("Disassociated.\r\n");
604
                        break;
605
                case 4:
606
                        WL_DEBUG_PRINT("Synchronization lost.\r\n");
607
                        break;
608
                case 5:
609
                        WL_DEBUG_PRINT("Coordinator realignment.\r\n");
610
                        break;
611
                case 6:
612
                        WL_DEBUG_PRINT("Coordinator started.\r\n");
613
                        break;
614
        }
615
}
616

    
617
/**
618
 * Handles AT command response packets.
619
 * @param command the two character AT command, e.g. MY or ID
620
 * @param result 0 for success, 1 for an error
621
 * @param extra the hex value of the requested register
622
 * @param extraLen the length in bytes of extra
623
 **/
624
void xbee_handle_at_command_response(char* command, char result,
625
        char* extra, int extraLen)
626
{
627
        if (result == 1)
628
        {
629
                WL_DEBUG_PRINT("Error with AT");
630
                WL_DEBUG_PRINT(command);
631
                WL_DEBUG_PRINT(" packet.\r\n");
632
        }
633
        WL_DEBUG_PRINT("AT");
634
        WL_DEBUG_PRINT(command);
635
        WL_DEBUG_PRINT(" command was successful.\r\n");
636
                
637
        if (command[0] == 'I' && command[1] == 'D')
638
        {
639
                xbee_panID = xbee_pending_panID;
640
                WL_DEBUG_PRINT("PAN ID set to ");
641
                WL_DEBUG_PRINT_INT(xbee_panID);
642
                WL_DEBUG_PRINT(".\r\n");
643
                return;
644
        }
645

    
646
        if (command[0] == 'C' && command[1] == 'H')
647
        {
648
                xbee_channel = xbee_pending_channel;
649
                WL_DEBUG_PRINT("Channel set to ");
650
                WL_DEBUG_PRINT_INT(xbee_channel);
651
                WL_DEBUG_PRINT(".\r\n");
652
                return;
653
        }
654
        
655
        if (command[0] == 'M' && command[1] == 'Y' && extraLen != 0)
656
        {
657
                xbee_address = 0;
658
                int i;
659
                for (i = 0; i < extraLen; i++)
660
                        xbee_address = (xbee_address << 8) + extra[i];
661

    
662
                WL_DEBUG_PRINT("XBee address is ");
663
                WL_DEBUG_PRINT_INT(xbee_address);
664
                WL_DEBUG_PRINT(".\r\n");
665

    
666
                if (xbee_address == 0)
667
                {
668
                        WL_DEBUG_PRINT("XBee 16-bit address must be set using ATMY.\r\n");
669
                        exit(0);
670
                }
671
        }
672
}
673

    
674
/**
675
 * Attempts to handle the packet if it is dealt with
676
 * by the library.
677
 * We will handle the following packet types:
678
 *    Modem Status
679
 *    AT Command Response
680
 *
681
 * @param packet the packet to handle
682
 * @param len the length of the packet
683
 * 
684
 * @return 1 if we have handled the packet, 0 otherwise
685
 */
686
int xbee_handle_packet(char* packet, int len)
687
{
688
        char command[3] = {1, 2, 3};
689
        if (len <= 0) //this should not happend
690
        {
691
                WL_DEBUG_PRINT("Non-positive packet length.\r\n");
692
                return 0;
693
        }
694
        
695
        switch ((unsigned char)packet[0]) //packet type
696
        {
697
                case XBEE_FRAME_STATUS:
698
                        xbee_handle_status(packet[1]);
699
                        return 1;
700
                case XBEE_FRAME_AT_COMMAND_RESPONSE:
701
                        command[0] = packet[2];
702
                        command[1] = packet[3];
703
                        command[2] = 0;
704
                        xbee_handle_at_command_response(command,
705
                                packet[4], packet + 5, len - 5);
706
                        return 1;
707
        }
708
        return 0;
709
}
710

    
711
/**
712
 * Sets the personal area network id.
713
 *
714
 * @param id the new personal area network (PAN) id
715
 **/
716
void xbee_set_pan_id(int id)
717
{
718
        char s[3];
719
        s[0] = (id >> 8) & 0xFF;
720
        s[1] = id & 0xFF;
721
        s[2] = 0;
722
        xbee_pending_panID = id;
723
        xbee_send_modify_at_command("ID", s);
724
}
725

    
726
/**
727
 * Get the PAN ID for the XBee.
728
 * 
729
 * @return the personal area network id, or
730
 * XBEE_PAN_DEFAULT if it has not yet been set.
731
 **/
732
unsigned int xbee_get_pan_id()
733
{
734
        return xbee_panID;
735
}
736

    
737
/**
738
 * Set the channel the XBee is using.
739
 *
740
 * @param channel the channel the XBee will not use, 
741
 * between 0x0B and 0x1A
742
 *
743
 * @see xbee_get_channel
744
 **/
745
void xbee_set_channel(int channel)
746
{
747
        if (channel < 0x0B || channel > 0x1A)
748
        {
749
                WL_DEBUG_PRINT("Channel out of range.\r\n");
750
                return;
751
        }
752
        char s[3];
753
        s[0] = channel & 0xFF;
754
        s[1] = 0;
755
        xbee_pending_channel = channel;
756
        xbee_send_modify_at_command("CH", s);
757
}
758

    
759
/**
760
 * Returns the channel which the XBee is currently using.
761
 *
762
 * @return the channel the XBee is using
763
 *
764
 * @see xbee_set_channel
765
 **/
766
int xbee_get_channel(void)
767
{
768
        return xbee_channel;
769
}
770

    
771
/**
772
 * Get the 16-bit address of the XBee.
773
 * This is used to specify who to send messages to
774
 * and who messages are from.
775
 *
776
 * @return the 16-bit address of the XBee.
777
 **/
778
unsigned int xbee_get_address()
779
{
780
        return xbee_address;
781
}
782

    
783
#ifndef ROBOT
784
void xbee_set_com_port(char* port){
785
  //printf("Port being passed is %s\n",port);
786
  xbee_com_port = (char *) malloc(strlen(port));
787
  strcpy(xbee_com_port,port); 
788
}
789
#endif
790