示例#1
0
文件: hdlcio.c 项目: gxliu/MQX_3.8.0
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 */
示例#2
0
/*
 * 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
}
示例#3
0
/*
 * 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;
}
示例#4
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;
} 
示例#5
0
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 */