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