Project

General

Profile

Statistics
| Revision:

root / branches / autonomous_recharging / code / projects / autonomous_recharging / charging_station / wireless.c @ 120

History | View | Annotate | Download (8.8 KB)

1
#include "wireless.h"
2
#include "xbee.h"
3
#include <stdlib.h>
4
#include <stdio.h>
5

    
6
#include "wl_defs.h"
7

    
8
#ifndef ROBOT
9
#include <time.h>
10
#include <signal.h>
11
#else
12
#include <time.h>
13
#ifndef FIREFLY
14
#include <bom.h>
15
#endif
16
#endif
17

    
18
/*Function Prototypes*/
19

    
20
void wl_do_timeout(void);
21

    
22
//Note: the actual frame sent has group as the first four bits and
23
//frame as the last four.
24
void wl_send_packet(char group, char type, char* data, int len,
25
                                        int dest, char options, char frame);
26

    
27
/*Data Members*/
28

    
29
//used to store incoming and outgoing packets
30
unsigned char wl_buf[128];
31
//1 if we have timed out since we last checked, 0 otherwise.
32
int wl_timeout = 0;
33

    
34
PacketGroupHandler* wl_packet_groups[WL_MAX_PACKET_GROUPS];
35

    
36
#ifndef ROBOT
37
timer_t wl_timeout_timer;
38

    
39
//called when we time out, or receive interrupt
40
void sig_handler(int signo)
41
{
42
        switch (signo)
43
        {
44
                case SIGALRM:
45
                        wl_timeout = 1;
46
                        break;
47
                case SIGINT:
48
                        wl_terminate();
49
                        exit(1);
50
                        break;
51
        }
52
        return;
53
}
54
#endif
55

    
56
/**
57
 * Initializes the wireless library. Must be called before any
58
 * other function.
59
 **/
60
void wl_init()
61
{
62
        int i;
63
        for (i = 0; i < WL_MAX_PACKET_GROUPS; i++)
64
                wl_packet_groups[i] = NULL;
65

    
66
        xbee_lib_init();
67
        
68
        //begin timeout timer
69
        #ifdef ROBOT
70
        #ifdef FIREFLY
71
        rtc_init(PRESCALE_DIV_128, 32, &wl_do_timeout);
72
        #else
73
        rtc_init(HALF_SECOND, &wl_do_timeout); 
74
        #endif
75
        #else
76
        //create a timer to trigger every half second
77
        struct sigevent evp;
78
        evp.sigev_signo = SIGALRM;
79
        evp.sigev_notify = SIGEV_SIGNAL;
80
        if (timer_create(CLOCK_REALTIME, &evp, &wl_timeout_timer) == -1)
81
        { 
82
                WL_DEBUG_PRINT("Error creating a timer.\r\n"); 
83
                exit(1); 
84
        }
85
        struct sigaction wl_sig_act;
86
        wl_sig_act.sa_handler = (void *)sig_handler;
87
        wl_sig_act.sa_flags = 0;
88
        sigemptyset(&wl_sig_act.sa_mask);
89
        sigaction(SIGALRM, &wl_sig_act, 0);
90
        sigaction(SIGINT, &wl_sig_act, 0);
91
        struct itimerspec wl_timeout_time;
92
        wl_timeout_time.it_interval.tv_sec = 0;
93
        wl_timeout_time.it_interval.tv_nsec = 500000000;
94
        wl_timeout_time.it_value.tv_sec = 0;
95
        wl_timeout_time.it_value.tv_nsec = 500000000;
96
        timer_settime(wl_timeout_timer, 0,
97
                        &wl_timeout_time, NULL);
98
        #endif
99
}
100

    
101
/**
102
 * Uninitializes the wireless library.
103
 **/
104
void wl_terminate()
105
{
106
        #ifndef ROBOT
107
        timer_delete(wl_timeout_timer);
108
        #endif
109
        
110
        int i;
111
        for (i = 0; i < WL_MAX_PACKET_GROUPS; i++)
112
                if (wl_packet_groups[i] != NULL &&
113
                        wl_packet_groups[i]->unregister != NULL)
114
                        wl_packet_groups[i]->unregister();
115
        
116
        xbee_terminate();
117
}
118

    
119
/**
120
 * Set the PAN for the XBee to join.
121
 *
122
 * @param pan the new PAN
123
 *
124
 * @see wl_get_pan
125
 **/
126
void wl_set_pan(int pan)
127
{
128
        xbee_set_pan_id(pan);
129
}
130

    
131
/**
132
 * Get the PAN the XBee is currently part of.
133
 *
134
 * @return the PAN of the XBee
135
 *
136
 * @see wl_set_pan
137
 **/
138
int wl_get_pan(void)
139
{
140
        return xbee_get_pan_id();
141
}
142

    
143
/**
144
 * Set the channel the XBee is listening to.
145
 *
146
 * @param channel the new channel to join
147
 *
148
 * @see wl_get_channel
149
 **/
150
void wl_set_channel(int channel)
151
{
152
        xbee_set_channel(channel);
153
}
154

    
155
/**
156
 * Get the channel the XBee is part of.
157
 *
158
 * @return the channel the XBee is part of
159
 *
160
 * @see wl_set_channel
161
 **/
162
int wl_get_channel(void)
163
{
164
        return xbee_get_channel();
165
}
166

    
167
/**
168
 * Returns the 16-bit address of the XBee module.
169
 *
170
 * @return the 16-bit address of the XBee module.
171
 **/
172
unsigned int wl_get_xbee_id()
173
{
174
        return xbee_get_address();
175
}
176

    
177
/**
178
 * Send a packet to a specific XBee without specifying a PAN.
179
 *
180
 * @param group the packet group
181
 * @param type the packet type
182
 * @param data the packet data
183
 * @param len the packet length in bytes
184
 * @param dest the 16-bit address of the XBee to send the packet to
185
 * @param frame the frame number to see with a TX_STATUS response
186
 **/
187
void wl_send_robot_to_robot_global_packet(char group, char type,
188
                char* data, int len, int dest, char frame)
189
{
190
        wl_send_packet(group, type, data, len, dest,
191
                        XBEE_OPTIONS_BROADCAST_ALL_PANS, frame);
192
}
193

    
194
/**
195
 * Send a packet to a specific XBee in the same PAN.
196
 *
197
 * @param group the packet group
198
 * @param type the packet type
199
 * @param data the packet data
200
 * @param len the packet length in bytes
201
 * @param dest the 16-bit address of the XBee to send the packet to
202
 * @param frame the frame number to see with a TX_STATUS response
203
 **/
204
void wl_send_robot_to_robot_packet(char group, char type,
205
                char* data, int len, int dest, char frame)
206
{
207
        wl_send_packet(group, type, data, len, dest, XBEE_OPTIONS_NONE,
208
                        frame);
209
}
210

    
211
/**
212
 * Send a packet to all XBees in all PANs.
213
 *
214
 * @param group the packet group
215
 * @param type the packet type
216
 * @param data the packet data
217
 * @param len the packet length in bytes
218
 * @param frame the frame number to see with a TX_STATUS response
219
 **/
220
void wl_send_global_packet(char group, char type,
221
                char* data, int len, char frame)
222
{
223
        wl_send_packet(group, type, data, len, XBEE_BROADCAST,
224
                        XBEE_OPTIONS_BROADCAST_ALL_PANS, frame);
225
}
226

    
227
/**
228
 * Send a packet to all XBee's in the same PAN.
229
 *
230
 * @param group the packet group
231
 * @param type the packet type
232
 * @param data the packet data
233
 * @param len the packet length in bytes
234
 * @param frame the frame number to see with a TX_STATUS response
235
 **/
236
void wl_send_pan_packet(char group, char type,
237
                char* data, int len, char frame)
238
{
239
        wl_send_packet(group, type, data, len, XBEE_BROADCAST, 
240
                        XBEE_OPTIONS_NONE, frame);
241
}
242

    
243
/**
244
 * Send a packet.
245
 *
246
 * @param group the packet group
247
 * @param type the packet type
248
 * @param data the packet data
249
 * @param len the packet length in bytes
250
 * @param dest the destination of the packet
251
 * @param options the options for sending the packet
252
 * @param frame the frame number to see with a TX_STATUS response
253
 **/
254
void wl_send_packet(char group, char type, char* data, int len,
255
                                        int dest, char options, char frame)
256
{
257
        char buf[128];
258
        int i;
259
        if (frame != 0)
260
                frame = (frame & 0x0F) | ((group & 0x0F) << 4);
261
        buf[0] = group;
262
        buf[1] = type;
263
        for (i = 0; i < len; i++)
264
                buf[2 + i] = data[i];
265
        xbee_send_packet(buf, len + 2, dest, options, frame);
266
}
267

    
268
/**
269
 * Register a packet group with the wireless library. The event
270
 * handlers in the packet group will be called whenever an
271
 * event dealing with the packet group's group code occurs.
272
 *
273
 * @param h the PacketGroupHandler to register
274
 **/
275
void wl_register_packet_group(PacketGroupHandler* h)
276
{
277
        if (h->groupCode >= WL_MAX_PACKET_GROUPS)
278
        {
279
                WL_DEBUG_PRINT("Packet group code too large.\r\n");
280
                return;
281
        }
282
        if (wl_packet_groups[h->groupCode] != NULL)
283
        {
284
                WL_DEBUG_PRINT("Packet group code already registered.\r\n");
285
                return;
286
        }
287
        wl_packet_groups[h->groupCode] = h;
288
}
289

    
290
/**
291
 * Unregister a packet group from the wireless library.
292
 * 
293
 * @param h the packet group to remove
294
 **/
295
void wl_unregister_packet_group(PacketGroupHandler* h)
296
{
297
        unsigned int groupCode = h->groupCode;
298
        PacketGroupHandler* p = wl_packet_groups[groupCode];
299
        if (p != NULL && p->unregister != NULL)
300
                p->unregister();
301
        wl_packet_groups[groupCode] = NULL;
302
}
303

    
304
/**
305
 * Called when the timer is triggered. This calls the timeout
306
 * handlers of all the registered packet groups.
307
 **/
308
void wl_do_timeout()
309
{
310
        int i;
311
        for (i = 0; i < WL_MAX_PACKET_GROUPS; i++)
312
                if (wl_packet_groups[i] != NULL &&
313
                        wl_packet_groups[i]->timeout_handler != NULL)
314
                        wl_packet_groups[i]->timeout_handler();
315
}
316

    
317
/**
318
 * Performs wireless library functionality. This function must
319
 * be called frequently for wireless to perform effectively.
320
 * This function will call timeout handlers, as well as
321
 * received packet and transmit status handlers.
322
 **/
323
void wl_do()
324
{
325
        if (wl_timeout)
326
        {
327
                wl_do_timeout();
328
                wl_timeout = 0;
329
        }
330
        
331
        int len = xbee_get_packet(wl_buf);
332
        if (len < 0)//no packet received
333
                return;
334
        
335
        if (wl_buf[0] == XBEE_TX_STATUS)
336
        {
337
                if (len != 3)
338
                {
339
                        WL_DEBUG_PRINT("Transmit Status packet should be of length 3.\r\n");
340
                        return;
341
                }
342
                
343
                //the first four bits are the packet group
344
                //this only works with under 16 groups
345
                int group = (int)(wl_buf[1] >> 4);
346
                int success = 0;
347
                if (wl_buf[2] == 0)
348
                        success = 1;
349
                else
350
                {
351
                        WL_DEBUG_PRINT("No response received.\r\n");
352
                        if (wl_buf[2] == 2)
353
                                WL_DEBUG_PRINT("CCA Failure\r\n");
354
                        if (wl_buf[2] == 3)
355
                                WL_DEBUG_PRINT("Purged\r\n");
356
                }
357
                
358
                if (wl_packet_groups[group] != NULL &&
359
                                        wl_packet_groups[group]->handle_response != NULL)
360
                        wl_packet_groups[group]->handle_response(
361
                                        (int)wl_buf[1] & 0x0F, success);
362
                return;
363
        }
364
        
365
        if (wl_buf[0] == XBEE_RX)
366
        {
367
                if (len < 7)
368
                {
369
                        WL_DEBUG_PRINT("Packet is too small.\r\n");
370
                        return;
371
                }
372
                
373
                int source = ((int)wl_buf[1] << 8) + ((int)wl_buf[2]);
374
                
375
                /*
376
                //unused for now
377
                int signalStrength = wl_buf[3];
378
                //1 for Address broadcast, 2 for PAN broadcast
379
                int options = wl_buf[4];
380
                */
381
                
382
                int group = wl_buf[5];
383
                int type = wl_buf[6];
384
                int packetLen = len - 7;
385
                
386
                if (wl_packet_groups[group] != NULL
387
                                && wl_packet_groups[group]->handle_receive != NULL)
388
                        wl_packet_groups[group]->handle_receive(type, source, 
389
                                wl_buf + 7, packetLen);
390
                return;
391
        }
392
        
393
        usb_puts("Unexpected packet received.\n");
394
        //WL_DEBUG_PRINT("Unexpected packet received from XBee.\r\n");
395
        return;
396
}
397