#include "udp.h" #include "FreeRTOSConfig.h" #include "lwip/etharp.h" #include "task_manager.h" #include #include "timings.h" #include "netif/etharp.h" static struct udp_pcb* udp_pcb; static struct netif pnetif; static ip_addr_t device_ip, netmask, gateway, computer_ip, router_ip, broadcast_ip; typedef struct { char message[100]; ip_addr_t target_ip; u16_t target_port; } udp_message_info_t; static void udp_recv_callback(void* arg, struct udp_pcb* pcb, struct pbuf* p, const ip_addr_t* addr, u16_t port); static void ethernet_thread(void* v); void ethernet_loop(void); void udp_send_message(const char* message, const ip_addr_t* target_ip, u16_t target_port); #define UDP_PORT_SRC 60000 #define UDP_PORT_DST 60000 void udp_network_init(void) { // set device's ip address, netmask and gateway ipaddr_aton("192.168.1.255", &broadcast_ip); ipaddr_aton("192.168.1.150", &device_ip); ipaddr_aton("192.168.1.99", &computer_ip); ipaddr_aton("192.168.1.1", &router_ip); ipaddr_aton("255.255.255.0", &netmask); ipaddr_aton("192.168.1.1", &gateway); struct eth_addr dst_mac; struct eth_addr src_mac; struct eth_addr router_mac; dst_mac.addr[0] = 0x00; dst_mac.addr[1] = 0xe0; dst_mac.addr[2] = 0x4c; dst_mac.addr[3] = 0x09; dst_mac.addr[4] = 0x16; dst_mac.addr[5] = 0x54; src_mac.addr[0] = 0x00; src_mac.addr[1] = 0x80; src_mac.addr[2] = 0xe1; src_mac.addr[3] = 0x00; src_mac.addr[4] = 0x00; src_mac.addr[5] = 0x00; router_mac.addr[0] = 0xd8; router_mac.addr[1] = 0xec; router_mac.addr[2] = 0x5e; router_mac.addr[3] = 0x1d; router_mac.addr[4] = 0x95; router_mac.addr[5] = 0x09; // initialize the ethernet interface eth_init(); // inits device mac adrress, starts eth clock, gpio, interrupts & checksums for ethernet packet eth_mac_init(); // starts the ETH DMA Rx & Tx lwip_init(); // starts network stack // Try setting static arp entries etharp_add_static_entry(&device_ip, &src_mac); etharp_add_static_entry(&computer_ip, &dst_mac); etharp_add_static_entry(&router_ip, &router_mac); // set up the network interface if (!netif_add(&pnetif, &device_ip, &netmask, &gateway, NULL, ethernetif_init, ethernet_input)) { ERROR("Failed to add network if"); } netif_set_default(&pnetif); netif_set_up(&pnetif); udp_pcb = udp_new(); if (udp_pcb != NULL) { err_t err = udp_bind(udp_pcb, &device_ip, UDP_PORT_SRC); if (err != ERR_OK) { INFO("Can't bind to device ip/ src port"); } err = udp_connect(udp_pcb, &computer_ip, UDP_PORT_DST); if (err != ERR_OK) { INFO("Can't connect to computer ip"); } udp_recv(udp_pcb, udp_recv_callback, NULL); } task_custom_size(ethernet_thread, "ethernet_thread", BYTES_TO_STACK_SIZE(2048), NULL, PRIORITY_MINIMUM ); INFO("Ready to receive udp packets"); // udp_send_message("targetted ip test", &computer_ip, UDP_PORT_DST); // udp_send_message("broadcast ip test", &broadcast_ip, UDP_PORT_DST); } static void udp_recv_callback(void* arg, struct udp_pcb* pcb, struct pbuf* p, const ip_addr_t* addr, u16_t port) { INFO("A packet has been received"); UNUSED(arg); UNUSED(pcb); if (p != NULL && addr != NULL) { char ip_str[16]; ipaddr_ntoa_r(addr, ip_str, sizeof(ip_str)); INFO("Packet received from IP: %s, Port: %u", ip_str, port); pbuf_free(p); } else { INFO("NULL PACKET OR ADDRESS RECEIVED"); } } static void ethernet_thread(void* v) { (void)v; for (;;) { ethernet_loop(); msleep(ETHERNET_LOOP_TIME); } } // utility function to send a udp packet quickly void udp_send_message(const char* message, const ip_addr_t* target_ip, u16_t target_port) { err_t wr_err = ERR_OK; struct pbuf* p = pbuf_alloc(PBUF_TRANSPORT, strlen(message), PBUF_RAM); if (p != NULL) { memcpy(p->payload, message, strlen(message)); wr_err = udp_sendto_if(udp_pcb, p, target_ip, target_port, &pnetif); if (wr_err) { INFO("UDP_SENDTO_IF error %d", (int)wr_err); } pbuf_free(p); } } void _udp_send_message(void* parameters) { udp_message_info_t* info = (udp_message_info_t*)parameters; if (info == NULL) { INFO("Params were not passed"); return; } const char* message = info->message; const ip_addr_t target_ip = info->target_ip; const u16_t target_port = info->target_port; err_t wr_err = ERR_OK; struct pbuf* p = pbuf_alloc(PBUF_TRANSPORT, strlen(message), PBUF_RAM); if (p != NULL) { memcpy(p->payload, message, strlen(message)); wr_err = udp_sendto_if(udp_pcb, p, &target_ip, target_port, &pnetif); if (wr_err) { INFO("UDP_SENDTO_IF error %d", (int)wr_err); } pbuf_free(p); } } void ethernet_loop(void) { // udp_send_message("broadcast ip test", &broadcast_ip, UDP_PORT_DST); err_t error = ethernetif_init(&pnetif); if (error) { ERROR("ethernetif_init failed"); configASSERT(0); } sys_check_timeouts(); }