Files
pico/wifi_tcp/wifi_tcp.c
T

138 lines
3.3 KiB
C

#include <stdio.h>
#include <string.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "lwip/pbuf.h"
#include "lwip/tcp.h"
#define SERVER_IP "192.168.161.25"
#define SERVER_PORT 8080
typedef struct {
struct tcp_pcb *pcb;
ip_addr_t remote;
volatile bool done;
} client_t;
static void finish(client_t *c) {
if (c->pcb) {
tcp_arg(c->pcb, NULL);
tcp_recv(c->pcb, NULL);
tcp_err(c->pcb, NULL);
tcp_close(c->pcb);
c->pcb = NULL;
}
c->done = true;
}
static void send_line(struct tcp_pcb *pcb, const char *msg) {
err_t err = tcp_write(pcb, msg, strlen(msg), TCP_WRITE_FLAG_COPY);
if (err == ERR_OK) {
tcp_output(pcb);
} else {
printf("tcp_write err=%d\n", err);
}
}
static err_t on_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) {
client_t *c = (client_t *)arg;
if (!p) {
printf("Server hat Verbindung geschlossen\n");
finish(c);
return ERR_OK;
}
char buf[64];
uint16_t n = pbuf_copy_partial(p, buf, sizeof(buf) - 1, 0);
buf[n] = '\0';
printf("<< %s", buf);
if (strstr(buf, "ping")) {
printf(">> pong\n");
send_line(pcb, "pong\n");
}
tcp_recved(pcb, p->tot_len);
pbuf_free(p);
return ERR_OK;
}
static void on_err(void *arg, err_t err) {
client_t *c = (client_t *)arg;
printf("TCP-Fehler: %d\n", err);
// lwIP hat das pcb in diesem Callback bereits freigegeben.
c->pcb = NULL;
c->done = true;
}
static err_t on_connected(void *arg, struct tcp_pcb *pcb, err_t err) {
client_t *c = (client_t *)arg;
if (err != ERR_OK) {
printf("connect-Callback err=%d\n", err);
finish(c);
return err;
}
printf("Verbunden — sende Hallo\n");
const char *msg = "Hallo vom Pico 2W\n";
err = tcp_write(pcb, msg, strlen(msg), TCP_WRITE_FLAG_COPY);
if (err == ERR_OK) {
tcp_output(pcb);
} else {
printf("tcp_write err=%d\n", err);
}
return err;
}
int main(void) {
stdio_init_all();
sleep_ms(2000); // Zeit, das USB-Serial-Terminal zu oeffnen
if (cyw43_arch_init()) {
printf("cyw43_arch_init fehlgeschlagen\n");
return 1;
}
cyw43_arch_enable_sta_mode();
printf("Verbinde mit WLAN \"%s\"...\n", WIFI_SSID);
if (cyw43_arch_wifi_connect_timeout_ms(WIFI_SSID, WIFI_PASSWORD,
CYW43_AUTH_WPA2_AES_PSK, 30000)) {
printf("WLAN-Verbindung fehlgeschlagen\n");
return 1;
}
printf("WLAN OK\n");
client_t client = {0};
if (!ip4addr_aton(SERVER_IP, &client.remote)) {
printf("Ungueltige Server-IP\n");
return 1;
}
client.pcb = tcp_new_ip_type(IP_GET_TYPE(&client.remote));
if (!client.pcb) {
printf("tcp_new fehlgeschlagen\n");
return 1;
}
tcp_arg(client.pcb, &client);
tcp_recv(client.pcb, on_recv);
tcp_err(client.pcb, on_err);
printf("Verbinde TCP %s:%d\n", SERVER_IP, SERVER_PORT);
cyw43_arch_lwip_begin();
err_t err = tcp_connect(client.pcb, &client.remote, SERVER_PORT, on_connected);
cyw43_arch_lwip_end();
if (err != ERR_OK) {
printf("tcp_connect err=%d\n", err);
return 1;
}
while (!client.done) {
sleep_ms(100);
}
cyw43_arch_deinit();
return 0;
}