Contiki 2.5
cdc-eth.c
1 #include <cdc-eth.h>
2 #include <usb-api.h>
3 #include <uip_arp.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include <net/uip-fw.h>
7 
8 #define DATA_IN 0x81
9 #define DATA_OUT 0x02
10 #define INTERRUPT_IN 0x83
11 
12 
13 struct uip_eth_addr default_uip_ethaddr = {{0x02,0x00,0x00,0x00,0x00,0x02}};
14 
15 static unsigned int
16 handle_cdc_eth_requests()
17 {
18  return 0;
19 }
20 
21 static const struct USBRequestHandler cdc_eth_request_handler =
22  {
23  0x21, 0x7f,
24  0x00, 0x00,
25  handle_cdc_eth_requests
26  };
27 
28 static struct USBRequestHandlerHook cdc_eth_request_hook =
29  {
30  NULL,
31  &cdc_eth_request_handler
32  };
33 
34 static USBBuffer recv_buffer;
35 static uint8_t recv_data[UIP_BUFSIZE];
36 
37 static USBBuffer xmit_buffer[3];
38 static uint8_t xmit_data[UIP_BUFSIZE];
39 
40 static void
41 init_recv_buffer()
42 {
43  recv_buffer.next = NULL;
44  recv_buffer.data = recv_data;
45  recv_buffer.left = UIP_BUFSIZE;
46  recv_buffer.flags = USB_BUFFER_SHORT_END | USB_BUFFER_NOTIFY;
47 }
48 
49 u8_t
50 usbeth_send(void)
51 {
52  if ((xmit_buffer[0].flags & USB_BUFFER_SUBMITTED)) return UIP_FW_DROPPED;
53  uip_arp_out();
54  memcpy(xmit_data, uip_buf, uip_len);
55  xmit_buffer[0].next = NULL;
56  xmit_buffer[0].left = uip_len;
57  xmit_buffer[0].flags = USB_BUFFER_NOTIFY | USB_BUFFER_SHORT_END;
58  xmit_buffer[0].data = xmit_data;
59 
60  /* printf("usbeth_send: %d\n", uip_len); */
61  usb_submit_xmit_buffer(DATA_IN, &xmit_buffer[0]);
62  return UIP_FW_OK;
63 }
64 
65 static struct uip_fw_netif usbethif =
66  {UIP_FW_NETIF(172,16,0,1, 255,255,255,255, usbeth_send)};
67 
68 #define BUF ((struct uip_eth_hdr *)&uip_buf[0])
69 
70 PROCESS(usb_eth_process, "USB ethernet");
71 
72 PROCESS_THREAD(usb_eth_process, ev , data)
73 {
74  PROCESS_BEGIN();
75  usb_register_request_handler(&cdc_eth_request_hook);
76  usb_setup();
77  usb_set_ep_event_process(DATA_OUT, process_current);
78  usb_set_global_event_process(process_current);
79  uip_fw_default(&usbethif);
80  uip_setethaddr(default_uip_ethaddr);
81  uip_arp_init();
82 
83  while(1) {
85  if (ev == PROCESS_EVENT_EXIT) break;
86  if (ev == PROCESS_EVENT_POLL) {
87  unsigned int events = usb_get_global_events();
88  if (events) {
89  if (events & USB_EVENT_CONFIG) {
90  if (usb_get_current_configuration() != 0) {
91  printf("Configured\n");
92  usb_setup_bulk_endpoint(DATA_IN);
93  usb_setup_bulk_endpoint(DATA_OUT);
94  usb_setup_interrupt_endpoint(INTERRUPT_IN);
95  init_recv_buffer();
96  usb_submit_recv_buffer(DATA_OUT, &recv_buffer);
97 #if 0
98  {
99  static const uint8_t foo[4] = {0x12,0x34,0x56,0x78};
100  xmit_buffer[0].next = NULL;
101  xmit_buffer[0].left = sizeof(foo);
102  xmit_buffer[0].flags = USB_BUFFER_SHORT_END;
103  xmit_buffer[0].data = &foo;
104 
105  usb_submit_xmit_buffer(DATA_IN, &xmit_buffer[0]);
106  }
107 #endif
108  } else {
109  usb_disable_endpoint(DATA_IN);
110  usb_disable_endpoint(DATA_OUT);
111  usb_disable_endpoint(INTERRUPT_IN);
112  }
113  }
114  }
115  events = usb_get_ep_events(DATA_OUT);
116  if (events & USB_EP_EVENT_NOTIFICATION) {
117  uip_len = sizeof(recv_data) - recv_buffer.left;
118  /* printf("Received: %d bytes\n", uip_len); */
119  memcpy(uip_buf, recv_data, uip_len);
120 #if UIP_CONF_IPV6
121  if(BUF->type == uip_htons(UIP_ETHTYPE_IPV6)) {
122  uip_neighbor_add(&IPBUF->srcipaddr, &BUF->src);
123  tcpip_input();
124  } else
125 #endif /* UIP_CONF_IPV6 */
126  if(BUF->type == uip_htons(UIP_ETHTYPE_IP)) {
127  uip_len -= sizeof(struct uip_eth_hdr);
128  tcpip_input();
129  } else if(BUF->type == uip_htons(UIP_ETHTYPE_ARP)) {
130  uip_arp_arpin();
131  /* If the above function invocation resulted in data that
132  should be sent out on the network, the global variable
133  uip_len is set to a value > 0. */
134  if (uip_len > 0) {
135  memcpy(xmit_data, uip_buf, uip_len);
136  xmit_buffer[0].next = NULL;
137  xmit_buffer[0].data = xmit_data;
138  xmit_buffer[0].left = uip_len;
139  xmit_buffer[0].flags = USB_BUFFER_SHORT_END;
140 
141  usb_submit_xmit_buffer(DATA_IN, &xmit_buffer[0]);
142  /* printf("Sent: %d bytes\n", uip_len); */
143  }
144  }
145 
146  init_recv_buffer();
147  usb_submit_recv_buffer(DATA_OUT, &recv_buffer);
148  }
149  }
150  }
151  PROCESS_END();
152 }
153 
154 void
155 usb_cdc_eth_setup()
156 {
157  process_start(&usb_eth_process, NULL);
158 }
159 
160 void
161 usb_cdc_eth_set_ifaddr(uip_ipaddr_t *addr)
162 {
163  usbethif.ipaddr = *addr;
164 }
165 
166 void
167 dummy(uip_ipaddr_t *addr1, uip_ipaddr_t *addr2)
168 {
169  *addr1 = *addr2;
170 }