FreeCalypso > hg > fc-tourmaline
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 */ |