Contiki 2.6
|
00001 /* This file has been prepared for Doxygen automatic documentation generation.*/ 00002 /*! \file cdc_task.c ********************************************************** 00003 * 00004 * \brief 00005 * Manages the CDC-ACM Virtual Serial Port Dataclass for the USB Device 00006 * 00007 * \addtogroup usbstick 00008 * 00009 * \author 00010 * Colin O'Flynn <coflynn@newae.com> 00011 * 00012 ******************************************************************************/ 00013 /* Copyright (c) 2008 ATMEL Corporation 00014 All rights reserved. 00015 00016 Redistribution and use in source and binary forms, with or without 00017 modification, are permitted provided that the following conditions are met: 00018 00019 * Redistributions of source code must retain the above copyright 00020 notice, this list of conditions and the following disclaimer. 00021 * Redistributions in binary form must reproduce the above copyright 00022 notice, this list of conditions and the following disclaimer in 00023 the documentation and/or other materials provided with the 00024 distribution. 00025 * Neither the name of the copyright holders nor the names of 00026 contributors may be used to endorse or promote products derived 00027 from this software without specific prior written permission. 00028 00029 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00030 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00031 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00032 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00033 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00034 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00035 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00036 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00037 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00038 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00039 POSSIBILITY OF SUCH DAMAGE. 00040 */ 00041 /** 00042 \ingroup usbstick 00043 \defgroup cdctask CDC Task 00044 @{ 00045 */ 00046 00047 //_____ I N C L U D E S ___________________________________________________ 00048 00049 00050 #include "contiki.h" 00051 #include "usb_drv.h" 00052 #include "usb_descriptors.h" 00053 #include "usb_specific_request.h" 00054 #include "cdc_task.h" 00055 #include "serial/uart_usb_lib.h" 00056 #include "rndis/rndis_protocol.h" 00057 #include "rndis/rndis_task.h" 00058 #include "sicslow_ethernet.h" 00059 #if RF230BB 00060 #include "rf230bb.h" 00061 #else 00062 #include "radio.h" 00063 #endif 00064 00065 #include <stdio.h> 00066 #include <stdlib.h> 00067 #include "dev/watchdog.h" 00068 #include "rng.h" 00069 00070 #include "bootloader.h" 00071 00072 #include <avr/pgmspace.h> 00073 #include <avr/eeprom.h> 00074 #include <avr/wdt.h> 00075 #include <util/delay.h> 00076 00077 #if JACKDAW_CONF_USE_SETTINGS 00078 #include "settings.h" 00079 #endif 00080 00081 #define BUF ((struct uip_eth_hdr *)&uip_buf[0]) 00082 #define PRINTF printf 00083 #define PRINTF_P printf_P 00084 00085 //_____ M A C R O S ________________________________________________________ 00086 00087 00088 #define bzero(ptr,size) memset(ptr,0,size) 00089 00090 //_____ D E F I N I T I O N S ______________________________________________ 00091 00092 00093 #define IAD_TIMEOUT_DETACH 300 00094 #define IAD_TIMEOUT_ATTACH 600 00095 00096 //_____ D E C L A R A T I O N S ____________________________________________ 00097 00098 00099 void menu_print(void); 00100 void menu_process(char c); 00101 00102 extern char usb_busy; 00103 00104 //! Counter for USB Serial port 00105 extern U8 tx_counter; 00106 00107 //! Timers for LEDs 00108 uint8_t led3_timer; 00109 00110 00111 //! previous configuration 00112 static uint8_t previous_uart_usb_control_line_state = 0; 00113 00114 00115 static uint8_t timer = 0; 00116 static struct etimer et; 00117 00118 #define CONVERTTXPOWER 1 00119 #if CONVERTTXPOWER //adds ~120 bytes to program flash size 00120 const char txonesdigit[16] PROGMEM = {'3','2','2','1','1','0','0','1','2','3','4','5','7','9','2','7'}; 00121 const char txtenthsdigit[16] PROGMEM = {'0','6','1','6','1','5','2','2','2','2','2','2','2','2','2','2'}; 00122 static void printtxpower(void) { 00123 uint8_t power=rf230_get_txpower()&0xf; 00124 char sign=(power<6?'+':'-'); 00125 char tens=(power>14?'1':'0'); 00126 char ones=pgm_read_byte(&txonesdigit[power]); 00127 char tenths=pgm_read_byte(&txtenthsdigit[power]); 00128 if (tens=='0') {tens=sign;sign=' ';} 00129 PRINTF_P(PSTR("%c%c%c.%cdBm"),sign,tens,ones,tenths); 00130 } 00131 #endif 00132 00133 PROCESS(cdc_process, "CDC serial process"); 00134 00135 /** 00136 * \brief Communication Data Class (CDC) Process 00137 * 00138 * This is the link between USB and the "good stuff". In this routine data 00139 * is received and processed by CDC-ACM Class 00140 */ 00141 PROCESS_THREAD(cdc_process, ev, data_proc) 00142 { 00143 PROCESS_BEGIN(); 00144 00145 #if USB_CONF_RS232 00146 static FILE *rs232_stdout,*usb_stdout; 00147 rs232_stdout=stdout; 00148 #endif 00149 00150 while(1) { 00151 // turn off LED's if necessary 00152 if (led3_timer) led3_timer--; 00153 else Led3_off(); 00154 00155 if(Is_device_enumerated()) { 00156 // If the configuration is different than the last time we checked... 00157 if((uart_usb_get_control_line_state()&1)!=previous_uart_usb_control_line_state) { 00158 previous_uart_usb_control_line_state = uart_usb_get_control_line_state()&1; 00159 static FILE* previous_stdout; 00160 00161 if(previous_uart_usb_control_line_state&1) { 00162 previous_stdout = stdout; 00163 uart_usb_init(); 00164 uart_usb_set_stdout(); 00165 // menu_print(); do this later 00166 } else { 00167 stdout = previous_stdout; 00168 } 00169 #if USB_CONF_RS232 00170 usb_stdout=stdout; 00171 #endif 00172 } 00173 00174 //Flush buffer if timeout 00175 if(timer >= 4 && tx_counter!=0 ){ 00176 timer = 0; 00177 uart_usb_flush(); 00178 } else { 00179 timer++; 00180 } 00181 00182 #if USB_CONF_RS232 00183 stdout=usb_stdout; 00184 #endif 00185 while (uart_usb_test_hit()){ 00186 menu_process(uart_usb_getchar()); // See what they want 00187 } 00188 #if USB_CONF_RS232 00189 if (usbstick_mode.debugOn) { 00190 stdout=rs232_stdout; 00191 } else { 00192 stdout=NULL; 00193 } 00194 #endif 00195 }//if (Is_device_enumerated()) 00196 00197 00198 00199 if (USB_CONFIG_HAS_DEBUG_PORT(usb_configuration_nb)) { 00200 etimer_set(&et, CLOCK_SECOND/80); 00201 } else { 00202 etimer_set(&et, CLOCK_SECOND); 00203 } 00204 00205 PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); 00206 00207 } // while(1) 00208 00209 PROCESS_END(); 00210 } 00211 00212 /** 00213 \brief Print debug menu 00214 */ 00215 void menu_print(void) 00216 { 00217 PRINTF_P(PSTR("\n\r*********** Jackdaw Menu **********\n\r")); 00218 PRINTF_P(PSTR(" [Built "__DATE__"] \n\r")); 00219 // PRINTF_P(PSTR("* *\n\r")); 00220 PRINTF_P(PSTR("* m Print current mode *\n\r")); 00221 PRINTF_P(PSTR("* s Set to sniffer mode *\n\r")); 00222 PRINTF_P(PSTR("* n Set to network mode *\n\r")); 00223 PRINTF_P(PSTR("* c Set RF channel *\n\r")); 00224 PRINTF_P(PSTR("* p Set RF power *\n\r")); 00225 PRINTF_P(PSTR("* 6 Toggle 6lowpan *\n\r")); 00226 PRINTF_P(PSTR("* r Toggle raw mode *\n\r")); 00227 #if USB_CONF_RS232 00228 PRINTF_P(PSTR("* d Toggle RS232 output *\n\r")); 00229 #endif 00230 #if RF230BB && RF230_CONF_SNEEZER 00231 PRINTF_P(PSTR("* S Enable sneezer mode *\n\r")); 00232 #endif 00233 #if UIP_CONF_IPV6_RPL 00234 PRINTF_P(PSTR("* N RPL Neighbors *\n\r")); 00235 PRINTF_P(PSTR("* G RPL Global Repair *\n\r")); 00236 #endif 00237 PRINTF_P(PSTR("* e Energy Scan *\n\r")); 00238 #if USB_CONF_STORAGE 00239 PRINTF_P(PSTR("* u Switch to mass-storage*\n\r")); 00240 #endif 00241 if(bootloader_is_present()) 00242 PRINTF_P(PSTR("* D Switch to DFU mode *\n\r")); 00243 PRINTF_P(PSTR("* R Reset (via WDT) *\n\r")); 00244 PRINTF_P(PSTR("* h,? Print this menu *\n\r")); 00245 PRINTF_P(PSTR("* *\n\r")); 00246 PRINTF_P(PSTR("* Make selection at any time by *\n\r")); 00247 PRINTF_P(PSTR("* pressing your choice on keyboard*\n\r")); 00248 PRINTF_P(PSTR("***********************************\n\r")); 00249 } 00250 00251 #if UIP_CONF_IPV6_RPL 00252 static void 00253 ipaddr_add(const uip_ipaddr_t *addr) 00254 { 00255 uint16_t a; 00256 int8_t i, f; 00257 for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) { 00258 a = (addr->u8[i] << 8) + addr->u8[i + 1]; 00259 if(a == 0 && f >= 0) { 00260 if(f++ == 0) PRINTF_P(PSTR("::")); 00261 } else { 00262 if(f > 0) { 00263 f = -1; 00264 } else if(i > 0) { 00265 PRINTF_P(PSTR(":")); 00266 } 00267 PRINTF_P(PSTR("%x"),a); 00268 } 00269 } 00270 } 00271 #endif 00272 00273 /** 00274 \brief Process incomming char on debug port 00275 */ 00276 void menu_process(char c) 00277 { 00278 00279 static enum menustate_enum /* Defines an enumeration type */ 00280 { 00281 normal, 00282 channel, 00283 txpower 00284 } menustate = normal; 00285 00286 static char channel_string[3]; 00287 static uint8_t channel_string_i;// = 0; 00288 00289 int tempchannel; 00290 00291 if (menustate == channel) { 00292 00293 switch(c) { 00294 case '\r': 00295 case '\n': 00296 00297 if (channel_string_i) { 00298 channel_string[channel_string_i] = 0; 00299 tempchannel = atoi(channel_string); 00300 00301 #if RF230BB 00302 if ((tempchannel < 11) || (tempchannel > 26)) { 00303 PRINTF_P(PSTR("\n\rInvalid input\n\r")); 00304 } else { 00305 rf230_set_channel(tempchannel); 00306 #else 00307 if(radio_set_operating_channel(tempchannel)!=RADIO_SUCCESS) { 00308 PRINTF_P(PSTR("\n\rInvalid input\n\r")); 00309 } else { 00310 #endif 00311 #if JACKDAW_CONF_USE_SETTINGS 00312 if(settings_set_uint8(SETTINGS_KEY_CHANNEL, tempchannel)==SETTINGS_STATUS_OK) { 00313 PRINTF_P(PSTR("\n\rChannel changed to %d and stored in EEPROM.\n\r"),tempchannel); 00314 } else { 00315 PRINTF_P(PSTR("\n\rChannel changed to %d, but unable to store in EEPROM!\n\r"),tempchannel); 00316 } 00317 #else 00318 PRINTF_P(PSTR("\n\rChannel changed to %d.\n\r"),tempchannel); 00319 #endif 00320 } 00321 } else { 00322 PRINTF_P(PSTR("\n\rChannel unchanged.\n\r")); 00323 } 00324 00325 menustate = normal; 00326 break; 00327 00328 case '\b': 00329 00330 if (channel_string_i) { 00331 channel_string_i--; 00332 PRINTF_P(PSTR("\b \b")); 00333 } 00334 break; 00335 00336 case '0': 00337 case '1': 00338 case '2': 00339 case '3': 00340 case '4': 00341 case '5': 00342 case '6': 00343 case '7': 00344 case '8': 00345 case '9': 00346 if (channel_string_i > 1) { 00347 // This time the user has gone too far. 00348 // Beep at them. 00349 putc('\a', stdout); 00350 //uart_usb_putchar('\a'); 00351 break; 00352 } 00353 putc(c, stdout); 00354 //uart_usb_putchar(c); 00355 00356 channel_string[channel_string_i] = c; 00357 channel_string_i++; 00358 break; 00359 00360 default: 00361 break; 00362 } 00363 } else if (menustate == txpower) { 00364 00365 switch(c) { 00366 case '\r': 00367 case '\n': 00368 00369 if (channel_string_i) { 00370 channel_string[channel_string_i] = 0; 00371 tempchannel = atoi(channel_string); 00372 #if RF230BB 00373 if ((tempchannel < 0) || (tempchannel > 15)) { 00374 PRINTF_P(PSTR("\n\rInvalid input\n\r")); 00375 } else { 00376 PRINTF_P(PSTR(" ")); //for some reason needs a print here to clear the string input... 00377 rf230_set_txpower(tempchannel); 00378 #else 00379 if(radio_set_tx_power_level(tempchannel)!=RADIO_SUCCESS) { 00380 PRINTF_P(PSTR("\n\rInvalid input\n\r")); 00381 } else { 00382 #endif 00383 #if JACKDAW_CONF_USE_SETTINGS 00384 if(settings_set_uint8(SETTINGS_KEY_TXPOWER, tempchannel)==SETTINGS_STATUS_OK) { 00385 PRINTF_P(PSTR("\n\rTransmit power changed to %d, and stored in EEPROM.\n\r"),tempchannel); 00386 } else { 00387 PRINTF_P(PSTR("\n\rTransmit power changed to %d, but unable to store in EEPROM!\n\r"),tempchannel); 00388 } 00389 #else 00390 PRINTF_P(PSTR("\n\rTransmit power changed to %d.\n\r"),tempchannel); 00391 #endif 00392 } 00393 } else { 00394 PRINTF_P(PSTR("\n\rTransmit power unchanged.\n\r")); 00395 } 00396 00397 menustate = normal; 00398 break; 00399 00400 case '\b': 00401 00402 if (channel_string_i) { 00403 channel_string_i--; 00404 PRINTF_P(PSTR("\b \b")); 00405 } 00406 break; 00407 00408 case '0': 00409 case '1': 00410 case '2': 00411 case '3': 00412 case '4': 00413 case '5': 00414 case '6': 00415 case '7': 00416 case '8': 00417 case '9': 00418 if (channel_string_i > 1) { 00419 // This time the user has gone too far. 00420 // Beep at them. 00421 putc('\a', stdout); 00422 //uart_usb_putchar('\a'); 00423 break; 00424 } 00425 putc(c, stdout); 00426 //uart_usb_putchar(c); 00427 00428 channel_string[channel_string_i] = c; 00429 channel_string_i++; 00430 break; 00431 00432 default: 00433 break; 00434 } 00435 00436 } else { 00437 00438 uint8_t i; 00439 00440 /* Any attempt to read an RF230 register in sneeze mode (e.g. rssi) will hang the MCU */ 00441 /* So convert any command into a sneeze off */ 00442 if (usbstick_mode.sneeze) c='S'; 00443 00444 switch(c) { 00445 case '\r': 00446 case '\n': 00447 break; 00448 00449 case 'h': 00450 case '?': 00451 menu_print(); 00452 break; 00453 case '-': 00454 PRINTF_P(PSTR("Bringing interface down\n\r")); 00455 usb_eth_set_active(0); 00456 break; 00457 case '=': 00458 case '+': 00459 PRINTF_P(PSTR("Bringing interface up\n\r")); 00460 usb_eth_set_active(1); 00461 break; 00462 #if JACKDAW_CONF_RANDOM_MAC 00463 case 'T': 00464 // Test "strong" random number generator of R Quattlebaum 00465 // This can potentially reboot the stick! 00466 PRINTF_P(PSTR("RNG Output: ")); 00467 { 00468 uint8_t value = rng_get_uint8(); 00469 uint8_t i; 00470 for(i=0;i<8;i++) { 00471 uart_usb_putchar(((value>>(7-i))&1)?'1':'0'); 00472 } 00473 PRINTF_P(PSTR("\n\r")); 00474 uart_usb_flush(); 00475 watchdog_periodic(); 00476 } 00477 break; 00478 #endif 00479 case 's': 00480 PRINTF_P(PSTR("Jackdaw now in sniffer mode\n\r")); 00481 usbstick_mode.sendToRf = 0; 00482 usbstick_mode.translate = 0; 00483 #if RF230BB 00484 rf230_listen_channel(rf230_get_channel()); 00485 #else 00486 radio_set_trx_state(RX_ON); 00487 #endif 00488 break; 00489 00490 #if RF230BB && RF230_CONF_SNEEZER 00491 case 'S': 00492 if (usbstick_mode.sneeze) { 00493 rf230_warm_reset(); 00494 PRINTF_P(PSTR("Jackdaw now behaving itself.\n\r")); 00495 usbstick_mode.sneeze = 0; 00496 } else { 00497 if (rf230_get_txpower()<3) 00498 PRINTF_P(PSTR("*****WARNING Radio may overheat in this mode*******\n\r")); 00499 rf230_start_sneeze(); 00500 PRINTF_P(PSTR("********Jackdaw is continuously broadcasting*******\n\r")); 00501 #if CONVERTTXPOWER 00502 PRINTF_P(PSTR("*********on channel %2d with power "),rf230_get_channel()); 00503 printtxpower(); 00504 PRINTF_P(PSTR("*********\n\r")); 00505 #else 00506 PRINTF_P(PSTR("************on channel %2d with power %2d************\n\r"),rf230_get_channel(),rf230_get_txpower()); 00507 #endif 00508 PRINTF_P(PSTR("Press any key to stop.\n\r")); 00509 watchdog_periodic(); 00510 usbstick_mode.sneeze = 1; 00511 } 00512 break; 00513 #endif 00514 00515 case 'n': 00516 PRINTF_P(PSTR("Jackdaw now in network mode\n\r")); 00517 usbstick_mode.sendToRf = 1; 00518 usbstick_mode.translate = 1; 00519 #if RF230BB 00520 rf230_set_channel(rf230_get_channel()); 00521 #else 00522 radio_set_trx_state(RX_AACK_ON); //TODO: Use startup state which may be RX_ON 00523 #endif 00524 break; 00525 00526 case '6': 00527 if (usbstick_mode.sicslowpan) { 00528 PRINTF_P(PSTR("Jackdaw does not perform 6lowpan translation\n\r")); 00529 usbstick_mode.sicslowpan = 0; 00530 } else { 00531 PRINTF_P(PSTR("Jackdaw now performs 6lowpan translations\n\r")); 00532 usbstick_mode.sicslowpan = 1; 00533 } 00534 00535 break; 00536 00537 case 'r': 00538 if (usbstick_mode.raw) { 00539 PRINTF_P(PSTR("Jackdaw does not capture raw frames\n\r")); 00540 usbstick_mode.raw = 0; 00541 } else { 00542 PRINTF_P(PSTR("Jackdaw now captures raw frames\n\r")); 00543 usbstick_mode.raw = 1; 00544 } 00545 break; 00546 #if USB_CONF_RS232 00547 case 'd': 00548 if (usbstick_mode.debugOn) { 00549 PRINTF_P(PSTR("Jackdaw does not output debug strings\n\r")); 00550 usbstick_mode.debugOn = 0; 00551 } else { 00552 PRINTF_P(PSTR("Jackdaw now outputs debug strings\n\r")); 00553 usbstick_mode.debugOn = 1; 00554 } 00555 break; 00556 #endif 00557 00558 00559 case 'c': 00560 #if RF230BB 00561 PRINTF_P(PSTR("\nSelect 802.15.4 Channel in range 11-26 [%d]: "), rf230_get_channel()); 00562 #else 00563 PRINTF_P(PSTR("\nSelect 802.15.4 Channel in range 11-26 [%d]: "), radio_get_operating_channel()); 00564 #endif 00565 menustate = channel; 00566 channel_string_i = 0; 00567 break; 00568 00569 case 'p': 00570 #if RF230BB 00571 PRINTF_P(PSTR("\nSelect transmit power (0=+3dBm 15=-17.2dBm) [%d]: "), rf230_get_txpower()); 00572 #else 00573 // PRINTF_P(PSTR("\nSelect transmit power (0=+3dBm 15=-17.2dBm) [%d]: "), ?_power());; 00574 #endif 00575 menustate = txpower; 00576 channel_string_i = 0; 00577 break; 00578 00579 00580 #if UIP_CONF_IPV6_RPL 00581 #include "rpl.h" 00582 extern uip_ds6_nbr_t uip_ds6_nbr_cache[]; 00583 extern uip_ds6_route_t uip_ds6_routing_table[]; 00584 extern uip_ds6_netif_t uip_ds6_if; 00585 case 'N': 00586 { uint8_t i,j; 00587 PRINTF_P(PSTR("\n\rAddresses [%u max]\n\r"),UIP_DS6_ADDR_NB); 00588 for (i=0;i<UIP_DS6_ADDR_NB;i++) { 00589 if (uip_ds6_if.addr_list[i].isused) { 00590 ipaddr_add(&uip_ds6_if.addr_list[i].ipaddr); 00591 PRINTF_P(PSTR("\n\r")); 00592 } 00593 } 00594 PRINTF_P(PSTR("\n\rNeighbors [%u max]\n\r"),UIP_DS6_NBR_NB); 00595 for(i = 0,j=1; i < UIP_DS6_NBR_NB; i++) { 00596 if(uip_ds6_nbr_cache[i].isused) { 00597 ipaddr_add(&uip_ds6_nbr_cache[i].ipaddr); 00598 PRINTF_P(PSTR("\n\r")); 00599 j=0; 00600 } 00601 } 00602 if (j) PRINTF_P(PSTR(" <none>")); 00603 PRINTF_P(PSTR("\n\rRoutes [%u max]\n\r"),UIP_DS6_ROUTE_NB); 00604 for(i = 0,j=1; i < UIP_DS6_ROUTE_NB; i++) { 00605 if(uip_ds6_routing_table[i].isused) { 00606 ipaddr_add(&uip_ds6_routing_table[i].ipaddr); 00607 PRINTF_P(PSTR("/%u (via "), uip_ds6_routing_table[i].length); 00608 ipaddr_add(&uip_ds6_routing_table[i].nexthop); 00609 if(uip_ds6_routing_table[i].state.lifetime < 600) { 00610 PRINTF_P(PSTR(") %lus\n\r"), uip_ds6_routing_table[i].state.lifetime); 00611 } else { 00612 PRINTF_P(PSTR(")\n\r")); 00613 } 00614 j=0; 00615 } 00616 } 00617 if (j) PRINTF_P(PSTR(" <none>")); 00618 PRINTF_P(PSTR("\n\r---------\n\r")); 00619 break; 00620 } 00621 00622 case 'G': 00623 PRINTF_P(PSTR("Global repair returns %d\n\r"),rpl_repair_root(RPL_DEFAULT_INSTANCE)); 00624 break; 00625 00626 case 'L': 00627 rpl_local_repair(rpl_get_any_dag()); 00628 PRINTF_P(PSTR("Local repair initiated\n\r")); 00629 break; 00630 00631 case 'Z': //zap the routing table 00632 { uint8_t i; 00633 for (i = 0; i < UIP_DS6_ROUTE_NB; i++) { 00634 uip_ds6_routing_table[i].isused=0; 00635 } 00636 PRINTF_P(PSTR("Routing table cleared!\n\r")); 00637 break; 00638 } 00639 #endif 00640 00641 case 'm': 00642 PRINTF_P(PSTR("Currently Jackdaw:\n\r * Will ")); 00643 if (usbstick_mode.sendToRf == 0) { PRINTF_P(PSTR("not "));} 00644 PRINTF_P(PSTR("send data over RF\n\r * Will ")); 00645 if (usbstick_mode.translate == 0) { PRINTF_P(PSTR("not "));} 00646 PRINTF_P(PSTR("change link-local addresses inside IP messages\n\r * Will ")); 00647 if (usbstick_mode.sicslowpan == 0) { PRINTF_P(PSTR("not "));} 00648 PRINTF_P(PSTR("decompress 6lowpan headers\n\r * Will ")); 00649 if (usbstick_mode.raw == 0) { PRINTF_P(PSTR("not "));} 00650 00651 #if USB_CONF_RS232 00652 PRINTF_P(PSTR("Output raw 802.15.4 frames\n\r * Will ")); 00653 if (usbstick_mode.debugOn == 0) { PRINTF_P(PSTR("not "));} 00654 PRINTF_P(PSTR("Output RS232 debug strings\n\r")); 00655 #else 00656 PRINTF_P(PSTR("Output raw 802.15.4 frames\n\r")); 00657 #endif 00658 00659 PRINTF_P(PSTR(" * USB Ethernet MAC: %02x:%02x:%02x:%02x:%02x:%02x\n"), 00660 ((uint8_t *)&usb_ethernet_addr)[0], 00661 ((uint8_t *)&usb_ethernet_addr)[1], 00662 ((uint8_t *)&usb_ethernet_addr)[2], 00663 ((uint8_t *)&usb_ethernet_addr)[3], 00664 ((uint8_t *)&usb_ethernet_addr)[4], 00665 ((uint8_t *)&usb_ethernet_addr)[5] 00666 ); 00667 extern uint64_t macLongAddr; 00668 PRINTF_P(PSTR(" * 802.15.4 EUI-64: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n"), 00669 ((uint8_t *)&macLongAddr)[0], 00670 ((uint8_t *)&macLongAddr)[1], 00671 ((uint8_t *)&macLongAddr)[2], 00672 ((uint8_t *)&macLongAddr)[3], 00673 ((uint8_t *)&macLongAddr)[4], 00674 ((uint8_t *)&macLongAddr)[5], 00675 ((uint8_t *)&macLongAddr)[6], 00676 ((uint8_t *)&macLongAddr)[7] 00677 ); 00678 #if RF230BB 00679 #if CONVERTTXPOWER 00680 PRINTF_P(PSTR(" * Operates on channel %d with TX power "),rf230_get_channel()); 00681 printtxpower(); 00682 PRINTF_P(PSTR("\n\r")); 00683 #else //just show the raw value 00684 PRINTF_P(PSTR(" * Operates on channel %d\n\r"), rf230_get_channel()); 00685 PRINTF_P(PSTR(" * TX Power(0=+3dBm, 15=-17.2dBm): %d\n\r"), rf230_get_txpower()); 00686 #endif 00687 if (rf230_smallest_rssi) { 00688 PRINTF_P(PSTR(" * Current/Last/Smallest RSSI: %d/%d/%ddBm\n\r"), -91+(rf230_rssi()-1), -91+(rf230_last_rssi-1),-91+(rf230_smallest_rssi-1)); 00689 rf230_smallest_rssi=0; 00690 } else { 00691 PRINTF_P(PSTR(" * Current/Last/Smallest RSSI: %d/%d/--dBm\n\r"), -91+(rf230_rssi()-1), -91+(rf230_last_rssi-1)); 00692 } 00693 00694 #else /* RF230BB */ 00695 PRINTF_P(PSTR(" * Operates on channel %d\n\r"), radio_get_operating_channel()); 00696 PRINTF_P(PSTR(" * TX Power Level: 0x%02X\n\r"), radio_get_tx_power_level()); 00697 { 00698 PRINTF_P(PSTR(" * Current RSSI: ")); 00699 int8_t rssi = 0; 00700 if(radio_get_rssi_value(&rssi)==RADIO_SUCCESS) 00701 PRINTF_P(PSTR("%ddB\n\r"), -91+3*(rssi-1)); 00702 else 00703 PRINTF_P(PSTR("Unknown\n\r")); 00704 } 00705 00706 #endif /* RF230BB */ 00707 00708 PRINTF_P(PSTR(" * Configuration: %d, USB<->ETH is "), usb_configuration_nb); 00709 if (usb_eth_is_active == 0) PRINTF_P(PSTR("not ")); 00710 PRINTF_P(PSTR("active\n\r")); 00711 00712 #if CONFIG_STACK_MONITOR 00713 /* See contiki-raven-main.c for initialization of the magic numbers */ 00714 { 00715 extern uint16_t __bss_end; 00716 uint16_t p=(uint16_t)&__bss_end; 00717 do { 00718 if (*(uint16_t *)p != 0x4242) { 00719 printf_P(PSTR(" * Never-used stack > %d bytes\n\r"),p-(uint16_t)&__bss_end); 00720 break; 00721 } 00722 p+=100; 00723 } while (p<RAMEND-100); 00724 } 00725 #endif 00726 00727 break; 00728 00729 case 'e': 00730 PRINTF_P(PSTR("Energy Scan:\n")); 00731 uart_usb_flush(); 00732 { 00733 uint8_t i; 00734 uint16_t j; 00735 #if RF230BB 00736 uint8_t previous_channel = rf230_get_channel(); 00737 #else // RF230BB 00738 uint8_t previous_channel = radio_get_operating_channel(); 00739 #endif 00740 int8_t RSSI, maxRSSI[17]; 00741 uint16_t accRSSI[17]; 00742 00743 bzero((void*)accRSSI,sizeof(accRSSI)); 00744 bzero((void*)maxRSSI,sizeof(maxRSSI)); 00745 00746 for(j=0;j<(1<<12);j++) { 00747 for(i=11;i<=26;i++) { 00748 #if RF230BB 00749 rf230_listen_channel(i); 00750 #else // RF230BB 00751 radio_set_operating_channel(i); 00752 #endif 00753 _delay_us(3*10); 00754 #if RF230BB 00755 RSSI = rf230_rssi(); //multiplies rssi register by 3 for consistency with energy-detect register 00756 #else // RF230BB 00757 radio_get_rssi_value(&RSSI); 00758 RSSI*=3; 00759 #endif 00760 maxRSSI[i-11]=Max(maxRSSI[i-11],RSSI); 00761 accRSSI[i-11]+=RSSI; 00762 } 00763 if(j&(1<<7)) { 00764 Led3_on(); 00765 if(!(j&((1<<7)-1))) { 00766 PRINTF_P(PSTR(".")); 00767 uart_usb_flush(); 00768 } 00769 } 00770 else 00771 Led3_off(); 00772 watchdog_periodic(); 00773 } 00774 #if RF230BB 00775 rf230_set_channel(previous_channel); 00776 #else // RF230BB 00777 radio_set_operating_channel(previous_channel); 00778 #endif 00779 PRINTF_P(PSTR("\n")); 00780 for(i=11;i<=26;i++) { 00781 uint8_t activity=Min(maxRSSI[i-11],accRSSI[i-11]/(1<<7)); 00782 PRINTF_P(PSTR(" %d: %02ddB "),i, -91+(maxRSSI[i-11]-1)); 00783 for(;activity--;maxRSSI[i-11]--) { 00784 PRINTF_P(PSTR("#")); 00785 } 00786 for(;maxRSSI[i-11]>0;maxRSSI[i-11]--) { 00787 PRINTF_P(PSTR(":")); 00788 } 00789 PRINTF_P(PSTR("\n")); 00790 uart_usb_flush(); 00791 } 00792 00793 } 00794 PRINTF_P(PSTR("Done.\n")); 00795 uart_usb_flush(); 00796 00797 break; 00798 00799 00800 case 'D': 00801 { 00802 PRINTF_P(PSTR("Entering DFU Mode...\n\r")); 00803 uart_usb_flush(); 00804 Leds_on(); 00805 for(i = 0; i < 10; i++)_delay_ms(100); 00806 Leds_off(); 00807 Jump_To_Bootloader(); 00808 } 00809 break; 00810 case 'R': 00811 { 00812 PRINTF_P(PSTR("Resetting...\n\r")); 00813 uart_usb_flush(); 00814 Leds_on(); 00815 for(i = 0; i < 10; i++)_delay_ms(100); 00816 Usb_detach(); 00817 for(i = 0; i < 20; i++)_delay_ms(100); 00818 watchdog_reboot(); 00819 } 00820 break; 00821 00822 #if USB_CONF_STORAGE 00823 case 'u': 00824 00825 //Mass storage mode 00826 usb_mode = mass_storage; 00827 00828 //No more serial port 00829 stdout = NULL; 00830 #if USB_CONF_RS232 00831 // usb_stdout = NULL; 00832 #endif 00833 00834 //RNDIS is over 00835 rndis_state = rndis_uninitialized; 00836 Leds_off(); 00837 00838 //Deatch USB 00839 Usb_detach(); 00840 00841 //Wait a few seconds 00842 for(i = 0; i < 50; i++) 00843 watchdog_periodic(); 00844 _delay_ms(100); 00845 00846 //Attach USB 00847 Usb_attach(); 00848 00849 00850 break; 00851 #endif 00852 00853 default: 00854 PRINTF_P(PSTR("%c is not a valid option! h for menu\n\r"), c); 00855 break; 00856 } 00857 00858 00859 } 00860 00861 return; 00862 00863 } 00864 00865 00866 /** 00867 @brief This will enable the VCP_TRX_END LED for a period 00868 */ 00869 void vcptx_end_led(void) 00870 { 00871 Led3_on(); 00872 led3_timer = 5; 00873 } 00874 /** @} */ 00875