56 #include "serial/uart_usb_lib.h"
59 #include "sicslow_ethernet.h"
68 #include "dev/watchdog.h"
71 #include "bootloader.h"
73 #include <avr/pgmspace.h>
74 #include <avr/eeprom.h>
76 #include <util/delay.h>
85 #if JACKDAW_CONF_USE_SETTINGS
89 #define BUF ((struct uip_eth_hdr *)&uip_buf[0])
91 #define PRINTF_P printf_P
96 #define bzero(ptr,size) memset(ptr,0,size)
101 #define IAD_TIMEOUT_DETACH 300
102 #define IAD_TIMEOUT_ATTACH 600
110 extern char usb_busy;
123 static uint8_t
timer = 0;
126 #define CONVERTTXPOWER 1
127 #if CONVERTTXPOWER //adds ~120 bytes to program flash size
128 const char txonesdigit[16] PROGMEM = {
'3',
'2',
'2',
'1',
'1',
'0',
'0',
'1',
'2',
'3',
'4',
'5',
'7',
'9',
'2',
'7'};
129 const char txtenthsdigit[16] PROGMEM = {
'0',
'6',
'1',
'6',
'1',
'5',
'2',
'2',
'2',
'2',
'2',
'2',
'2',
'2',
'2',
'2'};
130 static void printtxpower(
void) {
131 uint8_t power=rf230_get_txpower()&0xf;
132 char sign=(power<6?
'+':
'-');
133 char tens=(power>14?
'1':
'0');
134 char ones=pgm_read_byte(&txonesdigit[power]);
135 char tenths=pgm_read_byte(&txtenthsdigit[power]);
136 if (tens==
'0') {tens=sign;sign=
' ';}
137 PRINTF_P(PSTR(
"%c%c%c.%cdBm"),sign,tens,ones,tenths);
141 PROCESS(cdc_process,
"CDC serial process");
154 static FILE *rs232_stdout,*usb_stdout;
167 static FILE* previous_stdout;
170 previous_stdout = stdout;
172 uart_usb_set_stdout();
175 stdout = previous_stdout;
197 if (usbstick_mode.debugOn) {
225 PRINTF_P(PSTR(
"\n\r*********** Jackdaw Menu **********\n\r"));
226 PRINTF_P(PSTR(
" [Built "__DATE__
"] \n\r"));
228 PRINTF_P(PSTR(
"* m Print current mode *\n\r"));
229 PRINTF_P(PSTR(
"* s Set to sniffer mode *\n\r"));
230 PRINTF_P(PSTR(
"* n Set to network mode *\n\r"));
231 PRINTF_P(PSTR(
"* c Set RF channel *\n\r"));
232 PRINTF_P(PSTR(
"* p Set RF power *\n\r"));
233 PRINTF_P(PSTR(
"* 6 Toggle 6lowpan *\n\r"));
234 PRINTF_P(PSTR(
"* r Toggle raw mode *\n\r"));
236 PRINTF_P(PSTR(
"* d Toggle RS232 output *\n\r"));
238 #if RF230BB && RF230_CONF_SNEEZER
239 PRINTF_P(PSTR(
"* S Enable sneezer mode *\n\r"));
241 #if UIP_CONF_IPV6_RPL
242 PRINTF_P(PSTR(
"* N RPL Neighbors *\n\r"));
243 PRINTF_P(PSTR(
"* G RPL Global Repair *\n\r"));
245 PRINTF_P(PSTR(
"* e Energy Scan *\n\r"));
247 PRINTF_P(PSTR(
"* u Switch to mass-storage*\n\r"));
249 if(bootloader_is_present())
250 PRINTF_P(PSTR(
"* D Switch to DFU mode *\n\r"));
251 PRINTF_P(PSTR(
"* R Reset (via WDT) *\n\r"));
252 PRINTF_P(PSTR(
"* h,? Print this menu *\n\r"));
253 PRINTF_P(PSTR(
"* *\n\r"));
254 PRINTF_P(PSTR(
"* Make selection at any time by *\n\r"));
255 PRINTF_P(PSTR(
"* pressing your choice on keyboard*\n\r"));
256 PRINTF_P(PSTR(
"***********************************\n\r"));
259 #if UIP_CONF_IPV6_RPL
261 ipaddr_add(
const uip_ipaddr_t *
addr)
265 for(i = 0, f = 0; i <
sizeof(uip_ipaddr_t); i += 2) {
266 a = (addr->u8[i] << 8) + addr->u8[i + 1];
267 if(a == 0 && f >= 0) {
268 if(f++ == 0) PRINTF_P(PSTR(
"::"));
275 PRINTF_P(PSTR(
"%x"),a);
287 static enum menustate_enum
292 } menustate = normal;
294 static char channel_string[3];
295 static uint8_t channel_string_i;
299 if (menustate == channel) {
305 if (channel_string_i) {
306 channel_string[channel_string_i] = 0;
307 tempchannel = atoi(channel_string);
310 if ((tempchannel < 11) || (tempchannel > 26)) {
311 PRINTF_P(PSTR(
"\n\rInvalid input\n\r"));
313 rf230_set_channel(tempchannel);
316 PRINTF_P(PSTR(
"\n\rInvalid input\n\r"));
319 #if JACKDAW_CONF_USE_SETTINGS
321 PRINTF_P(PSTR(
"\n\rChannel changed to %d and stored in EEPROM.\n\r"),tempchannel);
323 PRINTF_P(PSTR(
"\n\rChannel changed to %d, but unable to store in EEPROM!\n\r"),tempchannel);
326 PRINTF_P(PSTR(
"\n\rChannel changed to %d.\n\r"),tempchannel);
330 PRINTF_P(PSTR(
"\n\rChannel unchanged.\n\r"));
338 if (channel_string_i) {
340 PRINTF_P(PSTR(
"\b \b"));
354 if (channel_string_i > 1) {
364 channel_string[channel_string_i] = c;
371 }
else if (menustate == txpower) {
377 if (channel_string_i) {
378 channel_string[channel_string_i] = 0;
379 tempchannel = atoi(channel_string);
381 if ((tempchannel < 0) || (tempchannel > 15)) {
382 PRINTF_P(PSTR(
"\n\rInvalid input\n\r"));
385 rf230_set_txpower(tempchannel);
388 PRINTF_P(PSTR(
"\n\rInvalid input\n\r"));
391 #if JACKDAW_CONF_USE_SETTINGS
393 PRINTF_P(PSTR(
"\n\rTransmit power changed to %d, and stored in EEPROM.\n\r"),tempchannel);
395 PRINTF_P(PSTR(
"\n\rTransmit power changed to %d, but unable to store in EEPROM!\n\r"),tempchannel);
398 PRINTF_P(PSTR(
"\n\rTransmit power changed to %d.\n\r"),tempchannel);
402 PRINTF_P(PSTR(
"\n\rTransmit power unchanged.\n\r"));
410 if (channel_string_i) {
412 PRINTF_P(PSTR(
"\b \b"));
426 if (channel_string_i > 1) {
436 channel_string[channel_string_i] = c;
450 if (usbstick_mode.sneeze) c=
'S';
462 PRINTF_P(PSTR(
"Bringing interface down\n\r"));
463 usb_eth_set_active(0);
467 PRINTF_P(PSTR(
"Bringing interface up\n\r"));
468 usb_eth_set_active(1);
470 #if JACKDAW_CONF_RANDOM_MAC
474 PRINTF_P(PSTR(
"RNG Output: "));
476 uint8_t value = rng_get_uint8();
481 PRINTF_P(PSTR(
"\n\r"));
488 PRINTF_P(PSTR(
"Jackdaw now in sniffer mode\n\r"));
489 usbstick_mode.sendToRf = 0;
490 usbstick_mode.translate = 0;
492 rf230_listen_channel(rf230_get_channel());
498 #if RF230BB && RF230_CONF_SNEEZER
500 if (usbstick_mode.sneeze) {
502 PRINTF_P(PSTR(
"Jackdaw now behaving itself.\n\r"));
503 usbstick_mode.sneeze = 0;
505 if (rf230_get_txpower()<3)
506 PRINTF_P(PSTR(
"*****WARNING Radio may overheat in this mode*******\n\r"));
507 rf230_start_sneeze();
508 PRINTF_P(PSTR(
"********Jackdaw is continuously broadcasting*******\n\r"));
510 PRINTF_P(PSTR(
"*********on channel %2d with power "),rf230_get_channel());
512 PRINTF_P(PSTR(
"*********\n\r"));
514 PRINTF_P(PSTR(
"************on channel %2d with power %2d************\n\r"),rf230_get_channel(),rf230_get_txpower());
516 PRINTF_P(PSTR(
"Press any key to stop.\n\r"));
518 usbstick_mode.sneeze = 1;
524 PRINTF_P(PSTR(
"Jackdaw now in network mode\n\r"));
525 usbstick_mode.sendToRf = 1;
526 usbstick_mode.translate = 1;
528 rf230_set_channel(rf230_get_channel());
535 if (usbstick_mode.sicslowpan) {
536 PRINTF_P(PSTR(
"Jackdaw does not perform 6lowpan translation\n\r"));
537 usbstick_mode.sicslowpan = 0;
539 PRINTF_P(PSTR(
"Jackdaw now performs 6lowpan translations\n\r"));
540 usbstick_mode.sicslowpan = 1;
546 if (usbstick_mode.raw) {
547 PRINTF_P(PSTR(
"Jackdaw does not capture raw frames\n\r"));
548 usbstick_mode.raw = 0;
550 PRINTF_P(PSTR(
"Jackdaw now captures raw frames\n\r"));
551 usbstick_mode.raw = 1;
556 if (usbstick_mode.debugOn) {
557 PRINTF_P(PSTR(
"Jackdaw does not output debug strings\n\r"));
558 usbstick_mode.debugOn = 0;
560 PRINTF_P(PSTR(
"Jackdaw now outputs debug strings\n\r"));
561 usbstick_mode.debugOn = 1;
569 PRINTF_P(PSTR(
"\nSelect 802.15.4 Channel in range 11-26 [%d]: "), rf230_get_channel());
574 channel_string_i = 0;
579 PRINTF_P(PSTR(
"\nSelect transmit power (0=+3dBm 15=-17.2dBm) [%d]: "), rf230_get_txpower());
584 channel_string_i = 0;
588 #if UIP_CONF_IPV6_RPL
593 PRINTF_P(PSTR(
"\n\rAddresses [%u max]\n\r"),UIP_DS6_ADDR_NB);
594 for (i=0;i<UIP_DS6_ADDR_NB;i++) {
595 if (uip_ds6_if.addr_list[i].isused) {
596 ipaddr_add(&uip_ds6_if.addr_list[i].ipaddr);
597 PRINTF_P(PSTR(
"\n\r"));
600 PRINTF_P(PSTR(
"\n\rNeighbors [%u max]\n\r"),NBR_TABLE_MAX_NEIGHBORS);
602 for(nbr = nbr_table_head(ds6_neighbors);
604 nbr = nbr_table_next(ds6_neighbors, nbr)) {
605 ipaddr_add(&nbr->ipaddr);
606 PRINTF_P(PSTR(
"\n\r"));
609 if (j) PRINTF_P(PSTR(
" <none>"));
610 PRINTF_P(PSTR(
"\n\rRoutes [%u max]\n\r"),UIP_DS6_ROUTE_NB);
612 for(route = uip_ds6_route_head();
614 route = uip_ds6_route_next(route)) {
615 ipaddr_add(&route->ipaddr);
616 PRINTF_P(PSTR(
"/%u (via "), route->length);
617 ipaddr_add(uip_ds6_route_nexthop(route));
618 if(route->state.lifetime < 600) {
619 PRINTF_P(PSTR(
") %lus\n\r"), route->state.lifetime);
621 PRINTF_P(PSTR(
")\n\r"));
625 if (j) PRINTF_P(PSTR(
" <none>"));
626 PRINTF_P(PSTR(
"\n\r---------\n\r"));
631 PRINTF_P(PSTR(
"Global repair returns %d\n\r"),rpl_repair_root(RPL_DEFAULT_INSTANCE));
635 rpl_local_repair(rpl_get_any_dag());
636 PRINTF_P(PSTR(
"Local repair initiated\n\r"));
640 PRINTF_P(PSTR(
"Not implemented.\n\r"));
645 PRINTF_P(PSTR(
"Currently Jackdaw:\n\r * Will "));
646 if (usbstick_mode.sendToRf == 0) { PRINTF_P(PSTR(
"not "));}
647 PRINTF_P(PSTR(
"send data over RF\n\r * Will "));
648 if (usbstick_mode.translate == 0) { PRINTF_P(PSTR(
"not "));}
649 PRINTF_P(PSTR(
"change link-local addresses inside IP messages\n\r * Will "));
650 if (usbstick_mode.sicslowpan == 0) { PRINTF_P(PSTR(
"not "));}
651 PRINTF_P(PSTR(
"decompress 6lowpan headers\n\r * Will "));
652 if (usbstick_mode.raw == 0) { PRINTF_P(PSTR(
"not "));}
655 PRINTF_P(PSTR(
"Output raw 802.15.4 frames\n\r * Will "));
656 if (usbstick_mode.debugOn == 0) { PRINTF_P(PSTR(
"not "));}
657 PRINTF_P(PSTR(
"Output RS232 debug strings\n\r"));
659 PRINTF_P(PSTR(
"Output raw 802.15.4 frames\n\r"));
662 PRINTF_P(PSTR(
" * USB Ethernet MAC: %02x:%02x:%02x:%02x:%02x:%02x\n"),
663 ((uint8_t *)&usb_ethernet_addr)[0],
664 ((uint8_t *)&usb_ethernet_addr)[1],
665 ((uint8_t *)&usb_ethernet_addr)[2],
666 ((uint8_t *)&usb_ethernet_addr)[3],
667 ((uint8_t *)&usb_ethernet_addr)[4],
668 ((uint8_t *)&usb_ethernet_addr)[5]
671 PRINTF_P(PSTR(
" * 802.15.4 EUI-64: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n"),
672 ((uint8_t *)&macLongAddr)[0],
673 ((uint8_t *)&macLongAddr)[1],
674 ((uint8_t *)&macLongAddr)[2],
675 ((uint8_t *)&macLongAddr)[3],
676 ((uint8_t *)&macLongAddr)[4],
677 ((uint8_t *)&macLongAddr)[5],
678 ((uint8_t *)&macLongAddr)[6],
679 ((uint8_t *)&macLongAddr)[7]
683 PRINTF_P(PSTR(
" * Operates on channel %d with TX power "),rf230_get_channel());
685 PRINTF_P(PSTR(
"\n\r"));
686 #else //just show the raw value
687 PRINTF_P(PSTR(
" * Operates on channel %d\n\r"), rf230_get_channel());
688 PRINTF_P(PSTR(
" * TX Power(0=+3dBm, 15=-17.2dBm): %d\n\r"), rf230_get_txpower());
690 if (rf230_smallest_rssi) {
691 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));
692 rf230_smallest_rssi=0;
694 PRINTF_P(PSTR(
" * Current/Last/Smallest RSSI: %d/%d/--dBm\n\r"), -91+(rf230_rssi()-1), -91+(rf230_last_rssi-1));
701 PRINTF_P(PSTR(
" * Current RSSI: "));
704 PRINTF_P(PSTR(
"%ddB\n\r"), -91+3*(rssi-1));
706 PRINTF_P(PSTR(
"Unknown\n\r"));
712 if (usb_eth_is_active == 0) PRINTF_P(PSTR(
"not "));
713 PRINTF_P(PSTR(
"active\n\r"));
715 #if CONFIG_STACK_MONITOR
718 extern uint16_t __bss_end;
719 uint16_t p=(uint16_t)&__bss_end;
721 if (*(uint16_t *)p != 0x4242) {
722 printf_P(PSTR(
" * Never-used stack > %d bytes\n\r"),p-(uint16_t)&__bss_end);
726 }
while (p<RAMEND-100);
733 PRINTF_P(PSTR(
"Energy Scan:\n"));
739 uint8_t previous_channel = rf230_get_channel();
743 int8_t RSSI, maxRSSI[17];
744 uint16_t accRSSI[17];
746 bzero((
void*)accRSSI,
sizeof(accRSSI));
747 bzero((
void*)maxRSSI,
sizeof(maxRSSI));
749 for(j=0;j<(1<<12);j++) {
750 for(i=11;i<=26;i++) {
752 rf230_listen_channel(i);
763 maxRSSI[i-11]=MAX(maxRSSI[i-11],RSSI);
768 if(!(j&((1<<7)-1))) {
778 rf230_set_channel(previous_channel);
782 PRINTF_P(PSTR(
"\n"));
783 for(i=11;i<=26;i++) {
784 uint8_t activity=MIN(maxRSSI[i-11],accRSSI[i-11]/(1<<7));
785 PRINTF_P(PSTR(
" %d: %02ddB "),i, -91+(maxRSSI[i-11]-1));
786 for(;activity--;maxRSSI[i-11]--) {
789 for(;maxRSSI[i-11]>0;maxRSSI[i-11]--) {
792 PRINTF_P(PSTR(
"\n"));
797 PRINTF_P(PSTR(
"Done.\n"));
805 PRINTF_P(PSTR(
"Entering DFU Mode...\n\r"));
808 for(i = 0; i < 10; i++)_delay_ms(100);
810 Jump_To_Bootloader();
815 PRINTF_P(PSTR(
"Resetting...\n\r"));
818 for(i = 0; i < 10; i++)_delay_ms(100);
820 for(i = 0; i < 20; i++)_delay_ms(100);
829 usb_mode = mass_storage;
838 rndis_state = rndis_uninitialized;
845 for(i = 0; i < 50; i++)
857 PRINTF_P(PSTR(
"%c is not a valid option! h for menu\n\r"), c);
int uart_usb_putchar(int data_to_send)
This function fills the USB transmit buffer with the new data.
This file contains the USB driver routines.
U8 usb_configuration_nb
Public : (U8) usb_configuration_nb Store the number of the USB configuration used by the USB device w...
U8 tx_counter
Counter for USB Serial port.
bit uart_usb_test_hit(void)
This function checks if a character has been received on the USB bus.
radio_status_t radio_set_trx_state(uint8_t new_state)
This function will change the current state of the radio transceiver's internal state machine...
static uip_ds6_addr_t * addr
Pointer to a router list entry.
uint8_t radio_get_tx_power_level(void)
This function will read and return the output power level.
#define Usb_attach()
attaches to USB bus
Default definitions of C compiler quirk work-arounds.
The requested service was performed successfully.
void etimer_set(struct etimer *et, clock_time_t interval)
Set an event timer.
#define PROCESS_END()
Define the end of a process.
#define PROCESS(name, strname)
Declare a process.
char uart_usb_getchar(void)
This function reads one byte from the USB bus.
static struct etimer et
NIC receiver thread.
This file contains the user callback functions corresponding to the application.
void uart_usb_init(void)
Initializes the uart_usb library.
static uint8_t previous_uart_usb_control_line_state
previous configuration
This file contains radio driver code.
#define Usb_detach()
detaches from USB bus
An entry in the nbr cache.
radio_status_t radio_set_operating_channel(uint8_t channel)
This function will change the operating channel.
#define PROCESS_WAIT_EVENT_UNTIL(c)
Wait for an event to be posted to the process, with an extra condition.
static uip_ds6_route_t * route
The next route to use.
void watchdog_reboot(void)
Keeps control until the WDT throws a reset signal.
Interface structure (contains all the interface variables)
#define Is_device_enumerated()
Returns true when device connected and correctly enumerated with an host.
This file manages the CDC task for the virtual COM port.
#define NULL
The null pointer.
static uip_ds6_nbr_t * nbr
Pointer to llao option in uip_buf.
This file contains the usb parameters that uniquely identify the application through descriptor table...
This file manages the RNDIS task.
PROCESS_THREAD(cdc_process, ev, data_proc)
Communication Data Class (CDC) Process.
int etimer_expired(struct etimer *et)
Check if an event timer has expired.
uint8_t led3_timer
Timers for LEDs.
void watchdog_periodic(void)
Writes the WDT clear sequence.
void menu_print(void)
Print debug menu.
#define CLOCK_SECOND
A second, measured in system clock time.
#define SETTINGS_KEY_CHANNEL
radio_status_t radio_get_rssi_value(uint8_t *rssi)
This function returns the Received Signal Strength Indication.
uint8_t radio_get_operating_channel(void)
This function will return the channel used by the radio transceiver.
radio_status_t radio_set_tx_power_level(uint8_t power_level)
This function will change the output power level.
uip_ds6_netif_t uip_ds6_if
The single interface.
void vcptx_end_led(void)
This will enable the VCP_TRX_END LED for a period.
#define RX_AACK_ON
Constant RX_AACK_ON for sub-register SR_TRX_STATUS.
#define RX_ON
Constant RX_ON for sub-register SR_TRX_STATUS.
void uart_usb_flush(void)
This function sends the data stored in the USB transmit buffer.
An entry in the routing table.
uint64_t macLongAddr
Our own long address.
#define SETTINGS_KEY_TXPOWER
void menu_process(char c)
Process incomming char on debug port.
#define PROCESS_BEGIN()
Define the beginning of a process.