forked from raspberrypi/pico-examples
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpicow_access_point.c
180 lines (153 loc) · 4.81 KB
/
picow_access_point.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/**
* Copyright (c) 2022 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <string.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "lwip/pbuf.h"
#include "lwip/tcp.h"
#include "dhcpserver.h"
#ifndef USE_LED
#define USE_LED 1
#endif
#define TCP_PORT 80
#define DEBUG_printf printf
typedef struct TCP_ASERVER_T_ {
struct tcp_pcb *server_pcb;
struct tcp_pcb *client_pcb;
bool complete;
} TCP_SERVER_T;
static err_t tcp_server_close(void *arg) {
TCP_SERVER_T *state = (TCP_SERVER_T*)arg;
err_t err = ERR_OK;
if (state->client_pcb != NULL) {
tcp_arg(state->client_pcb, NULL);
tcp_poll(state->client_pcb, NULL, 0);
tcp_sent(state->client_pcb, NULL);
tcp_recv(state->client_pcb, NULL);
tcp_err(state->client_pcb, NULL);
err = tcp_close(state->client_pcb);
if (err != ERR_OK) {
DEBUG_printf("close failed %d, calling abort\n", err);
tcp_abort(state->client_pcb);
err = ERR_ABRT;
}
state->client_pcb = NULL;
}
if (state->server_pcb) {
tcp_arg(state->server_pcb, NULL);
tcp_close(state->server_pcb);
state->server_pcb = NULL;
}
return err;
}
static err_t tcp_ap_result(void *arg, int status) {
TCP_SERVER_T *state = (TCP_SERVER_T*)arg;
if (status == 0) {
DEBUG_printf("test success\n");
} else {
DEBUG_printf("test failed %d\n", status);
}
state->complete = true;
return tcp_server_close(arg);
}
static err_t tcp_server_accept(void *arg, struct tcp_pcb *client_pcb, err_t err) {
// TCP_SERVER_T *state = (TCP_SERVER_T*)arg;
if (err != ERR_OK || client_pcb == NULL) {
DEBUG_printf("Failure in accept\n");
tcp_ap_result(arg, err);
return ERR_VAL;
}
DEBUG_printf("Client connected\n");
/*state->client_pcb = client_pcb;
tcp_arg(client_pcb, state);
tcp_sent(client_pcb, tcp_server_sent);
tcp_recv(client_pcb, tcp_server_recv);
tcp_poll(client_pcb, tcp_server_poll, POLL_TIME_S * 2);
tcp_err(client_pcb, tcp_server_err);
return tcp_server_send_data(arg, state->client_pcb);*/
return ERR_OK;
}
static bool tcp_server_open(void *arg) {
TCP_SERVER_T *state = (TCP_SERVER_T*)arg;
DEBUG_printf("Starting server on port %u\n", TCP_PORT);
struct tcp_pcb *pcb = tcp_new_ip_type(IPADDR_TYPE_ANY);
if (!pcb) {
DEBUG_printf("failed to create pcb\n");
return false;
}
err_t err = tcp_bind(pcb, NULL, TCP_PORT);
if (err) {
DEBUG_printf("failed to bind to port %d\n");
return false;
}
state->server_pcb = tcp_listen_with_backlog(pcb, 1);
if (!state->server_pcb) {
DEBUG_printf("failed to listen\n");
if (pcb) {
tcp_close(pcb);
}
return false;
}
tcp_arg(state->server_pcb, state);
tcp_accept(state->server_pcb, tcp_server_accept);
return true;
}
int main() {
stdio_init_all();
TCP_SERVER_T *state = calloc(1, sizeof(TCP_SERVER_T));
if (!state) {
DEBUG_printf("failed to allocate state\n");
return 1;
}
if (cyw43_arch_init()) {
printf("failed to initialise\n");
return 1;
}
const char *ap_name = "picow_test";
#if 1
const char *password = "password";
#else
const char *password = NULL;
#endif
cyw43_arch_enable_ap_mode(ap_name, password, CYW43_AUTH_WPA2_AES_PSK);
ip4_addr_t gw, mask;
IP4_ADDR(&gw, 192, 168, 4, 1);
IP4_ADDR(&mask, 255, 255, 255, 0);
// Start the dhcp server
dhcp_server_t dhcp_server;
dhcp_server_init(&dhcp_server, &gw, &mask);
if (!tcp_server_open(state)) {
tcp_ap_result(state, -1);
}
while(!state->complete) {
#if USE_LED
static absolute_time_t led_time;
static int led_on = true;
// Invert the led
if (absolute_time_diff_us(get_absolute_time(), led_time) < 0) {
led_on = !led_on;
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, led_on);
led_time = make_timeout_time_ms(1000);
}
#endif
// the following #ifdef is only here so this same example can be used in multiple modes;
// you do not need it in your code
#if PICO_CYW43_ARCH_POLL
// if you are using pico_cyw43_arch_poll, then you must poll periodically from your
// main loop (not from a timer) to check for WiFi driver or lwIP work that needs to be done.
cyw43_arch_poll();
sleep_ms(1);
#else
// if you are not using pico_cyw43_arch_poll, then WiFI driver and lwIP work
// is done via interrupt in the background. This sleep is just an example of some (blocking)
// work you might be doing.
sleep_ms(1000);
#endif
}
dhcp_server_deinit(&dhcp_server);
cyw43_arch_deinit();
return 0;
}