PageRenderTime 85ms CodeModel.GetById 2ms app.highlight 73ms RepoModel.GetById 1ms app.codeStats 0ms

/peek-build/m23/g23m-fad/tcpip/tcpip_api_layer.c

https://bitbucket.org/C0deMaver1ck/peeklinux
C | 1883 lines | 1223 code | 240 blank | 420 comment | 56 complexity | 59ca6333045277b6a9aeaf376c61b733 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/* 
   2+------------------------------------------------------------------------------
   3|  File:       tcpip_api_layer.c
   4+------------------------------------------------------------------------------
   5|  Copyright 2003 Texas Instruments Berlin, AG 
   6|                 All rights reserved. 
   7| 
   8|                 This file is confidential and a trade secret of Texas 
   9|                 Instruments Berlin, AG 
  10|                 The receipt of or possession of this file does not convey 
  11|                 any rights to reproduce or disclose its contents or to 
  12|                 manufacture, use, or sell anything it may describe, in 
  13|                 whole, or in part, without the specific written consent of 
  14|                 Texas Instruments Berlin, AG. 
  15+----------------------------------------------------------------------------- 
  16|  Purpose :  GPF-based TCP/IP's glue layer towards the socket API.
  17+----------------------------------------------------------------------------- 
  18*/ 
  19
  20
  21#define TCPIP_API_LAYER_C
  22
  23#define ENTITY_TCPIP
  24
  25/*==== INCLUDES =============================================================*/
  26
  27#include <string.h>             /* String functions, e. g. strncpy(). */
  28
  29#include "typedefs.h"   /* to get Condat data types */
  30#include "vsi.h"        /* to get a lot of macros */
  31#include "custom.h"
  32#include "gsm.h"        /* to get a lot of macros */
  33#include "prim.h"       /* to get the definitions of used SAP and directions */
  34#include "pei.h"        /* to get PEI interface */
  35#include "tools.h"      /* to get common tools */
  36#include "dti.h"        /* For DTI library definitions. */
  37#include "glob_defs.h"
  38#include "tcpip.h"      /* to get the global entity definitions */
  39#include "tcpip_int.h"
  40
  41/* RNET includes
  42 */
  43#include "rv_general.h"
  44#include "rnet_api.h"
  45#include "rnet_rt_env.h"
  46#include "rnet_message.h"
  47#include "rnet_rt_i.h"
  48
  49/* NexGenIP includes
  50 */
  51#include <ngip/if.h>
  52
  53#ifdef _SIMULATION_
  54#include "tcpip_sim_utils.h"    /* Utilities for use in the simulation. */
  55#endif /* _SIMULATION_ */
  56
  57
  58
  59/*==== Local prototypes =====================================================*/
  60
  61
  62
  63
  64/*==== Macros ===============================================================*/
  65
  66/* Two macros to go from socket descriptor to sock_table[] index and vice
  67 * versa.
  68 */
  69#define SOCK_S_INDEX(desc) (SOCKPAR_GET(desc)->s_index)
  70#define SOCK_RT_DESC(s_index) (sock_table[s_index]->rtdesc)
  71
  72/* Retrieve the parameter block associated with a socket descriptor (as
  73 * user_data).
  74 */
  75#define SOCKPAR_GET(socket) ((T_sockpar *) rnet_get_user_data(socket))
  76
  77/* Check if there is a valid socket for the specified socket index.
  78 */
  79#define INVALID_S_INDEX(socket) \
  80  ((socket) >= RNET_RT_SOCK_MAX OR sock_table[socket] EQ NULL)
  81    
  82
  83/* We don't have a fixed value for the application handle (there will be more
  84 * than one). TCPIP wants to send a message to itself, so it is not convenient
  85 * to redirect all primitives, so we use the MMI handle for the application
  86 * for testing. This will then be redirected to the TAP.
  87 */
  88#ifdef _SIMULATION_
  89#define APP_HANDLE hCommMMI
  90#else  /* _SIMULATION_ */
  91#define APP_HANDLE app_handle
  92#endif /* _SIMULATION_ */
  93
  94
  95/*==== Types ================================================================*/
  96
  97/* This struct is to be associated to a socket descriptor as user_data in
  98 * order to provide context for the event handler functions. The struct is
  99 * zero-initialized, so all default values must be zero.
 100 *
 101 * Pointers to these structures are kept in sock_table[].
 102 */
 103typedef struct sock_params {
 104  int s_index ;                 /* Index in socket table. */
 105  T_RNET_DESC *rtdesc ;         /* The RNET_RT socket descriptor. */
 106  T_HANDLE app_handle ;         /* Communication handle of application
 107                                 * entity. */
 108  U8 ipproto ;                  /* IP protocol number of socket. */
 109  U32 request_id ;              /* Request identification (if present). */
 110  U32 expected_event ;          /* The event we are waiting for on this
 111                                 * connection. This is necessary
 112                                 * for error handling, because the
 113                                 * RNET_ERROR_IND function gets no information
 114                                 * *which* request caused the error. */
 115  BOOL is_connected ;           /* Connected UDP or TCP socket. (NexGenIP does
 116                                 * not give us an error code when we try to
 117                                 * send on a non-connected socket, so we have
 118                                 * to maintain this status by ourselves in
 119                                 * order to report the error to the
 120                                 * application.  */
 121  BOOL recv_waiting ;           /* TRUE iff incoming data is (or might be)
 122                                 * available. */
 123  BOOL appl_xoff ;              /* TRUE iff flow control to the application is
 124                                 * in "xoff" status.  */
 125  struct
 126  {
 127    U16 total_length ;          /* Total length of buffer, zero if no data is
 128                                 * waiting. */
 129    U16 offset ;                /* Offset of first byte not yet sent. */
 130    U8 *buffer ;                /* Pointer to data buffer waiting to be
 131                                 * sent. */
 132  } send ;
 133} T_sockpar ;
 134
 135
 136/*==== Local data ===========================================================*/
 137
 138  
 139/* Table of active socket descriptors; provides the mapping between the small
 140 * integers used in the primitives and the actual RNET socket descriptors.
 141 */
 142static T_sockpar *sock_table[RNET_RT_SOCK_MAX] ;
 143
 144
 145
 146/*==== Primitive sender functions ===========================================*/
 147
 148
 149/** Confirm the result of a TCPIP_INITIALIZE_REQ.
 150 * 
 151 * @param result   Result of the initialization.
 152 */
 153static void tcpip_initialize_cnf(U8 result)
 154{
 155  TRACE_FUNCTION("tcpip_initialize_cnf()") ;
 156
 157  {
 158    PALLOC(prim, TCPIP_INITIALIZE_CNF) ;
 159    prim->result = result ;
 160    PSENDX(MMI, prim) ;
 161  }
 162}
 163
 164
 165/** Confirm the result of a TCPIP_SHUTDOWN_REQ
 166 * 
 167 * @param result   Result of the shutdown.
 168 */
 169static void tcpip_shutdown_cnf(U8 result)
 170{
 171  TRACE_FUNCTION("tcpip_shutdown_cnf()") ;
 172
 173  {
 174    PALLOC(prim, TCPIP_SHUTDOWN_CNF) ;
 175    prim->result = result ;
 176    PSENDX(MMI, prim) ;
 177  }
 178}
 179
 180
 181/** Confirm the result of a TCPIP_IFCONFIG_REQ
 182 * 
 183 * @param result   Result of the configuration.
 184 */
 185static void tcpip_ifconfig_cnf(U8 result)
 186{
 187  TRACE_FUNCTION("tcpip_ifconfig_cnf()") ;
 188
 189  {
 190    PALLOC(prim, TCPIP_IFCONFIG_CNF) ;
 191    prim->result = result ;
 192    PSENDX(MMI, prim) ;
 193  }
 194}
 195
 196
 197/** Confirm the result of a TCPIP_DTI_REQ. This function is called
 198 * from tcpip_dti.c, so it must not be static.
 199 * 
 200 * @param dti_conn    Indicates whether the DTI link is to be established or
 201 *                    disconnected
 202 * @param link_id     DTI link identifier
 203 */
 204void tcpip_dti_cnf(U8 dti_conn, U32 link_id)
 205{
 206  TRACE_FUNCTION("tcpip_dti_cnf()") ;
 207
 208  {
 209    PALLOC(prim, TCPIP_DTI_CNF) ;
 210    prim->dti_conn = dti_conn ;
 211    prim->link_id = link_id ;
 212    PSENDX(MMI, prim) ;
 213  }
 214}
 215
 216
 217/** Confirm the result of a TCPIP_CREATE_REQ.
 218 *
 219 * @param app_handle    Communication handle of requesting task.
 220 * @param result        Result of the operation.
 221 * @param socket        Index of newly created socket (if OK).
 222 * @param request_id    Request ID as passed in TCPIP_CREATE_REQ.
 223 */
 224static void tcpip_create_cnf(T_HANDLE app_handle, U8 result, int socket,
 225                             U32 request_id)
 226{
 227  TRACE_FUNCTION("tcpip_create_cnf()") ;
 228  TRACE_EVENT_P1("app_handle %d",APP_HANDLE);
 229
 230  {
 231    PALLOC(prim, TCPIP_CREATE_CNF) ;
 232    prim->event_type = TCPIP_EVT_CREATE_CNF ;
 233    prim->result = result ;
 234    prim->socket = socket ;
 235    prim->request_id = request_id ;
 236    PSEND(APP_HANDLE, prim) ;
 237  }
 238}
 239
 240
 241/** Confirm the result of a TCPIP_CLOSE_REQ.
 242 * 
 243 * @param app_handle    Communication handle of requesting task.
 244 * @param result        Result of the operation.
 245 * @param socket        Index of (no longer valid) socket.
 246 */
 247static void tcpip_close_cnf(T_HANDLE app_handle, U8 result, int socket)
 248{
 249  TRACE_FUNCTION("tcpip_close_cnf()") ;
 250
 251  {
 252    PALLOC(prim, TCPIP_CLOSE_CNF) ;
 253    prim->event_type = TCPIP_EVT_CLOSE_CNF ;
 254    prim->result = result ;
 255    prim->socket = socket ;
 256    PSEND(APP_HANDLE, prim) ;
 257  }
 258}
 259
 260
 261/** Confirm the result of a TCPIP_BIND_REQ.
 262 *
 263 * @param app_handle    Communication handle of requesting task.
 264 * @param result        Result of the operation.
 265 * @param socket        Index of the socket.
 266 */
 267static void tcpip_bind_cnf(T_HANDLE app_handle, U8 result, int socket)
 268{
 269  TRACE_FUNCTION("tcpip_bind_cnf()") ;
 270
 271  {
 272    PALLOC(prim, TCPIP_BIND_CNF) ;
 273    prim->event_type = TCPIP_EVT_BIND_CNF ;
 274    prim->result = result ;
 275    prim->socket = socket ;
 276    PSEND(APP_HANDLE, prim) ;
 277  }
 278}
 279
 280
 281/** Confirm the result of a TCPIP_LISTEN_REQ.
 282 * 
 283 * @param app_handle    Communication handle of requesting task.
 284 * @param result        Result of the operation.
 285 * @param socket        Index of the socket.
 286 */
 287static void tcpip_listen_cnf(T_HANDLE app_handle, U8 result, int socket)
 288{
 289  TRACE_FUNCTION("tcpip_listen_cnf()") ;
 290
 291  {
 292    PALLOC(prim, TCPIP_LISTEN_CNF) ;
 293    prim->event_type = TCPIP_EVT_LISTEN_CNF ;
 294    prim->result = result ;
 295    prim->socket = socket ;
 296    PSEND(APP_HANDLE, prim) ;
 297  }
 298}
 299
 300
 301/** Confirm the result of a TCPIP_CONNECT_REQ.
 302 * 
 303 * @param app_handle    Communication handle of requesting task.
 304 * @param result        Result of the operation.
 305 * @param socket        Index of the socket.
 306 */
 307static void tcpip_connect_cnf(T_HANDLE app_handle, U8 result, int socket)
 308{
 309  TRACE_FUNCTION("tcpip_connect_cnf()") ;
 310
 311  {
 312    PALLOC(prim, TCPIP_CONNECT_CNF) ;
 313    prim->event_type = TCPIP_EVT_CONNECT_CNF ;
 314    prim->result = result ;
 315    prim->socket = socket ;
 316    PSEND(APP_HANDLE, prim) ;
 317  }
 318}
 319
 320
 321/** Confirm the result of a TCPIP_DATA_REQ.
 322 * 
 323 * @param app_handle    Communication handle of requesting task.
 324 * @param result        Result of the operation.
 325 * @param socket        Index of the socket.
 326 * @param window        Window size for sender.
 327 */
 328static void tcpip_data_cnf(T_HANDLE app_handle, U8 result, int socket,
 329                           U16 window)
 330{
 331  TRACE_FUNCTION("tcpip_data_cnf()") ;
 332
 333  {
 334    PALLOC(prim, TCPIP_DATA_CNF) ;
 335    prim->event_type = TCPIP_EVT_FLOW_READY_IND ;
 336    prim->result = result ;
 337    prim->socket = socket ;
 338    prim->window = window ;
 339    PSEND(APP_HANDLE, prim) ;
 340  }
 341}
 342
 343
 344/** Indicate incoming data.
 345 * 
 346 * @param app_handle    Communication handle of requesting task.
 347 * @param result        Result of the operation.
 348 * @param socket        Index of the socket.
 349 * @param ipaddr        Source IP address.
 350 * @param port          Source port number.
 351 * @param buflen        Length of payload data.
 352 * @param data          Adress of payload data buffer.
 353 */
 354static void tcpip_data_ind(T_HANDLE app_handle, U8 result, int socket,
 355                           U32 ipaddr, U16 port, U16 buflen, U8 *data)
 356{
 357  TRACE_FUNCTION("tcpip_data_ind()") ;
 358
 359  {
 360    PALLOC(prim, TCPIP_DATA_IND) ;
 361    prim->event_type = TCPIP_EVT_RECV_IND ; /* Unfortunately not _DATA_IND */
 362    prim->result = result ;
 363    prim->socket = socket ;
 364    prim->ipaddr = ipaddr ;
 365    prim->port = port ;
 366    prim->buflen = buflen ;
 367    prim->data = (U32) data ;
 368    PSEND(APP_HANDLE, prim) ;
 369  }
 370}
 371
 372
 373/** Confirm the result of a TCPIP_SOCKNAME_REQ.
 374 * 
 375 * @param app_handle    Communication handle of the requesting task.
 376 * @param result        Result of the operation.
 377 * @param socket        Index of the socket.
 378 * @param ipaddr        IP address of the socket.
 379 * @param port          Port number of the socket.
 380 */
 381static void tcpip_sockname_cnf(T_HANDLE app_handle, U8 result, int socket,
 382                               U32 ipaddr, U16 port)
 383{
 384  TRACE_FUNCTION("tcpip_sockname_cnf()") ;
 385
 386  {
 387    PALLOC(prim, TCPIP_SOCKNAME_CNF) ;
 388    prim->event_type = TCPIP_EVT_SOCKNAME_CNF ;
 389    prim->result = result ;
 390    prim->socket = socket ;
 391    prim->ipaddr = ipaddr ;
 392    prim->port = port ;
 393    PSEND(APP_HANDLE, prim) ;
 394  }
 395}
 396
 397
 398/** Confirm the result of a TCPIP_PEERNAME_REQ.
 399 * 
 400 * @param app_handle    Communication handle of the requesting task.
 401 * @param result        Result of the operation.
 402 * @param socket        Index of the socket.
 403 * @param ipaddr        IP address of the remote peer.
 404 * @param port          Remore port number of the socket.
 405 */
 406static void tcpip_peername_cnf(T_HANDLE app_handle, U8 result, int socket,
 407                               U32 ipaddr, U16 port)
 408{
 409  TRACE_FUNCTION("tcpip_peername_cnf()") ;
 410
 411  {
 412    PALLOC(prim, TCPIP_PEERNAME_CNF) ;
 413    prim->event_type = TCPIP_EVT_PEERNAME_CNF ;
 414    prim->result = result ;
 415    prim->socket = socket ;
 416    prim->ipaddr = ipaddr ;
 417    prim->port = port ;
 418    PSEND(APP_HANDLE, prim) ;
 419  }
 420}
 421
 422
 423/** Confirm the result of a TCPIP_HOSTINFO_REQ.
 424 * 
 425 * @param app_handle    Communication handle of the requesting task.
 426 * @param result        Result of the operation.
 427 * @param request_id    Request ID as passed in TCPIP_CREATE_REQ.
 428 * @param hostname      Full-qualified domain name of the host, may be NULL.
 429 * @param ipaddr        IP address of the host.
 430 */
 431static void tcpip_hostinfo_cnf(T_HANDLE app_handle, U8 result, U32 request_id,
 432                        char *hostname, U32 ipaddr)
 433{
 434  TRACE_FUNCTION("tcpip_hostinfo_cnf()") ;
 435
 436  {
 437    PALLOC(prim, TCPIP_HOSTINFO_CNF) ;
 438    prim->event_type = TCPIP_EVT_HOSTINFO_CNF ;
 439    prim->result = result ;
 440    prim->request_id = request_id ;
 441    if (hostname NEQ NULL)
 442    {
 443      strncpy((char *) prim->hostname, hostname, TCPIP_HNAMELEN) ;
 444      prim->hostname[TCPIP_HNAMELEN-1] = '\0' ;
 445    }
 446    else
 447    {
 448      prim->hostname[0] = '\0' ;
 449    }
 450    prim->ipaddr = ipaddr ;
 451    PSEND(APP_HANDLE, prim) ;
 452  }
 453}
 454
 455
 456/** Confirm the result of a TCPIP_MTU_SIZE_REQ.
 457 * 
 458 * @param app_handle    Communication handle of the requesting task.
 459 * @param result        Result of the operation.
 460 * @param socket        Index of the socket.
 461 * @param mtu_size      Size of the MTU.
 462 */
 463static void tcpip_mtu_size_cnf(T_HANDLE app_handle, U8 result, int socket,
 464                               U16 mtu_size)
 465{
 466  TRACE_FUNCTION("tcpip_mtu_size_cnf()") ;
 467
 468  {
 469    PALLOC(prim, TCPIP_MTU_SIZE_CNF) ;
 470    prim->event_type = TCPIP_EVT_MTU_SIZE_CNF ;
 471    prim->result = result ;
 472    prim->socket = socket ;
 473    prim->mtu_size = mtu_size ;
 474    PSEND(APP_HANDLE, prim) ;
 475  }
 476}
 477
 478
 479/** Indicate an incoming TCP connection.
 480 * 
 481 * @param app_handle    Communication handle of the task.
 482 * @param socket        Index of the listening socket.
 483 * @param new_socket    New socket for this connection.
 484 * @param ipaddr        IP address of the remote peer.
 485 * @param port          Remore port number of the socket.
 486 */
 487static void tcpip_connect_ind(T_HANDLE app_handle, int socket,
 488                              int new_socket, U32 ipaddr, U16 port)
 489{
 490  TRACE_FUNCTION("tcpip_connect_ind()") ;
 491
 492  {
 493    PALLOC(prim, TCPIP_CONNECT_IND) ;
 494    prim->event_type = TCPIP_EVT_CONNECT_IND ;
 495    prim->result = TCPIP_RESULT_OK ;
 496    prim->socket = socket ;
 497    prim->new_socket = new_socket ;
 498    prim->ipaddr = ngHTONL(ipaddr) ;
 499    prim->port = ngHTONS(port) ;
 500    PSEND(APP_HANDLE, prim) ;
 501  }
 502}
 503
 504
 505/** Indicate that a connection has been closed.
 506 * 
 507 * @param app_handle    Communication handle of the task.
 508 * @param socket        Index of the socket.
 509 */
 510static void tcpip_conn_closed_ind(T_HANDLE app_handle, int socket)
 511{
 512  TRACE_FUNCTION("tcpip_conn_closed_ind()") ;
 513
 514  {
 515    PALLOC(prim, TCPIP_CONN_CLOSED_IND) ;
 516    prim->event_type = TCPIP_EVT_CONN_CLOSED_IND ;
 517    prim->result = TCPIP_RESULT_OK ;
 518    prim->socket = socket ;
 519    PSEND(APP_HANDLE, prim) ;
 520  }
 521}
 522
 523
 524/** Indicate an asynchronous error on a socket.
 525 * 
 526 * @param app_handle    Communication handle of the task.
 527 * @param result        Result code of the error.
 528 * @param socket        Index of the socket.
 529 */
 530static void tcpip_error_ind(T_HANDLE app_handle, U8 result, int socket)
 531{
 532  TRACE_FUNCTION("tcpip_error_ind()") ;
 533  
 534  {
 535    PALLOC(prim, TCPIP_ERROR_IND) ;
 536    prim->event_type = TCPIP_EVT_ERROR_IND ;
 537    prim->result = result ;
 538    prim->socket = socket ;
 539    PSEND(APP_HANDLE, prim) ;
 540  }
 541}
 542
 543
 544/** Send a message to self.
 545 * 
 546 * @param msg_p    pointer to message
 547 * @param msg_id   message identification
 548 */
 549void tcpip_send_internal_ind(U32 msg_p, U32 msg_id)
 550{
 551  TRACE_FUNCTION("tcpip_send_internal_ind()") ;
 552
 553  {
 554    PALLOC(prim, TCPIP_INTERNAL_IND) ;
 555    prim->msg_p = msg_p ;
 556    prim->msg_id = msg_id ;
 557    PSEND(hCommTCPIP, prim) ;
 558  }
 559}
 560
 561
 562/*==== Local utility functions ==============================================*/
 563
 564/** Allocate a new socket parameter block, initialize it with the given
 565 * parameters, and put it into the list. Allocate a slot in the sock_table[]
 566 * and fill it. If we cannot allocate a slot, return NULL. This is considered
 567 * an internal error, because we *have* a slot free for each possible socket.
 568 * 
 569 * @param socket        The socket descriptor (if applicable).
 570 * @param app_handle    Communication handle of application task.
 571 * @param request_id    Request identification (if applicable).
 572 * @return a pointer to the sock_params struct or NULL on error.
 573 */
 574static T_sockpar *sockpar_new(T_RNET_DESC *socket, T_HANDLE app_handle,
 575                              U8 ipproto, U32 request_id)
 576{
 577  T_sockpar *sp ;               /* Pointer to new struct. */
 578  int sti ;                     /* Socket table index. */
 579
 580  TRACE_FUNCTION("sockpar_new()") ;
 581
 582  /* Allocate and enqueue. */
 583  MALLOC(sp, sizeof(T_sockpar)) ;
 584  /* TRACE_EVENT_P1("MALLOC gives us %08x", sp) ; */
 585  memset(sp, 0, sizeof(T_sockpar)) ;
 586
 587  sp->rtdesc = socket ;
 588  sp->app_handle = app_handle ;
 589  sp->ipproto = ipproto ;
 590  sp->request_id = request_id ;
 591
 592  for (sti = 0; sti < RNET_RT_SOCK_MAX; sti++)
 593  {
 594    if (sock_table[sti] EQ NULL)
 595    {
 596      sock_table[sti] = sp ;
 597      sp->s_index = sti ;
 598      return sp ;
 599    }
 600  }
 601  /* No free slot in table found -- this must be an error, because we have a
 602   * slot for each possible socket. */
 603  TRACE_ERROR("No free slot in sock_table[] found") ;
 604  /* TRACE_EVENT_P1("We MFREE %08x", sp) ; */
 605  MFREE(sp) ;
 606  return NULL ;
 607}
 608
 609
 610/** Dequeue and deallocate a socket parameter block. Free the slot in
 611 * sock_table[].
 612 * 
 613 * @param sp    Pointer to sock_params struct.
 614 */
 615static void sockpar_delete(T_sockpar *sp)
 616{
 617  TRACE_FUNCTION("sockpar_delete()") ;
 618
 619  sock_table[sp->s_index] = 0 ;
 620  /* TRACE_EVENT_P1("We MFREE %08x", sp) ; */
 621  MFREE(sp) ;
 622}
 623
 624
 625/** Clear the send buffer of a socket parameter block and free the associated
 626 * data.
 627 * 
 628 * @param sockpar    The socket parameter block.
 629 */
 630static void tcpip_clear_send_buffer(T_sockpar *sockpar)
 631{
 632  sockpar->send.total_length = 0 ;
 633  sockpar->send.offset = 0 ;
 634#ifndef _SIMULATION_
 635  /* The simulation would crash in the MFREE(), as the send.buffer is not a
 636   * frame-allocated piece of memory. */
 637  /* TRACE_EVENT_P1("MFREE sockpar->send.buffer %x", sockpar->send.buffer) ; */
 638  MFREE(sockpar->send.buffer) ;
 639#endif /* _SIMULATION_ */
 640  sockpar->send.buffer = NULL ;
 641}
 642
 643
 644/** Convert an RNET error code to the appropriate TCPIP result code.
 645 * 
 646 * @param rnet_ret    The RNET error code.
 647 * @return            The TCPIP result code.
 648 */
 649static U8 rnet_error_to_tcpip_result(T_RNET_RET rnet_ret)
 650{
 651  switch (rnet_ret)
 652  {
 653    case RNET_OK:
 654      TRACE_EVENT("RNET_OK -> TCPIP_RESULT_OK") ;
 655      return TCPIP_RESULT_OK ;
 656    case RNET_MEMORY_ERR:
 657      TRACE_EVENT("RNET_MEMORY_ERR -> TCPIP_RESULT_OUT_OF_MEMORY") ;
 658      return TCPIP_RESULT_OUT_OF_MEMORY ;
 659    case RNET_INVALID_PARAMETER:
 660      TRACE_EVENT("RNET_INVALID_PARAMETER -> TCPIP_RESULT_INVALID_PARAMETER") ;
 661      return TCPIP_RESULT_INVALID_PARAMETER ;
 662    case RNET_NOT_SUPPORTED:
 663      TRACE_EVENT("RNET_NOT_SUPPORTED -> TCPIP_RESULT_NOT_SUPPORTED") ;
 664      return TCPIP_RESULT_NOT_SUPPORTED ;
 665    case RNET_NOT_READY:
 666      TRACE_EVENT("RNET_NOT_READY -> TCPIP_RESULT_NOT_READY") ;
 667      return TCPIP_RESULT_NOT_READY ;
 668    case RNET_INTERNAL_ERR:
 669      TRACE_EVENT("RNET_INTERNAL_ERR -> TCPIP_RESULT_INTERNAL_ERROR") ;
 670      return TCPIP_RESULT_INTERNAL_ERROR ;
 671    case RNET_IN_USE:
 672      TRACE_EVENT("RNET_IN_USE -> TCPIP_RESULT_ADDR_IN_USE") ;
 673      return TCPIP_RESULT_ADDR_IN_USE ;
 674    case RNET_NOT_INITIALIZED:
 675      TRACE_EVENT("RNET_NOT_INITIALIZED -> TCPIP_RESULT_NOT_READY") ;
 676      return TCPIP_RESULT_NOT_READY ;
 677    case RNET_NET_UNREACHABLE:
 678      TRACE_EVENT("RNET_NET_UNREACHABLE -> TCPIP_RESULT_UNREACHABLE") ;
 679      return TCPIP_RESULT_UNREACHABLE ;
 680    case RNET_TIMEOUT:
 681      TRACE_EVENT("RNET_TIMEOUT -> TCPIP_RESULT_TIMEOUT") ;
 682      return TCPIP_RESULT_TIMEOUT ;
 683    case RNET_CONN_REFUSED:
 684      TRACE_EVENT("RNET_CONN_REFUSED -> TCPIP_RESULT_CONN_REFUSED") ;
 685      return TCPIP_RESULT_CONN_REFUSED ;
 686    case RNET_CONN_RESET:
 687      TRACE_EVENT("RNET_CONN_RESET -> TCPIP_RESULT_CONN_RESET") ;
 688      return TCPIP_RESULT_CONN_RESET ;
 689    case RNET_CONN_ABORTED:
 690      TRACE_EVENT("RNET_CONN_ABORTED -> TCPIP_RESULT_CONN_ABORTED") ;
 691      return TCPIP_RESULT_CONN_ABORTED ;
 692    case RNET_MSG_SIZE:
 693      TRACE_EVENT("RNET_MSG_SIZE -> TCPIP_RESULT_MSG_TOO_BIG") ;
 694      return TCPIP_RESULT_MSG_TOO_BIG ;
 695    case RNET_HOST_NOT_FOUND:
 696      TRACE_EVENT("RNET_HOST_NOT_FOUND -> TCPIP_RESULT_HOST_NOT_FOUND") ;
 697      return TCPIP_RESULT_HOST_NOT_FOUND ;
 698
 699      /* The following should not be delivered as a result code: */
 700    case RNET_CONN_CLOSED:
 701      TRACE_EVENT("RNET_CONN_CLOSED -> TCPIP_RESULT_INTERNAL_ERROR") ;
 702      return TCPIP_RESULT_INTERNAL_ERROR ;
 703    case RNET_PARTIAL_SENT:
 704      TRACE_EVENT("RNET_PARTIAL_SENT -> TCPIP_RESULT_INTERNAL_ERROR") ;
 705      return TCPIP_RESULT_INTERNAL_ERROR ;
 706    default:
 707      TRACE_EVENT_P1("unknown (%d) ->TCPIP_RESULT_INTERNAL_ERROR", rnet_ret) ;
 708      return TCPIP_RESULT_INTERNAL_ERROR ;
 709  }
 710}
 711
 712
 713/** Read incoming data (from TCP/IP to the application). This function is
 714 * called only when the flow control status towards the application is in xon
 715 * state.
 716 * 
 717 * @param sockpar      Socket parameter block.
 718 */
 719static void tcpip_read_incoming_to_app(T_sockpar *sockpar)
 720{
 721  U8 *buffer ;                  /* Payload data buffer. */
 722  U16 length ;                  /* Payload data length. */
 723  T_RNET_RET retval ;           /* Return value of rnet_recv(). */
 724  T_RNET_IP_ADDR ipaddr ;       /* IP address of sender. */
 725  T_RNET_PORT port ;            /* Port numer at remote end. */
 726
 727  TRACE_FUNCTION("tcpip_read_incoming_to_app()") ;
 728
 729  /* If flow control status is off, we must not send incoming data. */
 730  if (sockpar->appl_xoff)
 731  {
 732    TRACE_EVENT("tcpip_read_incoming_to_app() called in xoff state") ;
 733    return ;
 734  }
 735
 736  /* We don't expect to read packets larger than this. To be precise, we
 737   * aren't able to. */
 738  MALLOC(buffer, TCPIP_DEFAULT_MTU_SIZE) ;
 739  /* TRACE_EVENT_P1("MALLOC gives us %08x", buffer) ; */
 740  length = TCPIP_DEFAULT_MTU_SIZE ;
 741
 742  /* Should be unspecified for TCP; will be set by rnet_recv_from() for
 743   * UDP. */
 744  ipaddr = TCPIP_UNSPECIFIED_IPADDR ;
 745  port = TCPIP_UNSPECIFIED_PORT ;
 746  
 747  switch (sockpar->ipproto)
 748  {
 749    case TCPIP_IPPROTO_TCP:
 750      TRACE_EVENT_P2("Calling rnet_recv() for socket %d length %d",
 751                     sockpar->s_index, length) ;
 752      retval = rnet_recv(sockpar->rtdesc, buffer, &length) ;
 753      TRACE_EVENT_P2("rnet_recv() returns %d length %d", retval, length) ;
 754      break ;
 755    case TCPIP_IPPROTO_UDP:     /* Need to read sender address with UDP. */
 756      TRACE_EVENT_P4("Calling rnet_recv_from() for socket %d length %d "
 757                     "ipaddr %x port %d",
 758                     sockpar->s_index, length, ipaddr, port) ;
 759      retval = rnet_recv_from(sockpar->rtdesc, buffer, &length,
 760                              &ipaddr, &port) ;
 761      TRACE_EVENT_P4("rnet_recv_from() returns %d length %d ipaddr %x port %d",
 762                     retval, length, ipaddr, port) ;
 763      break ;
 764    default:
 765      retval = RNET_INVALID_PARAMETER ;
 766      TRACE_ERROR("tcpip_read_incoming_to_app: unknown IP protocol") ;
 767      break ;
 768  }
 769
 770  if (retval EQ RNET_OK)
 771  {
 772    /* Only if the length is zero, there is no more data waiting. */
 773    if (length EQ 0)
 774    {
 775      sockpar->recv_waiting = FALSE ;
 776      /* TRACE_EVENT_P1("We MFREE %08x", buffer) ; */
 777      MFREE(buffer) ;
 778    }
 779    else
 780    {
 781      /* We use an effective window size of zero, so flow control status is
 782       * xoff after sending a primitive. */
 783      tcpip_data_ind(sockpar->app_handle, TCPIP_RESULT_OK,
 784                     sockpar->s_index, ipaddr, port, length, buffer) ;
 785      TRACE_EVENT("switch flow control towards application to xoff") ;
 786      dti_stop(tcpip_data->dti_handle, 0, TCPIP_DTI_TO_LOWER_LAYER, 0) ;    // Add one flow control to not allow SNDCP send next data package. OMAPS00172999  05132008
 787	  
 788      sockpar->appl_xoff = TRUE ;
 789#ifdef _SIMULATION_
 790      /* In the simulation, free the buffer -- it is meaningless for the TAP
 791       * and will not be freed at any other place. */
 792      MFREE(buffer) ;
 793#endif /* _SIMULATION_ */
 794    }
 795  }
 796  else                          /* retval != RNET_OK */
 797  {
 798    /* TRACE_EVENT_P1("We MFREE %08x", buffer) ; */
 799    MFREE(buffer) ;
 800    tcpip_error_ind(sockpar->app_handle, rnet_error_to_tcpip_result(retval),
 801                    sockpar->s_index) ;
 802  }
 803}
 804
 805
 806/** Try to send data over RNET. To be called after the application has sent
 807 * data, and if we have waiting data and RNET has signalled that we may send
 808 * again.
 809 * 
 810 * @param sockpar      Socket parameter block.
 811 */
 812static void tcpip_try_send_data(T_sockpar *sockpar)
 813{
 814  U16 length ;                  /* Length of data to send or sent. */
 815  T_RNET_RET retval ;           /* Return value of rnet_send(). */
 816  
 817  TRACE_FUNCTION("tcpip_try_send_data()") ;
 818  
 819  if (sockpar->send.total_length EQ 0)
 820  {
 821    TRACE_ERROR("tcpip_try_send_data: called although no data present") ;
 822  }
 823  else
 824  {
 825    length = sockpar->send.total_length - sockpar->send.offset ;
 826    TRACE_EVENT_P2("Calling rnet_send() socket %d length %d",
 827                   sockpar->s_index, length) ;
 828    retval = rnet_send(sockpar->rtdesc, sockpar->send.buffer, &length) ;
 829    TRACE_EVENT_P2("rnet_send() returns %d length %d", retval, length) ;
 830    switch (retval)
 831    {
 832      case RNET_OK:             /* We could send all data, so clear send
 833                                 * buffer and send a confirmation to the
 834                                 * application. */
 835        tcpip_clear_send_buffer(sockpar) ;
 836        tcpip_data_cnf(sockpar->app_handle, TCPIP_RESULT_OK,
 837                       sockpar->s_index, TCPIP_DEFAULT_WINDOW) ;
 838        break ;
 839      case RNET_PARTIAL_SENT:   /* Not all of the data could be sent. We
 840                                 * update the send buffer offset and wait for
 841                                 * an RNET_SEND_RDY event to continue. */
 842        sockpar->send.offset += length ;
 843        break ;
 844      default:                  /* Every other return value indicates an
 845                                 * error. We translate the return value to our
 846                                 * result codes and send an error indication
 847                                 * to the application. The data will no longer
 848                                 * be needed and is freed. */
 849        tcpip_clear_send_buffer(sockpar) ;
 850        tcpip_data_cnf(sockpar->app_handle,
 851                       rnet_error_to_tcpip_result(retval),
 852                       sockpar->s_index, TCPIP_DEFAULT_WINDOW) ;
 853        break ;
 854    }
 855  }
 856}
 857
 858
 859/** Initialize RNET and the data of the TCPIP entity.
 860 *
 861 * This in a separate function to make control flow more elegant -- this way
 862 * we can jump out of the initialization sequence without having to use a
 863 * goto.
 864 * 
 865 * @return a result code with the usual semantics
 866 */
 867static U8 tcpip_do_initialization(void)
 868{
 869  static T_RVF_MB_ID   entity_bk_id_table[8];
 870  static T_RV_RETURN_PATH entity_return_pathes[8];
 871  T_RNET_RET retval ;           /* Return value of RNET initialisation. */
 872
 873  TRACE_FUNCTION("tcpip_do_initialization()") ;
 874
 875  if (tcpip_data->is_initialized)
 876  {
 877    TRACE_ERROR("initialization called although tcpip_data->is_initialized") ;
 878    return TCPIP_RESULT_INTERNAL_ERROR ;
 879  }
 880
 881  memset(sock_table,0,sizeof(sock_table));
 882  
 883  /* quite ad-hoc: both arrays "entity_return_pathes",
 884    "entity_bk_id_table" are uninitialized and arbitrarily set to length
 885    8. last param, call_back_error_ft function, undefined. */
 886  rnet_rt_set_info((T_RVF_ADDR_ID) tcpip_handle, entity_return_pathes,
 887                   entity_bk_id_table, 0);
 888
 889  retval = (T_RNET_RET)rnet_rt_init() ;
 890  if (retval NEQ RNET_OK )
 891  {
 892    TRACE_ERROR("rnet_rt_init() != RV_OK") ;
 893    return rnet_error_to_tcpip_result(retval) ;
 894  }
 895
 896  retval = (T_RNET_RET)rnet_rt_start() ;
 897  if (retval NEQ RNET_OK )
 898  {
 899    TRACE_ERROR("rnet_rt_start() != RV_OK") ;
 900    rnet_rt_kill() ;
 901    return rnet_error_to_tcpip_result(retval) ;
 902  }
 903
 904#ifdef _SIMULATION_
 905  tcpip_if_properties(&rnet_rt_env_ctrl_blk_p->ifnet_lo) ;
 906#endif  /* _SIMULATION_ */
 907
 908  tcpip_data->is_initialized = TRUE ;
 909
 910  return TCPIP_RESULT_OK ;
 911}
 912
 913
 914
 915
 916/** Mark an event as expected for the specified socket.
 917 * 
 918 * @param sock_desc          The Socket descriptor.
 919 * @param expected_event     The event type.
 920 */
 921static void socket_expect_event(T_RNET_DESC* sock_desc, U32 expected_event)
 922{
 923#ifdef TRACING
 924  char *event_name ;
 925  
 926  switch (expected_event)
 927  {
 928    case TCPIP_EVT_CONNECT_CNF:
 929      event_name = "CONNECT_CNF" ;
 930      break ;
 931    case TCPIP_EVT_RECV_IND:
 932      event_name = "RECV_IND" ;
 933      break ;
 934    case TCPIP_EVT_CONNECT_IND:
 935      event_name = "CONNECT_IND" ;
 936      break ;
 937    default:
 938      event_name = "<none>" ;
 939      break ;
 940  }
 941  TRACE_EVENT_P1("ready for TCPIP_EVT_%s for %d",
 942                 event_name, SOCK_S_INDEX(sock_desc)) ;
 943#endif /* TRACING */
 944  SOCKPAR_GET(sock_desc)->expected_event = expected_event ;
 945}
 946
 947
 948
 949/*==== Specific event handler functions =====================================*/
 950
 951
 952/** Handle an RNET_CONNECT_IND event; pass it through to the application.
 953 * 
 954 * @param connect_ind    Pointer to the event message.
 955 */
 956static void tcpip_handle_rnet_connect_ind(T_RNET_CONNECT_IND *connect_ind)
 957{
 958  T_sockpar *sockpar, *sp_new ;
 959
 960  TRACE_FUNCTION("tcpip_handle_rnet_connect_ind()") ;
 961
 962  sockpar = SOCKPAR_GET(connect_ind->listen_desc) ;
 963  sp_new = sockpar_new(connect_ind->new_desc,
 964                       sockpar->app_handle,
 965                       sockpar->ipproto, 0) ;
 966  if (sp_new EQ NULL)
 967  {
 968    tcpip_error_ind(sockpar->app_handle, TCPIP_RESULT_INTERNAL_ERROR,
 969                    sockpar->s_index) ;
 970  }
 971  else
 972  {
 973    sp_new->is_connected = TRUE ;
 974    rnet_set_user_data(connect_ind->new_desc, (void *) sp_new) ;
 975    tcpip_connect_ind(sockpar->app_handle,
 976                      sockpar->s_index,
 977                      sp_new->s_index,
 978                      connect_ind->peer_addr,
 979                      connect_ind->peer_port) ;
 980    socket_expect_event(connect_ind->new_desc, TCPIP_EVT_RECV_IND) ;
 981  }
 982  rvf_free_buf(connect_ind) ;
 983}
 984
 985
 986/** Handle an RNET_CONNECT_CFM event; pass it through to the application.
 987 * 
 988 * @param connect_cfm    Pointer to the event message.
 989 */
 990static void tcpip_handle_rnet_connect_cfm(T_RNET_CONNECT_CFM *connect_cfm)
 991{
 992  T_sockpar *sockpar ;
 993
 994  TRACE_FUNCTION("tcpip_handle_rnet_connect_cfm()") ;
 995  
 996  sockpar = SOCKPAR_GET(connect_cfm->desc) ;
 997  sockpar->is_connected = TRUE ;
 998  tcpip_connect_cnf(sockpar->app_handle,
 999                    TCPIP_RESULT_OK, SOCK_S_INDEX(connect_cfm->desc)) ;
1000  socket_expect_event(connect_cfm->desc, TCPIP_EVT_RECV_IND) ;
1001  rvf_free_buf(connect_cfm) ;
1002}
1003
1004
1005/** Handle an RNET_SEND_RDY event; try to send more data if anything is left.
1006 * 
1007 * @param send_rdy    Pointer to the event message.
1008 */
1009static void tcpip_handle_rnet_send_rdy(T_RNET_SEND_RDY *send_rdy)
1010{
1011  T_sockpar *sockpar ;
1012
1013  TRACE_FUNCTION("tcpip_handle_rnet_send_rdy()") ;
1014
1015  sockpar = SOCKPAR_GET(send_rdy->desc) ;
1016  if( sockpar )
1017  {
1018    if (sockpar->send.total_length)
1019    {
1020      tcpip_try_send_data(sockpar) ;
1021    }
1022    else
1023    {
1024      TRACE_EVENT("received RNET_SEND_RDY; no data waiting") ;
1025    }
1026  }else
1027    TRACE_ERROR("tcpip_handle_rnet_send_rdy(): WARNING: sockpar=0");
1028
1029  rvf_free_buf(send_rdy) ;
1030}
1031
1032
1033/** Handle an RNET_RECV_IND event; read incoming data.
1034 * 
1035 * @param recv_ind    Pointer to the event message.
1036 */
1037static void tcpip_handle_rnet_recv_ind(T_RNET_RECV_IND *recv_ind)
1038{
1039  T_sockpar *sockpar ;      /* Socket parameters. */
1040
1041  TRACE_FUNCTION("tcpip_handle_rnet_recv_ind()") ;
1042
1043  sockpar = SOCKPAR_GET(recv_ind->desc) ;
1044  sockpar->recv_waiting = TRUE ;
1045  tcpip_read_incoming_to_app(sockpar) ;
1046
1047  rvf_free_buf(recv_ind) ;
1048}
1049
1050
1051/** Handle an RNET_ERROR_IND event; 
1052 * 
1053 * @param error_ind    Pointer to the event message.
1054 */
1055static void tcpip_handle_rnet_error_ind(T_RNET_ERROR_IND *error_ind)
1056{
1057  T_sockpar *sockpar ;
1058
1059  TRACE_FUNCTION("tcpip_handle_rnet_error_ind()") ;
1060  TRACE_EVENT_P1("RNET_ERROR_IND for socket %08x", error_ind->desc) ;
1061    
1062  sockpar = SOCKPAR_GET(error_ind->desc) ;
1063  if (error_ind->error EQ RNET_CONN_CLOSED)
1064  {
1065    TRACE_EVENT("RNET_CONN_CLOSED") ;
1066    tcpip_conn_closed_ind(sockpar->app_handle, sockpar->s_index) ;
1067  }
1068  else
1069  {
1070    /* TODO: this switch looks bogus -- we are only interested in
1071     * TCPIP_EVT_CONNECT_CNF, right? Everything else is handled the same
1072     * anyway. */
1073    switch (sockpar->expected_event)
1074    {
1075      case TCPIP_EVT_CONNECT_CNF:
1076        TRACE_EVENT("error received when expecting TCPIP_EVT_CONNECT_CNF") ;
1077        tcpip_connect_cnf(sockpar->app_handle,
1078                          rnet_error_to_tcpip_result(error_ind->error),
1079                          sockpar->s_index) ;
1080        break ;
1081      case TCPIP_EVT_RECV_IND:
1082        TRACE_EVENT("error received when expecting TCPIP_EVT_RECV_IND") ;
1083        tcpip_error_ind(sockpar->app_handle,
1084                        rnet_error_to_tcpip_result(error_ind->error),
1085                        sockpar->s_index) ;
1086        break ;
1087      case TCPIP_EVT_CONNECT_IND:
1088        TRACE_EVENT("error received when expecting TCPIP_EVT_CONNECT_IND") ;
1089        tcpip_error_ind(sockpar->app_handle,
1090                        rnet_error_to_tcpip_result(error_ind->error),
1091                        sockpar->s_index) ;
1092        break ;
1093      default:
1094        TRACE_EVENT_P1("error received when expecting unknown event (%d)?",
1095                       sockpar->expected_event) ;
1096        TRACE_ERROR("Unexpected sockpar->expected_event in "
1097                    "tcpip_handle_rnet_error_ind()") ;
1098        tcpip_error_ind(sockpar->app_handle,
1099                        rnet_error_to_tcpip_result(error_ind->error),
1100                        sockpar->s_index) ;
1101        break ;
1102    }
1103  }
1104
1105  rvf_free_buf(error_ind) ;
1106}
1107
1108
1109
1110/*==== Callback functions ===================================================*/
1111
1112
1113/** Callback for rnet_get_host_info().
1114 * 
1115 * @param 
1116 * @return 
1117 */
1118void tcpip_hostinfo_callback(void *msg)
1119{
1120  T_RNET_HOST_INFO *hinfo ;
1121  T_TCPIP_HOSTINFO_REQ *request ;
1122
1123  TRACE_FUNCTION("tcpip_hostinfo_callback()") ;
1124
1125  hinfo = msg ;
1126  request = hinfo->user_data ;
1127  switch (hinfo->error)
1128  {
1129    case RNET_OK:
1130      tcpip_hostinfo_cnf(request->app_handle,
1131                         TCPIP_RESULT_OK,
1132                         request->request_id,
1133                         hinfo->host_name,
1134                         ngHTONL(hinfo->host_addr)) ;
1135      break ;
1136    default:
1137      tcpip_hostinfo_cnf(request->app_handle,
1138                         rnet_error_to_tcpip_result(hinfo->error),
1139                         request->request_id,
1140                         NULL,
1141                         0) ;
1142      break ;
1143  }
1144  PFREE(request) ;
1145  //PatternVibrator("o20f10", 1);
1146  //rvf_free_buf(msg) ;
1147  //PatternVibrator("o20f10", 1);
1148}
1149
1150
1151/** Callback for RNET events.
1152 * 
1153 * @param rv_msg    Pointer to Riviera message.
1154 */
1155static void tcpip_rnet_callback(void *rv_msg)
1156{
1157  T_RV_HDR *rv_hdr ;            /* Header of Riviera message. */
1158  rv_hdr = (T_RV_HDR *) rv_msg ;
1159
1160  TRACE_FUNCTION("tcpip_rnet_callback()") ;
1161  TRACE_EVENT_P1("rv_hdr->msg_id = %d",rv_hdr->msg_id);
1162
1163  switch (rv_hdr->msg_id)
1164  {
1165    case RNET_CONNECT_IND:
1166      TRACE_EVENT("tcpip_rnet_callback() called with RNET_CONNECT_IND") ;
1167      tcpip_handle_rnet_connect_ind((T_RNET_CONNECT_IND *) rv_hdr) ;
1168      break ;
1169    case RNET_CONNECT_CFM:
1170      TRACE_EVENT("tcpip_rnet_callback() called with RNET_CONNECT_CFM") ;
1171      tcpip_handle_rnet_connect_cfm((T_RNET_CONNECT_CFM *) rv_hdr) ;
1172      break ;
1173    case RNET_SEND_RDY:
1174      TRACE_EVENT("tcpip_rnet_callback() called with RNET_SEND_RDY") ;
1175      tcpip_handle_rnet_send_rdy((T_RNET_SEND_RDY *) rv_hdr) ;
1176      break ;
1177    case RNET_RECV_IND:
1178      TRACE_EVENT("tcpip_rnet_callback() called with RNET_RECV_IND") ;
1179      tcpip_handle_rnet_recv_ind((T_RNET_RECV_IND *) rv_hdr) ;
1180      break ;
1181    case RNET_ERROR_IND:
1182      TRACE_EVENT("tcpip_rnet_callback() called with RNET_ERROR_IND") ;
1183      tcpip_handle_rnet_error_ind((T_RNET_ERROR_IND *) rv_hdr) ;
1184      break ;
1185    default:
1186      TRACE_ERROR("Default: unknown RNET event:") ;
1187      TRACE_EVENT_P1("[ERROR] event 0x%08x from RNET\n", rv_hdr->msg_id) ;
1188      break ;
1189  }
1190}
1191
1192
1193/*==== Other public functions ===============================================*/
1194
1195/** Shut down RNET and deallocate data. This defined as a separate function
1196 * because it will also be called by pei_exit().
1197 * 
1198 */
1199void tcpip_do_shutdown(void)
1200{
1201  int s_index ;                 /* Socket index in sock_table[]. */
1202
1203  TRACE_FUNCTION("tcpip_do_shutdown()") ;
1204
1205  if (tcpip_data->is_initialized)
1206  {
1207    /* The error code conversion is done only for the trace in
1208     * rnet_error_to_tcpip_result(). It doesn't hurt anyway. */
1209    rnet_error_to_tcpip_result((T_RNET_RET)rnet_rt_stop()) ;
1210    rnet_error_to_tcpip_result((T_RNET_RET)rnet_rt_kill()) ;
1211
1212    for (s_index = 0; s_index < RNET_RT_SOCK_MAX; s_index++)
1213    {
1214      T_sockpar *sp ;           /* Pointer to socket parameter struct. */
1215
1216      sp = sock_table[s_index] ;
1217      if (sp)
1218      {
1219        tcpip_error_ind(sp->app_handle, TCPIP_RESULT_NETWORK_LOST,
1220                        sp->s_index) ;
1221        sockpar_delete(sp) ;
1222      }
1223    }
1224    tcpip_data->is_initialized = FALSE ;
1225  }
1226}
1227
1228
1229
1230
1231/*==== Primitive handler functions ==========================================*/
1232
1233
1234/** Handle a TCPIP_INITIALIZE_REQ primitive from the Socket API.
1235 * 
1236 * @param primdata   Data part of the primitive.
1237 */
1238void tcpip_initialize_req(void *primdata)
1239{
1240  U8 result ;                   /* Result code of initialization. */
1241  
1242  TRACE_FUNCTION("tcpip_initialize_req()") ;
1243
1244  /* The variable should be optimized away by the compiler, but it looks
1245   * clearer with the initialization call on a separate line.
1246   */
1247  result = tcpip_do_initialization() ;
1248  tcpip_initialize_cnf(result) ;
1249  PFREE(primdata) ;
1250}
1251
1252
1253/** Handle a TCPIP_SHUTDOWN_REQ primitive from the Socket API.
1254 * 
1255 * @param primdata   Data part of the primitive.
1256 */
1257void tcpip_shutdown_req(void *primdata)
1258{
1259  TRACE_FUNCTION("tcpip_shutdown_req()") ;
1260
1261  tcpip_do_shutdown() ;
1262  tcpip_shutdown_cnf(TCPIP_RESULT_OK) ;
1263  PFREE(primdata) ;
1264}
1265
1266
1267/** Handle a TCPIP_IFCONFIG_REQ primitive from the Socket API.
1268 * 
1269 * @param primdata   Data part of the primitive.
1270 */
1271void tcpip_ifconfig_req(void *primdata)
1272{
1273  T_TCPIP_IFCONFIG_REQ *prim ;
1274  NGifnet *netp ;               /* Pointer to network interface struct. */
1275  NGuint local_addr ;           /* Local address of interface (host byte
1276                                 * order). */
1277  NGuint dest_addr ;            /* Destination address (always zero in our
1278                                 * case). */
1279  NGuint netmask ;
1280  U8 result = TCPIP_RESULT_INTERNAL_ERROR ; /* Result code of operation. */
1281
1282  /* We don't jump through all the hoops of constructing a message in a
1283   * message and sending it to the network interface control function, but
1284   * rather twiddle the necessary bits by ourselves. This saves quite some
1285   * code and is lots easier to read. */
1286  TRACE_FUNCTION("tcpip_ifconfig_req()") ;
1287
1288  prim = (T_TCPIP_IFCONFIG_REQ *) primdata ;
1289
1290  /* First, find the network interface. This turned out to be surprisingly
1291   * easy. :-) */
1292  netp = &rnet_rt_env_ctrl_blk_p->ifnet_dti.dti_ifnet ;
1293  
1294  switch (prim->if_up)
1295  {
1296    case TCPIP_IFCONFIG_DOWN:
1297      TRACE_EVENT("ifconfig down") ;
1298      netp->if_flags &= ~NG_IFF_UP ;
1299      /* Lint loves the void: */
1300      (void) ngProto_IP.pr_cntl_f(NG_CNTL_SET, NG_IPO_NETDOWN, netp) ;
1301      result = TCPIP_RESULT_OK ;
1302      break ;
1303    case TCPIP_IFCONFIG_UP:
1304      netp->if_flags |= NG_IFF_UP ;
1305      netp->if_mtu = prim->mtu_size ;
1306      local_addr = prim->ipaddr ;
1307      dest_addr = TCPIP_UNSPECIFIED_IPADDR ;
1308      netmask = 0xffffffff ;
1309
1310      if (tcpip_data->config_dns_address)
1311      {
1312        TRACE_EVENT("override dnsaddr1 by address from config primitive") ;
1313        prim->dnsaddr1 = tcpip_data->config_dns_address ;
1314      }        
1315
1316      TRACE_EVENT_P3("ifconfig %08x dns %08x, %08x up",
1317                     ngNTOHL(local_addr),
1318                     ngNTOHL(prim->dnsaddr1), ngNTOHL(prim->dnsaddr2)) ;
1319      
1320      ngIfGenCntl(netp, NG_CNTL_SET, NG_IFO_ADDR, &local_addr) ;
1321      ngIfGenCntl(netp, NG_CNTL_SET, NG_IFO_DSTADDR, &dest_addr) ;
1322      ngIfGenCntl(netp, NG_CNTL_GET, NG_IFO_NETMASK, &netmask) ;
1323      (void) ngProto_IP.pr_cntl_f(NG_CNTL_SET, NG_IPO_ROUTE_DEFAULT,
1324                                  &local_addr);
1325      (void) ngProto_RESOLV.pr_cntl_f(NG_CNTL_SET, NG_RSLVO_SERV1_IPADDR,
1326                                      &prim->dnsaddr1) ;
1327      (void) ngProto_RESOLV.pr_cntl_f(NG_CNTL_SET, NG_RSLVO_SERV2_IPADDR,
1328                                      &prim->dnsaddr2) ;
1329      result = TCPIP_RESULT_OK ;
1330      break ;
1331    default:
1332      TRACE_ERROR("ifconfig: bogus prim->if_up value") ;
1333      result = TCPIP_RESULT_INVALID_PARAMETER ;
1334      break ;
1335  }
1336
1337#ifdef _SIMULATION_
1338  tcpip_if_properties(netp) ;
1339#endif  /* _SIMULATION_ */
1340  
1341  tcpip_ifconfig_cnf(result) ;
1342  PFREE(primdata) ;
1343}
1344
1345
1346/** Handle a TCPIP_DTI_REQ primitive from the Socket API.
1347 * 
1348 * @param primdata   Data part of the primitive.
1349 */
1350void tcpip_dti_req(void *primdata)
1351{
1352  T_TCPIP_DTI_REQ *prim ;
1353
1354  TRACE_FUNCTION("tcpip_dti_req()") ;
1355
1356  prim = (T_TCPIP_DTI_REQ *) primdata ;
1357  if (prim->dti_direction EQ TCPIP_DTI_TO_LOWER_LAYER)
1358  {
1359    tcpip_data->ll[0].link_id = prim->link_id ;
1360
1361    if(prim->dti_conn == TCPIP_CONNECT_DTI)
1362    {
1363      if(dti_open(tcpip_data->dti_handle,
1364                  0,  /* instance */
1365                  prim->dti_direction, 
1366                  0,                /* channel */
1367                  TCPIP_DTI_QUEUE_SIZE, 
1368                  prim->dti_direction, 
1369                  DTI_QUEUE_WATERMARK,
1370                  DTI_VERSION_10,
1371#ifdef _SIMULATION_
1372                  "SND",
1373#else
1374                  (U8 *) prim->entity_name,
1375#endif
1376                  prim->link_id) != TRUE)
1377	    {
1378        TRACE_ERROR("dti_open returns with error") ;
1379	    }
1380    }
1381    else
1382    {
1383      dti_close(tcpip_data->dti_handle,0,prim->dti_direction,0,FALSE);
1384      // TCPIP_DISCONNECT_CNF is sent here, because the DTI callback is not called
1385      // after DTI2_DISCONNECT_REQ was sent (no CNF-primitive)
1386      tcpip_dti_cnf(TCPIP_DISCONNECT_DTI,prim->link_id);
1387    }
1388  }
1389  else
1390  {
1391    TRACE_ERROR("DTI link to other than upper layer not (yet) supported!") ;
1392  }    
1393  /* The result will be signalled by DTI. */
1394  PFREE(primdata) ;
1395}
1396
1397
1398/** Handle a TCPIP_CREATE_REQ primitive from the Socket API.
1399 * 
1400 * @param primdata   Data part of the primitive.
1401 */
1402void tcpip_create_req(void *primdata)
1403{
1404  T_TCPIP_CREATE_REQ *prim = primdata ;
1405  T_RNET_RET retval ;
1406  T_RNET_DESC *sdesc ;          /* The socket descriptor. */
1407  T_RV_RETURN_PATH retpath = { 0, tcpip_rnet_callback } ;
1408  T_sockpar *sockpar ;          /* Pointer to socket parameter struct ; */
1409
1410  TRACE_FUNCTION("tcpip_create_req()") ;
1411  
1412  TRACE_EVENT_P1("Calling rnet_new() for ipproto %d", prim->ipproto) ;
1413  retval = rnet_new((T_RNET_IPPROTO) prim->ipproto, &sdesc, retpath) ;
1414  TRACE_EVENT_P1("rnet_new() returns %d", retval) ;
1415
1416  if (retval EQ RNET_OK)
1417  {
1418    sockpar = sockpar_new(sdesc, prim->app_handle, prim->ipproto, 0) ;
1419    TRACE_EVENT_P1("New socket is %d", sockpar->s_index) ;
1420    if (sockpar EQ NULL)
1421    {
1422      tcpip_create_cnf(prim->app_handle, TCPIP_RESULT_INTERNAL_ERROR,
1423                       0, prim->request_id) ;
1424      rnet_close(sdesc) ;
1425    }
1426    else
1427    {
1428      rnet_set_user_data(sdesc, (void *) sockpar) ;
1429      tcpip_create_cnf(prim->app_handle, TCPIP_RESULT_OK,
1430                       sockpar->s_index, prim->request_id) ;
1431    }
1432  }
1433  else
1434  {
1435    tcpip_create_cnf(prim->app_handle, rnet_error_to_tcpip_result(retval),
1436                     0, prim->request_id) ;
1437  }
1438  PFREE(primdata) ;
1439}
1440
1441
1442/** Handle a TCPIP_CLOSE_REQ primitive from the Socket API.
1443 * 
1444 * @param primdata   Data part of the primitive.
1445 */
1446void tcpip_close_req(void *primdata)
1447{
1448  T_TCPIP_CLOSE_REQ *prim = primdata ;
1449  T_RNET_RET retval ;           /* Return value of rnet_close(). */
1450  T_sockpar *sockpar ;          /* Socket parameter block. */
1451  T_RNET_DESC *sdesc ;          /* Socket descriptor. */
1452
1453  TRACE_FUNCTION("tcpip_close_req()") ;
1454  if (INVALID_S_INDEX(prim->socket))
1455  {
1456    TRACE_ERROR("Invalid socket index in tcpip_close_req()") ;
1457    tcpip_close_cnf(prim->app_handle, TCPIP_RESULT_INVALID_PARAMETER,
1458                    prim->socket) ;
1459  }
1460  else
1461  {
1462    sdesc = SOCK_RT_DESC(prim->socket) ;
1463    sockpar = SOCKPAR_GET(sdesc) ;
1464    TRACE_EVENT_P1("Calling rnet_close() for socket %d", sockpar->s_index) ;
1465    retval = rnet_close(sdesc) ;
1466    TRACE_EVENT_P1("rnet_close() returns %d", retval) ;
1467    tcpip_close_cnf(prim->app_handle,
1468                    (U8) ((retval EQ RNET_OK) ?
1469                          TCPIP_RESULT_OK : rnet_error_to_tcpip_result(retval)),
1470                    prim->socket) ;
1471    sockpar_delete(sockpar) ;
1472  }
1473  PFREE(primdata) ;
1474}
1475
1476
1477/** Handle a TCPIP_BIND_REQ primitive from the Socket API.
1478 * 
1479 * @param primdata   Data part of the primitive.
1480 */
1481void tcpip_bind_req(void *primdata)
1482{
1483  T_TCPIP_BIND_REQ *prim = primdata ;
1484  T_RNET_RET retval ;           /* Return value of rnet_bind(). */
1485  T_RNET_DESC *sdesc ;          /* Socket descriptor. */
1486
1487  TRACE_FUNCTION("tcpip_bind_req()") ;
1488  if (INVALID_S_INDEX(prim->socket))
1489  {
1490    TRACE_ERROR("Invalid socket index in tcpip_bind_req()") ;
1491    tcpip_bind_cnf(prim->app_handle, TCPIP_RESULT_INVALID_PARAMETER,
1492                   prim->socket) ;
1493  }
1494  else
1495  {
1496    sdesc = SOCK_RT_DESC(prim->socket) ;
1497    TRACE_EVENT_P2("Calling rnet_bind() for socket %d port %d",
1498                   prim->socket, prim->port) ;
1499    retval = rnet_bind(sdesc, TCPIP_UNSPECIFIED_IPADDR,
1500                       (U16) ngNTOHS(prim->port)) ;
1501    TRACE_EVENT_P1("rnet_bind() returns %d", retval) ;
1502    tcpip_bind_cnf(prim->app_handle,
1503                   (U8) ((retval EQ RNET_OK) ?
1504                         TCPIP_RESULT_OK : rnet_error_to_tcpip_result(retval)),
1505                   prim->socket) ;
1506  }
1507  PFREE(primdata) ;
1508}
1509
1510
1511/** Handle a TCPIP_LISTEN_REQ primitive from the Socket API.
1512 * 
1513 * @param primdata   Data part of the primitive.
1514 */
1515void tcpip_listen_req(void *primdata)
1516{
1517  T_TCPIP_LISTEN_REQ *prim = primdata ;
1518  T_RNET_RET retval ;           /* Return value of rnet_listen(). */
1519  T_RNET_DESC *sdesc ;          /* Socket descriptor. */
1520
1521  TRACE_FUNCTION("tcpip_listen_req()") ;
1522  if (INVALID_S_INDEX(prim->socket))
1523  {
1524    TRACE_ERROR("Invalid socket index in tcpip_listen_req()") ;
1525    tcpip_listen_cnf(prim->app_handle, TCPIP_RESULT_INVALID_PARAMETER,
1526                    prim->socket) ;
1527  }
1528  else
1529  {
1530    sdesc = SOCK_RT_DESC(prim->socket) ;
1531    TRACE_EVENT_P1("Calling rnet_listen() for socket %d", prim->socket) ;
1532    retval = rnet_listen(sdesc) ;
1533    TRACE_EVENT_P1("rnet_listen() returns %d", retval) ;
1534    switch (retval)
1535    {
1536      case RNET_OK:
1537        socket_expect_event(sdesc, TCPIP_EVT_CONNECT_IND) ;
1538        tcpip_listen_cnf(prim->app_handle, TCPIP_RESULT_OK, prim->socket) ;
1539        break ;
1540      default:
1541        tcpip_listen_cnf(prim->app_handle, rnet_error_to_tcpip_result(retval),
1542                         prim->socket) ;
1543        break ;
1544    }
1545  }
1546  PFREE(primdata) ;
1547}
1548
1549
1550/** Handle a TCPIP_CONNECT_REQ primitive from the Socket API.
1551 * 
1552 * @param primdata   Data part of the primitive.
1553 */
1554void tcpip_connect_req(void *primdata)
1555{
1556  T_TCPIP_CONNECT_REQ *prim = primdata ;
1557  T_RNET_RET retval ;           /* Return value of rnet_connect(). */
1558  T_RNET_DESC *sdesc ;          /* Socket descriptor. */
1559  T_sockpar *sockpar ;          /* Socket parameter block. */
1560
1561  TRACE_FUNCTION("tcpip_connect_req()") ;
1562  if (INVALID_S_INDEX(prim->socket))
1563  {
1564    TRACE_ERROR("Invalid socket index in tcpip_connect_req()") ;
1565    tcpip_connect_cnf(prim->app_handle, TCPIP_RESULT_INVALID_PARAMETER,
1566                    prim->socket) ;
1567  }
1568  else
1569  {
1570    sdesc = SOCK_RT_DESC(prim->socket) ;
1571    socket_expect_event(sdesc, TCPIP_EVT_CONNECT_CNF) ;
1572    TRACE_EVENT_P3("Calling rnet_connect() for socket %d ipaddr %x port %d",
1573                   prim->socket, ngNTOHL(prim->ipaddr),
1574                   ngNTOHS(prim->port)) ;
1575    retval = rnet_connect(sdesc, ngNTOHL(prim->ipaddr),
1576                          (U16) ngNTOHS(prim->port)) ;
1577    TRACE_EVENT_P1("rnet_connect() returns %d", retval) ;
1578
1579    sockpar = SOCKPAR_GET(sdesc) ;
1580    switch (sockpar->ipproto)
1581    {
1582      case TCPIP_IPPROTO_TCP:
1583        if (retval EQ RNET_OK)
1584        {
1585          TRACE_EVENT("wait... TCPIP_CONNECT_CNF");
1586          /* Wait for the result of the connect; we will send a
1587           * TCPIP_CONNECT_CNF then. */
1588        }
1589        else
1590        {
1591          tcpip_connect_cnf(prim->app_handle,
1592                            rnet_error_to_tcpip_result(retval), prim->socket) ;
1593          socket_expect_event(sdesc, 0) ;
1594        }
1595        break ;
1596      case TCPIP_IPPROTO_UDP:
1597        sockpar->is_connected = TRUE ;
1598        tcpip_conne

Large files files are truncated, but you can click here to view the full file