00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
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
00086
00087
00088 #define bzero(ptr,size) memset(ptr,0,size)
00089
00090
00091
00092
00093 #define IAD_TIMEOUT_DETACH 300
00094 #define IAD_TIMEOUT_ATTACH 600
00095
00096
00097
00098
00099 void menu_print(void);
00100 void menu_process(char c);
00101
00102 extern char usb_busy;
00103
00104
00105 extern U8 tx_counter;
00106
00107
00108 uint8_t led3_timer;
00109
00110
00111
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
00137
00138
00139
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
00152 if (led3_timer) led3_timer--;
00153 else Led3_off();
00154
00155 if(Is_device_enumerated()) {
00156
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
00166 } else {
00167 stdout = previous_stdout;
00168 }
00169 #if USB_CONF_RS232
00170 usb_stdout=stdout;
00171 #endif
00172 }
00173
00174
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());
00187 }
00188 #if USB_CONF_RS232
00189 if (usbstick_mode.debugOn) {
00190 stdout=rs232_stdout;
00191 } else {
00192 stdout=NULL;
00193 }
00194 #endif
00195 }
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 }
00208
00209 PROCESS_END();
00210 }
00211
00212
00213
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
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
00275
00276 void menu_process(char c)
00277 {
00278
00279 static enum menustate_enum
00280 {
00281 normal,
00282 channel,
00283 txpower
00284 } menustate = normal;
00285
00286 static char channel_string[3];
00287 static uint8_t channel_string_i;
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
00348
00349 putc('\a', stdout);
00350
00351 break;
00352 }
00353 putc(c, stdout);
00354
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(" "));
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
00420
00421 putc('\a', stdout);
00422
00423 break;
00424 }
00425 putc(c, stdout);
00426
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
00441
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
00465
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);
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
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_dag(rpl_get_dag(RPL_ANY_INSTANCE)));
00624 break;
00625
00626 case 'L':
00627 rpl_local_repair(rpl_get_dag(RPL_ANY_INSTANCE));
00628 PRINTF_P(PSTR("Local repair initiated\n\r"));
00629 break;
00630
00631 case 'Z':
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
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
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
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();
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
00826 usb_mode = mass_storage;
00827
00828
00829 stdout = NULL;
00830 #if USB_CONF_RS232
00831
00832 #endif
00833
00834
00835 rndis_state = rndis_uninitialized;
00836 Leds_off();
00837
00838
00839 Usb_detach();
00840
00841
00842 for(i = 0; i < 50; i++)
00843 watchdog_periodic();
00844 _delay_ms(100);
00845
00846
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
00868
00869 void vcptx_end_led(void)
00870 {
00871 Led3_on();
00872 led3_timer = 5;
00873 }
00874
00875