rndis_task.c
Go to the documentation of this file.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 #include "contiki.h"
00050 #include "usb_drv.h"
00051 #include "usb_descriptors.h"
00052 #include "usb_specific_request.h"
00053 #include "rndis/rndis_task.h"
00054 #include "rndis/rndis_protocol.h"
00055 #if RF230BB
00056 #include "rf230bb.h"
00057 #endif
00058 #include "uip.h"
00059 #include "sicslow_ethernet.h"
00060 #include <stdio.h>
00061 
00062 #include <avr/pgmspace.h>
00063 #include <util/delay.h>
00064 #include "watchdog.h"
00065 
00066 #include "rndis/cdc_ecm.h"
00067 #include "rndis/cdc_eem.h"
00068 
00069 #define BUF ((struct uip_eth_hdr *)&uip_buf[0])
00070 #define PRINTF printf
00071 #define PRINTF_P printf_P
00072 
00073 
00074 
00075 
00076 
00077 
00078 
00079 
00080 
00081 
00082 #define IAD_TIMEOUT_DETACH 400
00083 #define IAD_TIMEOUT_ATTACH 800
00084 
00085 #define RNDIS_TIMEOUT_DETACH 900
00086 #define RNDIS_TIMEOUT_ATTACH 1000
00087 
00088 #define PBUF ((rndis_data_packet_t *) usb_eth_data_buffer)
00089 
00090 
00091 uint8_t usb_eth_data_buffer[64];
00092 
00093 uint64_t usb_ethernet_addr = 0x010000000002ULL;
00094 
00095 
00096 
00097 
00098 
00099 uint8_t led1_timer, led2_timer;
00100 
00101 uint8_t usb_eth_is_active = 1;
00102 
00103 
00104 uint8_t usb_eth_packet_is_available() {
00105         Usb_select_endpoint(RX_EP);
00106         return Is_usb_read_enabled();
00107 }
00108 
00109 
00110 uint8_t usb_eth_ready_for_next_packet() {
00111 #ifdef USB_ETH_HOOK_IS_READY_FOR_INBOUND_PACKET
00112         return USB_ETH_HOOK_IS_READY_FOR_INBOUND_PACKET();
00113 #else
00114         return 1;
00115 #endif
00116 
00117         return 1;
00118 }
00119 
00120 void rxtx_led_update(void)
00121 {
00122         
00123         if (led1_timer) {
00124                 led1_timer--;
00125                 if(led1_timer&(1<<2))
00126                         Led1_on();
00127                 else
00128                         Led1_off();
00129         }
00130         else
00131                 Led1_off();
00132 
00133         if (led2_timer) {
00134                 led2_timer--;
00135                 if(led2_timer&(1<<2))
00136                         Led2_on();
00137                 else
00138                         Led2_off();
00139         }
00140         else
00141                 Led2_off();
00142 }
00143 
00144 
00145 
00146 
00147 void rx_start_led(void)
00148 {
00149         led1_timer|=(1<<3);
00150         if(((led1_timer-1)&(1<<2)))
00151                 Led1_on();
00152 }
00153 
00154 
00155 
00156 
00157 void tx_end_led(void)
00158 {
00159         led2_timer|=(1<<3);
00160         if(((led2_timer-1)&(1<<2)))
00161                 Led1_on();
00162 }
00163 
00164 #if USB_ETH_CONF_MASS_STORAGE_FALLBACK
00165 static void
00166 usb_eth_setup_timeout_fallback_check() {
00167         extern uint8_t fingerPresent;
00168                 
00169 
00170 
00171         static uint16_t iad_fail_timeout, rndis_fail_timeout;   
00172         if (usb_mode == rndis_debug) {
00173                 
00174                 if (iad_fail_timeout == IAD_TIMEOUT_DETACH) {
00175                 
00176                         
00177                         
00178                         
00179                         if (fingerPresent && (rndis_state != rndis_data_initialized) && Is_device_enumerated() ) {
00180                                 iad_fail_timeout = 0;
00181                         } else {
00182                                         stdout = NULL;
00183                                         Usb_detach();
00184                                         doInit = 1; 
00185                         }
00186                         
00187                 
00188                 } else if (iad_fail_timeout == IAD_TIMEOUT_ATTACH) {
00189                 
00190                         if (fingerPresent) {
00191                                 usb_mode = mass_storage;
00192                         } else {
00193                                 usb_mode = rndis_only;
00194                         }
00195                         Usb_attach();
00196                 }
00197 
00198                 
00199                 
00200                 if ( ( (rndis_state != rndis_data_initialized) && Is_device_enumerated() ) ||
00201                   (iad_fail_timeout > IAD_TIMEOUT_DETACH) || 
00202                    (fingerPresent) ) {
00203                         iad_fail_timeout++;
00204                 } else {        
00205                 iad_fail_timeout = 0;
00206                 }
00207         } 
00208 
00209 
00210          
00211 
00212 
00213         if (usb_mode == rndis_only) {
00214                 
00215                 if (rndis_fail_timeout == RNDIS_TIMEOUT_DETACH) {
00216                         Usb_detach();
00217                 
00218                 } else if (rndis_fail_timeout == RNDIS_TIMEOUT_ATTACH) {
00219                         usb_mode = mass_storage;
00220                         Usb_attach();
00221                 }
00222 
00223                 
00224                 
00225                 if ( ( (rndis_state != rndis_data_initialized)) ||
00226                   (rndis_fail_timeout > RNDIS_TIMEOUT_DETACH) ) {
00227                         rndis_fail_timeout++;
00228                 } else {        
00229                 rndis_fail_timeout = 0;
00230                 }
00231         }
00232 }
00233 #endif
00234 
00235 PROCESS(usb_eth_process, "USB Ethernet process");
00236 
00237 
00238 
00239 
00240 
00241 
00242 
00243 PROCESS_THREAD(usb_eth_process, ev, data_proc)
00244 {
00245         static struct etimer et;
00246 
00247         PROCESS_BEGIN();
00248 
00249         while(1) {
00250                 rxtx_led_update();
00251 
00252 #if USB_ETH_CONF_MASS_STORAGE_FALLBACK
00253                 usb_eth_setup_timeout_fallback_check();
00254 #endif
00255                 
00256                 switch(usb_configuration_nb) {
00257                         case USB_CONFIG_RNDIS_DEBUG:
00258                         case USB_CONFIG_RNDIS:
00259                                 if(Is_device_enumerated()) {
00260                                         if(rndis_process()) {
00261                                                 etimer_set(&et, CLOCK_SECOND/80);
00262                                         } else {
00263                                                 Led0_toggle();
00264                                                 etimer_set(&et, CLOCK_SECOND/8);
00265                                         }
00266                                 }
00267                                 break;
00268                         case USB_CONFIG_EEM:
00269                                 if(Is_device_enumerated())
00270                                         cdc_eem_process();
00271                                 etimer_set(&et, CLOCK_SECOND/80);
00272                                 break;
00273                         case USB_CONFIG_ECM:
00274                         case USB_CONFIG_ECM_DEBUG:
00275                                 if(Is_device_enumerated()) {
00276                                         if(cdc_ecm_process()) {
00277                                                 etimer_set(&et, CLOCK_SECOND/80);
00278                                         } else {
00279                                                 Led0_toggle();
00280                                                 etimer_set(&et, CLOCK_SECOND/8);
00281                                         }
00282                                 }
00283                                 break;
00284                         default:
00285                                 Led0_toggle();
00286                                 etimer_set(&et, CLOCK_SECOND/4);
00287                                 break;
00288                 }
00289 
00290 
00291                 PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)||(usb_eth_packet_is_available()&&usb_eth_ready_for_next_packet()));
00292         } 
00293 
00294         PROCESS_END();
00295 }
00296 
00297 
00298 
00299 
00300 
00301 
00302 
00303 uint8_t usb_eth_send(uint8_t * senddata, uint16_t sendlen, uint8_t led)
00304 {
00305         uint8_t ret = 0;
00306         
00307         if(!usb_eth_is_active) {
00308                 USB_ETH_HOOK_TX_ERROR("Inactive");
00309                 goto bail;
00310         }
00311 
00312         
00313         if (Is_device_enumerated() == 0) {
00314                 USB_ETH_HOOK_TX_ERROR("Device not enumerated");
00315                 goto bail;
00316         }
00317 
00318         switch(usb_configuration_nb) {
00319                 case USB_CONFIG_RNDIS_DEBUG:
00320                 case USB_CONFIG_RNDIS:
00321                         ret = rndis_send(senddata, sendlen, led);
00322                         break;
00323                 case USB_CONFIG_EEM:
00324                         ret = eem_send(senddata, sendlen, led);
00325                         break;
00326                 case USB_CONFIG_ECM:
00327                 case USB_CONFIG_ECM_DEBUG:
00328                         ret = ecm_send(senddata, sendlen, led);
00329                         break;
00330         }
00331 
00332 bail:
00333 
00334         if(!ret) 
00335                 watchdog_periodic();
00336 
00337         return ret;
00338 }
00339 
00340 uint8_t
00341 usb_eth_set_active(uint8_t active) {
00342         if(usb_eth_is_active!=active) { 
00343                 switch(usb_configuration_nb) {
00344                         case USB_CONFIG_RNDIS_DEBUG:
00345                         case USB_CONFIG_RNDIS:
00346                                 usb_eth_is_active = active;
00347                                 rndis_send_interrupt();
00348                                 break;
00349                         case USB_CONFIG_EEM:
00350                                 break;
00351                         case USB_CONFIG_ECM:
00352                         case USB_CONFIG_ECM_DEBUG:
00353                                 cdc_ecm_set_active(active);
00354                                 usb_eth_is_active = active;
00355                                 break;
00356                 }
00357         }
00358         return 0;
00359 }
00360 
00361 void
00362 usb_eth_get_mac_address(uint8_t dest[6]) {
00363         memcpy(dest,&usb_ethernet_addr,6);
00364 }
00365 
00366 void
00367 usb_eth_set_mac_address(const uint8_t src[6]) {
00368         memcpy(&usb_ethernet_addr,src,6);
00369 }
00370 
00371