#include "user.h" #include "embfmt/embformat.h" #include "lwip/apps/fs.h" #include "lwip/apps/httpd.h" #include "lwip/igmp.h" #include "lwip/tcp.h" #include "lwip/udp.h" #include "netif/ethernet.h" #include "standard_output/standard_output.h" #include #define MAX(a, b) (((a) > (b)) ? (a) : (b)) #define MIN(a, b) (((a) < (b)) ? (a) : (b)) // ----------------------------------- #define RECV_BUF_LEN (511) static char recv_buf[RECV_BUF_LEN + 1]; static char *msg = "Üdvözlet a H735-ös kártyáról!"; // ----------- Custom EtherType client // TODO: 0x9000 fölött kb. bármit lehet választani #define CUSTOM_RX_ETHERTYPE (0x88F7) err_t hook_unknown_ethertype(struct pbuf *pbuf, struct netif *netif) { // aquire ethertype uint16_t etherType = 0; memcpy(ðerType, ((uint8_t *)pbuf->payload) + 12, 2); etherType = ntohs(etherType); uint8_t *shwa = ((uint8_t *)pbuf->payload) + 6; // get source hardware address uint16_t len = pbuf->len - 14; // get payload length uint8_t *payload = ((uint8_t *)pbuf->payload) + 14; // actual payload // check for match if (etherType == CUSTOM_RX_ETHERTYPE) { // copy payload uint16_t copy_len = MIN(RECV_BUF_LEN, len); recv_buf[copy_len] = '\0'; memcpy(recv_buf, payload, copy_len); // print it MSG("[%02X:%02X:%02X:%02X:%02X:%02X] %u\n%s\n", shwa[0], shwa[1], shwa[2], shwa[3], shwa[4], shwa[5], len, recv_buf); } pbuf_free(pbuf); return ERR_OK; } #define CUSTOM_TX_ETHERTYPE (0x9101) static struct eth_addr dest_hwa = {.addr = {0x00, 0x1b, 0x21, 0x91, 0x9E, 0x64}}; void send_frame() { uint16_t len = strlen(msg); struct pbuf *p = pbuf_alloc(PBUF_LINK, len, PBUF_RAM); if (p == NULL) { MSG("Nem sikerült pbuf-ot foglalni az Ethernet-keret küldéséhez!\n"); return; } memcpy(p->payload, msg, len); if (ethernet_output(netif_default, p, (struct eth_addr *)netif_default->hwaddr, &dest_hwa, CUSTOM_TX_ETHERTYPE) != ERR_OK) { MSG("Sikertelen volt az Ethernet-keret küldése!\n"); return; } pbuf_free(p); } // ----------- UDP client ------------ static struct udp_pcb *udpc; static ip4_addr_t dest_addr; static uint16_t dest_port; void udp_client_init() { // create new PCB udpc = udp_new(); if (udpc == NULL) { MSG("Hiba az UDP-kliens létrehozásánál!\n"); } // set destination IP address and port IP4_ADDR(&dest_addr, 10, 42, 0, 1); dest_port = 4000; // TODO: connect? } void udp_client_send() { uint16_t len = strlen(msg); // allocate pbuf and fill with contents struct pbuf *buf = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); if (buf == NULL) { MSG("Nem lehetett újabb pbuf-ot foglalni!\n"); return; } memcpy(buf->payload, msg, len); // send UDP datagram to defined destination if (udp_sendto(udpc, buf, &dest_addr, dest_port) != ERR_OK) { MSG("Nem sikerült elküldeni az UDP datagramot!\n"); } // decrease reference count of the buf pbuf_free(buf); } // ----------------------------------- static struct udp_pcb *udps; static uint16_t server_port; static void udp_server_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) { uint16_t copy_len = MIN(RECV_BUF_LEN, p->len); recv_buf[copy_len] = '\0'; memcpy(recv_buf, p->payload, copy_len); MSG("[%s:%u] %ub\n%s\n", ipaddr_ntoa(addr), port, p->len, recv_buf); pbuf_free(p); } void udp_server_init() { // create new PCB udps = udp_new(); if (udps == NULL) { MSG("Hiba az UDP-szerver létrehozásánál!\n"); } // set server port server_port = 3000; // bind it to a local address if (udp_bind(udps, IP4_ADDR_ANY, server_port) != ERR_OK) { MSG("Nem sikerült az UDP-szervert felcsatolni a %u portra!\n", server_port); udp_remove(udps); } // register receive callback udp_recv(udps, udp_server_recv, NULL); } // ----------------------------------- static struct udp_pcb *udpmc; static uint16_t mc_port; static ip4_addr_t mc_group; static void udp_mcast_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) { uint16_t copy_len = MIN(RECV_BUF_LEN, p->len); recv_buf[copy_len] = '\0'; memcpy(recv_buf, p->payload, copy_len); MSG("[%s:%u] %ub\n%s\n", ipaddr_ntoa(addr), port, p->len, recv_buf); pbuf_free(p); } void udp_mcast_init() { // create new PCB udpmc = udp_new(); if (udps == NULL) { MSG("Hiba a multicast UDP szolgáltatás létrehozásánál!\n"); } // set multicast group's address and port IP4_ADDR(&mc_group, 224, 0, 2, 5); mc_port = 2000; // join the relevant multicast group igmp_joingroup(&netif_default->ip_addr, &mc_group); // bind it to a local address if (udp_bind(udpmc, &mc_group, mc_port) != ERR_OK) { MSG("Nem sikerült az UDP-szervert felcsatolni a %u portra!\n", mc_port); goto cleanup; } // connect to the IGMP group if (udp_connect(udpmc, &mc_group, mc_port) != ERR_OK) { MSG("Nem sikerült az UDP multicast szolgáltatást becsatlakoztatni a multicast-csoportba!\n"); goto cleanup; } // register receive callback udp_recv(udpmc, udp_mcast_recv, NULL); return; // --- cleanup: udp_remove(udpmc); return; } void udp_mcast_send() { uint16_t len = strlen(msg); // allocate pbuf and fill with contents struct pbuf *buf = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); if (buf == NULL) { MSG("Nem lehetett újabb pbuf-ot foglalni!\n"); return; } memcpy(buf->payload, msg, len); // send UDP datagram to defined destination if (udp_send(udpmc, buf) != ERR_OK) { MSG("Nem sikerült elküldeni az UDP datagramot!\n"); } // decrease reference count of the buf pbuf_free(buf); } // ----------------------------------- static struct tcp_pcb *tcps; static uint16_t tcps_port; static ip_addr_t tcps_addr; static err_t tcp_server_conn_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) { if (p != NULL) { uint16_t copy_len = MIN(RECV_BUF_LEN, p->len); recv_buf[copy_len] = '\0'; memcpy(recv_buf, p->payload, copy_len); MSG("[%s:%u] %ub\n%s\n", ipaddr_ntoa(&tpcb->remote_ip), tpcb->remote_port, p->len, recv_buf); pbuf_free(p); tcp_recved(tpcb, copy_len); } else { MSG("A kliens lekapcsolódott %s:%u\n", ipaddr_ntoa(&tpcb->remote_ip), tpcb->remote_port); } return ERR_OK; } static void tcp_server_conn_err(void *arg, err_t err) { MSG("TCP-kapcsolat hiba! (%u)\n", err); } static err_t tcp_server_accept(void *arg, struct tcp_pcb *newpcb, err_t err) { tcp_recv(newpcb, tcp_server_conn_recv); tcp_err(newpcb, tcp_server_conn_err); MSG("Bejövő TCP-kapcsolat érkezett %s:%u!\n", ipaddr_ntoa(&newpcb->remote_ip), newpcb->remote_port); return ERR_OK; } static void tcp_server_error(void *arg, err_t err) { MSG("TCP-szerver hiba! (%u)\n", err); } void tcp_server_init() { // create new TCP service tcps = tcp_new(); if (tcps == NULL) { MSG("Nem sikerült létrehozni a TCP szerver szolgáltatást!\n"); return; } // set port tcps_port = 6000; IP4_ADDR(&tcps_addr, 10, 42, 0, 137); // bind to local port if (tcp_bind(tcps, &tcps_addr, tcps_port) != ERR_OK) { MSG("Nem sikerült a TCP-szervert a %u portra csatolni!\n", tcps_port); goto cleanup; } // enable server functions tcps = tcp_listen(tcps); // assign error handling function tcp_err(tcps, tcp_server_error); // register accept callback tcp_accept(tcps, tcp_server_accept); return; // ----- cleanup: tcp_close(tcps); return; } static struct tcp_pcb *tcpc; static ip4_addr_t tcpc_remote_addr; static uint16_t tcpc_remote_port; static void tcp_client_error(void *arg, err_t err) { MSG("TCP-kliens hiba! (%u)\n", err); } static err_t tcp_client_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) { if (p != NULL) { uint16_t copy_len = MIN(RECV_BUF_LEN, p->len); recv_buf[copy_len] = '\0'; memcpy(recv_buf, p->payload, copy_len); MSG("[%s:%u] %ub\n%s\n", ipaddr_ntoa(&tpcb->remote_ip), tpcb->remote_port, p->len, recv_buf); pbuf_free(p); tcp_recved(tpcb, copy_len); } else { MSG("A szerver bontotta a kapcsolatot %s:%u\n", ipaddr_ntoa(&tpcb->remote_ip), tpcb->remote_port); } return ERR_OK; } static err_t tcp_client_connected(void *arg, struct tcp_pcb *tpcb, err_t err) { MSG("Sikeresen fölkapcsolódtunk a TCP-szerverre: %s:%u!\n", ipaddr_ntoa(&tpcb->remote_ip), tpcb->remote_port); tcp_write(tcpc, msg, strlen(msg), 0); tcp_close(tcpc); return ERR_OK; } void tcp_client_init() { // create new TCP service tcpc = tcp_new(); if (tcpc == NULL) { MSG("Nem sikerült létrehozni a TCP szerver szolgáltatást!\n"); return; } // set remote address and port IP4_ADDR(&tcpc_remote_addr, 10, 42, 0, 1); tcpc_remote_port = 9000; // assign error handling function tcp_err(tcpc, tcp_client_error); // assign reception callback tcp_recv(tcpc, tcp_client_recv); // connect to remote host tcp_connect(tcpc, &tcpc_remote_addr, tcpc_remote_port, tcp_client_connected); } // ----------------------------------- #define GENDATA_LEN (31) static char generated_data[GENDATA_LEN + 1]; int fs_open_custom(struct fs_file *file, const char *name) { /* this example only provides one file */ if (!strcmp(name, "/generated.html")) { /* generate a random number */ uint32_t random = rand(); embfmt(generated_data, GENDATA_LEN, "%u is random!", random); /* initialize fs_file correctly */ memset(file, 0, sizeof(struct fs_file)); uint32_t len = strlen(generated_data); file->pextension = mem_malloc(len); if (file->pextension != NULL) { /* instead of doing memcpy, you would generate e.g. a JSON here */ memcpy(file->pextension, generated_data, len); file->data = (const char *)file->pextension; file->len = len; /* don't send the trailing 0 */ file->index = file->len; /* allow persisting connections */ file->flags = FS_FILE_FLAGS_HEADER_PERSISTENT; return 1; } } return 0; } void fs_close_custom(struct fs_file *file) { if (file && file->pextension) { mem_free(file->pextension); file->pextension = NULL; } } // ----------------------------------- // void btn_cb() { // MSG("Küldés!\n"); // //udp_client_send(); // // send_frame(); // // udp_mcast_send(); // tcp_client_init(); // } void user_init() { udp_client_init(); // udp_server_init(); // udp_mcast_init(); tcp_server_init(); httpd_init(); }