/* telnet server thread entry */ void telnet_thread(void* parameter) { rt_err_t result,err; rt_uint32_t event; struct netbuf *buf; struct netconn *conn, *newconn; /* Create a new connection identifier. */ conn = netconn_new(NETCONN_TCP); /* Bind connection to well known port number 7. */ netconn_bind(conn, NULL, TELNET_PORT); /* Tell connection to go into listening mode. */ netconn_listen(conn); /* register telnet device */ telnet->device.type = RT_Device_Class_Char; telnet->device.init = telnet_init; telnet->device.open = telnet_open; telnet->device.close = telnet_close; telnet->device.read = telnet_read; telnet->device.write = telnet_write; telnet->device.control = telnet_control; /* no private */ telnet->device.user_data = RT_NULL; /* register telnet device */ rt_device_register(&telnet->device, "telnet", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STREAM); while (1) { rt_kprintf("telnet server waiting for connection\n"); /* Grab new connection. */ err = netconn_accept(conn, &newconn); //if (err == RT_EOK) continue; /* set network rx call back */ newconn->callback = rx_callback; rt_kprintf("new telnet connection, switch console to telnet...\n"); /* Process the new connection. */ /* set console */ rt_console_set_device("telnet"); /* set finsh device */ finsh_set_device("telnet"); /* set init state */ telnet->state = STATE_NORMAL; telnet->echo_mode = finsh_get_echo(); /* disable echo mode */ finsh_set_echo(0); while (1) { /* try to send all data in tx ringbuffer */ telnet_process_tx(telnet, newconn); /* receive network event */ result = rt_event_recv(telnet->nw_event, NW_MASK, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_TICK_PER_SECOND, &event); if (result == RT_EOK) { /* get event successfully */ if (event & NW_RX) { /* do a rx procedure */ err= netconn_recv(newconn, &buf); if (buf != RT_NULL) { rt_uint8_t *data; rt_uint16_t length; /* get data */ netbuf_data(buf, (void**)&data, &length); telnet_process_rx(telnet, data, length); /* release buffer */ netbuf_delete(buf); } else { if (newconn->last_err == ERR_CLSD) { /* close connection */ telnet_process_close(telnet, newconn); break; } } } if (event & NW_TX) telnet_process_tx(telnet, newconn); if (event & NW_CLOSED) { /* process close */ telnet_process_close(telnet, newconn); break; } } else if (result == -RT_ETIMEOUT) { if (newconn->state == NETCONN_CLOSE) { telnet_process_close(telnet, newconn); break; } } } } }
/* telnet server thread entry */ static void telnet_thread(void* parameter) { #define RECV_BUF_LEN 64 struct sockaddr_in addr; socklen_t addr_size; rt_uint8_t recv_buf[RECV_BUF_LEN]; rt_int32_t recv_len = 0; if ((telnet->server_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { rt_kprintf("telnet: create socket failed\n"); return; } addr.sin_family = AF_INET; addr.sin_port = htons(TELNET_PORT); addr.sin_addr.s_addr = INADDR_ANY; rt_memset(&(addr.sin_zero), 0, sizeof(addr.sin_zero)); if (bind(telnet->server_fd, (struct sockaddr *)&addr, sizeof(struct sockaddr)) == -1) { rt_kprintf("telnet: bind socket failed\n"); return; } if (listen(telnet->server_fd, TELNET_BACKLOG) == -1) { rt_kprintf("telnet: listen socket failed\n"); return; } /* register telnet device */ telnet->device.type = RT_Device_Class_Char; telnet->device.init = telnet_init; telnet->device.open = telnet_open; telnet->device.close = telnet_close; telnet->device.read = telnet_read; telnet->device.write = telnet_write; telnet->device.control = telnet_control; /* no private */ telnet->device.user_data = RT_NULL; /* register telnet device */ rt_device_register(&telnet->device, "telnet", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STREAM); while (1) { rt_kprintf("telnet server waiting for connection\n"); /* grab new connection */ if ((telnet->client_fd = accept(telnet->server_fd, (struct sockaddr * )&addr, &addr_size)) == -1) { continue; } rt_kprintf("new telnet client(%s:%d) connection, switch console to telnet...\n", inet_ntoa(addr.sin_addr), addr.sin_port); /* process the new connection */ /* set console */ rt_console_set_device("telnet"); /* set finsh device */ finsh_set_device("telnet"); /* set init state */ telnet->state = STATE_NORMAL; telnet->echo_mode = finsh_get_echo(); /* disable echo mode */ finsh_set_echo(0); while (1) { /* try to send all data in tx ringbuffer */ send_to_client(telnet); /* do a rx procedure */ if ((recv_len = recv(telnet->client_fd, recv_buf, RECV_BUF_LEN, 0)) > 0) { process_rx(telnet, recv_buf, recv_len); } else { /* close connection */ client_close(telnet); break; } } } }