static PCB_PTR _iopcb_hdlc_read ( _iopcb_handle handle, /* [IN] - the structure handle */ uint_32 flags /* [IN] - flags */ ) { /* Body */ RTCS_HDLC_MESSAGE_STRUCT_PTR msg_ptr; HDLCIO_STRUCT_PTR hdlcio_ptr = (HDLCIO_STRUCT_PTR)((void _PTR_)handle); PCB_FRAGMENT _PTR_ pcb_frag_ptr; uint_32 data_length; PCB_PTR pcb; while (TRUE) { PPP_mutex_lock(hdlcio_ptr->MUTEX_PTR); msg_ptr = RTCS_msgq_receive(hdlcio_ptr->QID, 0, hdlcio_ptr->POOL_ID); hdlcio_ptr->STATS.COMMON.ST_RX_TOTAL++; if ( msg_ptr == NULL ) { hdlcio_ptr->STATS.COMMON.ST_RX_ERRORS++; RTCS_time_delay(1); } else { data_length = msg_ptr->HDLC_HEADER.PACKET_SIZE; if (data_length > RTCS_HDLC_MESSAGE_SIZE ) { hdlcio_ptr->STATS.ST_RX_GIANT++; RTCS_msg_free(msg_ptr); continue; } else if (data_length < 2) { hdlcio_ptr->STATS.ST_RX_RUNT++; RTCS_msg_free(msg_ptr); continue; } else { pcb = RTCS_part_alloc(hdlcio_ptr->PART_ID); if (!pcb) { hdlcio_ptr->STATS.COMMON.ST_RX_MISSED++; RTCS_msg_free(msg_ptr); continue; }/* Endif */ break; } /* Endif */ } /* Endif */ } /* Endwhile */ pcb->FREE = (void (_CODE_PTR_)(PCB_PTR))RTCS_part_free; pcb->PRIVATE = pcb; pcb_frag_ptr = pcb->FRAG; pcb_frag_ptr->FRAGMENT = (uchar_ptr)pcb + sizeof(PCB) + sizeof(PCB_FRAGMENT); pcb_frag_ptr->LENGTH = data_length - 2; pcb_frag_ptr++; pcb_frag_ptr->LENGTH = 0; pcb_frag_ptr->FRAGMENT = NULL; RTCS_memcopy(msg_ptr->DATA+2, pcb->FRAG[0].FRAGMENT, data_length - 2); RTCS_msg_free(msg_ptr); return pcb; } /* Endbody */
/* * Task for reading from socket and sending data to output file descriptor. */ void telnetcln_in_task(void * v_context, void * creator) { TELNETCLN_CONTEXT *context; context = (TELNETCLN_CONTEXT *) v_context; context->rx_tid = _task_get_id(); RTCS_task_resume_creator(creator, RTCS_OK); _task_block(); while(context->valid == TELNETCLN_CONTEXT_VALID) { bool b_result = TRUE; #if MQX_USE_IO_OLD /* old IO (fio.h) fstatus() */ b_result = fstatus(context->telnetfd); #endif if(b_result && context->tx_tid) { int32_t c; c = (int32_t) fgetc(context->telnetfd); if(c == IO_EOF) { if (context->tx_tid == 0) { context->params.callbacks.on_disconnected(context->params.callbacks.param); telnetcln_cleanup(context); _mem_free(context); return; } break; } fputc(c & 0x7F, context->params.fd_out); } else { /* * this executes only for old IO. * for NIO we expect fgetc() is blocking */ if (context->tx_tid == 0) { context->params.callbacks.on_disconnected(context->params.callbacks.param); telnetcln_cleanup(context); _mem_free(context); return; } RTCS_time_delay(10); } } context->rx_tid = 0; #if !MQX_USE_IO_OLD ioctl(fileno(context->params.fd_in), IOCTL_ABORT, NULL); #endif }
/* * Task for reading from input and sending data through socket. */ void telnetcln_out_task(void * v_context, void * creator) { TELNETCLN_CONTEXT *context; context = (TELNETCLN_CONTEXT *) v_context; context->tx_tid = _task_get_id(); RTCS_task_resume_creator(creator, RTCS_OK); while(context->valid == TELNETCLN_CONTEXT_VALID) { bool b_result = TRUE; #if MQX_USE_IO_OLD /* * old IO (fio.h) input might be polled UART driver * thus only for this case we check if a character is available. * is there is no character, sleep for a tick */ b_result = fstatus(context->params.fd_in); #endif if (b_result && context->rx_tid) { int32_t c; c = (int32_t) fgetc(context->params.fd_in); #if !MQX_USE_IO_OLD if (EOF == c) { clearerr(context->params.fd_in); if (context->rx_tid == 0) { context->params.callbacks.on_disconnected(context->params.callbacks.param); telnetcln_cleanup(context); _mem_free(context); return; } break; } if (c == '\n') { c = '\r' ; } #endif if (fputc(c & 0x7F, context->telnetfd) == IO_EOF) { break; } } else { /* * this executes only for old IO uart driver. * for NIO tty, fgetc() above is blocking function. */ if (context->rx_tid == 0) { context->params.callbacks.on_disconnected(context->params.callbacks.param); telnetcln_cleanup(context); _mem_free(context); return; } RTCS_time_delay(10); } } context->tx_tid = 0; }
_mqx_int lw_telnet_server(void (_CODE_PTR_ user_fn)(void)) { uint_32 listensock, sock; sockaddr_in addr; uint_32 error, option; MQX_FILE_PTR sockfd, telnetfd; _mqx_uint echoflag = IO_SERIAL_ECHO; pointer old_stdin, old_stdout; /* Install device drivers for socket and telnet I/O */ _io_socket_install("socket:"); _io_telnet_install("telnet:"); listensock = socket(PF_INET, SOCK_STREAM, 0); return_error_if(listensock == RTCS_SOCKET_ERROR); option = TELNETDCFG_BUFFER_SIZE; error = setsockopt(listensock, SOL_TCP, OPT_TBSIZE, &option, sizeof(option)); return_error_if(error != RTCS_OK); option = TELNETDCFG_BUFFER_SIZE; error = setsockopt(listensock, SOL_TCP, OPT_RBSIZE, &option, sizeof(option)); return_error_if(error != RTCS_OK); option = TELENETDCFG_TIMEWAIT_TIMEOUT; error = setsockopt(listensock, SOL_TCP, OPT_TIMEWAIT_TIMEOUT, &option, sizeof(option)); return_error_if(error != RTCS_OK); /* Bind the socket to the Telnet port */ addr.sin_family = AF_INET; addr.sin_port = IPPORT_TELNET; addr.sin_addr.s_addr = INADDR_ANY; error = bind(listensock, &addr, sizeof(addr)); return_error_if(error != RTCS_OK); /* Put the socket into listening mode */ error = listen(listensock, 0); return_error_if(error != RTCS_OK); do { /* Wait for a connection */ sock= accept(listensock, NULL, NULL); if (sock != RTCS_SOCKET_ERROR) { sockfd = fopen("socket:", (char_ptr)sock); if (sockfd != NULL) { telnetfd = fopen("telnet:", (char_ptr)sockfd); if (telnetfd != NULL) { ioctl(telnetfd, IO_IOCTL_SERIAL_SET_FLAGS, &echoflag); old_stdin = _io_set_handle(IO_STDIN, telnetfd); old_stdout = _io_set_handle(IO_STDOUT, telnetfd); (*user_fn)(); _io_set_handle(IO_STDIN, old_stdin); _io_set_handle(IO_STDOUT, old_stdout); /* ** Allow some time for queued data to go out. */ RTCS_time_delay(100); fclose(telnetfd); } fclose(sockfd); } shutdown(sock, FLAG_CLOSE_TX); } } while (sock != RTCS_SOCKET_ERROR); shutdown(listensock, FLAG_CLOSE_TX); return RTCS_OK; }
uint_32 TELNET_connect ( _ip_address ipaddress ) { /* Body */ MQX_FILE_PTR sockfd, telnetfd; sockaddr_in addr; uint_32 sock; uint_32 error; boolean work; int_32 c; /* ** Install device driver for socket and telnet */ _io_socket_install("socket:"); _io_telnet_install("telnet:"); sock = socket(PF_INET, SOCK_STREAM, 0); if (sock == RTCS_SOCKET_ERROR) { return RTCSERR_OUT_OF_SOCKETS; } /* Endif */ addr.sin_family = AF_INET; addr.sin_port = 0; addr.sin_addr.s_addr = INADDR_ANY; error = bind(sock,(const sockaddr *)&addr, sizeof(addr)); if (error != RTCS_OK) { return error; } /* Endif */ addr.sin_port = IPPORT_TELNET; addr.sin_addr.s_addr = ipaddress; error = connect(sock, (const sockaddr *)(&addr), sizeof(addr)); if (error != RTCS_OK) { shutdown(sock, FLAG_ABORT_CONNECTION); return error; } /* Endif */ sockfd = fopen("socket:", (char_ptr)sock); if (sockfd == NULL) { shutdown(sock, FLAG_ABORT_CONNECTION); return RTCSERR_FOPEN_FAILED; } /* Endif */ telnetfd = fopen("telnet:", (char_ptr)sockfd); if (telnetfd == NULL) { fclose(sockfd); shutdown(sock, FLAG_ABORT_CONNECTION); return RTCSERR_FOPEN_FAILED; } /* Endif */ /* Set the console stream to the client */ ioctl(telnetfd, IO_IOCTL_SET_STREAM, (uint_32_ptr)((void _PTR_)stdin)); while (TRUE) { work = FALSE; if (fstatus(stdin)) { work = TRUE; c = (int_32)fgetc(stdin); if (fputc(c & 0x7F, telnetfd) == IO_EOF) { break; } } /* Endif */ if (fstatus(telnetfd)) { work = TRUE; c = (int_32)fgetc(telnetfd); if (c == IO_EOF) { break; }/* Endif */ fputc(c & 0x7F, stdout); } /* Endif */ /* Let another task run if there is no I/O */ if (!work) { RTCS_time_delay(1); } /* Endif */ } /* Endwhile */ fclose(telnetfd); fclose(sockfd); shutdown(sock, FLAG_CLOSE_TX); return RTCS_OK; } /* Endbody */