138 lines
3.3 KiB
C
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;
|
|
}
|