Contiki 3.x
cdc_task.c
Go to the documentation of this file.
1 /* This file has been prepared for Doxygen automatic documentation generation.*/
2 /*! \file platform/avr-ravenusb/cdc_task.c **********************************************************
3  *
4  * \brief
5  * Manages the CDC-ACM Virtual Serial Port Dataclass for the USB Device
6  *
7  * \addtogroup usbstick
8  *
9  * \author
10  * Colin O'Flynn <coflynn@newae.com>
11  *
12  ******************************************************************************/
13 /* Copyright (c) 2008 ATMEL Corporation
14  All rights reserved.
15 
16  Redistribution and use in source and binary forms, with or without
17  modification, are permitted provided that the following conditions are met:
18 
19  * Redistributions of source code must retain the above copyright
20  notice, this list of conditions and the following disclaimer.
21  * Redistributions in binary form must reproduce the above copyright
22  notice, this list of conditions and the following disclaimer in
23  the documentation and/or other materials provided with the
24  distribution.
25  * Neither the name of the copyright holders nor the names of
26  contributors may be used to endorse or promote products derived
27  from this software without specific prior written permission.
28 
29  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
30  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
33  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
34  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
36  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
37  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39  POSSIBILITY OF SUCH DAMAGE.
40 */
41 /**
42  \ingroup usbstick
43  \defgroup cdctask CDC Task
44  @{
45  */
46 
47 //_____ I N C L U D E S ___________________________________________________
48 
49 
50 #include "contiki.h"
51 #include "usb_drv.h"
52 #include "usb_descriptors.h"
53 #include "usb_specific_request.h"
54 #include "cdc_task.h"
55 #include "serial/uart_usb_lib.h"
56 #include "rndis/rndis_protocol.h"
57 #include "rndis/rndis_task.h"
58 #include "sicslow_ethernet.h"
59 #if RF230BB
60 #include "rf230bb.h"
61 #else
62 #include "radio.h"
63 #endif
64 
65 #include <stdio.h>
66 #include <stdlib.h>
67 #include "dev/watchdog.h"
68 #include "rng.h"
69 
70 #include "bootloader.h"
71 
72 #include <avr/pgmspace.h>
73 #include <avr/eeprom.h>
74 #include <avr/wdt.h>
75 #include <util/delay.h>
76 
77 #if JACKDAW_CONF_USE_SETTINGS
78 #include "settings.h"
79 #endif
80 
81 #define BUF ((struct uip_eth_hdr *)&uip_buf[0])
82 #define PRINTF printf
83 #define PRINTF_P printf_P
84 
85 //_____ M A C R O S ________________________________________________________
86 
87 
88 #define bzero(ptr,size) memset(ptr,0,size)
89 
90 //_____ D E F I N I T I O N S ______________________________________________
91 
92 
93 #define IAD_TIMEOUT_DETACH 300
94 #define IAD_TIMEOUT_ATTACH 600
95 
96 //_____ D E C L A R A T I O N S ____________________________________________
97 
98 
99 void menu_print(void);
100 void menu_process(char c);
101 
102 extern char usb_busy;
103 
104 //! Counter for USB Serial port
105 extern U8 tx_counter;
106 
107 //! Timers for LEDs
108 uint8_t led3_timer;
109 
110 
111 //! previous configuration
112 static uint8_t previous_uart_usb_control_line_state = 0;
113 
114 
115 static uint8_t timer = 0;
116 static struct etimer et;
117 
118 #define CONVERTTXPOWER 1
119 #if CONVERTTXPOWER //adds ~120 bytes to program flash size
120 const char txonesdigit[16] PROGMEM = {'3','2','2','1','1','0','0','1','2','3','4','5','7','9','2','7'};
121 const char txtenthsdigit[16] PROGMEM = {'0','6','1','6','1','5','2','2','2','2','2','2','2','2','2','2'};
122 static void printtxpower(void) {
123  uint8_t power=rf230_get_txpower()&0xf;
124  char sign=(power<6?'+':'-');
125  char tens=(power>14?'1':'0');
126  char ones=pgm_read_byte(&txonesdigit[power]);
127  char tenths=pgm_read_byte(&txtenthsdigit[power]);
128  if (tens=='0') {tens=sign;sign=' ';}
129  PRINTF_P(PSTR("%c%c%c.%cdBm"),sign,tens,ones,tenths);
130 }
131 #endif
132 
133 PROCESS(cdc_process, "CDC serial process");
134 
135 /**
136  * \brief Communication Data Class (CDC) Process
137  *
138  * This is the link between USB and the "good stuff". In this routine data
139  * is received and processed by CDC-ACM Class
140  */
141 PROCESS_THREAD(cdc_process, ev, data_proc)
142 {
143  PROCESS_BEGIN();
144 
145 #if USB_CONF_RS232
146  static FILE *rs232_stdout,*usb_stdout;
147  rs232_stdout=stdout;
148 #endif
149 
150  while(1) {
151  // turn off LED's if necessary
152  if (led3_timer) led3_timer--;
153  else Led3_off();
154 
155  if(Is_device_enumerated()) {
156  // If the configuration is different than the last time we checked...
157  if((uart_usb_get_control_line_state()&1)!=previous_uart_usb_control_line_state) {
158  previous_uart_usb_control_line_state = uart_usb_get_control_line_state()&1;
159  static FILE* previous_stdout;
160 
161  if(previous_uart_usb_control_line_state&1) {
162  previous_stdout = stdout;
163  uart_usb_init();
164  uart_usb_set_stdout();
165  // menu_print(); do this later
166  } else {
167  stdout = previous_stdout;
168  }
169 #if USB_CONF_RS232
170  usb_stdout=stdout;
171 #endif
172  }
173 
174  //Flush buffer if timeout
175  if(timer >= 4 && tx_counter!=0 ){
176  timer = 0;
177  uart_usb_flush();
178  } else {
179  timer++;
180  }
181 
182 #if USB_CONF_RS232
183  stdout=usb_stdout;
184 #endif
185  while (uart_usb_test_hit()){
186  menu_process(uart_usb_getchar()); // See what they want
187  }
188 #if USB_CONF_RS232
189  if (usbstick_mode.debugOn) {
190  stdout=rs232_stdout;
191  } else {
192  stdout=NULL;
193  }
194 #endif
195  }//if (Is_device_enumerated())
196 
197 
198 
199  if (USB_CONFIG_HAS_DEBUG_PORT(usb_configuration_nb)) {
200  etimer_set(&et, CLOCK_SECOND/80);
201  } else {
202  etimer_set(&et, CLOCK_SECOND);
203  }
204 
206 
207  } // while(1)
208 
209  PROCESS_END();
210 }
211 
212 /**
213  \brief Print debug menu
214  */
215 void menu_print(void)
216 {
217  PRINTF_P(PSTR("\n\r*********** Jackdaw Menu **********\n\r"));
218  PRINTF_P(PSTR(" [Built "__DATE__"] \n\r"));
219 // PRINTF_P(PSTR("* *\n\r"));
220  PRINTF_P(PSTR("* m Print current mode *\n\r"));
221  PRINTF_P(PSTR("* s Set to sniffer mode *\n\r"));
222  PRINTF_P(PSTR("* n Set to network mode *\n\r"));
223  PRINTF_P(PSTR("* c Set RF channel *\n\r"));
224  PRINTF_P(PSTR("* p Set RF power *\n\r"));
225  PRINTF_P(PSTR("* 6 Toggle 6lowpan *\n\r"));
226  PRINTF_P(PSTR("* r Toggle raw mode *\n\r"));
227 #if USB_CONF_RS232
228  PRINTF_P(PSTR("* d Toggle RS232 output *\n\r"));
229 #endif
230 #if RF230BB && RF230_CONF_SNEEZER
231  PRINTF_P(PSTR("* S Enable sneezer mode *\n\r"));
232 #endif
233 #if UIP_CONF_IPV6_RPL
234  PRINTF_P(PSTR("* N RPL Neighbors *\n\r"));
235  PRINTF_P(PSTR("* G RPL Global Repair *\n\r"));
236 #endif
237  PRINTF_P(PSTR("* e Energy Scan *\n\r"));
238 #if USB_CONF_STORAGE
239  PRINTF_P(PSTR("* u Switch to mass-storage*\n\r"));
240 #endif
241  if(bootloader_is_present())
242  PRINTF_P(PSTR("* D Switch to DFU mode *\n\r"));
243  PRINTF_P(PSTR("* R Reset (via WDT) *\n\r"));
244  PRINTF_P(PSTR("* h,? Print this menu *\n\r"));
245  PRINTF_P(PSTR("* *\n\r"));
246  PRINTF_P(PSTR("* Make selection at any time by *\n\r"));
247  PRINTF_P(PSTR("* pressing your choice on keyboard*\n\r"));
248  PRINTF_P(PSTR("***********************************\n\r"));
249 }
250 
251 #if UIP_CONF_IPV6_RPL
252 static void
253 ipaddr_add(const uip_ipaddr_t *addr)
254 {
255  uint16_t a;
256  int8_t i, f;
257  for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) {
258  a = (addr->u8[i] << 8) + addr->u8[i + 1];
259  if(a == 0 && f >= 0) {
260  if(f++ == 0) PRINTF_P(PSTR("::"));
261  } else {
262  if(f > 0) {
263  f = -1;
264  } else if(i > 0) {
265  PRINTF_P(PSTR(":"));
266  }
267  PRINTF_P(PSTR("%x"),a);
268  }
269  }
270 }
271 #endif
272 
273 /**
274  \brief Process incomming char on debug port
275  */
276 void menu_process(char c)
277 {
278 
279  static enum menustate_enum /* Defines an enumeration type */
280  {
281  normal,
282  channel,
283  txpower
284  } menustate = normal;
285 
286  static char channel_string[3];
287  static uint8_t channel_string_i;// = 0;
288 
289  int tempchannel;
290 
291  if (menustate == channel) {
292 
293  switch(c) {
294  case '\r':
295  case '\n':
296 
297  if (channel_string_i) {
298  channel_string[channel_string_i] = 0;
299  tempchannel = atoi(channel_string);
300 
301 #if RF230BB
302  if ((tempchannel < 11) || (tempchannel > 26)) {
303  PRINTF_P(PSTR("\n\rInvalid input\n\r"));
304  } else {
305  rf230_set_channel(tempchannel);
306 #else
307  if(radio_set_operating_channel(tempchannel)!=RADIO_SUCCESS) {
308  PRINTF_P(PSTR("\n\rInvalid input\n\r"));
309  } else {
310 #endif
311 #if JACKDAW_CONF_USE_SETTINGS
312  if(settings_set_uint8(SETTINGS_KEY_CHANNEL, tempchannel)==SETTINGS_STATUS_OK) {
313  PRINTF_P(PSTR("\n\rChannel changed to %d and stored in EEPROM.\n\r"),tempchannel);
314  } else {
315  PRINTF_P(PSTR("\n\rChannel changed to %d, but unable to store in EEPROM!\n\r"),tempchannel);
316  }
317 #else
318  PRINTF_P(PSTR("\n\rChannel changed to %d.\n\r"),tempchannel);
319 #endif
320  }
321  } else {
322  PRINTF_P(PSTR("\n\rChannel unchanged.\n\r"));
323  }
324 
325  menustate = normal;
326  break;
327 
328  case '\b':
329 
330  if (channel_string_i) {
331  channel_string_i--;
332  PRINTF_P(PSTR("\b \b"));
333  }
334  break;
335 
336  case '0':
337  case '1':
338  case '2':
339  case '3':
340  case '4':
341  case '5':
342  case '6':
343  case '7':
344  case '8':
345  case '9':
346  if (channel_string_i > 1) {
347  // This time the user has gone too far.
348  // Beep at them.
349  putc('\a', stdout);
350  //uart_usb_putchar('\a');
351  break;
352  }
353  putc(c, stdout);
354  //uart_usb_putchar(c);
355 
356  channel_string[channel_string_i] = c;
357  channel_string_i++;
358  break;
359 
360  default:
361  break;
362  }
363  } else if (menustate == txpower) {
364 
365  switch(c) {
366  case '\r':
367  case '\n':
368 
369  if (channel_string_i) {
370  channel_string[channel_string_i] = 0;
371  tempchannel = atoi(channel_string);
372 #if RF230BB
373  if ((tempchannel < 0) || (tempchannel > 15)) {
374  PRINTF_P(PSTR("\n\rInvalid input\n\r"));
375  } else {
376  PRINTF_P(PSTR(" ")); //for some reason needs a print here to clear the string input...
377  rf230_set_txpower(tempchannel);
378 #else
379  if(radio_set_tx_power_level(tempchannel)!=RADIO_SUCCESS) {
380  PRINTF_P(PSTR("\n\rInvalid input\n\r"));
381  } else {
382 #endif
383 #if JACKDAW_CONF_USE_SETTINGS
384  if(settings_set_uint8(SETTINGS_KEY_TXPOWER, tempchannel)==SETTINGS_STATUS_OK) {
385  PRINTF_P(PSTR("\n\rTransmit power changed to %d, and stored in EEPROM.\n\r"),tempchannel);
386  } else {
387  PRINTF_P(PSTR("\n\rTransmit power changed to %d, but unable to store in EEPROM!\n\r"),tempchannel);
388  }
389 #else
390  PRINTF_P(PSTR("\n\rTransmit power changed to %d.\n\r"),tempchannel);
391 #endif
392  }
393  } else {
394  PRINTF_P(PSTR("\n\rTransmit power unchanged.\n\r"));
395  }
396 
397  menustate = normal;
398  break;
399 
400  case '\b':
401 
402  if (channel_string_i) {
403  channel_string_i--;
404  PRINTF_P(PSTR("\b \b"));
405  }
406  break;
407 
408  case '0':
409  case '1':
410  case '2':
411  case '3':
412  case '4':
413  case '5':
414  case '6':
415  case '7':
416  case '8':
417  case '9':
418  if (channel_string_i > 1) {
419  // This time the user has gone too far.
420  // Beep at them.
421  putc('\a', stdout);
422  //uart_usb_putchar('\a');
423  break;
424  }
425  putc(c, stdout);
426  //uart_usb_putchar(c);
427 
428  channel_string[channel_string_i] = c;
429  channel_string_i++;
430  break;
431 
432  default:
433  break;
434  }
435 
436  } else {
437 
438  uint8_t i;
439 
440  /* Any attempt to read an RF230 register in sneeze mode (e.g. rssi) will hang the MCU */
441  /* So convert any command into a sneeze off */
442  if (usbstick_mode.sneeze) c='S';
443 
444  switch(c) {
445  case '\r':
446  case '\n':
447  break;
448 
449  case 'h':
450  case '?':
451  menu_print();
452  break;
453  case '-':
454  PRINTF_P(PSTR("Bringing interface down\n\r"));
455  usb_eth_set_active(0);
456  break;
457  case '=':
458  case '+':
459  PRINTF_P(PSTR("Bringing interface up\n\r"));
460  usb_eth_set_active(1);
461  break;
462 #if JACKDAW_CONF_RANDOM_MAC
463  case 'T':
464  // Test "strong" random number generator of R Quattlebaum
465  // This can potentially reboot the stick!
466  PRINTF_P(PSTR("RNG Output: "));
467  {
468  uint8_t value = rng_get_uint8();
469  uint8_t i;
470  for(i=0;i<8;i++) {
471  uart_usb_putchar(((value>>(7-i))&1)?'1':'0');
472  }
473  PRINTF_P(PSTR("\n\r"));
474  uart_usb_flush();
476  }
477  break;
478 #endif
479  case 's':
480  PRINTF_P(PSTR("Jackdaw now in sniffer mode\n\r"));
481  usbstick_mode.sendToRf = 0;
482  usbstick_mode.translate = 0;
483 #if RF230BB
484  rf230_listen_channel(rf230_get_channel());
485 #else
487 #endif
488  break;
489 
490 #if RF230BB && RF230_CONF_SNEEZER
491  case 'S':
492  if (usbstick_mode.sneeze) {
493  rf230_warm_reset();
494  PRINTF_P(PSTR("Jackdaw now behaving itself.\n\r"));
495  usbstick_mode.sneeze = 0;
496  } else {
497  if (rf230_get_txpower()<3)
498  PRINTF_P(PSTR("*****WARNING Radio may overheat in this mode*******\n\r"));
499  rf230_start_sneeze();
500  PRINTF_P(PSTR("********Jackdaw is continuously broadcasting*******\n\r"));
501 #if CONVERTTXPOWER
502  PRINTF_P(PSTR("*********on channel %2d with power "),rf230_get_channel());
503  printtxpower();
504  PRINTF_P(PSTR("*********\n\r"));
505 #else
506  PRINTF_P(PSTR("************on channel %2d with power %2d************\n\r"),rf230_get_channel(),rf230_get_txpower());
507 #endif
508  PRINTF_P(PSTR("Press any key to stop.\n\r"));
510  usbstick_mode.sneeze = 1;
511  }
512  break;
513 #endif
514 
515  case 'n':
516  PRINTF_P(PSTR("Jackdaw now in network mode\n\r"));
517  usbstick_mode.sendToRf = 1;
518  usbstick_mode.translate = 1;
519 #if RF230BB
520  rf230_set_channel(rf230_get_channel());
521 #else
522  radio_set_trx_state(RX_AACK_ON); //TODO: Use startup state which may be RX_ON
523 #endif
524  break;
525 
526  case '6':
527  if (usbstick_mode.sicslowpan) {
528  PRINTF_P(PSTR("Jackdaw does not perform 6lowpan translation\n\r"));
529  usbstick_mode.sicslowpan = 0;
530  } else {
531  PRINTF_P(PSTR("Jackdaw now performs 6lowpan translations\n\r"));
532  usbstick_mode.sicslowpan = 1;
533  }
534 
535  break;
536 
537  case 'r':
538  if (usbstick_mode.raw) {
539  PRINTF_P(PSTR("Jackdaw does not capture raw frames\n\r"));
540  usbstick_mode.raw = 0;
541  } else {
542  PRINTF_P(PSTR("Jackdaw now captures raw frames\n\r"));
543  usbstick_mode.raw = 1;
544  }
545  break;
546 #if USB_CONF_RS232
547  case 'd':
548  if (usbstick_mode.debugOn) {
549  PRINTF_P(PSTR("Jackdaw does not output debug strings\n\r"));
550  usbstick_mode.debugOn = 0;
551  } else {
552  PRINTF_P(PSTR("Jackdaw now outputs debug strings\n\r"));
553  usbstick_mode.debugOn = 1;
554  }
555  break;
556 #endif
557 
558 
559  case 'c':
560 #if RF230BB
561  PRINTF_P(PSTR("\nSelect 802.15.4 Channel in range 11-26 [%d]: "), rf230_get_channel());
562 #else
563  PRINTF_P(PSTR("\nSelect 802.15.4 Channel in range 11-26 [%d]: "), radio_get_operating_channel());
564 #endif
565  menustate = channel;
566  channel_string_i = 0;
567  break;
568 
569  case 'p':
570 #if RF230BB
571  PRINTF_P(PSTR("\nSelect transmit power (0=+3dBm 15=-17.2dBm) [%d]: "), rf230_get_txpower());
572 #else
573 // PRINTF_P(PSTR("\nSelect transmit power (0=+3dBm 15=-17.2dBm) [%d]: "), ?_power());;
574 #endif
575  menustate = txpower;
576  channel_string_i = 0;
577  break;
578 
579 
580 #if UIP_CONF_IPV6_RPL
581 #include "rpl.h"
582 extern uip_ds6_netif_t uip_ds6_if;
583  case 'N':
584  { uint8_t i,j;
585  uip_ds6_nbr_t *nbr;
586  PRINTF_P(PSTR("\n\rAddresses [%u max]\n\r"),UIP_DS6_ADDR_NB);
587  for (i=0;i<UIP_DS6_ADDR_NB;i++) {
588  if (uip_ds6_if.addr_list[i].isused) {
589  ipaddr_add(&uip_ds6_if.addr_list[i].ipaddr);
590  PRINTF_P(PSTR("\n\r"));
591  }
592  }
593  PRINTF_P(PSTR("\n\rNeighbors [%u max]\n\r"),NBR_TABLE_MAX_NEIGHBORS);
594 
595  for(nbr = nbr_table_head(ds6_neighbors);
596  nbr != NULL;
597  nbr = nbr_table_next(ds6_neighbors, nbr)) {
598  ipaddr_add(&nbr->ipaddr);
599  PRINTF_P(PSTR("\n\r"));
600  j=0;
601  }
602  if (j) PRINTF_P(PSTR(" <none>"));
603  PRINTF_P(PSTR("\n\rRoutes [%u max]\n\r"),UIP_DS6_ROUTE_NB);
604  uip_ds6_route_t *route;
605  for(route = uip_ds6_route_head();
606  route != NULL;
607  route = uip_ds6_route_next(r)) {
608  ipaddr_add(&route->ipaddr);
609  PRINTF_P(PSTR("/%u (via "), route->length);
610  ipaddr_add(uip_ds6_route_nexthop(route));
611  if(route->state.lifetime < 600) {
612  PRINTF_P(PSTR(") %lus\n\r"), route->state.lifetime);
613  } else {
614  PRINTF_P(PSTR(")\n\r"));
615  }
616  j=0;
617  }
618  if (j) PRINTF_P(PSTR(" <none>"));
619  PRINTF_P(PSTR("\n\r---------\n\r"));
620  break;
621  }
622 
623  case 'G':
624  PRINTF_P(PSTR("Global repair returns %d\n\r"),rpl_repair_root(RPL_DEFAULT_INSTANCE));
625  break;
626 
627  case 'L':
628  rpl_local_repair(rpl_get_any_dag());
629  PRINTF_P(PSTR("Local repair initiated\n\r"));
630  break;
631 
632  case 'Z': //zap the routing table
633  PRINTF_P(PSTR("Not implemented.\n\r"));
634  break;
635 #endif
636 
637  case 'm':
638  PRINTF_P(PSTR("Currently Jackdaw:\n\r * Will "));
639  if (usbstick_mode.sendToRf == 0) { PRINTF_P(PSTR("not "));}
640  PRINTF_P(PSTR("send data over RF\n\r * Will "));
641  if (usbstick_mode.translate == 0) { PRINTF_P(PSTR("not "));}
642  PRINTF_P(PSTR("change link-local addresses inside IP messages\n\r * Will "));
643  if (usbstick_mode.sicslowpan == 0) { PRINTF_P(PSTR("not "));}
644  PRINTF_P(PSTR("decompress 6lowpan headers\n\r * Will "));
645  if (usbstick_mode.raw == 0) { PRINTF_P(PSTR("not "));}
646 
647 #if USB_CONF_RS232
648  PRINTF_P(PSTR("Output raw 802.15.4 frames\n\r * Will "));
649  if (usbstick_mode.debugOn == 0) { PRINTF_P(PSTR("not "));}
650  PRINTF_P(PSTR("Output RS232 debug strings\n\r"));
651 #else
652  PRINTF_P(PSTR("Output raw 802.15.4 frames\n\r"));
653 #endif
654 
655  PRINTF_P(PSTR(" * USB Ethernet MAC: %02x:%02x:%02x:%02x:%02x:%02x\n"),
656  ((uint8_t *)&usb_ethernet_addr)[0],
657  ((uint8_t *)&usb_ethernet_addr)[1],
658  ((uint8_t *)&usb_ethernet_addr)[2],
659  ((uint8_t *)&usb_ethernet_addr)[3],
660  ((uint8_t *)&usb_ethernet_addr)[4],
661  ((uint8_t *)&usb_ethernet_addr)[5]
662  );
663  extern uint64_t macLongAddr;
664  PRINTF_P(PSTR(" * 802.15.4 EUI-64: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n"),
665  ((uint8_t *)&macLongAddr)[0],
666  ((uint8_t *)&macLongAddr)[1],
667  ((uint8_t *)&macLongAddr)[2],
668  ((uint8_t *)&macLongAddr)[3],
669  ((uint8_t *)&macLongAddr)[4],
670  ((uint8_t *)&macLongAddr)[5],
671  ((uint8_t *)&macLongAddr)[6],
672  ((uint8_t *)&macLongAddr)[7]
673  );
674 #if RF230BB
675 #if CONVERTTXPOWER
676  PRINTF_P(PSTR(" * Operates on channel %d with TX power "),rf230_get_channel());
677  printtxpower();
678  PRINTF_P(PSTR("\n\r"));
679 #else //just show the raw value
680  PRINTF_P(PSTR(" * Operates on channel %d\n\r"), rf230_get_channel());
681  PRINTF_P(PSTR(" * TX Power(0=+3dBm, 15=-17.2dBm): %d\n\r"), rf230_get_txpower());
682 #endif
683  if (rf230_smallest_rssi) {
684  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));
685  rf230_smallest_rssi=0;
686  } else {
687  PRINTF_P(PSTR(" * Current/Last/Smallest RSSI: %d/%d/--dBm\n\r"), -91+(rf230_rssi()-1), -91+(rf230_last_rssi-1));
688  }
689 
690 #else /* RF230BB */
691  PRINTF_P(PSTR(" * Operates on channel %d\n\r"), radio_get_operating_channel());
692  PRINTF_P(PSTR(" * TX Power Level: 0x%02X\n\r"), radio_get_tx_power_level());
693  {
694  PRINTF_P(PSTR(" * Current RSSI: "));
695  int8_t rssi = 0;
697  PRINTF_P(PSTR("%ddB\n\r"), -91+3*(rssi-1));
698  else
699  PRINTF_P(PSTR("Unknown\n\r"));
700  }
701 
702 #endif /* RF230BB */
703 
704  PRINTF_P(PSTR(" * Configuration: %d, USB<->ETH is "), usb_configuration_nb);
705  if (usb_eth_is_active == 0) PRINTF_P(PSTR("not "));
706  PRINTF_P(PSTR("active\n\r"));
707 
708 #if CONFIG_STACK_MONITOR
709 /* See contiki-raven-main.c for initialization of the magic numbers */
710 {
711 extern uint16_t __bss_end;
712 uint16_t p=(uint16_t)&__bss_end;
713  do {
714  if (*(uint16_t *)p != 0x4242) {
715  printf_P(PSTR(" * Never-used stack > %d bytes\n\r"),p-(uint16_t)&__bss_end);
716  break;
717  }
718  p+=100;
719  } while (p<RAMEND-100);
720 }
721 #endif
722 
723  break;
724 
725  case 'e':
726  PRINTF_P(PSTR("Energy Scan:\n"));
727  uart_usb_flush();
728  {
729  uint8_t i;
730  uint16_t j;
731 #if RF230BB
732  uint8_t previous_channel = rf230_get_channel();
733 #else // RF230BB
734  uint8_t previous_channel = radio_get_operating_channel();
735 #endif
736  int8_t RSSI, maxRSSI[17];
737  uint16_t accRSSI[17];
738 
739  bzero((void*)accRSSI,sizeof(accRSSI));
740  bzero((void*)maxRSSI,sizeof(maxRSSI));
741 
742  for(j=0;j<(1<<12);j++) {
743  for(i=11;i<=26;i++) {
744 #if RF230BB
745  rf230_listen_channel(i);
746 #else // RF230BB
748 #endif
749  _delay_us(3*10);
750 #if RF230BB
751  RSSI = rf230_rssi(); //multiplies rssi register by 3 for consistency with energy-detect register
752 #else // RF230BB
753  radio_get_rssi_value(&RSSI);
754  RSSI*=3;
755 #endif
756  maxRSSI[i-11]=Max(maxRSSI[i-11],RSSI);
757  accRSSI[i-11]+=RSSI;
758  }
759  if(j&(1<<7)) {
760  Led3_on();
761  if(!(j&((1<<7)-1))) {
762  PRINTF_P(PSTR("."));
763  uart_usb_flush();
764  }
765  }
766  else
767  Led3_off();
769  }
770 #if RF230BB
771  rf230_set_channel(previous_channel);
772 #else // RF230BB
773  radio_set_operating_channel(previous_channel);
774 #endif
775  PRINTF_P(PSTR("\n"));
776  for(i=11;i<=26;i++) {
777  uint8_t activity=Min(maxRSSI[i-11],accRSSI[i-11]/(1<<7));
778  PRINTF_P(PSTR(" %d: %02ddB "),i, -91+(maxRSSI[i-11]-1));
779  for(;activity--;maxRSSI[i-11]--) {
780  PRINTF_P(PSTR("#"));
781  }
782  for(;maxRSSI[i-11]>0;maxRSSI[i-11]--) {
783  PRINTF_P(PSTR(":"));
784  }
785  PRINTF_P(PSTR("\n"));
786  uart_usb_flush();
787  }
788 
789  }
790  PRINTF_P(PSTR("Done.\n"));
791  uart_usb_flush();
792 
793  break;
794 
795 
796  case 'D':
797  {
798  PRINTF_P(PSTR("Entering DFU Mode...\n\r"));
799  uart_usb_flush();
800  Leds_on();
801  for(i = 0; i < 10; i++)_delay_ms(100);
802  Leds_off();
803  Jump_To_Bootloader();
804  }
805  break;
806  case 'R':
807  {
808  PRINTF_P(PSTR("Resetting...\n\r"));
809  uart_usb_flush();
810  Leds_on();
811  for(i = 0; i < 10; i++)_delay_ms(100);
812  Usb_detach();
813  for(i = 0; i < 20; i++)_delay_ms(100);
814  watchdog_reboot();
815  }
816  break;
817 
818 #if USB_CONF_STORAGE
819  case 'u':
820 
821  //Mass storage mode
822  usb_mode = mass_storage;
823 
824  //No more serial port
825  stdout = NULL;
826 #if USB_CONF_RS232
827 // usb_stdout = NULL;
828 #endif
829 
830  //RNDIS is over
831  rndis_state = rndis_uninitialized;
832  Leds_off();
833 
834  //Deatch USB
835  Usb_detach();
836 
837  //Wait a few seconds
838  for(i = 0; i < 50; i++)
840  _delay_ms(100);
841 
842  //Attach USB
843  Usb_attach();
844 
845 
846  break;
847 #endif
848 
849  default:
850  PRINTF_P(PSTR("%c is not a valid option! h for menu\n\r"), c);
851  break;
852  }
853 
854 
855  }
856 
857  return;
858 
859 }
860 
861 
862 /**
863  @brief This will enable the VCP_TRX_END LED for a period
864 */
865 void vcptx_end_led(void)
866 {
867  Led3_on();
868  led3_timer = 5;
869 }
870 /** @} */
871 
#define RX_ON
Constant RX_ON for sub-register SR_TRX_STATUS.
int etimer_expired(struct etimer *et)
Check if an event timer has expired.
Definition: etimer.c:205
An entry in the routing table.
#define SETTINGS_KEY_CHANNEL
Definition: settings.h:119
A timer.
Definition: timer.h:86
radio_status_t radio_get_rssi_value(uint8_t *rssi)
This function returns the Received Signal Strength Indication.
Definition: radio.c:485
#define Is_device_enumerated()
Returns true when device connected and correctly enumerated with an host.
radio_status_t radio_set_tx_power_level(uint8_t power_level)
This function will change the output power level.
Definition: radio.c:391
RNDIS Defines
#define RX_AACK_ON
Constant RX_AACK_ON for sub-register SR_TRX_STATUS.
#define PROCESS_BEGIN()
Define the beginning of a process.
Definition: process.h:120
#define Usb_detach()
detaches from USB bus
Definition: usb_drv.h:367
bit uart_usb_test_hit(void)
This function checks if a character has been received on the USB bus.
Definition: uart_usb_lib.c:241
void uart_usb_init(void)
Initializes the uart_usb library.
Definition: uart_usb_lib.c:154
This file contains the user callback functions corresponding to the application.
uint8_t radio_get_tx_power_level(void)
This function will read and return the output power level.
Definition: radio.c:374
This file contains the USB driver routines.
char uart_usb_getchar(void)
This function reads one byte from the USB bus.
Definition: uart_usb_lib.c:270
#define NULL
The null pointer.
int uart_usb_putchar(int data_to_send)
This function fills the USB transmit buffer with the new data.
Definition: uart_usb_lib.c:206
uint8_t radio_get_operating_channel(void)
This function will return the channel used by the radio transceiver.
Definition: radio.c:313
U8 usb_configuration_nb
Public : (U8) usb_configuration_nb Store the number of the USB configuration used by the USB device w...
void uart_usb_flush(void)
This function sends the data stored in the USB transmit buffer.
Definition: uart_usb_lib.c:299
#define SETTINGS_KEY_TXPOWER
Definition: settings.h:120
uint64_t macLongAddr
Our own long address.
Definition: mac.c:145
void watchdog_reboot(void)
Keeps control until the WDT throws a reset signal.
Definition: watchdog.c:128
void menu_process(char c)
Process incomming char on debug port.
Definition: cdc_task.c:276
#define Usb_attach()
attaches to USB bus
Definition: usb_drv.h:369
const uint32_t OIDSupportedList[] PROGMEM
List of supported RNDIS OID&#39;s.
Definition: rndis.c:96
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
Definition: process.h:273
#define PROCESS_END()
Define the end of a process.
Definition: process.h:131
Settings Manager.
This file manages the RNDIS task.
void watchdog_periodic(void)
Writes the WDT clear sequence.
Definition: watchdog.c:64
radio_status_t radio_set_operating_channel(uint8_t channel)
This function will change the operating channel.
Definition: radio.c:329
The requested service was performed successfully.
Definition: radio.h:106
#define PROCESS_WAIT_EVENT_UNTIL(c)
Wait for an event to be posted to the process, with an extra condition.
Definition: process.h:157
#define PROCESS(name, strname)
Declare a process.
Definition: process.h:307
This file manages the CDC task for the virtual COM port.
void vcptx_end_led(void)
This will enable the VCP_TRX_END LED for a period.
Definition: cdc_task.c:865
Interface structure (contains all the interface variables)
Definition: uip-ds6.h:212
void etimer_set(struct etimer *et, clock_time_t interval)
Set an event timer.
Definition: etimer.c:177
This file contains the usb parameters that uniquely identify the application through descriptor table...
Uchar tx_counter
Counter for USB Serial port.
Definition: uart_usb_lib.c:81
uint8_t led3_timer
Timers for LEDs.
Definition: cdc_task.c:108
void menu_print(void)
Print debug menu.
Definition: cdc_task.c:215
A timer.
Definition: etimer.h:76
radio_status_t radio_set_trx_state(uint8_t new_state)
This function will change the current state of the radio transceiver&#39;s internal state machine...
Definition: radio.c:809
#define CLOCK_SECOND
A second, measured in system clock time.
Definition: clock.h:82
An entry in the nbr cache.
Definition: uip-ds6-nbr.h:70