Contiki 2.6

cdc-eth.c

00001 #include <cdc-eth.h>
00002 #include <usb-api.h>
00003 #include <uip_arp.h>
00004 #include <stdio.h>
00005 #include <string.h>
00006 #include <net/uip-fw.h>
00007 
00008 #define DATA_IN 0x81
00009 #define DATA_OUT 0x02
00010 #define INTERRUPT_IN 0x83
00011 
00012 
00013 struct uip_eth_addr default_uip_ethaddr = {{0x02,0x00,0x00,0x00,0x00,0x02}};
00014  
00015 static unsigned int
00016 handle_cdc_eth_requests()
00017 {
00018   return 0;
00019 }
00020 
00021 static const struct USBRequestHandler cdc_eth_request_handler =
00022   {
00023     0x21, 0x7f,
00024     0x00, 0x00,
00025     handle_cdc_eth_requests
00026   };
00027 
00028 static struct USBRequestHandlerHook cdc_eth_request_hook =
00029   {
00030     NULL,
00031     &cdc_eth_request_handler
00032   };
00033 
00034 static USBBuffer recv_buffer;
00035 static uint8_t recv_data[UIP_BUFSIZE];
00036 
00037 static USBBuffer xmit_buffer[3];
00038 static uint8_t xmit_data[UIP_BUFSIZE];
00039 
00040 static void
00041 init_recv_buffer()
00042 {
00043   recv_buffer.next = NULL;
00044   recv_buffer.data = recv_data;
00045   recv_buffer.left = UIP_BUFSIZE;
00046   recv_buffer.flags = USB_BUFFER_SHORT_END | USB_BUFFER_NOTIFY;
00047 }
00048 
00049 uint8_t
00050 usbeth_send(void)
00051 {
00052   if ((xmit_buffer[0].flags & USB_BUFFER_SUBMITTED)) return UIP_FW_DROPPED;
00053   uip_arp_out();
00054   memcpy(xmit_data, uip_buf, uip_len);
00055   xmit_buffer[0].next = NULL;
00056   xmit_buffer[0].left = uip_len;
00057   xmit_buffer[0].flags = USB_BUFFER_NOTIFY | USB_BUFFER_SHORT_END;
00058   xmit_buffer[0].data = xmit_data;
00059   
00060   /* printf("usbeth_send: %d\n", uip_len);  */
00061   usb_submit_xmit_buffer(DATA_IN, &xmit_buffer[0]);
00062   return UIP_FW_OK;
00063 }
00064 
00065 static struct uip_fw_netif usbethif =
00066   {UIP_FW_NETIF(172,16,0,1, 255,255,255,255, usbeth_send)};
00067 
00068 #define BUF ((struct uip_eth_hdr *)&uip_buf[0])
00069 
00070 PROCESS(usb_eth_process, "USB ethernet");
00071 
00072 PROCESS_THREAD(usb_eth_process, ev , data)
00073 {
00074   PROCESS_BEGIN();
00075   usb_register_request_handler(&cdc_eth_request_hook);
00076   usb_setup();
00077   usb_set_ep_event_process(DATA_OUT, process_current);
00078   usb_set_global_event_process(process_current);
00079   uip_fw_default(&usbethif);
00080   uip_setethaddr(default_uip_ethaddr);
00081   uip_arp_init();
00082   
00083   while(1) {
00084     PROCESS_WAIT_EVENT();
00085     if (ev == PROCESS_EVENT_EXIT) break;
00086     if (ev == PROCESS_EVENT_POLL) {
00087       unsigned int events = usb_get_global_events();
00088       if (events) {
00089         if (events & USB_EVENT_CONFIG) {
00090           if (usb_get_current_configuration() != 0) {
00091             printf("Configured\n");
00092             usb_setup_bulk_endpoint(DATA_IN);
00093             usb_setup_bulk_endpoint(DATA_OUT);
00094             usb_setup_interrupt_endpoint(INTERRUPT_IN);
00095             init_recv_buffer();
00096             usb_submit_recv_buffer(DATA_OUT, &recv_buffer);
00097 #if 0
00098             {
00099               static const uint8_t foo[4] = {0x12,0x34,0x56,0x78};
00100               xmit_buffer[0].next = NULL;
00101               xmit_buffer[0].left = sizeof(foo);
00102               xmit_buffer[0].flags = USB_BUFFER_SHORT_END;
00103               xmit_buffer[0].data = &foo;
00104               
00105               usb_submit_xmit_buffer(DATA_IN, &xmit_buffer[0]);
00106             }
00107 #endif
00108           } else {
00109             usb_disable_endpoint(DATA_IN);
00110             usb_disable_endpoint(DATA_OUT);
00111             usb_disable_endpoint(INTERRUPT_IN);
00112           }
00113         }
00114       }
00115       events = usb_get_ep_events(DATA_OUT);
00116       if (events & USB_EP_EVENT_NOTIFICATION) {
00117         uip_len = sizeof(recv_data) - recv_buffer.left;
00118         /* printf("Received: %d bytes\n", uip_len);  */
00119         memcpy(uip_buf, recv_data, uip_len);
00120 #if UIP_CONF_IPV6
00121         if(BUF->type == uip_htons(UIP_ETHTYPE_IPV6)) {
00122           uip_neighbor_add(&IPBUF->srcipaddr, &BUF->src);
00123             tcpip_input();
00124         } else 
00125 #endif /* UIP_CONF_IPV6 */
00126           if(BUF->type == uip_htons(UIP_ETHTYPE_IP)) {
00127             uip_len -= sizeof(struct uip_eth_hdr);
00128             tcpip_input();
00129           } else if(BUF->type == uip_htons(UIP_ETHTYPE_ARP)) {
00130             uip_arp_arpin();
00131             /* If the above function invocation resulted in data that
00132                should be sent out on the network, the global variable
00133                uip_len is set to a value > 0. */
00134             if (uip_len > 0) {
00135               memcpy(xmit_data, uip_buf, uip_len);
00136               xmit_buffer[0].next = NULL;
00137               xmit_buffer[0].data = xmit_data;
00138               xmit_buffer[0].left = uip_len;
00139               xmit_buffer[0].flags = USB_BUFFER_SHORT_END;
00140               
00141               usb_submit_xmit_buffer(DATA_IN, &xmit_buffer[0]);
00142               /* printf("Sent: %d bytes\n", uip_len); */
00143             }
00144           }
00145         
00146         init_recv_buffer();
00147         usb_submit_recv_buffer(DATA_OUT, &recv_buffer);
00148       }
00149     }
00150   }
00151   PROCESS_END();
00152 }
00153 
00154 void
00155 usb_cdc_eth_setup()
00156 {
00157   process_start(&usb_eth_process, NULL);
00158 }
00159 
00160 void
00161 usb_cdc_eth_set_ifaddr(uip_ipaddr_t *addr)
00162 {
00163   usbethif.ipaddr = *addr;
00164 }
00165   
00166 void
00167 dummy(uip_ipaddr_t *addr1,  uip_ipaddr_t *addr2)
00168 {
00169   *addr1 = *addr2;
00170 }