This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

question about c6678 telnet server

HI TI engineers:
      When I development  c6678 , I meet a question about the telnet server problem. Can you give me
      some advice?
      My purpose is to implement a telnet shell command and can print out the message from telnent
      So my solution is to change the console.c code provided by TI.
     
      (1) first ,I merged the console.c into my project and config the NDK ,everything works ok
      (2) second I change the console.c code and and add my shell parse function.
          the netshell_console is almost the same as the console function.I stored the shell input
          string in the global buffer:netshellbuffer.Then I find the strange problem:
                       before call the run_netshell_command,I print out the netshellbuffer address is ok( the same as map file description)
                       in the run_netshell_command ,I aslo print out the netshellbuffer address .It is not the correct value
                  
                      

ConPrintf("netshellbuffer=0x%x",netshellbuffer);

run_netshell_command();     

          
      (3) I also changed the run_netshell_command function to send semaphore acction,but it seems that it doesnot work
           

ConPrintf("netshellbuffer=0x%x",netshellbuffer);

Sempost();     

       
       (4) In another taks ,I use ConPrintf to output some debug information ,but I seems doesnot work.
         
      So ,I think the spawned console task is different from other normal task . Can you give me some advice ?
      Thank you 
      
     

SOCKET MyConsoleOpen( PSA pClient )
{
    HANDLE fd1, fd2;

    // Create the local pipe - abort on error
    if( pipe( &fd1, &fd2 ) != 0 )
        return( INVALID_SOCKET );

    /* If an instance is already running, abort */
    if( hConsole )
    {
        /* If the console is already running, return a quick message and */
        /* close the pipe. */
        send( fd2, StrBusy, strlen(StrBusy), 0 );
        fdClose( fd2 );
    }
    else
    {
        /* Create the console thread */
     /*   hConsole = TaskCreate( console, "Console", OS_TASKPRINORM, 0x1000,
                               (UINT32)fd2, (UINT32)pClient, 0 );*/
        // create the telnet console thread
        hConsole = TaskCreate( netshell_console, "Console", OS_TASKPRINORM, 
        0x1000,
                               (UINT32)fd2, (UINT32)pClient, 0 );
        /* Close the pipe and abort on an error */
        if( !hConsole )
        {
            send( fd2, StrError, strlen(StrError), 0 );
            fdClose( fd2 );
        }
    }
    
    
    void netshell_console( SOCKET sCon, PSA pClient )
{
    uint   tmp;
    char   tstr[80];
    char   *tok[10];
    int    i,logon=0;
    fdOpenSession( TaskSelf() );

    /* Get our socket */
    scon = sCon;

#ifndef _INCLUDE_IPv6_CODE
    /* New console connection */
    {
        PSA_IN pClient_in = (PSA_IN)pClient;
        
        ConPrintf( VerStr );
        ConPrintf("Welcome connection : ");
        ConPrintIPN( pClient_in->sin_addr.s_addr );
        ConPrintf(":%d\n", htons( pClient_in->sin_port ) );
    }
#else
    {        
        PSA_IN6 pClient_in = (PSA_IN6)pClient;

        /* Print the banner */
        ConPrintf( VerStr );
        ConPrintf("Welcome connection : ");

        /* Check if the peer is V4 or V6? */
        if (pClient_in->sin6_family == AF_INET)
        {            
            PSA_IN pClient4_in = (PSA_IN)pClient;

            /* Print the V4 Peer Information. */
            ConPrintIPN( pClient4_in->sin_addr.s_addr );
            ConPrintf(":%d\n", htons( pClient4_in->sin_port ) );
        }
        else
        {
            char    strIPAddress[40];
            IP6N    clientIPAddress;

            /* Get the pointer to the V6 socket information and convert the V6 address to 
             * a printable format. */
            memcpy ((void *)&clientIPAddress, (void *)&pClient_in->sin6_addr, sizeof(IP6N));
            IPv6IPAddressToString (clientIPAddress, &strIPAddress[0]);

            /* Display the client information. */
            ConPrintf("%s:%d\n", strIPAddress, htons(pClient_in->sin6_port));
        }
    }
#endif /* _INCLUDE_IPv6_CODE */
      int strlength;
    /* Just for fun, ask for a password */
    for( tmp=0; tmp<3; tmp++ )
    {
        if( !strlen(Password) )
            break;
        ConPrintf("\nPassword: ");

        if( !strcmp(tstr, Password) )
            break;
        ConPrintf("\nInvalid login\n");
    }
    if( tmp >= 3 )
        logon = 0;
    else
    {
        ConPrintf("\n\nWelcome to the console program.\n");
        ConPrintf("Enter 'conhelp' or 'help' for a list of commands.\n\n");
        logon = 1;
    }

    /* Start the console command loop */
    while( logon )
    {
        /* Get a command string */
        ConPrintf(SHELLPROMPT);
        tstr[0]='\0';
        strlength=ConGetString( tstr, 80, CGSECHO_INPUT );
        ConPrintf("\n");
        ConPrintf("strlength=0x%x\n",strlength);
  
 memcpy(netshellbuffer,tstr,strlength);
 netshellbuffer[strlength]='\0';
    
        /* Break the string down into tokens */
        tmp = 0;
        i = 0;
        tok[0] = tstr;

        while( tstr[i] && tmp < 10 )
        {
            if( tstr[i] == ' ' )
            {
                tstr[i] = 0;
                if( ++tmp < 10 )
                    tok[tmp] = tstr+i+1;
            }
            i++;
        }
        /* We terminated due to a NULL, then we have one more token */
        if( tmp < 10 )
            tmp++;

        /* Process the command */
#if 0
        if( i )
        {
           if( !stricmp( tok[0], "bye" ) || !stricmp( tok[0], "quit" ) )
                    logon = 0;       
    else
       run_netshell_command(shellbuffer,0);
 }
#endif
#if 1
        {

     if( *tok[0] == '?' || !stricmp( tok[0], "conhelp" ) )
            {
                ConPrintf( VerStr );
                ConPrintf("\n[Help Command]\n\nThe basic commands are:\n");
                ConPrintf("  acct     - Manage PPP user accounts\n");
                ConPrintf("  bye      - Logoff the console\n");
                ConPrintf("  echo     - Perform echo test\n");
                ConPrintf("  help     - Displays this message\n");
                ConPrintf("  mem      - Display memory status\n");
                ConPrintf("  nslookup - Lookup hostname or IP address\n");
#ifdef _INCLUDE_PPPOE_CODE
                ConPrintf("  pppoe      - Invoke PPPOE client logon\n");
                ConPrintf("  pppoeserver- Start the PPPoE Server\n");
#endif
                ConPrintf("  pswd     - Change console password\n");
                ConPrintf("  ping     - Test echo request\n");
                ConPrintf("  quit     - Logoff the console\n");
                ConPrintf("  reboot   - Reboot system (terminates session)\n");
                ConPrintf("  route    - Maintain route table\n");
                ConPrintf("  shutdown - Shutdown stack (terminates session)\n");
                ConPrintf("  socket   - Print socket table\n");
                ConPrintf("  stat     - Print internal stack statistics\n");
                ConPrintf("  tftp     - Test TFTP file transfer\n");
                ConPrintf("  lli      - Test Static LLI (ARP) Configuration\n");
                ConPrintf("  vlan     - Add/Delete VLAN devices\n");
                ConPrintf("  ipaddr   - Configuration of IPAddress\n");
#ifdef _INCLUDE_IPv6_CODE
                ConPrintf("  ipv6     - IPv6 Configuration.\n");
                ConPrintf("  ping6    - Test echo request over IPv6\n");
                ConPrintf("  v6nslookup - Lookup hostname or IPv6 address\n");
#endif
                ConPrintf("\nSome commands have additional help information. For example\n");
                ConPrintf("entering 'route' gives more information on the route command.\n\n");
            }
            else if( !stricmp( tok[0], "bye" ) || !stricmp( tok[0], "quit" ) )
                logon = 0;
            else if( !stricmp( tok[0], "route" ) )
                ConCmdRoute( tmp-1, tok[1], tok[2], tok[3], tok[4] );
            else if( !stricmp( tok[0], "acct" ) )
                ConCmdAcct( tmp-1, tok[1], tok[2], tok[3], tok[4] );
            else if( !stricmp( tok[0], "stat" ) )
                ConCmdStat( tmp-1, tok[1] );
            else if( !stricmp( tok[0], "nslookup" ) )
                ConCmdLookup( tmp-1, tok[1] );
#ifdef _INCLUDE_IPv6_CODE
            else if( !stricmp( tok[0], "v6nslookup" ) )
                ConCmdLookupIPv6( tmp-1, tok[1] );
#endif
            else if( !stricmp( tok[0], "ping" ) )
                ConCmdPing( tmp-1, tok[1], tok[2] );
            else if( !stricmp( tok[0], "echo" ) )
                ConCmdEcho( tmp-1, tok[1], tok[2] );
            else if( !stricmp( tok[0], "socket" ) )
                ConCmdSocket( tmp-1, tok[1] );
            else if( !stricmp( tok[0], "tftp" ) )
                ConCmdTFTP( tmp-1, tok[1], tok[2] );
            else if( !stricmp( tok[0], "lli" ) )
                ConCmdLLI ( tmp-1, tok[1], tok[2], tok[3] );
            else if( !stricmp( tok[0], "test" ) )
                ConCmdTest( tmp-1, tok[1], tok[2] );
#ifdef _INCLUDE_PPPOE_CODE
            else if( !stricmp( tok[0], "pppoe" ) )
                ConCmdPPPOE( tmp-1, tok[1], tok[2], tok[3] );
            else if( !stricmp( tok[0], "pppoeserver" ) )
                ConCmdPPPOEServer( tmp-1, tok[1], tok[2], tok[3], tok[4] );
#endif
            else if( !stricmp( tok[0], "vlan" ) )
                ConCmdVLAN( tmp-1, tok[1], tok[2], tok[3], tok[4] );
            else if( !stricmp( tok[0], "ipaddr" ) )
                ConCmdIPAddr ( tmp-1, tok[1], tok[2], tok[3], tok[4] );
#ifdef _INCLUDE_IPv6_CODE
            else if( !stricmp( tok[0], "ipv6" ) )
                ConCmdIPv6 ( tmp-1, tok[1], tok[2], tok[3], tok[4], tok[5], tok[6], tok[7] );
            else if( !stricmp( tok[0], "ping6" ) )
                ConCmdPing6( tmp-1, tok[1], tok[2] );            
#endif
            else if( !stricmp( tok[0], "reboot" ) )
                NC_NetStop(1);
            else if( !stricmp( tok[0], "shutdown" ) )
                NC_NetStop(0);
            else if( !stricmp( tok[0], "mem" ) )
                _mmCheck( MMCHECK_MAP, &ConPrintf );
            else if( !stricmp( tok[0], "pswd" ) )
            {
                if( tmp<2 || strlen(tok[1]) > 31 )
                    ConPrintf("Usage: pswd newpassword\n\n");
                else
                {
                    strcpy(Password,tok[1]);
                    ConPrintf("Console password is now '%s'\n\n",Password);
                }
            }

            else
            {
                      ConPrintf("netshellbuffer=0x%x",netshellbuffer);

   run_netshell_command();


  }
              //  ConPrintf("Invalid command - Enter '?' or 'help' for a list of commands.\n");
        }
#endif
    }

    /* Close the console */
    ConPrintf("\nGoodbye\n");

    /* Close console thread */
    ConsoleClose();

    fdClose( scon );
    TaskExit();
}

  • Hi Ping,

    Welcome to the TI E2E forum. I hope you will find many good answers here and in the TI.com documents and in the TI Wiki Pages (for processor issues). Be sure to search those for helpful information and to browse for the questions others may have asked on similar topics (e2e.ti.com).

    This is the device forum in which we support device(SoC), peripheral and MCSDK related queries. I feel you are best person to debug and test the above code. Please refer all the links below my signature. Please post back if you have API related queries.

    Thank you.

  • Ping Wang,

    The Network Client Example Application:

    The client example application also includes a console application with several tests and status query
    functions available. In order to get to the console, simply telnet into the application's IP address.

    Note that the console program will timeout and disconnect after a period of inactivity.

    To get a list of console commands, type help or simply ?. This action prints a list of console commands to
    the telnet terminal.

    The console program is important as a programming demonstration as much as a run time demonstration. There are many functions in the console program that display or test features particular to the NDK.

    When an application developer wants to use these features in their application, the console example source code can be useful as a guide.

    The similar discussion is happened on the below E2E post, this will be useful.
    http://e2e.ti.com/support/dsp/c6000_multi-core_dsps/f/639/t/257121.aspx

  • HI,

  • After checking the console.c , I think I have find the root cause of issue 2.  Conprint cannot be used in other task.

        In the send function, we can find it will do fdint_lockfd  to get current task file description. But acctually ,our task has not the stored the file table .So In my understanding ,Conprintf cannot be called by other task directly.

    But issue1 i still cannot understand.

    int ConPrintf(const char *format, ...)
    {
    va_list ap;
    char buffer[128];
    int size;

    va_start(ap, format);
    size = vsprintf(buffer, (char *)format, ap);
    va_end(ap);

    send( scon, buffer, size, 0 );
    return( size );
    }

    int fdint_lockfd( FILEDESC *pfd, uint Type )
    {
    FDTABLE *pfdt;

    // Check the file descriptor table
    pfdt = TaskGetEnv( TaskSelf(), 0 );
    if( !pfdt || pfdt->Type != HTYPE_FDTABLE )
    return( SOCKET_ERROR );

  • Ping Wang,

    I hope, You said that after you adding console.c, its working like command gets response. You can refer the below snapshot for how to enable telnet server if it is not enabled by default.

    I think, you are struggling at the task and sem. You have to debug more on your custom code. Is it possible share your whole project to check and provide technical solution.

  • HI ,all:

       thanks for your help .I have resolved the problem. It is some bugs of my code and other reasons about the NDK limitation.

        After reading the NDK doc ,I find that , fdopenssion and fclosesession are needed ,what's more ,if the packet is laruger than MTU ,there maybe some strange problem.

  • Ping Wang,

    Glad to hear, you have resolved the problem. Obviously, when you create the file descriptor on the task, its needed to open/close the task with the help of fdOpenSession() and fdCloseSession(). However this discussion of thread can helpful for future readers, If you verified this thread.