Ignore:
Timestamp:
Jan 13, 2021, 12:36:17 AM (3 years ago)
Author:
alain
Message:

All modifications required to support the <tcp_chat> application
including error recovery in case of packet loss.A

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/kern/ksocket.c

    r669 r683  
    11/*
    2  * ksocket.c - kernel socket API implementation.
     2 * ksocket.c - kernel socket implementation.
    33 *
    4  * Authors  Alain Greiner   (2016,2017,2018,2019,2020)
     4 * Authors  Alain Greiner        (2016,2017,2018,2019,2020)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    117117    switch( sts )
    118118    {
    119         case CMD_STS_SUCCESS  : return "TX_CONNECT";
     119        case CMD_STS_SUCCESS  : return "SUCCESS";
    120120        case CMD_STS_EOF      : return "EOF";
    121121        case CMD_STS_RST      : return "RST";
     
    135135// and request the NIC_TX server thread to re-send the unacknowledged segment.
    136136///////////////////////////////////////////////////////////////////////////////////////////
    137 // @ args_xp    : extended pointer on the involved socket.
     137// @ sock_xp    : extended pointer on the involved socket.
    138138///////////////////////////////////////////////////////////////////////////////////////////
    139 static void __attribute__((noinline)) socket_alarm_handler( xptr_t args_xp )
     139static void __attribute__((noinline)) socket_alarm_handler( xptr_t sock_xp )
    140140{
    141141    // get cluster and local pointer on socket descriptor
    142     socket_t * sock_ptr = GET_PTR( args_xp );
    143     cxy_t      sock_cxy = GET_CXY( args_xp );
     142    socket_t * sock_ptr = GET_PTR( sock_xp );
     143    cxy_t      sock_cxy = GET_CXY( sock_xp );
     144
     145#if DEBUG_SOCKET_ALARM
     146uint32_t cycle = (uint32_t)hal_get_cycles();
     147#endif
     148
     149   // build extended pointer on lock protecting socket
     150    xptr_t socket_lock_xp = XPTR( sock_cxy , &sock_ptr->lock );
     151
     152    // take the socket lock
     153    remote_queuelock_acquire( socket_lock_xp );
    144154
    145155    // get relevant infos from socket descriptor
     
    151161"illegal tx_client field for a retransmission timeout" );
    152162
    153     // get TX client thread cluster and local pointer
    154     thread_t * thread_ptr = GET_PTR( thread_xp );
     163    // get TX client thread cluster
    155164    cxy_t      thread_cxy = GET_CXY( thread_xp );
    156165
     
    168177
    169178    // update the date in alarm
    170     alarm_update( thread_ptr , hal_get_cycles() + TCP_RETRANSMISSION_TIMEOUT );
     179    alarm_update( thread_xp , hal_get_cycles() + CONFIG_SOCK_RETRY_TIMEOUT );
    171180   
    172181    //////////////////////////////
     
    175184
    176185#if DEBUG_SOCKET_ALARM
    177 uint32_t cycle = (uint32_t)hal_get_cycles();
    178 printk("\n[%s] rings for TX_CONNECT : request a new SYN segment / cycle %d\n",
     186if( DEBUG_SOCKET_ALARM < cycle )
     187printk("\n[%s] rings for CONNECT : request a new SYN segment / cycle %d\n",
    179188__FUNCTION__ , cycle );
    180189#endif
     
    193202
    194203#if DEBUG_SOCKET_ALARM
    195 uint32_t cycle = (uint32_t)hal_get_cycles();
    196 printk("\n[%s] rings for TX_ACCEPT : request a new SYN-ACK segment / cycle %d\n",
     204if( DEBUG_SOCKET_ALARM < cycle )
     205printk("\n[%s] rings for ACCEPT : request a new SYN-ACK segment / cycle %d\n",
    197206__FUNCTION__ , cycle );
    198207#endif
     
    211220
    212221#if DEBUG_SOCKET_ALARM
    213 uint32_t cycle = (uint32_t)hal_get_cycles();
    214 printk("\n[%s] rings for TX_CLOSE : request a new FIN-ACK segment / cycle %d\n",
     222if( DEBUG_SOCKET_ALARM < cycle )
     223printk("\n[%s] rings for CLOSE : request a new FIN-ACK segment / cycle %d\n",
    215224__FUNCTION__ , cycle );
    216225#endif
     
    227236    if( tx_cmd == CMD_TX_SEND )
    228237    {
    229         // TODO build a new TX_SEND command
    230     }
     238        // get get relevant infos from socket pointer
     239        uint32_t  tx_una = hal_remote_l32( XPTR( sock_cxy , &sock_ptr->tx_una ));
     240        uint32_t  tx_ack = hal_remote_l32( XPTR( sock_cxy , &sock_ptr->tx_ack ));
     241        uint32_t  tx_len = hal_remote_l32( XPTR( sock_cxy , &sock_ptr->tx_len ));
     242
     243#if DEBUG_SOCKET_ALARM       
     244if( DEBUG_SOCKET_ALARM < cycle )
     245printk("\n[%s] rings for SEND : request %d bytes / cycle %d\n",
     246__FUNCTION__ , tx_len , cycle );
     247#endif
     248        // update command fields in socket
     249        hal_remote_s32( XPTR( sock_cxy , &sock_ptr->tx_nxt    ) , tx_una );
     250        hal_remote_s32( XPTR( sock_cxy , &sock_ptr->tx_todo   ) , tx_len - tx_ack );
     251        hal_remote_s32( XPTR( sock_cxy , &sock_ptr->tx_valid  ) , true );
     252
     253        // unblock the NIC_TX server thread
     254        thread_unblock( tx_server_xp , THREAD_BLOCKED_CLIENT );
     255    }
     256
     257    // release the socket lock
     258    remote_queuelock_release( socket_lock_xp );
     259
    231260}   // end socket_alarm_handler()
    232 
    233 ///////////////////////////////////////////////////////////////////////////////////////////
    234 // This static function activates the alarm embedded in the calling thread descriptor,
    235 // using the <date> argument.
    236 ///////////////////////////////////////////////////////////////////////////////////////////
    237 // @ delay   : number of cycles (from the current absolute date).
    238 ///////////////////////////////////////////////////////////////////////////////////////////
    239 static void socket_alarm_start( xptr_t   socket_xp,
    240                                 uint32_t delay )
    241 {
    242     // compute absolute date
    243     cycle_t date = hal_get_cycles() + delay;
    244 
    245     // get pointer on calling threadf
    246     thread_t * this = CURRENT_THREAD;
    247 
    248     // start the alarm
    249     alarm_start( date,
    250                  &socket_alarm_handler,   // func_ptr
    251                  socket_xp,               // args_xp
    252                  this );
    253 }
    254 
    255 ///////////////////////////////////////////////////////////////////////////////////////////
    256 // This static function activates the alarm embedded in the calling thread descriptor,
    257 // using the <date> argument.
    258 ///////////////////////////////////////////////////////////////////////////////////////////
    259 // @ date   : absolute date for this alarm.
    260 ///////////////////////////////////////////////////////////////////////////////////////////
    261 static void socket_alarm_stop( void )
    262 {
    263     // get pointer on calling threadf
    264     thread_t * this = CURRENT_THREAD;
    265 
    266     // stop the alarm
    267     alarm_stop( this );
    268 }
    269261
    270262/////////////////////////////////////////////////////////////////////////////////////////
     
    470462// associated to a socket: file descriptor, socket descriptor, RX buffer, R2T queue,
    471463// and CRQ queue. It allocates an fdid, and register it in the process fd_array.
    472 // It initialise the  the socket desccriptor static fields, other than local_addr,
     464// It initialise the socket desccriptor static fields, other than local_addr,
    473465// local_port, remote_addr, remote_port), and set the socket state to UNBOUND.
    474466// It returns the local pointer on socket descriptor and the fdid value in buffers
     
    489481{
    490482    uint32_t       fdid;
    491     kmem_req_t     req;
    492483    socket_t     * socket;
    493484    vfs_file_t   * file;
    494485    uint32_t       state;
     486    void         * tx_buf;
    495487    error_t        error;
     488
    496489
    497490    thread_t  * this    = CURRENT_THREAD;
    498491    process_t * process = this->process;
    499492
     493#if DEBUG_SOCKET_CREATE || DEBUG_SOCKET_ERROR
     494uint32_t cycle = (uint32_t)hal_get_cycles();
     495#endif
     496
    500497#if DEBUG_SOCKET_CREATE
    501 uint32_t cycle = (uint32_t)hal_get_cycles();
    502498if( DEBUG_SOCKET_CREATE < cycle )
    503499printk("\n[%s] thread[%x,%x] enter / cycle %d\n",
     
    506502   
    507503    // 1. allocate memory for socket descriptor
    508     req.type   = KMEM_KCM;
    509     req.order  = bits_log2( sizeof(socket_t) );
    510     req.flags  = AF_ZERO;
    511     socket     = kmem_remote_alloc( cxy , &req );
     504    socket = kmem_remote_alloc( cxy , bits_log2(sizeof(socket_t)) , AF_ZERO );
    512505
    513506    if( socket == NULL )
    514507    {
    515         printk("\n[ERROR] in %s : cannot allocate socket descriptor / thread[%x,%x]\n",
    516         __FUNCTION__, process->pid, this->trdid );
    517         return -1;
    518     }
    519 
    520     // 2. allocate memory for rx_buf buffer
     508
     509#if DEBUG_SOCKET_ERROR
     510printk("\n[ERROR] in %s : cannot allocate socket descriptor / thread[%x,%x] / cycle %d\n",
     511__FUNCTION__, process->pid, this->trdid, cycle );
     512#endif
     513        return -1;
     514    }
     515
     516    // 2. allocate memory for rx_buf data buffer
    521517    error = remote_buf_init( XPTR( cxy , &socket->rx_buf ),
    522                              bits_log2( CONFIG_SOCK_RX_BUF_SIZE ) );
     518                             CONFIG_SOCK_RX_BUF_ORDER );
    523519
    524520    if( error )
    525521    {
    526         printk("\n[ERROR] in %s : cannot allocate rx_buf / thread[%x,%x]\n",
    527         __FUNCTION__, process->pid, this->trdid );
    528         req.type = KMEM_KCM;
    529         req.ptr  = socket;
    530         kmem_remote_free( cxy , &req );
    531         return -1;
    532     }
    533 
    534     // 3. allocate memory for r2tq queue
     522
     523#if DEBUG_SOCKET_ERROR
     524printk("\n[ERROR] in %s : no memory for rx_buf / thread[%x,%x] / cycle %d\n",
     525__FUNCTION__, process->pid, this->trdid, cycle );
     526#endif
     527        kmem_remote_free( cxy , socket , bits_log2(sizeof(socket_t)) );  // 1
     528        return -1;
     529    }
     530
     531    // 3. allocate memory for tx_buf
     532    tx_buf = kmem_remote_alloc( cxy , CONFIG_SOCK_TX_BUF_ORDER , AF_NONE );
     533
     534    if( tx_buf == NULL )
     535    {
     536
     537#if DEBUG_SOCKET_ERROR
     538printk("\n[ERROR] in %s : no memory for tx_buf / thread[%x,%x] / cycle %d\n",
     539__FUNCTION__, process->pid, this->trdid, cycle );
     540#endif
     541        remote_buf_release_data( XPTR( cxy , &socket->rx_buf ) );        // 2
     542        kmem_remote_free( cxy , socket , bits_log2(sizeof(socket_t)) );  // 1
     543        return -1;
     544    }
     545
     546    // 4. allocate memory for r2tq queue
    535547    error = remote_buf_init( XPTR( cxy , &socket->r2tq ),
    536548                             bits_log2( CONFIG_SOCK_R2T_BUF_SIZE ) );
    537549    if( error )
    538550    {
    539         printk("\n[ERROR] in %s : cannot allocate R2T queue / thread[%x,%x]\n",
    540         __FUNCTION__, process->pid, this->trdid );
    541         remote_buf_release_data( XPTR( cxy , &socket->rx_buf ) );
    542         req.type = KMEM_KCM;
    543         req.ptr  = socket;
    544         kmem_remote_free( cxy , &req );
    545         return -1;
    546     }
    547 
    548     // don't allocate memory for crqq queue, as it is done by the socket_listen function
    549 
    550     //  4. allocate memory for file descriptor
    551         req.type  = KMEM_KCM;
    552         req.order = bits_log2( sizeof(vfs_file_t) );
    553     req.flags = AF_ZERO;
    554         file      = kmem_remote_alloc( cxy , &req );
     551
     552#if DEBUG_SOCKET_ERROR
     553printk("\n[ERROR] in %s : cannot allocate R2T queue / thread[%x,%x] / cycle %d\n",
     554__FUNCTION__, process->pid, this->trdid, cycle );
     555#endif
     556        kmem_remote_free( cxy , tx_buf , CONFIG_SOCK_TX_BUF_ORDER );     // 3
     557        remote_buf_release_data( XPTR( cxy , &socket->rx_buf ) );        // 2
     558        kmem_remote_free( cxy , socket , bits_log2(sizeof(socket_t)) );  // 1
     559        return -1;
     560    }
     561
     562    // don't allocate memory for CRQ queue / done by the socket_listen function
     563
     564    // 5. allocate memory for file descriptor
     565        file = kmem_remote_alloc( cxy , bits_log2(sizeof(vfs_file_t)) , AF_ZERO );
    555566
    556567    if( file == NULL )
    557568    {
    558         printk("\n[ERROR] in %s : cannot allocate file descriptor / thread[%x,%x]\n",
    559         __FUNCTION__, process->pid, this->trdid );
    560         remote_buf_release_data( XPTR( cxy , &socket->r2tq ) );
    561         remote_buf_release_data( XPTR( cxy , &socket->rx_buf ) );
    562         req.type = KMEM_KCM;
    563         req.ptr  = socket;
    564         kmem_remote_free( cxy , &req );
     569
     570#if DEBUG_SOCKET_ERROR
     571printk("\n[ERROR] in %s : cannot allocate file descriptor / thread[%x,%x] / cycle %d\n",
     572__FUNCTION__, process->pid, this->trdid, cycle );
     573#endif
     574        remote_buf_release_data( XPTR( cxy , &socket->r2tq ) );          // 4
     575        kmem_remote_free( cxy , tx_buf , CONFIG_SOCK_TX_BUF_ORDER );     // 3
     576        remote_buf_release_data( XPTR( cxy , &socket->rx_buf ) );        // 2
     577        kmem_remote_free( cxy , socket , bits_log2(sizeof(socket_t)) );  // 1
    565578        return -1;
    566579    }
    567580   
    568     // 5. get an fdid value, and register file descriptor in fd_array[]
     581    // 6. get an fdid value, and register file descriptor in fd_array[]
    569582    error = process_fd_register( process->ref_xp,
    570583                                 XPTR( cxy , file ),
     
    572585    if ( error )
    573586    {
    574         printk("\n[ERROR] in %s : cannot register file descriptor / thread[%x,%x]\n",
    575         __FUNCTION__, process->pid, this->trdid );
    576         req.type = KMEM_KCM;
    577         req.ptr  = file;
    578         kmem_free( &req );
    579         remote_buf_release_data( XPTR( cxy , &socket->r2tq ) );
    580         remote_buf_release_data( XPTR( cxy , &socket->rx_buf ) );
    581         req.ptr  = socket;
    582         kmem_free( &req );
     587
     588#if DEBUG_SOCKET_ERROR
     589if( DEBUG_SOCKET_ERROR < cycle )
     590printk("\n[ERROR] in %s : cannot register file descriptor / thread[%x,%x] / cycle %d\n",
     591__FUNCTION__, process->pid, this->trdid, cycle );
     592#endif
     593        kmem_remote_free( cxy , file , bits_log2(sizeof(vfs_file_t)) );  // 5
     594        remote_buf_release_data( XPTR( cxy , &socket->r2tq ) );          // 4
     595        kmem_remote_free( cxy , tx_buf , CONFIG_SOCK_TX_BUF_ORDER );     // 3
     596        remote_buf_release_data( XPTR( cxy , &socket->rx_buf ) );        // 2
     597        kmem_remote_free( cxy , socket , bits_log2(sizeof(socket_t)) );  // 1
    583598        return -1;
    584599    }
     
    597612    hal_remote_s32( XPTR( cxy , &socket->rx_valid    ) , false );
    598613    hal_remote_s32( XPTR( cxy , &socket->nic_channel ) , 0 );
     614    hal_remote_spt( XPTR( cxy , &socket->tx_buf      ) , tx_buf );
    599615
    600616    // initialize file descriptor
     
    606622
    607623#if DEBUG_SOCKET_CREATE
     624cycle = (uint32_t)hal_get_cycles();
    608625if( DEBUG_SOCKET_CREATE < cycle )
    609626printk("\n[%s] thread[%x,%x] exit / socket[%x,%d] / xptr[%x,%x] / cycle %d\n",
     
    631648static void socket_destroy( xptr_t file_xp )
    632649{
    633     kmem_req_t          req;
    634 
    635650    thread_t  * this    = CURRENT_THREAD;
    636651    process_t * process = this->process;
     
    677692
    678693    // release memory allocated for file descriptor
    679     req.type = KMEM_KCM;
    680     req.ptr  = file_ptr;
    681     kmem_remote_free( file_cxy , &req );
     694    kmem_remote_free( file_cxy , file_ptr , bits_log2(sizeof(vfs_file_t)) );
    682695
    683696    // release memory allocated for buffers attached to socket descriptor
     
    687700
    688701    // release memory allocated for socket descriptor
    689     req.type = KMEM_KCM;
    690     req.ptr  = socket_ptr;
    691     kmem_remote_free( file_cxy , &req );
     702    kmem_remote_free( file_cxy , socket_ptr , bits_log2(sizeof(socket_t)) );
    692703
    693704#if DEBUG_SOCKET_DESTROY
     
    702713////////////////////////////////////////////////
    703714void socket_put_r2t_request( xptr_t    queue_xp,
    704                              uint32_t  flags,
     715                             uint8_t   flags,
    705716                             uint32_t  channel )
    706717{
     
    715726        // try to register R2T request
    716727        error_t error = remote_buf_put_from_kernel( queue_xp,
    717                                                     (uint8_t *)(&flags),
     728                                                    &flags,
    718729                                                    1 );
    719730        if( error )
     
    740751    }
    741752}  // end socket_put_r2t_request()
     753
     754///////////////////////////////////////////////////
     755error_t socket_get_r2t_request( xptr_t    queue_xp,
     756                                uint8_t * flags )
     757{
     758    // get one request from R2T queue
     759    return remote_buf_get_to_kernel( queue_xp,
     760                                     flags,
     761                                     1 );
     762}  // end socket_get_r2T_request()
    742763 
    743764///////////////////////////////////////////////////
     
    843864    process_t * process = this->process;
    844865
     866#if DEBUG_SOCKET_BIND || DEBUG_SOCKET_ERROR
     867uint32_t cycle = (uint32_t)hal_get_cycles();
     868#endif
     869
    845870#if DEBUG_SOCKET_BIND
    846 uint32_t cycle = (uint32_t)hal_get_cycles();
    847871if( DEBUG_SOCKET_BIND < cycle )
    848872printk("\n[%s] thread[%x,%x] enter / socket[%x,%d] / addr %x / port %x / cycle %d\n",
     
    858882    if( file_xp == XPTR_NULL )
    859883    {
    860         printk("\n[ERROR] in %s : undefined fdid %d / thread[%x,%x]\n",
    861         __FUNCTION__, fdid, process->pid, this->trdid );
     884
     885#if DEBUG_SOCKET_ERROR
     886printk("\n[ERROR] in %s : undefined fdid %d / thread[%x,%x] / cycle %d\n",
     887__FUNCTION__, fdid, process->pid, this->trdid, cycle );
     888#endif
    862889        return -1;
    863890    }
     
    869896    if( file_type != FILE_TYPE_SOCK )
    870897    {
    871         printk("\n[ERROR] in %s : illegal file type %s / thread[%x,%x]",
    872         __FUNCTION__, vfs_inode_type_str( file_type ), process->pid, this->trdid );
     898
     899#if DEBUG_SOCKET_ERROR
     900printk("\n[ERROR] in %s : illegal file type %s / thread[%x,%x] / cycle %d",
     901__FUNCTION__, vfs_inode_type_str( file_type ), process->pid, this->trdid, cycle );
     902#endif
    873903        return -1;
    874904    }
     
    918948    process_t * process = this->process;
    919949
     950#if DEBUG_SOCKET_LISTEN || DEBUG_SOCKET_ERROR
     951uint32_t cycle = (uint32_t)hal_get_cycles();
     952#endif
     953
    920954#if DEBUG_SOCKET_LISTEN
    921 uint32_t cycle = (uint32_t)hal_get_cycles();
    922955if( DEBUG_SOCKET_LISTEN < cycle )
    923956printk("\n[%s] thread[%x,%x] enter / socket[%x,%d] / crq_depth %x / cycle %d\n",
     
    933966    if( file_xp == XPTR_NULL )
    934967    {
    935         printk("\n[ERROR] in %s : undefined fdid %d / thread[%x,%x]\n",
    936         __FUNCTION__, fdid, process->pid, this->trdid );
     968
     969#if DEBUG_SOCKET_ERROR
     970printk("\n[ERROR] in %s : undefined fdid %d / thread[%x,%x] / cycle %d\n",
     971__FUNCTION__, fdid, process->pid, this->trdid, cycle );
     972#endif
    937973        return -1;
    938974    }
     
    944980    if( file_type != FILE_TYPE_SOCK )
    945981    {
    946         printk("\n[ERROR] in %s : illegal file type %s / thread[%x,%x]\n",
    947         __FUNCTION__, vfs_inode_type_str(file_type), process->pid, this->trdid );
     982
     983#if DEBUG_SOCKET_ERROR
     984printk("\n[ERROR] in %s : illegal file type %s / thread[%x,%x] / cycle %d\n",
     985__FUNCTION__, vfs_inode_type_str(file_type), process->pid, this->trdid, cycle );
     986#endif
    948987        return -1;
    949988    }
     
    958997    if( socket_type != SOCK_STREAM )
    959998    {
    960         printk("\n[ERROR] in %s : illegal socket type %s / thread[%x,%x]\n",
    961         __FUNCTION__, socket_type_str(socket_type), process->pid, this->trdid );
     999
     1000#if DEBUG_SOCKET_ERROR
     1001printk("\n[ERROR] in %s : illegal socket type %s / thread[%x,%x] / cycle %d\n",
     1002__FUNCTION__, socket_type_str(socket_type), process->pid, this->trdid, cycle );
     1003#endif
    9621004        return -1;
    9631005    }
     
    9661008    if( socket_state != TCP_STATE_BOUND )
    9671009    {
    968         printk("\n[ERROR] in %s : illegal socket state %s / thread[%x,%x]\n",
    969         __FUNCTION__, socket_state_str(socket_state), process->pid, this->trdid );
     1010
     1011#if DEBUG_SOCKET_ERROR
     1012printk("\n[ERROR] in %s : illegal socket state %s / thread[%x,%x] / cycle %d\n",
     1013__FUNCTION__, socket_state_str(socket_state), process->pid, this->trdid, cycle );
     1014#endif
    9701015        return -1;
    9711016    }
     
    9801025    if( error )
    9811026    {
    982         printk("\n[ERROR] in %s : cannot allocate CRQ queue / thread[%x,%x]\n",
    983         __FUNCTION__, process->pid, this->trdid );
     1027
     1028#if DEBUG_SOCKET_ERROR
     1029printk("\n[ERROR] in %s : cannot allocate CRQ queue / thread[%x,%x] / cycle %d\n",
     1030__FUNCTION__, process->pid, this->trdid, cycle );
     1031#endif
    9841032        return -1;
    9851033    }
     
    10111059    vfs_file_t        * file_ptr;
    10121060    cxy_t               file_cxy;
    1013     vfs_file_type_t    file_type;           // file descriptor type
     1061    vfs_file_type_t     file_type;           // file descriptor type
    10141062    socket_t          * socket_ptr;          // local pointer on remote waiting socket
    10151063    uint32_t            socket_type;         // listening socket type   
     
    10451093    process_t * process   = this->process;
    10461094
    1047 #if DEBUG_SOCKET_ACCEPT
     1095#if DEBUG_SOCKET_ACCEPT || DEBUG_SOCKET_ERROR
    10481096uint32_t cycle = (uint32_t)hal_get_cycles();
     1097#endif
     1098
     1099#if DEBUG_SOCKET_ACCEPT
    10491100if( DEBUG_SOCKET_ACCEPT < cycle )
    10501101printk("\n[%s] thread[%x,%x] enter for socket[%x,%d] / cycle %d\n",
     
    10601111    if( file_xp == XPTR_NULL )
    10611112    {
    1062         printk("\n[ERROR] in %s : undefined fdid %d",
    1063         __FUNCTION__, fdid );
     1113
     1114#if DEBUG_SOCKET_ERROR
     1115printk("\n[ERROR] in %s : undefined fdid %d / thead[%x,%x] / cycle %d",
     1116__FUNCTION__, fdid, process->pid, this->trdid, cycle );
     1117#endif
    10641118        return -1;
    10651119    }
     
    10711125    if( file_type != FILE_TYPE_SOCK )
    10721126    {
    1073         printk("\n[ERROR] in %s : illegal file type %s / thread[%x,%x]\n",
    1074         __FUNCTION__, vfs_inode_type_str(file_type), process->pid, this->trdid );
     1127
     1128#if DEBUG_SOCKET_ERROR
     1129printk("\n[ERROR] in %s : illegal file type %s / thread[%x,%x] / cycle %d\n",
     1130__FUNCTION__, vfs_inode_type_str(file_type), process->pid, this->trdid, cycle );
     1131#endif
    10751132        return -1;
    10761133    }
     
    10971154    if( socket_type != SOCK_STREAM )
    10981155    {
    1099         // release listening socket lock
     1156                   
     1157#if DEBUG_SOCKET_ERROR
     1158printk("\n[ERROR] in %s : illegal socket type %s / thread[%x,%x] / cycle %d\n",
     1159__FUNCTION__, socket_type_str(socket_type), process->pid , this->trdid, cycle );
     1160#endif
    11001161        remote_queuelock_release( socket_lock_xp );
    1101                    
    1102         printk("\n[ERROR] in %s : illegal socket type %s / thread[%x,%x]\n",
    1103         __FUNCTION__, socket_type_str(socket_type), process->pid , this->trdid );
    11041162        return -1;
    11051163    }
     
    11081166    if( socket_state != TCP_STATE_LISTEN )
    11091167    {
    1110         // release listening socket lock
     1168
     1169#if DEBUG_SOCKET_ERROR
     1170printk("\n[ERROR] in %s : illegal socket state %s / thread[%x,%x] / cycle %d\n",
     1171__FUNCTION__, socket_state_str(socket_state), process->pid, this->trdid, cycle );
     1172#endif
    11111173        remote_queuelock_release( socket_lock_xp );
    1112                    
    1113         printk("\n[ERROR] in %s : illegal socket state %s / thread[%x,%x]\n",
    1114         __FUNCTION__, socket_state_str(socket_state), process->pid, this->trdid );
    11151174        return -1;
    11161175    }
     
    11191178    if( (socket_rx_valid == true) || (socket_rx_client != XPTR_NULL) )
    11201179    {
    1121         // release listening socket lock
     1180
     1181#if DEBUG_SOCKET_ERROR
     1182printk("\n[ERROR] in %s : previous RX cmd on socket[%x,%d] / thread[%x,%x] / cycle %d\n",
     1183__FUNCTION__, process->pid, fdid, process->pid, this->trdid, cycle );
     1184#endif
    11221185        remote_queuelock_release( socket_lock_xp );
    1123                    
    1124         printk("\n[ERROR] in %s : previous RX cmd on socket[%x,%d] / thread[%x,%x]\n",
    1125         __FUNCTION__, process->pid, fdid, process->pid, this->trdid );
    11261186        return -1;
    11271187    }
     
    11301190    if( (socket_tx_valid == true) || (socket_tx_client != XPTR_NULL) )
    11311191    {
    1132         // release socket lock
     1192                   
     1193#if DEBUG_SOCKET_ERROR
     1194printk("\n[ERROR] in %s : previous TX cmd on socket[%x,%d] / thread[%x,%x] / cycle %d\n",
     1195__FUNCTION__, process->pid, fdid, process->pid, this->trdid, cycle );
     1196#endif
    11331197        remote_queuelock_release( socket_lock_xp );
    1134                    
    1135         printk("\n[ERROR] in %s : previous TX cmd on socket[%x,%d] / thread[%x,%x]\n",
    1136         __FUNCTION__, process->pid, fdid, process->pid, this->trdid );
    1137         return -1;
    1138     }
    1139 
    1140     // 2) build extended pointer on listening socket.crq
     1198        return -1;
     1199    }
     1200
     1201    // 2) check the listenig socket CRQ
    11411202    crq_xp  = XPTR( file_cxy , &socket_ptr->crqq );
    11421203
     
    11441205    crq_status = remote_buf_status( crq_xp );
    11451206
    1146     // block & deschedule when CRQ empty
     1207    // block & deschedule to wait a client request when CRQ empty
    11471208    if( crq_status == 0 )
    11481209    {
    1149         // register command arguments in listening socket
     1210        // register command arguments for NIC_RX server in listening socket
    11501211        hal_remote_s32( XPTR( file_cxy , &socket_ptr->rx_cmd    ), CMD_RX_ACCEPT );
    11511212        hal_remote_s64( XPTR( file_cxy , &socket_ptr->rx_client ), client_xp );
     
    11791240        crq_status   = remote_buf_status( crq_xp );
    11801241
    1181 assert( __FUNCTION__, (((crq_status > 0) || (cmd_status!= CMD_STS_SUCCESS)) && (cmd_valid == false)),
     1242assert( __FUNCTION__,
     1243(((crq_status > 0) || (cmd_status!= CMD_STS_SUCCESS)) && (cmd_valid == false)),
    11821244"illegal socket state when client thread resumes after RX_ACCEPT" );
    11831245
     
    11871249        if( cmd_status != CMD_STS_SUCCESS )
    11881250        {
    1189             // release socket lock
     1251
     1252#if DEBUG_SOCKET_ERROR
     1253printk("\n[ERROR] in %s : reported for RX / socket[%x,%d] / thread[%x,%x] / cycle %d\n",
     1254__FUNCTION__, process->pid, fdid, process->pid, this->trdid, cycle );
     1255#endif
    11901256            remote_queuelock_release( socket_lock_xp );
    1191 
    1192             printk("\n[ERROR] in %s for RX_ACCEPT command / socket[%x,%d] / thread[%x,%x]\n",
    1193             __FUNCTION__, process->pid, fdid, process->pid, this->trdid );
    11941257            return -1;
    11951258        }
    1196 
    1197         // extract first request from the listening socket CRQ
    1198         error = socket_get_crq_request( crq_xp,
     1259    }  // end blocking on CRQ empty
     1260
     1261    // from this point, we can extract a request from listening socket CRQ
     1262    error = socket_get_crq_request( crq_xp,
    11991263                                    &new_remote_addr,
    12001264                                    &new_remote_port,
    12011265                                    &new_remote_iss,
    12021266                                    &new_remote_window );
    1203 
    12041267assert( __FUNCTION__, (error == 0),
    12051268"cannot get a connection request from a non-empty CRQ" );
    12061269
    1207         // reset listening socket rx_client
    1208         hal_remote_s32( XPTR( file_cxy , &socket_ptr->rx_client ) , XPTR_NULL );
    1209 
    1210         // release socket lock
    1211         remote_queuelock_release( socket_lock_xp );
    1212 
    1213     }  // end blocking on CRQ status
    1214 
    1215     // from this point, we can create a new socket
    1216     // and ask the NIC_TX to send a SYN-ACK segment
     1270    // release listening socket lock
     1271    remote_queuelock_release( socket_lock_xp );
    12171272
    12181273#if DEBUG_SOCKET_ACCEPT
    12191274cycle = (uint32_t)hal_get_cycles();
    12201275if( DEBUG_SOCKET_ACCEPT < cycle )
    1221 printk("\n[%s] thread[%x,%x] socket[%x,%d] / got a CRQ request / cycle %d\n",
    1222 __FUNCTION__, process->pid, this->trdid, process->pid, fdid, cycle );
     1276printk("\n[%s] thread[%x,%x] socket[%x,%d] / CRQ request [addr %x / port %x] / cycle %d\n",
     1277__FUNCTION__, process->pid, this->trdid, process->pid, fdid,
     1278new_remote_addr, new_remote_port, cycle );
    12231279#endif
    12241280
     
    12341290    if( error )
    12351291    {
    1236         printk("\n[ERROR] in %s : cannot allocate new socket / thread[%x,%x]\n",
    1237         __FUNCTION__, process->pid, this->trdid );
     1292
     1293#if DEBUG_SOCKET_ERROR
     1294printk("\n[ERROR] in %s : cannot create new socket / thread[%x,%x] / cycle %d\n",
     1295__FUNCTION__, process->pid, this->trdid, cycle );
     1296#endif
    12381297        return -1;
    12391298    }
     
    12871346 
    12881347    // start retransmission timer
    1289     socket_alarm_start( new_socket_xp , TCP_RETRANSMISSION_TIMEOUT );
     1348    alarm_start( client_xp,
     1349                 hal_get_cycles() + CONFIG_SOCK_RETRY_TIMEOUT,
     1350                 &socket_alarm_handler,
     1351                 new_socket_xp );
    12901352
    12911353#if DEBUG_SOCKET_ACCEPT
    12921354cycle = (uint32_t)hal_get_cycles();
    12931355if( DEBUG_SOCKET_ACCEPT < cycle )
    1294 printk("\n[%s] thread[%x,%x] new_socket[%x,%d] blocks on <IO> waiting ESTAB / cycle %d\n",
     1356printk("\n[%s] thread[%x,%x] for socket[%x,%d] request SYN-ACK & blocks on <IO> / cycle %d\n",
    12951357__FUNCTION__, process->pid, this->trdid, process->pid, new_fdid, cycle );
    12961358#endif
     
    13071369#endif
    13081370
    1309     // stop retransmission timer
    1310     socket_alarm_stop();
     1371    // stop retransmission timer in thread descriptor
     1372    alarm_stop( client_xp );
    13111373
    13121374    // get new socket state, tx_valid and tx_sts
     
    13151377    cmd_status = hal_remote_l32( XPTR( new_socket_cxy , &new_socket_ptr->tx_sts ));
    13161378
    1317 assert( __FUNCTION__, (((new_state == TCP_STATE_ESTAB) || (cmd_status != CMD_STS_SUCCESS))
    1318         && (cmd_valid == false)),
     1379assert( __FUNCTION__,
     1380(((new_state == TCP_STATE_ESTAB) || (cmd_status != CMD_STS_SUCCESS)) && (cmd_valid == false)),
    13191381"illegal socket state when client thread resumes after TX_ACCEPT" );
    13201382
     
    13241386    if( cmd_status != CMD_STS_SUCCESS )
    13251387    {
    1326         printk("\n[ERROR] in %s for TX_ACCEPT command / socket[%x,%d] / thread[%x,%x]\n",
    1327         __FUNCTION__, process->pid, new_fdid, process->pid, this->trdid );
     1388
     1389#if DEBUG_SOCKET_ERROR
     1390printk("\n[ERROR] in %s reported for TX / socket[%x,%d] / thread[%x,%x] / cycle %d\n",
     1391__FUNCTION__, process->pid, new_fdid, process->pid, this->trdid, cycle );
     1392#endif
    13281393        return -1;
    13291394    }
     
    13701435    trdid_t     trdid     = this->trdid;
    13711436
     1437#if DEBUG_SOCKET_CONNECT || DEBUG_SOCKET_ERROR
     1438uint32_t cycle = (uint32_t)hal_get_cycles();
     1439#endif
     1440
    13721441    // get pointers on file descriptor
    13731442    xptr_t       file_xp  = process_fd_get_xptr_from_local( this->process , fdid );
     
    13781447    if( file_xp == XPTR_NULL )
    13791448    {
    1380         printk("\n[ERROR] in %s : undefined fdid %d",
    1381         __FUNCTION__, fdid );
     1449
     1450#if DEBUG_SOCKET_ERROR
     1451printk("\n[ERROR] in %s : undefined fdid %d / thread[%x,%x] / cycle %d",
     1452__FUNCTION__, fdid, pid, trdid, cycle );
     1453#endif
    13821454        return -1;
    13831455    }
     
    13881460
    13891461#if DEBUG_SOCKET_CONNECT
    1390 uint32_t cycle = (uint32_t)hal_get_cycles();
    13911462if( DEBUG_SOCKET_CONNECT < cycle )
    1392 printk("\n[%s] thread[%x,%x] enter for socket[%x,%d] / addr %x / port %d / cycle %d\n",
     1463printk("\n[%s] thread[%x,%x] enter for socket[%x,%d] / addr %x / port %x / cycle %d\n",
    13931464__FUNCTION__,  pid, trdid, pid, fdid, remote_addr, remote_port, cycle );
    13941465#endif
     
    13971468    if( file_type != FILE_TYPE_SOCK )
    13981469    {
    1399         printk("\n[ERROR] in %s : illegal file type %s",
    1400         __FUNCTION__, vfs_inode_type_str( file_type ) );
     1470
     1471#if DEBUG_SOCKET_ERROR
     1472printk("\n[ERROR] in %s : illegal file type %s / thread[%x,%x] / cycle %d",
     1473__FUNCTION__, vfs_inode_type_str( file_type ), pid, trdid, cycle );
     1474#endif
    14011475        return -1;
    14021476    }
     
    14121486        if( socket_state != UDP_STATE_BOUND )
    14131487        {
    1414             printk("\n[ERROR] in %s : illegal socket state %s for type %s",
    1415             __FUNCTION__, socket_state_str(socket_state), socket_type_str(socket_type) );
     1488
     1489#if DEBUG_SOCKET_ERROR
     1490printk("\n[ERROR] in %s : illegal socket state %s for type %s / thread[%x,%x] / cycle %d",
     1491__FUNCTION__, socket_state_str(socket_state), socket_type_str(socket_type), pid, trdid, cycle );
     1492#endif
    14161493            return -1;
    14171494        }
     
    14211498        if( socket_state != TCP_STATE_BOUND )
    14221499        {
    1423             printk("\n[ERROR] in %s : illegal socket state %s for type %s",
    1424             __FUNCTION__, socket_state_str(socket_state), socket_type_str(socket_type) );
     1500
     1501#if DEBUG_SOCKET_ERROR
     1502printk("\n[ERROR] in %s : illegal socket state %s for type %s / thread[%x,%x] / cycle %d",
     1503__FUNCTION__, socket_state_str(socket_state), socket_type_str(socket_type), pid, trdid, cycle );
     1504#endif
    14251505            return -1;
    14261506        }
     
    14281508    else
    14291509    {
    1430         printk("\n[ERROR] in %s : illegal socket type %s",
    1431         __FUNCTION__,  socket_type_str(socket_type) );
     1510
     1511#if DEBUG_SOCKET_ERROR
     1512printk("\n[ERROR] in %s : illegal socket type / thread[%x,%x] / cycle %d",
     1513__FUNCTION__, pid, trdid, cycle );
     1514#endif
    14321515        return -1;
    14331516    }
     
    14751558 
    14761559        // start retransmission timer
    1477         socket_alarm_start( socket_xp , TCP_RETRANSMISSION_TIMEOUT );
     1560        alarm_start( client_xp,
     1561                     hal_get_cycles() + CONFIG_SOCK_RETRY_TIMEOUT,
     1562                     &socket_alarm_handler,
     1563                     socket_xp );
    14781564
    14791565#if DEBUG_SOCKET_CONNECT
     
    14941580#endif
    14951581
    1496         // stop retransmission timer
    1497         socket_alarm_stop();
     1582        // stop retransmission timer in thread descriptor
     1583        alarm_stop( client_xp );
    14981584
    14991585        // get socket state, tx_valid and tx_sts
     
    15071593
    15081594        // reset socket.tx_client
    1509         hal_remote_s32( XPTR( file_cxy , &socket_ptr->tx_client ) , XPTR_NULL );
     1595        hal_remote_s64( XPTR( file_cxy , &socket_ptr->tx_client ) , XPTR_NULL );
    15101596
    15111597        if( cmd_status != CMD_STS_SUCCESS )
    15121598        {
    1513             printk("\n[ERROR] in %s : for command TX_CONNECT / socket[%x,%d] / thread[%x,%x]\n",
    1514             __FUNCTION__, pid, fdid, pid, trdid );
     1599
     1600#if DEBUG_SOCKET_ERROR
     1601printk("\n[ERROR] in %s reported by server / socket[%x,%d] / thread[%x,%x] / cycle %d\n",
     1602__FUNCTION__, pid, fdid, pid, trdid, cycle );
     1603#endif
    15151604            return -1;
    15161605        }
     
    15481637    trdid_t      trdid     = this->trdid;
    15491638
     1639#if DEBUG_SOCKET_CLOSE || DEBUG_SOCKET_ERROR
     1640uint32_t cycle = (uint32_t)hal_get_cycles();
     1641#endif
     1642
    15501643    // get pointers on socket descriptor
    15511644    cxy_t        file_cxy   = GET_CXY( file_xp );
     
    15581651
    15591652#if DEBUG_SOCKET_CLOSE
    1560 uint32_t cycle = (uint32_t)hal_get_cycles();
    15611653if (DEBUG_SOCKET_CLOSE < cycle )
    15621654printk("\n[%s] thread[%x,%x] enters for socket[%x,%d] / cycle %d\n",
     
    15741666        (hal_remote_l64( XPTR( file_cxy , &socket_ptr->tx_client)) != XPTR_NULL) )
    15751667    {
    1576         // release socket lock
     1668                   
     1669#if DEBUG_SOCKET_ERROR
     1670printk("\n[ERROR] in %s : previous TX cmd on socket[%x,%d] / thread[%x,%x] / cycle %d\n",
     1671__FUNCTION__, pid, fdid, pid, trdid, cycle );
     1672#endif
    15771673        remote_queuelock_release( socket_lock_xp );
    1578                    
    1579         printk("\n[ERROR] in %s : previous TX cmd on socket[%x,%d] / thread[%x,%x]\n",
    1580         __FUNCTION__, pid, fdid, pid, trdid );
    15811674        return -1;
    15821675    }
     
    16451738
    16461739        // start retransmission timer
    1647         socket_alarm_start( socket_xp , TCP_RETRANSMISSION_TIMEOUT );
     1740        alarm_start( client_xp,
     1741                     hal_get_cycles() + CONFIG_SOCK_RETRY_TIMEOUT,
     1742                     &socket_alarm_handler,
     1743                     socket_xp );
    16481744
    16491745#if DEBUG_SOCKET_CLOSE
     
    16631759__FUNCTION__, pid, trdid, pid, fdid, cycle );
    16641760#endif
    1665         // stop retransmission timer
    1666         socket_alarm_stop();
     1761        // stop retransmission timer in thread descriptor
     1762        alarm_stop( client_xp );
    16671763
    16681764        // take socket lock
     
    16741770        cmd_valid    = hal_remote_l32( XPTR( file_cxy , &socket_ptr->tx_valid ) );
    16751771
    1676 assert( __FUNCTION__, (((socket_state == TCP_STATE_CLOSED) || (cmd_status != CMD_STS_SUCCESS))
    1677          && (cmd_valid == false)),
    1678 "illegal socket state when client thread resumes after TX_CLOSE\n"
    1679 " socket_state = %s / cmd_status = %d / cmd_valid = %d\n",
     1772assert( __FUNCTION__,
     1773(((socket_state == TCP_STATE_CLOSED) || (cmd_status != CMD_STS_SUCCESS)) && (cmd_valid == false)),
     1774" socket_state = %s / cmd_status = %d / cmd_valid = %d",
    16801775socket_state_str(socket_state), cmd_status, cmd_valid );
    16811776
    16821777        // reset socket.tx_client
    1683         hal_remote_s32( XPTR( file_cxy , &socket_ptr->tx_client ) , XPTR_NULL );
     1778        hal_remote_s64( XPTR( file_cxy , &socket_ptr->tx_client ) , XPTR_NULL );
    16841779
    16851780        if( cmd_status != CMD_STS_SUCCESS )  // error reported
    16861781        {
    1687             printk("\n[ERROR] in %s for command TX_CLOSE / socket[%x,%d] / thread[%x,%x]\n",
    1688             __FUNCTION__, pid, fdid, pid, this->trdid );
     1782
     1783#if DEBUG_SOCKET_ERROR
     1784printk("\n[ERROR] in %s for command TX_CLOSE / socket[%x,%d] / thread[%x,%x] / cycle %d\n",
     1785__FUNCTION__, pid, fdid, pid, this->trdid, cycle );
     1786#endif
    16891787            return -1;
    16901788        }
     
    17081806////////////////////////////////////////////////////////////////////////////////////////
    17091807// This static function is called by the two functions socket_send() & socket_recv().
    1710 // It can be used for both UDP and TCP sockets.
     1808// It is used for both UDP and TCP sockets.
    17111809////////////////////////////////////////////////////////////////////////////////////////
    17121810// @ is_send   : send when true / receive when false.
    17131811// @ fdid      : socket identifier.
    17141812// @ u_buf     : pointer on user buffer in user space.
    1715 // @ length    : number of bytes.
     1813// @ length    : number of bytes in buffer.
    17161814////////////////////////////////////////////////////////////////////////////////////////
    17171815// Implementation note : The behavior is different for SEND & RECV
     
    17491847    chdev_t           * chdev_ptr;
    17501848    cxy_t               chdev_cxy;
    1751     uint32_t            buf_status;      // number of bytes in rx_buf
    17521849    int32_t             moved_bytes;     // total number of moved bytes (fot return)
    1753     xptr_t              server_xp;       // extended pointer on NIC_TX / NIC_RX server thread
    1754     thread_t          * server_ptr;      // local pointer on NIC_TX / NIC_RX server thread
    1755     kmem_req_t          req;             // KCM request for TX kernel buffer
    1756     uint8_t           * tx_buf;          // kernel buffer for TX transfer
    1757     bool_t              cmd_valid;       // from socket descriptor
    1758     uint32_t            cmd_status;      // from socket descriptor
    1759     uint32_t            tx_todo;         // from socket descriptor
     1850    xptr_t              server_xp;       // ext pointer on NIC_TX / NIC_RX thread
     1851    thread_t          * server_ptr;      // local pointer on NIC_TX / NIC_RX thread
     1852    uint8_t           * tx_buf;          // pointer on kernel buffer for TX transfer
     1853    bool_t              cmd_valid;       // RX or TX command from socket descriptor
     1854    uint32_t            cmd_sts;         // RX or TX command from socket descriptor
     1855    uint32_t            tx_todo;         // number of bytes still to send
     1856    xptr_t              rx_buf_xp;       // extended pointer on socket rx_buf
     1857    uint32_t            rx_buf_sts;      // current status of socket rx_buf
    17601858
    17611859    thread_t  * this    = CURRENT_THREAD;
    17621860    process_t * process = this->process;
     1861
     1862#if DEBUG_SOCKET_SEND || DEBUG_SOCKET_RECV || DEBUG_SOCKET_ERROR
     1863uint32_t cycle = (uint32_t)hal_get_cycles();
     1864#endif
     1865
     1866#if DEBUG_SOCKET_SEND || DEBUG_SOCKET_RECV
     1867if( is_send )
     1868printk("\n[%s] thread[%x,%x] socket[%x,%d] enter : SEND / buf %x / length %d / cycle %d\n",
     1869__FUNCTION__, process->pid, this->trdid, process->pid, fdid, u_buf, length, cycle );
     1870else
     1871printk("\n[%s] thread[%x,%x] socket[%x,%d] enter : RECV / buf %x / length %d / cycle %d\n",
     1872__FUNCTION__, process->pid, this->trdid, process->pid, fdid, u_buf, length, cycle );
     1873#endif
    17631874
    17641875    // build extended pointer on client thread
     
    17721883    if( file_xp == XPTR_NULL )
    17731884    {
    1774         printk("\n[ERROR] in %s : undefined fdid %d / thread%x,%x]\n",
    1775         __FUNCTION__, fdid , process->pid, this->trdid );
     1885
     1886#if DEBUG_SOCKET_ERROR
     1887printk("\n[ERROR] in %s : undefined fdid %d / thread%x,%x] / cycle %d\n",
     1888__FUNCTION__, fdid , process->pid, this->trdid, cycle );
     1889#endif
    17761890        return -1;
    17771891    }
     
    17871901    if( file_type != FILE_TYPE_SOCK )
    17881902    {
    1789         printk("\n[ERROR] in %s : illegal file type %s / socket[%x,%d]\n",
    1790         __FUNCTION__, vfs_inode_type_str(file_type), process->pid, fdid );
     1903
     1904#if DEBUG_SOCKET_ERROR
     1905printk("\n[ERROR] in %s : illegal file type thread[%x,%x] / cycle %d\n",
     1906__FUNCTION__, process->pid, this->trdid, cycle );
     1907#endif
    17911908        return -1;
    17921909    }
     
    18031920    nic_channel  = hal_remote_l32( XPTR( file_cxy , &socket_ptr->nic_channel ));
    18041921
    1805     /////////////
     1922    //////////////////////////////////////////////////////
    18061923    if( is_send )                       // SEND command
    18071924    {
    18081925
    18091926#if DEBUG_SOCKET_SEND
    1810 uint32_t    cycle = (uint32_t)hal_get_cycles();
     1927cycle = (uint32_t)hal_get_cycles();
    18111928if (DEBUG_SOCKET_SEND < cycle )
    1812 printk("\n[%s] thread[%x,%x] received SEND command for socket[%x,%d] / length %d / cycle %d\n",
     1929printk("\n[%s] thread[%x,%x] / socket[%x,%d] get SEND / length %d / cycle %d\n",
    18131930__FUNCTION__, process->pid, this->trdid, process->pid, fdid, length, cycle );
    18141931#endif
     1932
    18151933        // check no previous TX command
    1816         if( (hal_remote_l32( XPTR( file_cxy , &socket_ptr->tx_valid )) == true) ||
    1817             (hal_remote_l64( XPTR( file_cxy , &socket_ptr->tx_client)) != XPTR_NULL) )
     1934        if( hal_remote_l32( XPTR( file_cxy , &socket_ptr->tx_valid )) == true )
    18181935        {
    1819             // release socket lock
     1936                   
     1937#if DEBUG_SOCKET_ERROR
     1938printk("\n[ERROR] in %s : previous TX command / socket[%x,%d] / thread[%x,%x] / cycle %d\n",
     1939__FUNCTION__, process->pid, fdid, process->pid, this->trdid, cycle );
     1940#endif
    18201941            remote_queuelock_release( socket_lock_xp );
    1821                    
    1822             printk("\n[ERROR] in %s : previous TX command / socket[%x,%d] / thread[%x,%x]\n",
    1823             __FUNCTION__, process->pid, fdid, process->pid, this->trdid );
    18241942            return -1;
    18251943        }
    18261944
    1827         // allocate a temporary kernel buffer
    1828         req.type  = KMEM_KCM;
    1829         req.order = bits_log2( length );
    1830         req.flags = AF_NONE;
    1831         tx_buf    = kmem_alloc( &req ); 
    1832 
    1833         if( tx_buf == NULL )
    1834         {
    1835             // release socket lock
    1836             remote_queuelock_release( socket_lock_xp );
    1837                    
    1838             printk("\n[ERROR] in %s : no memory for tx_buf / socket[%x,%d] / thread[%x,%x]\n",
    1839             __FUNCTION__, process->pid, fdid, process->pid, this->trdid );
    1840             return -1;
    1841         }
    1842 
    1843         // copy data from user u_buf to kernel tx_buf   
    1844         hal_copy_from_uspace( XPTR( local_cxy , tx_buf ),
     1945        // get tx_buf pointer from socket pointer
     1946        tx_buf = (uint8_t*)hal_remote_lpt( XPTR( file_cxy , &socket_ptr->tx_buf ));
     1947
     1948        // copy data from user u_buf to kernel socket tx_buf   
     1949        hal_copy_from_uspace( XPTR( file_cxy , tx_buf ),
    18451950                              u_buf,
    18461951                              length );
     1952#if DEBUG_SOCKET_SEND
     1953if (DEBUG_SOCKET_SEND < cycle )
     1954printk("\n[%s] thread[%x,%x] / socket[%x,%d] copied %d bytes to tx_buf (%x,%x)\n",
     1955__FUNCTION__, process->pid, this->trdid, process->pid, fdid, length, file_cxy, tx_buf );
     1956putb("tx_buf : 16 first data bytes" , tx_buf , 16 );
     1957#endif
    18471958
    18481959        // register command in socket descriptor
     
    18521963        hal_remote_s32( XPTR( file_cxy , &socket_ptr->tx_len    ) , length );
    18531964        hal_remote_s32( XPTR( file_cxy , &socket_ptr->tx_todo   ) , length );
     1965        hal_remote_s32( XPTR( file_cxy , &socket_ptr->tx_ack    ) , 0 );
    18541966        hal_remote_s32( XPTR( file_cxy , &socket_ptr->tx_valid  ) , true );
    18551967
     
    18691981        thread_unblock( server_xp , THREAD_BLOCKED_CLIENT );
    18701982
    1871         // start retransmission timer
    1872         socket_alarm_start( socket_xp , TCP_RETRANSMISSION_TIMEOUT );
     1983        // start retransmission timer for TCP socket
     1984        if( socket_type == SOCK_STREAM ) 
     1985        {
     1986            alarm_start( client_xp,
     1987                         hal_get_cycles() + CONFIG_SOCK_RETRY_TIMEOUT,
     1988                         &socket_alarm_handler,
     1989                         socket_xp );
     1990        }
    18731991
    18741992#if DEBUG_SOCKET_SEND   
    1875 cycle = (uint32_t)hal_get_cycles();
    18761993if( DEBUG_SOCKET_SEND < cycle )
    1877 printk("\n[%s] thread[%x,%x] socket[%x,%d] register SEND => blocks on <IO> / cycle %d\n",
    1878 __FUNCTION__, process->pid, this->trdid, process->pid, fdid, cycle );
     1994printk("\n[%s] thread[%x,%x] / socket[%x,%d] registers SEND => blocks on <IO>\n",
     1995__FUNCTION__, process->pid, this->trdid, process->pid, fdid );
    18791996#endif
    18801997        // client thread blocks itself and deschedules
     
    18852002cycle = (uint32_t)hal_get_cycles();
    18862003if( DEBUG_SOCKET_SEND < cycle )
    1887 printk("\n[%s] thread[%x,%x] socket[%x,%d] for SEND resumes / cycle %d\n",
     2004printk("\n[%s] thread[%x,%x] / socket[%x,%d] resumes for SEND / cycle %d\n",
    18882005__FUNCTION__, process->pid, this->trdid, process->pid, fdid, cycle );
    18892006#endif
    1890         // stop retransmission timer
    1891         socket_alarm_stop();
    1892 
    1893         // take socket lock
     2007        // stop retransmission timer for TCP socket
     2008        if( socket_type == SOCK_STREAM )
     2009        {
     2010            alarm_stop( client_xp );
     2011        }
     2012
     2013        // take socket lock
    18942014        remote_queuelock_acquire( socket_lock_xp );
    18952015     
     
    18972017        tx_todo    = hal_remote_l32( XPTR( file_cxy , &socket_ptr->tx_todo ));
    18982018        cmd_valid  = hal_remote_l32( XPTR( file_cxy , &socket_ptr->tx_valid ));
    1899         cmd_status = hal_remote_l32( XPTR( file_cxy , &socket_ptr->tx_sts ));
     2019        cmd_sts    = hal_remote_l32( XPTR( file_cxy , &socket_ptr->tx_sts ));
    19002020
    19012021        // reset tx_client in socket descriptor
     
    19062026     
    19072027// check SEND command completed when TX client thread resumes
    1908 assert( __FUNCTION__, (((tx_todo == 0) || (cmd_status != CMD_STS_SUCCESS)) && (cmd_valid == false)),
    1909 "illegal socket state when client thread resumes after TX_SEND\n"
    1910 " tx_todo = %d / tx_status = %d / tx_valid = %d\n",
    1911 tx_todo, cmd_status, cmd_valid );
    1912 
    1913         // release the tx_buf
    1914         req.ptr = tx_buf;
    1915         kmem_free( &req );
    1916 
    1917         if( cmd_status != CMD_STS_SUCCESS )
     2028assert( __FUNCTION__,
     2029(((tx_todo == 0) || (cmd_sts != CMD_STS_SUCCESS)) && (cmd_valid == false)),
     2030"client thread resumes from SEND / bad state : tx_todo %d / tx_sts %d / tx_valid %d",
     2031tx_todo, cmd_sts, cmd_valid );
     2032
     2033        if( cmd_sts != CMD_STS_SUCCESS )
    19182034        {
    19192035
    1920 #if DEBUG_SOCKET_SEND
    1921 cycle = (uint32_t)hal_get_cycles();
    1922 if( DEBUG_SOCKET_RECV < cycle )
    1923 printk("\n[%s] error %s for TX_SEND / socket[%x,%d] / thread[%x,%x]\n",
    1924 __FUNCTION__, socket_cmd_sts_str(cmd_status), process->pid, fdid, process->pid, this->trdid );
     2036#if DEBUG_SOCKET_ERROR   
     2037printk("\n[ERROR] in %s : reported for SEND / socket[%x,%d] / thread[%x,%x] / cycle %d\n",
     2038__FUNCTION__, process->pid, fdid, process->pid, this->trdid, cycle );
    19252039#endif
    19262040            return -1;
     
    19322046cycle = (uint32_t)hal_get_cycles();
    19332047if (DEBUG_SOCKET_SEND < cycle )
    1934 printk("\n[%s] thread[%x,%x] success for SEND / socket[%x,%d] / length %d / cycle %d\n",
     2048printk("\n[%s] thread[%x,%x] SEND success / socket[%x,%d] / bytes %d / cycle %d\n",
    19352049__FUNCTION__, process->pid, this->trdid, process->pid, fdid, length, cycle );
    19362050#endif
     
    19402054    }  // end SEND command
    19412055
    1942     ////
    1943     else                                 // RECV command
     2056    /////////////////////////////////////////////////////////////
     2057    else                                       // RECV command
    19442058    {
    19452059
    19462060#if DEBUG_SOCKET_RECV
    1947 uint32_t    cycle = (uint32_t)hal_get_cycles();
    1948 if (DEBUG_SOCKET_SEND < cycle )
    1949 printk("\n[%s] thread[%x,%x] received RECV command for socket[%x,%d] / length %d / cycle %d\n",
     2061if (DEBUG_SOCKET_RECV < cycle )
     2062printk("\n[%s] thread[%x,%x] / socket[%x,%d] get RECV / length %d / cycle %d\n",
    19502063__FUNCTION__, process->pid, this->trdid, process->pid, fdid, length, cycle );
    19512064#endif
    19522065        // check no previous RX command
    1953         if( (hal_remote_l32( XPTR( file_cxy , &socket_ptr->rx_valid )) == true) ||
    1954             (hal_remote_l64( XPTR( file_cxy , &socket_ptr->rx_client)) != XPTR_NULL) )
     2066        if( hal_remote_l32( XPTR( file_cxy , &socket_ptr->rx_valid )) == true )
    19552067        {
    1956             // release socket lock
     2068                   
     2069#if DEBUG_SOCKET_ERROR   
     2070printk("\n[ERROR] in %s : previous RX command on socket[%x,%d] / thread[%x,%x] / cycle %d\n",
     2071__FUNCTION__, process->pid, fdid, process->pid, this->trdid, cycle );
     2072#endif
    19572073            remote_queuelock_release( socket_lock_xp );
    1958                    
    1959             printk("\n[ERROR] in %s : previous RX command on socket[%x,%d] / thread[%x,%x]\n",
    1960             __FUNCTION__, process->pid, fdid, process->pid, this->trdid );
    19612074            return -1;
    19622075        }
     
    19692082                   
    19702083#if DEBUG_SOCKET_RECV 
    1971 uint32_t cycle = (uint32_t)hal_get_cycles();
     2084cycle = (uint32_t)hal_get_cycles();
    19722085if( DEBUG_SOCKET_RECV < cycle )
    1973 printk("\n[%s] thread[%x,%x] socket[%x,%d] TCP connection closed / cycle %d\n",
     2086printk("\n[%s] thread[%x,%x] / socket[%x,%d] TCP connection closed / cycle %d\n",
    19742087__FUNCTION__, process->pid, this->trdid, process->pid, fdid, cycle );
    19752088#endif
    19762089            return 0;
    19772090        }
    1978         // build extended pointer on socket.rx_buf
    1979         xptr_t rx_buf_xp   = XPTR( file_cxy , &socket_ptr->rx_buf );
    1980 
    1981         // get rx_buf status
    1982         buf_status = remote_buf_status( rx_buf_xp );
    1983 
    1984         if( buf_status == 0 )
     2091
     2092        // build extended pointer on socket rx_buf
     2093        rx_buf_xp = XPTR( file_cxy , &socket_ptr->rx_buf );
     2094
     2095        // get socket rx_buf status
     2096        rx_buf_sts = remote_buf_status( rx_buf_xp );
     2097
     2098        // register RECV command and deschedule when rx_buf empty
     2099        if( rx_buf_sts == 0 )
    19852100        {
    19862101            // registers RX_RECV command in socket descriptor
     
    19932108
    19942109#if DEBUG_SOCKET_RECV 
    1995 uint32_t cycle = (uint32_t)hal_get_cycles();
    19962110if( DEBUG_SOCKET_RECV < cycle )
    1997 printk("\n[%s] thread[%x,%x] socket[%x,%d] rx_buf empty => blocks on <IO> / cycle %d\n",
    1998 __FUNCTION__, process->pid, this->trdid, process->pid, fdid, cycle );
     2111printk("\n[%s] thread[%x,%x] socket[%x,%d] for RECV : rx_buf empty => blocks on <IO>\n",
     2112__FUNCTION__, process->pid, this->trdid, process->pid, fdid );
    19992113#endif
    20002114            // client thread blocks itself and deschedules
     
    20052119cycle = (uint32_t)hal_get_cycles();
    20062120if( DEBUG_SOCKET_RECV < cycle )
    2007 printk("\n[%s] thread[%x,%x] socket[%x,%d] for RECV resumes / cycle %d\n",
     2121printk("\n[%s] thread[%x,%x] socket[%x,%d] for RECV : resumes / cycle %d\n",
    20082122__FUNCTION__, process->pid, this->trdid, process->pid, fdid, cycle );
    20092123#endif
     
    20112125            remote_queuelock_acquire( socket_lock_xp );
    20122126
    2013             // get rx_sts and rx_buf status
     2127            // get command status, command valid, and rx_buf status
    20142128            cmd_valid  = hal_remote_l32( XPTR( file_cxy , &socket_ptr->rx_valid ));
    2015             cmd_status = hal_remote_l32( XPTR( file_cxy , &socket_ptr->rx_sts ));
    2016             buf_status = remote_buf_status( rx_buf_xp );
     2129            cmd_sts    = hal_remote_l32( XPTR( file_cxy , &socket_ptr->rx_sts ));
     2130            rx_buf_sts = remote_buf_status( rx_buf_xp );
    20172131       
    2018 assert( __FUNCTION__, (((buf_status != 0) || (cmd_status != CMD_STS_SUCCESS)) && (cmd_valid == false)),
    2019 "illegal socket state when client thread resumes after RX_RECV\n"
    2020 " buf_status = %d / rx_sts = %d / rx_valid = %d\n",
    2021 buf_status , cmd_status , cmd_valid );
    2022 
    2023             // reset rx_client in socket descriptor
    2024             hal_remote_s64( XPTR( file_cxy , &socket_ptr->rx_client  ) , XPTR_NULL );
    2025 
    2026             // reset rx_buf for an UDP socket
    2027             if( socket_type == SOCK_DGRAM ) remote_buf_reset( rx_buf_xp );
    2028 
    2029             // release socket lock
    2030             remote_queuelock_release( socket_lock_xp );
    2031 
    2032             if( cmd_status == CMD_STS_EOF )           // EOF (remote close) reported
     2132assert( __FUNCTION__, (cmd_valid == false),
     2133"client thread resumes from RECV but rx_valid is true" );
     2134
     2135            if( cmd_sts == CMD_STS_EOF )           // EOF reported by RX server
    20332136            {
    20342137
    20352138#if DEBUG_SOCKET_RECV
    2036 cycle = (uint32_t)hal_get_cycles();
    20372139if( DEBUG_SOCKET_RECV < cycle )
    2038 printk("\n[%s] EOF for RX_RECV / socket[%x,%d] / thread[%x,%x]\n",
     2140printk("\n[%s] EOF received for socket[%x,%d] / thread[%x,%x]\n",
    20392141__FUNCTION__, process->pid, fdid, process->pid, this->trdid );
    20402142#endif
     2143                // release socket lock
     2144                remote_queuelock_release( socket_lock_xp );
     2145
    20412146                return 0;
    20422147            }
    2043             else if( cmd_status != CMD_STS_SUCCESS )   // other error reported
     2148            else if( cmd_sts != CMD_STS_SUCCESS )   // error reported by RX server
    20442149            {
    20452150
    2046 #if DEBUG_SOCKET_RECV
    2047 cycle = (uint32_t)hal_get_cycles();
    2048 if( DEBUG_SOCKET_RECV < cycle )
    2049 printk("\n[%s] error %s for RX_RECV / socket[%x,%d] / thread[%x,%x]\n",
    2050 __FUNCTION__, socket_cmd_sts_str(cmd_status), process->pid, fdid, process->pid, this->trdid );
    2051 #endif
     2151#if DEBUG_SOCKET_ERROR
     2152printk("\n[ERROR] in %s : rx_server for socket[%x,%d] / thread[%x,%x] / cycle %d\n",
     2153__FUNCTION__, process->pid, fdid, process->pid, this->trdid, cycle );
     2154#endif
     2155                // release socket lock
     2156                remote_queuelock_release( socket_lock_xp );
     2157
    20522158                return -1;
    20532159            }
    2054 
     2160            else if( rx_buf_sts == 0 )              // annormally empty rx_buf
     2161            {
     2162
     2163#if DEBUG_SOCKET_ERROR
     2164printk("\n[ERROR] in %s : rx_buf empty for socket[%x,%d] / thread[%x,%x] / cycle %d\n",
     2165__FUNCTION__, process->pid, fdid, process->pid, this->trdid, cycle );
     2166#endif
     2167                // release socket lock
     2168                remote_queuelock_release( socket_lock_xp );
     2169
     2170                return -1;
     2171            }
    20552172        }
    20562173
    20572174        // number of bytes extracted from rx_buf cannot be larger than u_buf size
    2058         moved_bytes = ( length < buf_status ) ? length : buf_status;
     2175        moved_bytes = ( length < rx_buf_sts ) ? length : rx_buf_sts;
    20592176
    20602177        // move data from kernel rx_buf to user u_buf
     
    20622179                                u_buf,
    20632180                                moved_bytes );
    2064 #if DEBUG_SOCKET_SEND
    2065 cycle = (uint32_t)hal_get_cycles();
    2066 if (DEBUG_SOCKET_SEND < cycle )
    2067 printk("\n[%s] thread[%x,%x] success for RECV / socket[%x,%d] / length %d / cycle %d\n",
     2181#if DEBUG_SOCKET_RECV
     2182cycle = (uint32_t)hal_get_cycles();
     2183if (DEBUG_SOCKET_RECV < cycle )
     2184printk("\n[%s] thread[%x,%x] : RECV success / socket[%x,%d] / bytes %d / cycle %d\n",
    20682185__FUNCTION__, process->pid, this->trdid, process->pid, fdid, moved_bytes, cycle );
    20692186#endif
     2187        // release socket lock
     2188        remote_queuelock_release( socket_lock_xp );
     2189
    20702190        return moved_bytes;
    20712191
     
    20952215} // end socket_recv()
    20962216
     2217////////////////////////////////////
     2218int socket_sendto( uint32_t    fdid,
     2219                   uint8_t   * u_buf,
     2220                   uint32_t    length,
     2221                   uint32_t    remote_ip,
     2222                   uint16_t    remote_port )
     2223{
     2224    printk("\n[ERROR] in %s : this function is not implemented yet\n",
     2225    __FUNCTION__, fdid, u_buf, length, remote_ip, remote_port );
     2226    return -1;
     2227
     2228}  // end socket_sendto()
     2229
     2230//////////////////////////////////////
     2231int socket_recvfrom( uint32_t    fdid,
     2232                     uint8_t   * u_buf,
     2233                     uint32_t    length,
     2234                     uint32_t    remote_ip,
     2235                     uint16_t    remote_port )
     2236{
     2237    printk("\n[ERROR] in %s : this function is not implemented yet\n",
     2238    __FUNCTION__, fdid, u_buf, length, remote_ip, remote_port );
     2239    return -1;
     2240
     2241} // end socket_recvfrom()
     2242
    20972243////////////////////////////////////////////
    20982244void socket_display( xptr_t       socket_xp,
    2099                      const char * func_str )
    2100 {
     2245                     const char * func_str,
     2246                     const char * string )
     2247{
     2248    uint32_t   cycle = (uint32_t)hal_get_cycles();
     2249
    21012250    socket_t * socket = GET_PTR( socket_xp );
    21022251    cxy_t      cxy    = GET_CXY( socket_xp );
     
    21112260    uint32_t   remote_port = hal_remote_l32( XPTR( cxy , &socket->remote_port ));
    21122261    uint32_t   tx_valid    = hal_remote_l32( XPTR( cxy , &socket->tx_valid ));
     2262    xptr_t     tx_client   = hal_remote_l64( XPTR( cxy , &socket->tx_client ));
    21132263    uint32_t   tx_cmd      = hal_remote_l32( XPTR( cxy , &socket->tx_cmd ));
    21142264    uint32_t   tx_sts      = hal_remote_l32( XPTR( cxy , &socket->tx_sts ));
     
    21182268    uint32_t   tx_nxt      = hal_remote_l32( XPTR( cxy , &socket->tx_nxt ));         
    21192269    uint32_t   tx_wnd      = hal_remote_l32( XPTR( cxy , &socket->tx_wnd ));         
     2270    uint32_t   tx_ack      = hal_remote_l32( XPTR( cxy , &socket->tx_ack ));         
    21202271    uint32_t   rx_valid    = hal_remote_l32( XPTR( cxy , &socket->rx_valid ));
     2272    xptr_t     rx_client   = hal_remote_l64( XPTR( cxy , &socket->rx_client ));
    21212273    uint32_t   rx_cmd      = hal_remote_l32( XPTR( cxy , &socket->rx_cmd ));
    21222274    uint32_t   rx_sts      = hal_remote_l32( XPTR( cxy , &socket->rx_sts ));
    21232275    uint32_t   rx_nxt      = hal_remote_l32( XPTR( cxy , &socket->rx_nxt ));         
    21242276    uint32_t   rx_wnd      = hal_remote_l32( XPTR( cxy , &socket->rx_wnd ));         
    2125     uint32_t   rx_irs      = hal_remote_l32( XPTR( cxy , &socket->rx_irs ));         
    2126 
    2127     if( func_str == NULL )
    2128     {
    2129         printk("\n****** socket[%x,%d] / xptr[%x,%x]*****\n",
    2130         pid, fdid, cxy, socket );
     2277    uint32_t   rx_irs      = hal_remote_l32( XPTR( cxy , &socket->rx_irs )); 
     2278
     2279    remote_queuelock_t * lock_ptr = &socket->lock; 
     2280    uint32_t   taken       = hal_remote_l32( XPTR( cxy , &lock_ptr->taken ));
     2281
     2282    thread_t * tx_ptr = GET_PTR( tx_client );
     2283    cxy_t      tx_cxy = GET_CXY( tx_client );
     2284    trdid_t    tx_tid = hal_remote_l32( XPTR( tx_cxy , &tx_ptr->trdid ));
     2285
     2286    thread_t * rx_ptr = GET_PTR( rx_client );
     2287    cxy_t      rx_cxy = GET_CXY( rx_client );
     2288    trdid_t    rx_tid = hal_remote_l32( XPTR( rx_cxy , &rx_ptr->trdid ));
     2289
     2290    if( string == NULL )
     2291    {
     2292        printk("\n****** socket[%x,%d] / lock %d / in %s / cycle %d *****\n",
     2293        pid, fdid, taken, func_str, cycle );
    21312294    }
    21322295    else
    21332296    {
    2134         printk("\n***** socket[%x,%d] / xptr[%x,%x] / from %s *****\n",
    2135         pid, fdid, cxy, socket, func_str );
    2136     }
    2137     printk(" - state %s / channel %d\n"
    2138            " - local_addr %x / local_port %x\n"
    2139            " - remote_addr %x / remote_port %x\n"
    2140            " - tx_valid %d (%s) / tx_sts %d / tx_len %x / tx_todo %x\n"
    2141            " - tx_una %x / tx_nxt %x / tx_wnd %x\n"
    2142            " - rx_valid %d (%s) / rx_sts %d\n"
    2143            " - rx_nxt %x / rx_wnd %x / rx_irs %x\n",
    2144            socket_state_str(state), channel ,
    2145            local_addr, local_port,
    2146            remote_addr, remote_port,
    2147            tx_valid, socket_cmd_type_str(tx_cmd), tx_sts, tx_len, tx_todo,
    2148            tx_una, tx_nxt, tx_wnd,
    2149            rx_valid, socket_cmd_type_str(rx_cmd), rx_sts,
    2150            rx_nxt, rx_wnd, rx_irs );
     2297        printk("\n***** socket[%x,%d] / lock %d / in %s %s / cycle %d *****\n",
     2298        pid, fdid, taken, func_str, string, cycle );
     2299    }
     2300    printk(" - state %s / channel %d / local [%x,%x] / remote[%x,%x]\n"
     2301           " - tx : valid %d / client [%x,%x] / cmd %s \n"
     2302           "        sts %d / len %x / todo %x / ack %x / una %x / nxt %x / wnd %x\n"
     2303           " - rx : valid %d / client [%x,%x] / cmd %s\n"
     2304           "        sts %d / nxt %x / wnd %x / irs %x\n",
     2305           socket_state_str(state), channel,
     2306           local_addr, local_port, remote_addr, remote_port,
     2307           tx_valid, pid, tx_tid, socket_cmd_type_str(tx_cmd),
     2308           tx_sts, tx_len, tx_todo, tx_ack, tx_una, tx_nxt, tx_wnd,
     2309           rx_valid, pid, rx_tid, socket_cmd_type_str(rx_cmd),
     2310           rx_sts, rx_nxt, rx_wnd, rx_irs );
    21512311
    21522312}  // end socket_display()
Note: See TracChangeset for help on using the changeset viewer.