Contiki 3.x
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/ipv4/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 uint8_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 }
void uip_arp_out(void)
Prepend Ethernet header to an outbound IP packet and see if we need to send out an ARP request...
Definition: uip_arp.c:363
#define UIP_FW_DROPPED
An error message that indicates that a packet that should be forwarded or output was dropped...
Definition: uip-fw.h:171
uip_len
The length of the packet in the uip_buf buffer.
Definition: tcp_loader.c:75
uIP packet forwarding header file.
#define uip_setethaddr(eaddr)
Specifiy the Ethernet MAC address.
Definition: uip_arp.h:131
#define UIP_FW_NETIF(ip1, ip2, ip3, ip4, nm1, nm2, nm3, nm4, outputfunc)
Instantiating macro for a uIP network interface.
Definition: uip-fw.h:80
void tcpip_input(void)
Deliver an incoming packet to the TCP/IP stack.
Definition: tcpip.c:529
Representation of a uIP network interface.
Definition: uip-fw.h:54
#define PROCESS_BEGIN()
Define the beginning of a process.
Definition: process.h:120
uip_ipaddr_t ipaddr
The IP address of this interface.
Definition: uip-fw.h:57
#define NULL
The null pointer.
#define UIP_BUFSIZE
The size of the uIP packet buffer.
Definition: uipopt.h:173
void uip_arp_init(void)
Initialize the ARP module.
Definition: uip_arp.c:130
The Ethernet header.
Definition: uip_arp.h:60
#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
Macros and definitions for the ARP module.
CCIF uint16_t uip_htons(uint16_t val)
Convert a 16-bit quantity from host byte order to network byte order.
Definition: uip6.c:2298
#define PROCESS_WAIT_EVENT()
Wait for an event to be posted to the process.
Definition: process.h:141
802.3 address
Definition: uip.h:135
void uip_fw_default(struct uip_fw_netif *netif)
Register a default network interface.
Definition: uip-fw.c:515
#define PROCESS(name, strname)
Declare a process.
Definition: process.h:307
void process_start(struct process *p, process_data_t data)
Start a process.
Definition: process.c:99
#define UIP_FW_OK
A non-error message that indicates that something went OK.
Definition: uip-fw.h:132
void uip_arp_arpin(void)
ARP processing for incoming IP packets.
Definition: uip_arp.c:283