mirror of
https://github.com/oliverschmidt/contiki.git
synced 2024-11-19 03:05:14 +00:00
171 lines
4.2 KiB
C
171 lines
4.2 KiB
C
#include <cdc-eth.h>
|
|
#include <usb-api.h>
|
|
#include <uip_arp.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <net/ipv4/uip-fw.h>
|
|
|
|
#define DATA_IN 0x81
|
|
#define DATA_OUT 0x02
|
|
#define INTERRUPT_IN 0x83
|
|
|
|
|
|
struct uip_eth_addr default_uip_ethaddr = {{0x02,0x00,0x00,0x00,0x00,0x02}};
|
|
|
|
static unsigned int
|
|
handle_cdc_eth_requests()
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static const struct USBRequestHandler cdc_eth_request_handler =
|
|
{
|
|
0x21, 0x7f,
|
|
0x00, 0x00,
|
|
handle_cdc_eth_requests
|
|
};
|
|
|
|
static struct USBRequestHandlerHook cdc_eth_request_hook =
|
|
{
|
|
NULL,
|
|
&cdc_eth_request_handler
|
|
};
|
|
|
|
static USBBuffer recv_buffer;
|
|
static uint8_t recv_data[UIP_BUFSIZE];
|
|
|
|
static USBBuffer xmit_buffer[3];
|
|
static uint8_t xmit_data[UIP_BUFSIZE];
|
|
|
|
static void
|
|
init_recv_buffer()
|
|
{
|
|
recv_buffer.next = NULL;
|
|
recv_buffer.data = recv_data;
|
|
recv_buffer.left = UIP_BUFSIZE;
|
|
recv_buffer.flags = USB_BUFFER_SHORT_END | USB_BUFFER_NOTIFY;
|
|
}
|
|
|
|
uint8_t
|
|
usbeth_send(void)
|
|
{
|
|
if ((xmit_buffer[0].flags & USB_BUFFER_SUBMITTED)) return UIP_FW_DROPPED;
|
|
uip_arp_out();
|
|
memcpy(xmit_data, uip_buf, uip_len);
|
|
xmit_buffer[0].next = NULL;
|
|
xmit_buffer[0].left = uip_len;
|
|
xmit_buffer[0].flags = USB_BUFFER_NOTIFY | USB_BUFFER_SHORT_END;
|
|
xmit_buffer[0].data = xmit_data;
|
|
|
|
/* printf("usbeth_send: %d\n", uip_len); */
|
|
usb_submit_xmit_buffer(DATA_IN, &xmit_buffer[0]);
|
|
return UIP_FW_OK;
|
|
}
|
|
|
|
static struct uip_fw_netif usbethif =
|
|
{UIP_FW_NETIF(172,16,0,1, 255,255,255,255, usbeth_send)};
|
|
|
|
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
|
|
|
|
PROCESS(usb_eth_process, "USB ethernet");
|
|
|
|
PROCESS_THREAD(usb_eth_process, ev , data)
|
|
{
|
|
PROCESS_BEGIN();
|
|
usb_register_request_handler(&cdc_eth_request_hook);
|
|
usb_setup();
|
|
usb_set_ep_event_process(DATA_OUT, process_current);
|
|
usb_set_global_event_process(process_current);
|
|
uip_fw_default(&usbethif);
|
|
uip_setethaddr(default_uip_ethaddr);
|
|
uip_arp_init();
|
|
|
|
while(1) {
|
|
PROCESS_WAIT_EVENT();
|
|
if (ev == PROCESS_EVENT_EXIT) break;
|
|
if (ev == PROCESS_EVENT_POLL) {
|
|
unsigned int events = usb_get_global_events();
|
|
if (events) {
|
|
if (events & USB_EVENT_CONFIG) {
|
|
if (usb_get_current_configuration() != 0) {
|
|
printf("Configured\n");
|
|
usb_setup_bulk_endpoint(DATA_IN);
|
|
usb_setup_bulk_endpoint(DATA_OUT);
|
|
usb_setup_interrupt_endpoint(INTERRUPT_IN);
|
|
init_recv_buffer();
|
|
usb_submit_recv_buffer(DATA_OUT, &recv_buffer);
|
|
#if 0
|
|
{
|
|
static const uint8_t foo[4] = {0x12,0x34,0x56,0x78};
|
|
xmit_buffer[0].next = NULL;
|
|
xmit_buffer[0].left = sizeof(foo);
|
|
xmit_buffer[0].flags = USB_BUFFER_SHORT_END;
|
|
xmit_buffer[0].data = &foo;
|
|
|
|
usb_submit_xmit_buffer(DATA_IN, &xmit_buffer[0]);
|
|
}
|
|
#endif
|
|
} else {
|
|
usb_disable_endpoint(DATA_IN);
|
|
usb_disable_endpoint(DATA_OUT);
|
|
usb_disable_endpoint(INTERRUPT_IN);
|
|
}
|
|
}
|
|
}
|
|
events = usb_get_ep_events(DATA_OUT);
|
|
if (events & USB_EP_EVENT_NOTIFICATION) {
|
|
uip_len = sizeof(recv_data) - recv_buffer.left;
|
|
/* printf("Received: %d bytes\n", uip_len); */
|
|
memcpy(uip_buf, recv_data, uip_len);
|
|
#if NETSTACK_CONF_WITH_IPV6
|
|
if(BUF->type == uip_htons(UIP_ETHTYPE_IPV6)) {
|
|
uip_neighbor_add(&IPBUF->srcipaddr, &BUF->src);
|
|
tcpip_input();
|
|
} else
|
|
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
|
if(BUF->type == uip_htons(UIP_ETHTYPE_IP)) {
|
|
uip_len -= sizeof(struct uip_eth_hdr);
|
|
tcpip_input();
|
|
} else if(BUF->type == uip_htons(UIP_ETHTYPE_ARP)) {
|
|
uip_arp_arpin();
|
|
/* If the above function invocation resulted in data that
|
|
should be sent out on the network, the global variable
|
|
uip_len is set to a value > 0. */
|
|
if (uip_len > 0) {
|
|
memcpy(xmit_data, uip_buf, uip_len);
|
|
xmit_buffer[0].next = NULL;
|
|
xmit_buffer[0].data = xmit_data;
|
|
xmit_buffer[0].left = uip_len;
|
|
xmit_buffer[0].flags = USB_BUFFER_SHORT_END;
|
|
|
|
usb_submit_xmit_buffer(DATA_IN, &xmit_buffer[0]);
|
|
/* printf("Sent: %d bytes\n", uip_len); */
|
|
}
|
|
}
|
|
|
|
init_recv_buffer();
|
|
usb_submit_recv_buffer(DATA_OUT, &recv_buffer);
|
|
}
|
|
}
|
|
}
|
|
PROCESS_END();
|
|
}
|
|
|
|
void
|
|
usb_cdc_eth_setup()
|
|
{
|
|
process_start(&usb_eth_process, NULL);
|
|
}
|
|
|
|
void
|
|
usb_cdc_eth_set_ifaddr(uip_ipaddr_t *addr)
|
|
{
|
|
usbethif.ipaddr = *addr;
|
|
}
|
|
|
|
void
|
|
dummy(uip_ipaddr_t *addr1, uip_ipaddr_t *addr2)
|
|
{
|
|
*addr1 = *addr2;
|
|
}
|