#include "at32f403a_407.h" #include "usb_eth.h" #include "dhserver.h" #include "dnserver.h" #include "usbd_rndis_core.h" #include "netif/etharp.h" #include "lwip/init.h" #include "lwip/netif.h" #include "lwip/pbuf.h" #include "lwip/icmp.h" #include "lwip/udp.h" #include "lwip/opt.h" #include "lwip/arch.h" #include "lwip/api.h" #include "lwip/inet.h" #include "lwip/dns.h" #include "tcpip.h" #include "usbd_core.h" #include "usb.h" #include "common.h" #include "FreeRTOS.h" #include "task.h" #include "semphr.h" #include #include static uint8_t hwaddr[6] = {0x20,0x89,0x84,0x6A,0x96,00}; static uint8_t ipaddr[4] = {192, 168, 7, 1}; static uint8_t netmask[4] = {255, 255, 255, 0}; static uint8_t gateway[4] = {0, 0, 0, 0}; #define USE_LINK_LED 0 #define NUM_DHCP_ENTRY 3 static dhcp_entry_t entries[NUM_DHCP_ENTRY] = { // mac ip address subnet mask lease time { {0}, {192, 168, 7, 2}, {255, 255, 255, 0}, 24 * 60 * 60 }, { {0}, {192, 168, 7, 3}, {255, 255, 255, 0}, 24 * 60 * 60 }, { {0}, {192, 168, 7, 4}, {255, 255, 255, 0}, 24 * 60 * 60 } }; static dhcp_config_t dhcp_config = { {192, 168, 7, 1}, 67, // server address, port {192, 168, 7, 1}, // dns server "prs", // dns suffix NUM_DHCP_ENTRY, // num entry entries // entries }; struct netif netif_data; static uint8_t received[RNDIS_MTU + 14]; static int recvSize = 0; SemaphoreHandle_t xSemUsbEth; void on_packet(const char *data, int size) { BaseType_t xHigherPriorityTaskWoken = pdFALSE;; memcpy(received, data, size); recvSize = size; xSemaphoreGiveFromISR( xSemUsbEth, &xHigherPriorityTaskWoken ); if( xHigherPriorityTaskWoken != pdFALSE ) { taskYIELD(); } } void usb_polling() { xSemaphoreTake( xSemUsbEth, portMAX_DELAY); if (recvSize == 0) return; struct pbuf *frame; frame = pbuf_alloc(PBUF_RAW, recvSize, PBUF_POOL); if (frame == NULL) return; memcpy(frame->payload, received, recvSize); frame->len = recvSize; recvSize = 0; tcpip_input(frame, &netif_data); pbuf_free(frame); } static int outputs = 0; err_t output_fn(struct netif *netif, struct pbuf *p, ip_addr_t *ipaddr) { return etharp_output(netif, p, ipaddr); } err_t linkoutput_fn(struct netif *netif, struct pbuf *p) { int i; struct pbuf *q; static char data[RNDIS_MTU + 14 + 4]; int size = 0; for (i = 0; i < 200; i++) { if (rndis_can_send()) break; vTaskDelay(1); } for(q = p; q != NULL; q = q->next) { if (size + q->len > RNDIS_MTU + 14) return ERR_ARG; memcpy(data + size, (char *)q->payload, q->len); size += q->len; } if (!rndis_can_send()) return ERR_USE; rndis_send(data, size); outputs++; return ERR_OK; } err_t netif_init_cb(struct netif *netif) { LWIP_ASSERT("netif != NULL", (netif != NULL)); netif->mtu = RNDIS_MTU; netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP; netif->state = NULL; netif->name[0] = 'E'; netif->name[1] = 'X'; netif->linkoutput = linkoutput_fn; netif->output = (netif_output_fn)output_fn; return ERR_OK; } #define PADDR(ptr) ((ip_addr_t *)ptr) void init_lwip() { struct netif *netif = &netif_data; netif->hwaddr_len = 6; memcpy(netif->hwaddr, hwaddr, 6); netif = netif_add(netif, PADDR(ipaddr), PADDR(netmask), PADDR(gateway), NULL, netif_init_cb, tcpip_input); netif_set_link_up(netif); netif_set_up(netif); } void usb_hw_init(void) { usb_init(); rndis_rxproc = on_packet; xSemUsbEth = xSemaphoreCreateBinary(); } bool dns_query_proc(const char *name, ip_addr_t *addr) { if (strcmp(name, "energomera.prs") == 0 || strcmp(name, "www.energomera.prs") == 0) { addr->addr = *(uint32_t *)ipaddr; return true; } return false; } void usb_eth_task(void *arg) { while (1) { usb_polling(); // usb device polling } } void usb_eth_init(void) { usb_hw_init(); tcpip_init(NULL, NULL); init_lwip(); while (!netif_is_up(&netif_data)) ; while (dhserv_init(&dhcp_config) != ERR_OK) ; while (dnserv_init(PADDR(ipaddr), 53, dns_query_proc) != ERR_OK) ; xTaskCreate(usb_eth_task, ( char * ) "usb_eth_task", 3*configMINIMAL_STACK_SIZE, NULL, 2, NULL); }