Mercurial > repos > blastem
comparison megawifi.c @ 1961:d14630883b1d
Implement CMD_TCP_CON command
author | doragasu <doragasu@hotmail.com> |
---|---|
date | Sun, 03 May 2020 12:40:03 -0700 |
parents | f79e16d8baa4 |
children | 16d46ff1f620 |
comparison
equal
deleted
inserted
replaced
1960:f79e16d8baa4 | 1961:d14630883b1d |
---|---|
8 #include <ws2tcpip.h> | 8 #include <ws2tcpip.h> |
9 #else | 9 #else |
10 #include <sys/socket.h> | 10 #include <sys/socket.h> |
11 #include <unistd.h> | 11 #include <unistd.h> |
12 #include <netinet/in.h> | 12 #include <netinet/in.h> |
13 #include <netdb.h> | |
13 #endif | 14 #endif |
14 #include <errno.h> | 15 #include <errno.h> |
15 #include <fcntl.h> | 16 #include <fcntl.h> |
16 #include "genesis.h" | 17 #include "genesis.h" |
17 #include "net.h" | 18 #include "net.h" |
183 { | 184 { |
184 poll_socket(mw, i); | 185 poll_socket(mw, i); |
185 } | 186 } |
186 } | 187 } |
187 | 188 |
189 | |
188 static void start_reply(megawifi *mw, uint8_t cmd) | 190 static void start_reply(megawifi *mw, uint8_t cmd) |
189 { | 191 { |
190 mw_putc(mw, STX); | 192 mw_putc(mw, STX); |
191 //reserve space for length | 193 //reserve space for length |
192 mw->receive_bytes += 2; | 194 mw->receive_bytes += 2; |
234 mw_putc(mw, mw->transmit_buffer[4]); | 236 mw_putc(mw, mw->transmit_buffer[4]); |
235 mw_putc(mw, 0); | 237 mw_putc(mw, 0); |
236 mw_putc(mw, 0); | 238 mw_putc(mw, 0); |
237 mw_putc(mw, 0); | 239 mw_putc(mw, 0); |
238 mw_putraw(mw, (char*)ipv4s, sizeof(ipv4s)); | 240 mw_putraw(mw, (char*)ipv4s, sizeof(ipv4s)); |
241 end_reply(mw); | |
242 } | |
243 | |
244 static void cmd_tcp_con(megawifi *mw, uint32_t size) | |
245 { | |
246 struct addrinfo hints; | |
247 struct addrinfo *res = NULL; | |
248 char dst_port[6]; | |
249 char src_port[6]; | |
250 char host[MAX_RECV_SIZE - 13]; | |
251 int s; | |
252 | |
253 int err; | |
254 | |
255 uint8_t channel = mw->transmit_buffer[16]; | |
256 if (!channel || channel > 15 || mw->sock_fds[channel - 1] >= 0) { | |
257 start_reply(mw, CMD_ERROR); | |
258 end_reply(mw); | |
259 return; | |
260 } | |
261 channel--; | |
262 | |
263 strncpy(dst_port, (char*)&mw->transmit_buffer[4], 5); | |
264 dst_port[5] = '\0'; | |
265 // TODO src_port is unused | |
266 strncpy(src_port, (char*)&mw->transmit_buffer[10], 5); | |
267 src_port[5] = '\0'; | |
268 strncpy(host, (char*)&mw->transmit_buffer[17], MAX_RECV_SIZE - 14); | |
269 host[MAX_RECV_SIZE - 14] = '\0'; | |
270 | |
271 memset(&hints, 0, sizeof(hints)); | |
272 hints.ai_family = AF_INET; | |
273 hints.ai_flags = AI_NUMERICSERV; | |
274 hints.ai_socktype = SOCK_STREAM; | |
275 | |
276 if ((err = getaddrinfo(host, dst_port, &hints, &res)) != 0) { | |
277 printf("getaddrinfo failed: %s\n", gai_strerror(err)); | |
278 start_reply(mw, CMD_ERROR); | |
279 end_reply(mw); | |
280 return; | |
281 } | |
282 | |
283 s = socket(AF_INET, SOCK_STREAM, 0); | |
284 if (s < 0) { | |
285 goto err; | |
286 } | |
287 | |
288 // Should this be handled in a separate thread to avoid blocking emulation? | |
289 if (connect(s, res->ai_addr, res->ai_addrlen) != 0) { | |
290 goto err; | |
291 } | |
292 | |
293 #ifndef _WIN32 | |
294 //FIXME: Set nonblocking on Windows too | |
295 fcntl(s, F_SETFL, O_NONBLOCK); | |
296 #endif | |
297 mw->sock_fds[channel] = s; | |
298 mw->channel_state[channel] = SOCKST_TCP_EST; | |
299 mw->channel_flags |= 1 << (channel + 1); | |
300 printf("Connection established on ch %d with %s:%s\n", channel + 1, host, dst_port); | |
301 | |
302 if (res) { | |
303 freeaddrinfo(res); | |
304 } | |
305 start_reply(mw, CMD_OK); | |
306 end_reply(mw); | |
307 return; | |
308 | |
309 err: | |
310 freeaddrinfo(res); | |
311 printf("Connection to %s:%s failed, %s\n", host, dst_port, strerror(errno)); | |
312 start_reply(mw, CMD_ERROR); | |
239 end_reply(mw); | 313 end_reply(mw); |
240 } | 314 } |
241 | 315 |
242 static void process_command(megawifi *mw) | 316 static void process_command(megawifi *mw) |
243 { | 317 { |
301 case CMD_AP_JOIN: | 375 case CMD_AP_JOIN: |
302 mw->module_state = STATE_READY; | 376 mw->module_state = STATE_READY; |
303 start_reply(mw, CMD_OK); | 377 start_reply(mw, CMD_OK); |
304 end_reply(mw); | 378 end_reply(mw); |
305 break; | 379 break; |
380 case CMD_TCP_CON: | |
381 cmd_tcp_con(mw, size); | |
382 break; | |
306 case CMD_TCP_BIND:{ | 383 case CMD_TCP_BIND:{ |
307 if (size < 7){ | 384 if (size < 7){ |
308 start_reply(mw, CMD_ERROR); | 385 start_reply(mw, CMD_ERROR); |
309 end_reply(mw); | 386 end_reply(mw); |
310 break; | 387 break; |