Wireless Personal Area Network routines. More...
Defines | |
#define | debug_on |
Functions | |
void | mrf24j40_receive_callback () |
Callback is actioned when mrf24j40 has a packet received off air. | |
void | mrf24j40_transmit_callback (uns8 status, uns8 retries, uns8 channel_busy) |
Callback is actioned when mrf24j40 has finished transmitting a packet, or failed to do so. | |
void | wpan_handle_receive () |
Handle reception of packet. | |
void | wpan_init () |
Initialise this and lower layers ready for use. | |
void | wpan_print_address (wpan_address *addr) |
Print the address of the packet. | |
void | wpan_print_frame_type (uns8 frame_type) |
Print information about the WPAN frame type. | |
void | wpan_print_mac_command (uns8 *data) |
Debug routine that prints out the mac command type. | |
void | wpan_process () |
Process WPAN layer. | |
void | wpan_setup_io () |
Setup IO as requred. | |
Variables | |
uns8 | pkt_received = 0 |
uns8 | receive_lost = 0 |
uns8 | wpan_rx_buffer [50] |
uns8 | wpan_rx_count |
#define debug_on |
void mrf24j40_receive_callback | ( | ) |
Callback indicating the mrf24j40 has a packet ready.
00056 { 00057 serial_putc('r'); 00058 if (pkt_received) { 00059 receive_lost++; 00060 debug_str("<Lost receive>"); 00061 mrf24j40_flush_receive_buffer(); 00062 } else { 00063 pkt_received++; 00064 wpan_rx_count = mrf24j40_receive(&wpan_rx_buffer, sizeof(wpan_rx_buffer)); 00065 00066 debug_str("Rx: "); 00067 debug_int(wpan_rx_count); 00068 debug_str(" bytes "); 00069 } 00070 00071 // this will get picked up in wpan_process 00072 00073 }
void mrf24j40_transmit_callback | ( | uns8 | status, | |
uns8 | retries, | |||
uns8 | channel_busy | |||
) |
Callback indicating the mrf24j40 has finished the transmission sequence.
status | Set to 0 for success or 1 for failure | |
retries | Set to the number of retries | |
channel_busy | Set to 1 if failure was due to the channel being busy. |
00077 { // 1 if fail due to channel busy 00078 debug_str(" <Tx: "); 00079 if (!status) { 00080 debug_str(" Good"); 00081 } else { 00082 debug_str(" Fail"); 00083 if (channel_busy) { 00084 debug_str(" (channel busy)"); 00085 } 00086 } 00087 debug_str(" Retries: "); 00088 debug_int(retries); 00089 debug_str(">\n"); 00090 00091 wpan_data_transmitted_callback(status, retries, channel_busy); 00092 00093 }
void wpan_handle_receive | ( | ) |
Internal routine for WPAN layer to handle the reception of a packet.
00225 { 00226 00227 wpan_address addr; 00228 00229 uns8 temp; 00230 uns8 count; 00231 uns8 frame_type; 00232 uns8 buffer_pos; 00233 00234 00235 // destination address 00236 addr.dest_address_type = wpan_rx_buffer[1] >> 6; // fc lsb dest address type 00237 00238 buffer_pos = 0; 00239 00240 switch (addr.dest_address_type) { 00241 case WPAN_ADDR_TYPE_EXTENDED: // extended address 00242 00243 // get dest pan 00244 addr.dest_pan_id = wpan_rx_buffer[4]; // msb 00245 addr.dest_pan_id <<= 8; 00246 addr.dest_pan_id += wpan_rx_buffer[3]; // lsb 00247 // get extended address 00248 for (count = 0; count < 8; count++) { 00249 addr.dest_ea[count] = wpan_rx_buffer[5+count]; 00250 } 00251 // might be faster to unwind this loop... 00252 buffer_pos = 13; 00253 break; 00254 case WPAN_ADDR_TYPE_SHORT: // short address 00255 // get dest pan 00256 addr.dest_pan_id = wpan_rx_buffer[4]; // msb 00257 addr.dest_pan_id <<= 8; 00258 addr.dest_pan_id += wpan_rx_buffer[3]; // lsb 00259 // get short address 00260 addr.dest_sa = wpan_rx_buffer[6]; // msb 00261 addr.dest_sa <<= 8; 00262 addr.dest_sa += wpan_rx_buffer[5]; // lsb 00263 buffer_pos = 7; 00264 break; 00265 case WPAN_ADDR_TYPE_NONE: // no address 00266 buffer_pos = 3; 00267 break; 00268 } 00269 00270 // source address 00271 00272 addr.source_address_type = (wpan_rx_buffer[1] >> 2) & 0b00000011; // fc lsb src address type 00273 00274 switch (addr.source_address_type) { 00275 case WPAN_ADDR_TYPE_EXTENDED: // extended address 00276 // get source pan 00277 if (test_bit(wpan_rx_buffer[0], 6)) { // pan id compression 00278 addr.source_pan_id = addr.dest_pan_id; 00279 } else { 00280 addr.source_pan_id = wpan_rx_buffer[buffer_pos+1]; // msb 00281 addr.source_pan_id <<= 8; 00282 addr.source_pan_id += wpan_rx_buffer[buffer_pos]; // lsb 00283 buffer_pos += 2; 00284 } 00285 // get extended address 00286 for (count = 0; count < 8; count++) { 00287 addr.source_ea[count] = wpan_rx_buffer[buffer_pos++]; 00288 } 00289 00290 break; 00291 case WPAN_ADDR_TYPE_SHORT: // short address 00292 if (test_bit(wpan_rx_buffer[0], 6)) { // pan id compression 00293 addr.source_pan_id = addr.dest_pan_id; 00294 } else { 00295 // get pan 00296 addr.source_pan_id = wpan_rx_buffer[buffer_pos+1]; // msb 00297 addr.source_pan_id <<= 8; 00298 addr.source_pan_id += wpan_rx_buffer[buffer_pos]; // lsb 00299 buffer_pos += 2; 00300 } 00301 // get short address 00302 addr.source_sa = wpan_rx_buffer[buffer_pos+1]; // msb 00303 addr.source_sa <<= 8; 00304 addr.source_sa += wpan_rx_buffer[buffer_pos]; // lsb 00305 buffer_pos += 2; 00306 break; 00307 case WPAN_ADDR_TYPE_NONE: // no address 00308 break; 00309 } 00310 //debug_var(" buffer pos = ", buffer_pos); 00311 //debug_var(" wpan_rx_count = ", wpan_rx_count); 00312 // data should be at buffer_pos 00313 frame_type = wpan_rx_buffer[0] & 0b00000111; // frame type 00314 switch(frame_type) { 00315 case FRAME_TYPE_MAC_COMMAND: 00316 //wpan_handle_mac_command(&addr, &wpan_rx_buffer[buffer_pos], wpan_rx_count - buffer_pos); 00317 break; 00318 case FRAME_TYPE_BEACON: 00319 //wpan_handle_beacon(&addr, &wpan_rx_buffer[buffer_pos], wpan_rx_count - buffer_pos); 00320 break; 00321 case FRAME_TYPE_DATA: 00322 wpan_data_received_callback(&addr, &wpan_rx_buffer[buffer_pos], wpan_rx_count - buffer_pos - 4, 00323 /* lqi */ wpan_rx_buffer[wpan_rx_count-2], /* rssi */ wpan_rx_buffer[wpan_rx_count-1]); 00324 break; 00325 // We'll never see an ACK frame, that should be handled by the MRF 00326 } 00327 00328 pkt_received = 0; 00329 }
void wpan_init | ( | ) |
Initialise underlying hardware (typically mrf24j40)
00336 { 00337 00338 mrf24j40_init(); 00339 00340 }
void wpan_print_address | ( | wpan_address * | addr | ) |
Print out the source and destination address
00096 { 00097 00098 uns8 count; 00099 00100 debug_str("\nPKT:\nSrc "); 00101 if (addr->source_address_type) { // ie, not 0 00102 serial_print_str(" PAN: "); 00103 serial_print_int_hex_16bit(addr->source_pan_id); 00104 00105 switch (addr->source_address_type) { 00106 case WPAN_ADDR_TYPE_EXTENDED: 00107 serial_print_str(" EA: "); 00108 for (count = 7; count != 255; count--) { 00109 serial_print_int_hex(addr->source_ea[count]); 00110 serial_putc(' '); 00111 } 00112 break; 00113 case WPAN_ADDR_TYPE_SHORT: 00114 serial_print_str(" SA: "); 00115 serial_print_int_hex_16bit(addr->source_sa); 00116 serial_putc(' '); 00117 break; 00118 } 00119 } else { 00120 serial_print_str(" (blank) "); 00121 } 00122 00123 serial_print_str(" Dest "); 00124 00125 if (addr->dest_address_type) { // ie, not 0 00126 serial_print_str(" PAN: "); 00127 serial_print_int_hex_16bit(addr->dest_pan_id); 00128 00129 switch (addr->dest_address_type) { 00130 case WPAN_ADDR_TYPE_EXTENDED: 00131 serial_print_str(" EA: "); 00132 for (count = 7; count != 255; count--) { 00133 serial_print_int_hex(addr->dest_ea[count]); 00134 serial_putc(' '); 00135 } 00136 break; 00137 case WPAN_ADDR_TYPE_SHORT: 00138 serial_print_str(" SA: "); 00139 serial_print_int_hex_16bit(addr->dest_sa); 00140 serial_putc(' '); 00141 break; 00142 } 00143 } else { 00144 serial_print_str(" (blank) "); 00145 } 00146 }
void wpan_print_frame_type | ( | uns8 | frame_type | ) |
00148 { 00149 00150 switch(frame_type) { 00151 case FRAME_TYPE_BEACON: 00152 serial_print_str(" Beacon "); 00153 break; 00154 case FRAME_TYPE_DATA: 00155 serial_print_str(" Data "); 00156 break; 00157 case FRAME_TYPE_ACK: 00158 serial_print_str(" Ack "); 00159 break; 00160 case FRAME_TYPE_MAC_COMMAND: 00161 serial_print_str(" Mac "); 00162 break; 00163 } 00164 }
void wpan_print_mac_command | ( | uns8 * | data | ) |
Print the MAC layer command details
00166 { 00167 00168 uns8 mac_command = data[0]; // Uses less flash this way 00169 00170 switch (data[0]) { 00171 00172 case MAC_CMD_ASSOC_REQ: 00173 serial_print_str("ASSOC REQ (Capability: "); 00174 serial_print_int_hex(data[1]); 00175 serial_putc(')'); 00176 break; 00177 case MAC_CMD_ASSOC_RES: 00178 serial_print_str("ASSOC RES (Short addr: "); 00179 serial_print_int_hex(data[2]); // msb 00180 serial_print_int_hex(data[1]); // lsb 00181 serial_print_str(" Status: "); 00182 serial_print_int_hex(data[3]); 00183 serial_putc(')'); 00184 break; 00185 case MAC_CMD_DISASSOC: 00186 serial_print_str("DISASSOC (Reason: "); 00187 serial_print_int_hex(data[1]); 00188 serial_putc(')'); 00189 break; 00190 case MAC_CMD_DATA_REQ: 00191 serial_print_str("DATA REQ"); 00192 break; 00193 case MAC_CMD_PAN_ID_CONFLICT: 00194 serial_print_str("PAN ID CONFLICT"); 00195 break; 00196 case MAC_CMD_ORPHAN: 00197 serial_print_str("ORPHAN"); 00198 break; 00199 case MAC_CMD_BEACON_REQ: 00200 serial_print_str("BEACON REQ"); 00201 break; 00202 case MAC_CMD_COORD_REALIGN: 00203 serial_print_str("COORD REALIGN (data TBD)"); 00204 break; 00205 case MAC_CMD_GTS_REQ: 00206 serial_print_str("GTS REQ (Char: "); 00207 serial_print_int_hex(data[1]); 00208 serial_putc(')'); 00209 break; 00210 } 00211 }
void wpan_process | ( | ) |
Call wpan_process() regularly to handle events at the WPAN layer. Typically this includes handling any received packets, processing them, and handing up to a higher layer.
00214 { 00215 00216 if (pkt_received) { 00217 wpan_handle_receive(); 00218 } 00219 }
void wpan_setup_io | ( | ) |
Set up ports and pins for WPAN use
00332 { 00333 mrf24j40_setup_io(); 00334 }
uns8 pkt_received = 0 |
uns8 receive_lost = 0 |
uns8 wpan_rx_buffer[50] |
uns8 wpan_rx_count |