397 lines
11 KiB
C
397 lines
11 KiB
C
#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 <string.h>
|
|
|
|
#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();
|
|
} |