Wifi, TCP-Client and Ping/Pong
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
#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;
|
||||
}
|
||||
Reference in New Issue
Block a user