comparison src/g23m-fad/tcpip/tcpip_api_layer.c @ 1:fa8dc04885d8

src/g23m-*: import from Magnetite
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 16 Oct 2020 06:25:50 +0000
parents
children
comparison
equal deleted inserted replaced
0:4e78acac3d88 1:fa8dc04885d8
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 */
103 typedef 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 */
142 static 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 */
153 static 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 */
169 static 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 */
185 static 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 */
204 void 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 */
224 static 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 */
247 static 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 */
267 static 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 */
287 static 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 */
307 static 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 */
328 static 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 */
354 static 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 */
381 static 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 */
406 static 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 */
431 static 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 */
463 static 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 */
487 static 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 */
510 static 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 */
530 static 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 */
549 void 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 */
574 static 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 */
615 static 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 */
630 static 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 */
649 static 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 */
719 static 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 */
812 static 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 */
867 static 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 */
921 static 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 */
956 static 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 */
990 static 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 */
1009 static 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 */
1037 static 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 */
1055 static 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 */
1118 void 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 */
1155 static 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 */
1199 void 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 */
1238 void 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 */
1257 void 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 */
1271 void 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 */
1350 void 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 */
1402 void 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 */
1446 void 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 */
1481 void 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 */
1515 void 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 */
1554 void 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_connect_cnf(prim->app_handle, rnet_error_to_tcpip_result(retval),
1599 prim->socket) ;
1600 socket_expect_event(sdesc, 0) ;
1601 break ;
1602 default:
1603 TRACE_ERROR("unknown protocol in tcpip_connect_req()!?") ;
1604 break ;
1605 }
1606 }
1607 PFREE(primdata) ;
1608 }
1609
1610
1611 /** Handle a TCPIP_DATA_REQ primitive from the Socket API.
1612 *
1613 * @param primdata Data part of the primitive.
1614 */
1615 void tcpip_data_req(void *primdata)
1616 {
1617 T_TCPIP_DATA_REQ *prim = primdata ;
1618 T_sockpar *sockpar ;
1619 T_RNET_DESC *sdesc ; /* Socket descriptor. */
1620
1621 TRACE_FUNCTION("tcpip_data_req()") ;
1622 if (INVALID_S_INDEX(prim->socket))
1623 {
1624 tcpip_data_cnf(prim->app_handle, TCPIP_RESULT_INVALID_PARAMETER,
1625 prim->socket, 0) ;
1626 TRACE_ERROR("Invalid socket index in tcpip_data_req()") ;
1627 }
1628 else
1629 {
1630 sdesc = SOCK_RT_DESC(prim->socket) ;
1631 sockpar = SOCKPAR_GET(sdesc) ;
1632
1633 if (sockpar->send.total_length)
1634 {
1635 /* We haven't sent the previous block completely, but the API already
1636 * sends more data. That must be an error -- either an error of the
1637 * socket API or we have sent out a TCPIP_DATA_CNF too early. */
1638 TRACE_ERROR("tcpip_data_req: new data although old data is still left") ;
1639 tcpip_data_cnf(prim->app_handle, TCPIP_RESULT_INTERNAL_ERROR,
1640 prim->socket, 0) ;
1641 }
1642 else if (!sockpar->is_connected AND
1643 (sockpar->ipproto EQ TCPIP_IPPROTO_TCP
1644 OR prim->ipaddr EQ 0
1645 OR prim->port EQ 0))
1646 {
1647 /* Application tried to send on a non-connected TCP socket or a
1648 * non-connected UDP socket without specifying IP address and port
1649 * number. RNET or, respectively, NexGenIP does for some reason not
1650 * catch this error, so we do it here.
1651 */
1652 tcpip_data_cnf(prim->app_handle, TCPIP_RESULT_NOT_CONNECTED,
1653 prim->socket, 1) ;
1654 }
1655 else /* Finally ok. */
1656 {
1657 sockpar->send.total_length = prim->buflen ;
1658 sockpar->send.offset = 0 ;
1659 #ifdef _SIMULATION_
1660 prim->data = tcpip_sim_fake_data(prim->socket, prim->buflen) ;
1661 #endif /* _SIMULATION_ */
1662 sockpar->send.buffer = (U8 *) prim->data ;
1663 tcpip_try_send_data(sockpar) ;
1664 }
1665 }
1666 PFREE(primdata) ;
1667 }
1668
1669
1670 /** Handle a TCPIP_DATA_RES primitive from the Socket API.
1671 *
1672 * @param primdata Data part of the primitive.
1673 */
1674 void tcpip_data_res(void *primdata)
1675 {
1676 T_TCPIP_DATA_RES *prim = primdata ;
1677 T_sockpar *sockpar ;
1678
1679 TRACE_FUNCTION("tcpip_data_res()") ;
1680 if (INVALID_S_INDEX(prim->socket))
1681 {
1682 /* Do nothing -- what *could* we do in response to a response? */
1683 TRACE_ERROR("Invalid socket index in tcpip_data_res()") ;
1684 }
1685 else
1686 {
1687 TRACE_EVENT("switch flow control towards application to xon") ;
1688 sockpar = sock_table[prim->socket] ;
1689 sockpar->appl_xoff = FALSE ;
1690 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
1691 // OMAPS00172999 fix
1692 if (sockpar->recv_waiting)
1693 {
1694 tcpip_read_incoming_to_app(sockpar) ;
1695 }
1696 }
1697 PFREE(primdata) ;
1698 }
1699
1700
1701 /** Handle a TCPIP_SOCKNAME_REQ primitive from the Socket API.
1702 *
1703 * @param primdata Data part of the primitive.
1704 */
1705 void tcpip_sockname_req(void *primdata)
1706 {
1707 T_TCPIP_SOCKNAME_REQ *prim = primdata ;
1708 T_RNET_RET retval ;
1709 T_RNET_IP_ADDR ipaddr ;
1710 T_RNET_PORT port ;
1711 T_RNET_DESC *sdesc ; /* The socket descriptor. */
1712
1713 TRACE_FUNCTION("tcpip_sockname_req()") ;
1714 if (INVALID_S_INDEX(prim->socket))
1715 {
1716 TRACE_ERROR("Invalid socket index in tcpip_sockname_req()") ;
1717 tcpip_sockname_cnf(prim->app_handle, TCPIP_RESULT_INVALID_PARAMETER,
1718 prim->socket, TCPIP_UNSPECIFIED_IPADDR,
1719 TCPIP_UNSPECIFIED_PORT) ;
1720 }
1721 else
1722 {
1723 sdesc = SOCK_RT_DESC(prim->socket) ;
1724 TRACE_EVENT_P1("Calling rnet_get_local_addr_port() for socket %d",
1725 prim->socket) ;
1726 retval = rnet_get_local_addr_port(sdesc, &ipaddr, &port) ;
1727 TRACE_EVENT_P3("rnet_get_local_addr_port() returns %d, "
1728 "ipaddr %d port %d", retval, ipaddr, port) ;
1729 switch (retval)
1730 {
1731 case RNET_OK:
1732 tcpip_sockname_cnf(prim->app_handle, TCPIP_RESULT_OK, prim->socket,
1733 ngHTONL(ipaddr), (U16) ngHTONS(port)) ;
1734 break ;
1735 default:
1736 tcpip_sockname_cnf(prim->app_handle, rnet_error_to_tcpip_result(retval),
1737 prim->socket, TCPIP_UNSPECIFIED_IPADDR,
1738 TCPIP_UNSPECIFIED_PORT) ;
1739 break ;
1740 }
1741 }
1742 PFREE(primdata) ;
1743 }
1744
1745
1746 /** Handle a TCPIP_PEERNAME_REQ primitive from the Socket API.
1747 *
1748 * @param primdata Data part of the primitive.
1749 */
1750 void tcpip_peername_req(void *primdata)
1751 {
1752 T_TCPIP_PEERNAME_REQ *prim = primdata ;
1753 T_RNET_RET retval ;
1754 T_RNET_DESC *sdesc ; /* The socket descriptor. */
1755 NGsockaddr addr ; /* Socket address struct. */
1756 int optlen ; /* Length of option (address struct). */
1757
1758 TRACE_FUNCTION("tcpip_peername_req()") ;
1759 if (INVALID_S_INDEX(prim->socket))
1760 {
1761 TRACE_ERROR("Invalid socket index in tcpip_peername_req()") ;
1762 tcpip_peername_cnf(prim->app_handle, TCPIP_RESULT_INVALID_PARAMETER,
1763 prim->socket, TCPIP_UNSPECIFIED_IPADDR,
1764 TCPIP_UNSPECIFIED_PORT) ;
1765 }
1766 else
1767 {
1768 sdesc = SOCK_RT_DESC(prim->socket) ;
1769 optlen = sizeof(addr) ;
1770 TRACE_EVENT_P1("Calling ngSAIOGetOption() for peername socket %d",
1771 prim->socket) ;
1772 retval = (T_RNET_RET) ngSAIOGetOption((NGsock *) sdesc, NG_IOCTL_SOCKET,
1773 NG_SO_PEERNAME, &addr, &optlen) ;
1774 TRACE_EVENT_P3("ngSAIOGetOption() returns %d ipaddr %x port %d (net order)",
1775 retval, addr.sin_addr, addr.sin_port) ;
1776 switch (rnet_rt_ngip_error(retval))
1777 {
1778 case RNET_OK:
1779 tcpip_peername_cnf(prim->app_handle, TCPIP_RESULT_OK, prim->socket,
1780 addr.sin_addr, addr.sin_port) ;
1781 break ;
1782 default:
1783 tcpip_peername_cnf(prim->app_handle, rnet_error_to_tcpip_result(retval),
1784 prim->socket, TCPIP_UNSPECIFIED_IPADDR,
1785 TCPIP_UNSPECIFIED_PORT) ;
1786 break ;
1787 }
1788 }
1789 PFREE(primdata) ;
1790 }
1791
1792
1793 /** Handle a TCPIP_HOSTINFO_REQ primitive from the Socket API.
1794 *
1795 * @param primdata Data part of the primitive.
1796 */
1797 void tcpip_hostinfo_req(void *primdata)
1798 {
1799 T_TCPIP_HOSTINFO_REQ *prim = primdata ;
1800 T_RV_RETURN_PATH retpath = { 0, tcpip_hostinfo_callback } ;
1801
1802 /* Trick: We use the primitive itself as user data for the RNET call. This
1803 * way we do not have to allocate extra memory to save the request_id and
1804 * the app_handle. */
1805
1806 TRACE_FUNCTION("tcpip_hostinfo_req()") ;
1807
1808 switch (rnet_get_host_info((char *) prim->hostname, ngNTOHL(prim->ipaddr),
1809 retpath, primdata))
1810 {
1811 case RNET_OK:
1812 /* We now wait for the hostinfo callback being called. */
1813 break ;
1814 case RNET_MEMORY_ERR:
1815 tcpip_hostinfo_cnf(prim->app_handle, TCPIP_RESULT_OUT_OF_MEMORY,
1816 prim->request_id, NULL, TCPIP_UNSPECIFIED_IPADDR) ;
1817 PFREE(prim) ;
1818 break ;
1819 default: /* Unexpected error code. */
1820 tcpip_hostinfo_cnf(prim->app_handle, TCPIP_RESULT_INTERNAL_ERROR,
1821 prim->request_id, NULL, TCPIP_UNSPECIFIED_IPADDR) ;
1822 PFREE(prim) ;
1823 break ;
1824 }
1825 /* Do *not* PFREE(primdata) -- the primitive is used as userdata for the
1826 * RNET call. */
1827 }
1828
1829
1830 /** Handle a TCPIP_MTU_SIZE_REQ primitive from the Socket API.
1831 *
1832 * @param primdata Data part of the primitive.
1833 */
1834 void tcpip_mtu_size_req(void *primdata)
1835 {
1836 T_TCPIP_MTU_SIZE_REQ *prim = primdata ;
1837
1838 TRACE_FUNCTION("tcpip_mtu_size_req()") ;
1839
1840 if (INVALID_S_INDEX(prim->socket))
1841 {
1842 TRACE_ERROR("Invalid socket index in tcpip_mtu_size_req()") ;
1843 tcpip_mtu_size_cnf(prim->app_handle, TCPIP_RESULT_INVALID_PARAMETER,
1844 prim->socket, TCPIP_DEFAULT_MTU_SIZE) ;
1845 }
1846 else
1847 {
1848 /* The MTU size is usually not negotiated between the network and the
1849 * mobile station. It is guaranteed, though, that it is not less than 1500
1850 * bytes, and that is what we report here. This might be changed to some
1851 * "real" value queried from the interface when the need comes up.
1852 */
1853 tcpip_mtu_size_cnf(prim->app_handle, TCPIP_RESULT_OK, prim->socket,
1854 TCPIP_DEFAULT_MTU_SIZE) ;
1855 }
1856 PFREE(primdata) ;
1857 }
1858
1859
1860 /** Handle a TCPIP_INTERNAL_IND primitive sent by TCPIP itself.
1861 *
1862 * @param primdata Data part of the primitive.
1863 * @return
1864 */
1865 void tcpip_internal_ind(void *primdata)
1866 {
1867 T_TCPIP_INTERNAL_IND *prim = primdata ;
1868 T_RVM_RETURN retval ;
1869
1870 TRACE_FUNCTION("tcpip_internal_ind()") ;
1871
1872 TRACE_EVENT_P1("received TCPIP_INTERNAL_IND id %d", prim->msg_id) ;
1873 retval = rnet_rt_handle_message((T_RV_HDR *) prim->msg_p) ;
1874 if (retval != RV_OK)
1875 {
1876 TRACE_EVENT_P1("rnet_rt_handle_message() returned %d", retval) ;
1877 }
1878 PFREE(primdata) ;
1879 }
1880
1881 /* EOF */