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;